From c32089f5ebf77ab3de0d1ccb4206d5df236a1b57 Mon Sep 17 00:00:00 2001 From: rafalense Date: Wed, 8 Jul 2015 20:40:10 +0200 Subject: [PATCH] Update to 3.0.1.6 (576): - Fixed options to share music and stickers - Added option to share contact number - Added option to add member directly from group options - Added option to mute or activate notifications from main screen - Bug fixes --- TMessagesProj/build.gradle | 16 +- 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 | 18 + .../telegram/android/AndroidUtilities.java | 58 +- .../AnimationCompat/AnimatorSetProxy.java | 9 + .../telegram/android/ContactsController.java | 32 +- .../main/java/org/telegram/android/Emoji.java | 29 +- .../org/telegram/android/ImageLoader.java | 17 +- .../org/telegram/android/ImageReceiver.java | 2 +- .../telegram/android/LocaleController.java | 20 +- .../org/telegram/android/MediaController.java | 84 +- .../org/telegram/android/MessageObject.java | 61 +- .../telegram/android/MessagesController.java | 183 ++- .../org/telegram/android/MessagesStorage.java | 135 +- .../telegram/android/NotificationCenter.java | 6 +- .../telegram/android/NotificationDelay.java | 29 - .../android/NotificationsController.java | 248 +-- .../org/telegram/android/ScreenReceiver.java | 2 +- .../telegram/android/SendMessagesHelper.java | 75 +- .../android/query/SharedMediaQuery.java | 10 +- .../telegram/android/query/StickersQuery.java | 366 +++-- .../android/support/widget/RecyclerView.java | 24 +- .../telegram/messenger/ApplicationLoader.java | 8 +- .../messenger/ConnectionsManager.java | 147 +- .../telegram/messenger/FileLoadOperation.java | 2 +- .../telegram/messenger/HandshakeAction.java | 3 + .../java/org/telegram/messenger/TLRPC.java | 1037 +++++++++--- .../org/telegram/messenger/UserConfig.java | 6 +- .../org/telegram/messenger/Utilities.java | 4 +- .../ui/ActionBar/ActionBarLayout.java | 60 +- .../telegram/ui/ActionBar/ActionBarMenu.java | 4 + .../ui/ActionBar/ActionBarMenuItem.java | 158 +- .../ui/ActionBar/ActionBarPopupWindow.java | 238 ++- .../telegram/ui/ActionBar/BaseFragment.java | 51 +- .../ui/ActionBar/DrawerLayoutContainer.java | 12 +- .../telegram/ui/Adapters/DialogsAdapter.java | 56 +- .../ui/Adapters/DialogsSearchAdapter.java | 18 +- .../ui/Adapters/DrawerLayoutAdapter.java | 3 +- .../telegram/ui/Adapters/MentionsAdapter.java | 74 +- .../telegram/ui/Adapters/SearchAdapter.java | 6 +- .../telegram/ui/Adapters/StickersAdapter.java | 2 +- .../org/telegram/ui/BlockedUsersActivity.java | 21 +- .../org/telegram/ui/Cells/AddMemberCell.java | 7 +- .../java/org/telegram/ui/Cells/BaseCell.java | 5 + .../org/telegram/ui/Cells/ChatAudioCell.java | 25 +- .../org/telegram/ui/Cells/ChatBaseCell.java | 57 +- .../telegram/ui/Cells/ChatContactCell.java | 8 + .../org/telegram/ui/Cells/ChatMediaCell.java | 30 +- .../telegram/ui/Cells/ChatMessageCell.java | 12 +- .../org/telegram/ui/Cells/DialogCell.java | 56 +- .../telegram/ui/Cells/DrawerProfileCell.java | 11 +- .../org/telegram/ui/Cells/MentionCell.java | 23 +- .../telegram/ui/Cells/ProfileSearchCell.java | 7 +- .../telegram/ui/Cells/SharedDocumentCell.java | 2 +- .../ui/Cells/SharedPhotoVideoCell.java | 2 +- .../java/org/telegram/ui/Cells/TextCell.java | 20 +- .../java/org/telegram/ui/Cells/UserCell.java | 17 +- .../telegram/ui/ChangeChatNameActivity.java | 26 +- .../org/telegram/ui/ChangeNameActivity.java | 30 +- .../org/telegram/ui/ChangePhoneActivity.java | 31 +- .../telegram/ui/ChangeUsernameActivity.java | 20 +- .../java/org/telegram/ui/ChatActivity.java | 1388 ++++++++++++----- .../telegram/ui/Components/AvatarUpdater.java | 46 +- .../ui/Components/ChatActivityEnterView.java | 796 +++++----- .../ui/Components/ClippingImageView.java | 2 +- .../org/telegram/ui/Components/EmojiView.java | 511 +++++- .../ui/Components/PhotoFilterView.java | 8 +- .../PhotoViewerCaptionEnterView.java | 491 ++---- .../ui/Components/PopupAudioView.java | 2 +- .../ui/Components/RecyclerListView.java | 2 +- .../SizeNotifierRelativeLayout.java | 112 -- .../SizeNotifierRelativeLayoutPhoto.java | 58 - .../org/telegram/ui/ContactsActivity.java | 69 +- .../telegram/ui/CountrySelectActivity.java | 10 +- .../org/telegram/ui/GroupCreateActivity.java | 16 +- .../org/telegram/ui/IdenticonActivity.java | 12 +- .../telegram/ui/LanguageSelectActivity.java | 33 +- .../org/telegram/ui/LastSeenActivity.java | 19 +- .../telegram/ui/LastSeenUsersActivity.java | 14 + .../java/org/telegram/ui/LaunchActivity.java | 81 +- .../org/telegram/ui/LocationActivity.java | 24 +- .../java/org/telegram/ui/LoginActivity.java | 9 +- .../java/org/telegram/ui/MediaActivity.java | 13 +- .../org/telegram/ui/MessagesActivity.java | 196 ++- .../ui/NotificationsSettingsActivity.java | 31 +- .../org/telegram/ui/PasscodeActivity.java | 22 +- .../telegram/ui/PhotoAlbumPickerActivity.java | 2 +- .../org/telegram/ui/PhotoPickerActivity.java | 10 +- .../java/org/telegram/ui/PhotoViewer.java | 222 ++- .../ui/PopupNotificationActivity.java | 141 +- .../telegram/ui/PrivacySettingsActivity.java | 14 + .../java/org/telegram/ui/ProfileActivity.java | 206 ++- .../ui/ProfileNotificationsActivity.java | 2 + .../org/telegram/ui/SessionsActivity.java | 12 + .../org/telegram/ui/SettingsActivity.java | 159 +- .../java/org/telegram/ui/ThemingActivity.java | 91 +- .../org/telegram/ui/ThemingChatActivity.java | 14 + .../org/telegram/ui/ThemingChatsActivity.java | 37 +- .../telegram/ui/ThemingContactsActivity.java | 14 + .../telegram/ui/ThemingDrawerActivity.java | 46 +- .../telegram/ui/ThemingProfileActivity.java | 14 + .../org/telegram/ui/WallpapersActivity.java | 21 +- .../src/main/res/drawable-hdpi/Thumbs.db | Bin 360960 -> 363520 bytes .../main/res/drawable-hdpi/arrow_down_w.png | Bin 1362 -> 0 bytes .../res/drawable-hdpi/ic_attach_music.png | Bin 333 -> 1206 bytes .../res/drawable-hdpi/ic_msg_panel_hide.png | Bin 1351 -> 0 bytes .../src/main/res/drawable-mdpi/Thumbs.db | Bin 296448 -> 296448 bytes .../main/res/drawable-mdpi/arrow_down_w.png | Bin 1182 -> 0 bytes .../res/drawable-mdpi/ic_attach_music.png | Bin 266 -> 1102 bytes .../res/drawable-mdpi/ic_msg_panel_hide.png | Bin 1165 -> 0 bytes .../src/main/res/drawable-xhdpi/Thumbs.db | Bin 508416 -> 508416 bytes .../main/res/drawable-xhdpi/arrow_down_w.png | Bin 1415 -> 0 bytes .../res/drawable-xhdpi/ic_attach_music.png | Bin 422 -> 1272 bytes .../res/drawable-xhdpi/ic_msg_panel_hide.png | Bin 1439 -> 0 bytes .../src/main/res/drawable-xxhdpi/Thumbs.db | Bin 707072 -> 768000 bytes .../main/res/drawable-xxhdpi/arrow_down_w.png | Bin 1774 -> 0 bytes .../res/drawable-xxhdpi/ic_attach_music.png | Bin 561 -> 1496 bytes .../res/drawable-xxhdpi/ic_msg_panel_hide.png | Bin 1784 -> 0 bytes .../src/main/res/drawable-xxxhdpi/Thumbs.db | Bin 18944 -> 9728 bytes .../main/res/layout/chat_loading_layout.xml | 27 - .../main/res/layout/chat_unread_layout.xml | 33 - .../src/main/res/values-ar/strings.xml | 159 +- .../src/main/res/values-ca/strings.xml | 12 + .../src/main/res/values-de/strings.xml | 196 ++- .../src/main/res/values-es/strings.xml | 41 +- .../src/main/res/values-fr/strings.xml | 3 +- .../src/main/res/values-hi/strings.xml | 666 +++++++- .../src/main/res/values-it/strings.xml | 53 +- .../src/main/res/values-ko/strings.xml | 36 +- .../src/main/res/values-nl/strings.xml | 54 +- .../src/main/res/values-pt-rBR/strings.xml | 48 +- .../src/main/res/values-pt-rPT/strings.xml | 42 +- .../src/main/res/values-tr/strings.xml | 11 +- .../src/main/res/values-v21/styles.xml | 7 + .../src/main/res/values-zh-rCN/strings.xml | 70 +- .../src/main/res/values-zh-rTW/strings.xml | 56 +- TMessagesProj/src/main/res/values/strings.xml | 45 +- TMessagesProj/src/main/res/values/styles.xml | 8 + build.gradle | 8 + 142 files changed, 7148 insertions(+), 3126 deletions(-) delete mode 100644 TMessagesProj/src/main/java/org/telegram/android/NotificationDelay.java delete mode 100644 TMessagesProj/src/main/java/org/telegram/ui/Components/SizeNotifierRelativeLayout.java delete mode 100644 TMessagesProj/src/main/java/org/telegram/ui/Components/SizeNotifierRelativeLayoutPhoto.java delete mode 100644 TMessagesProj/src/main/res/drawable-hdpi/arrow_down_w.png delete mode 100644 TMessagesProj/src/main/res/drawable-hdpi/ic_msg_panel_hide.png delete mode 100644 TMessagesProj/src/main/res/drawable-mdpi/arrow_down_w.png delete mode 100644 TMessagesProj/src/main/res/drawable-mdpi/ic_msg_panel_hide.png delete mode 100644 TMessagesProj/src/main/res/drawable-xhdpi/arrow_down_w.png delete mode 100644 TMessagesProj/src/main/res/drawable-xhdpi/ic_msg_panel_hide.png delete mode 100644 TMessagesProj/src/main/res/drawable-xxhdpi/arrow_down_w.png delete mode 100644 TMessagesProj/src/main/res/drawable-xxhdpi/ic_msg_panel_hide.png 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 778bc592..b15fb74e 100644 --- a/TMessagesProj/build.gradle +++ b/TMessagesProj/build.gradle @@ -1,11 +1,4 @@ -buildscript { - repositories { - mavenCentral() - } - dependencies { - classpath 'com.android.tools.build:gradle:1.2.3' - } -} + apply plugin: 'com.android.application' repositories { @@ -13,8 +6,9 @@ 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 'com.google.android.gms:play-services:7.5.0' compile 'net.hockeyapp.android:HockeySDK:3.5.+' compile 'com.googlecode.mp4parser:isoparser:1.0.+' } @@ -88,7 +82,7 @@ android { applicationId "org.telegram.plus" minSdkVersion 8 targetSdkVersion 22 - versionCode 546 - versionName "2.9.1.4" + versionCode 576 + versionName "3.0.1.5" } } diff --git a/TMessagesProj/jni/image.c b/TMessagesProj/jni/image.c index a3a0fb86..a2cc1dfb 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 100644 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 100644 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 100644 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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®v0&ada+bY_c2;C+DEf$A_@YH>XdaANX&D-f2ZKf;`W>U3-7 zrh2xqi+TeqX{QER3pUp?J_4Kl*V?I3w)n^EamW-~7e_la+;#}~@4}NTDoDj`z!o+t z2;NG5qMko1=`RPt<9mQ_lxsj$kQ#0Y+RB=P;G6WVEULXa9f#F=?k~OmM0*v_xSloe zZ-HAnJWoA8HL&U{`0Yi?3xmr0yX91dN#WQcqe`#s5f06jrpPUYs{#}>siMu)EFh}c)c)WNpM@9XJV6TRI!DOioNrujjH*T_Xgg9gPhauQpp{z%kibGi!7xuzpm0A)8?{Dks;;P(meMWee zYQ_h(cbvjTs+&Q(uPgOfcb93M8PtCJ&*150(5?w5Ik5(gwWmKT3s-|I+u~TTg27#K z9+O|`Y51r=5vJNg2D*5F)OM8u&r~I7o{3vrh;vk!Sste1jSQ)D$(H)^PSX4J^>=rhw8^(8sIWBx`MFjS@-OzoB^Ih1e3H+KU za={%gyv!wTT~|e+(UL_j%pdx>w{ysZ%SEi@pT#23c2PNs(iXR>MLV}f6qTXqL)qY} z?r1PJ-$k#T(KF{Cx=KtJtw<71zG2T>6WEAu%dm1Oz@o zj>NGsh?&fXSifHCF!pSWdYk1$F}oO}US)GU;=)~_I0=vHfmyI=y$g4l;sz_f2WG*5 z4QxXXYIHL@)|>JdSdQ9watY?fOv8Bo}Os3%T-NBqaA+@}eRN87=ztcr8w9+Q{Y%jIIvKAM7z16LjJuk3X zSF1zXAE|{?UvS}htJpV9xk`<&CA{dO&)3jJr(pcryV6Koz`(1Uo`+UiT8$2QPu2{8e`zp|~y=W1ZgD=UJ4#%Q$i$vOO zabm0bvWs1JjXJnpC6IiH472XmsI2T7Ofsi5to_=0wDyV%cPio*?WR6x?J#HwUbF~n z#w#w?F-{%KO8cPtat&*j@4|whBV|C20O@|MI?QU9nZc~&T2$z;M^VUv;ti zzVJs8kS!7!W<97;Syn&tht8AGh_2eJRmcOF;RanR%2x!r;c4tu(|C*H6F8Tr@6UfFvXmOj&4Bnam{t69gcLFSaue(@bf;vE| z8Pbd~ASuIa#jm??U4MKC*7y?%YPj`mIlK>6TlAYQJk$}_)WZj3Qm8oKqO&A@Y+@1N zId8f6%MyPMxb^JYm=p%1V)DB#JfECH5<3jR-YfTg7ynZG5XTVgA_6{evDrhgy=eK+ z#d}M}GAd|10(TFA1lPwdTsMfzpva+Wq%Gr97oH!97rWyU)zEf+e<5&>y4d2OkaFlV z7xp5e@bFMHckpu;_9CKkBUO&BFjo$@Mt&(O4rmv05ogz9qRGDPQh*eFg~2mS9ngL` z5PPLrY-qbO(9Rwg41;YGzj5(5rPK0;q0N&gXbKcvpI}8V& z`@IWSjY8*S!oz={Wl8M7mJY`hn)MT{v;u#b@Pj|Q@Bm)k3K3p*hWbK05{?+5Dz=Hg zxbWOvY}C?5z>_Eb2^&YKw^_H?Vc!V2^l-HckAK7?y2vE7m{jA!RlblgISCSqYsKnJ zowgR`*77Eki2YG2UWdL23CLJN{n(CC>OfpNyYb{l z)O3K;R$+DXQ*6L**z8ANhlQjdfQ=fX4s0J_^Y<$YbYn8b^?6rTnXHDlPXg^^keL?B z;)mj}osR;)%ia85>9!UKvQ50gjnzfCF&>p|+d8_jVhKDOIDHUdWwJWNwmr-&Fw$}) zoH;?aI8-)kv^p@*73lAm(2ep#Y|Fd5u|X80p=`7oX~~aa$3VB__7qA7R<`r^+tr)$ zLoBDRmbBy`f4|T^Y%gfGiE(cJlf38nYmAD|O!am1vodtzuZNBY`@3oM&YdOR9-R2%}-0b61cTsu$yjDl)&xn{r$ELW|yU4$A3@~#q|mfse|3Tzf?Ip zh0GqxR;HjIs)o7oIbtEY0(9H@5rm6R+WeIQ)sjZK@z6k+8b220vDdlri4(z}4cu}h z8J{+RoYFCFT-}J+`(i9&ujP6--u@IJc5y61EOo4#-X5Tj{S6(56HLZ;C;p&|Z$d2_vKX`r3;qD9y;=9zgqi|dy78zHa)1$)`?LTrtu-H5Gf(tJ0b1&KMT zAa7%s;JAI=%q>tkcw|ts~WrMEp4t4VPi(TlUg@aZJTJ}OVY9hR2 z7b!lIH&G23o_i-60fT&h#Iloa-KavZD>2$~-5fXQdf6*_Su)DD?@frW^d;;xr2$J>@Fb*1 zma!uR3rr68_X}7<^@dpXtf4x6Sjf%L zWa3(?*oP$((z2F0Z$_&j3cUQFA>pZ;(dxv9L|I@F${Ix;6Y|3b4>Su4bfGMzm|E$_ z)~BmMlN`lvj@P2}*ju5;UW$q#`iNUTViDbczj&-nag~L#e3V^J_3#%B$Oohc>wRAgYhQXuv7(-~(jriC&_=-1r^TngAd?WGohzcpeQcMD*4l_xIUO@A}lU~A3&rq+5iQMew zk7zuYOdh75qA^?!o)VO8qR(K^N6yvoNq&#J`Bo3_7UCtF{Gu=>P@a2K$#1rgv2BJC~7mY}xlD4`{FW@aD zRw3^Qc(b;$fw!nVhF5@Rokw1=E-#=v<}2prD?DWn=w;C;+r`+1ThP`~#$HAm6}Juh zC=c(C#7n-*2d`@z`}G!F4HQ4+#s#(bWO~d@tgWd}v*9z*hrPD5Su@qEERoL;9u=4r z?eEw04AG(r$v4@+T|3;I{49O5P}oAgEJ9hpv)Uj4PP8qc#e;Su^7KbCc7v7++GrvO z{}u`vRCWYqrEQnB^Q%JPiD%iQTVZTaDO-3e6wTVnHs1=x*Y9L+QhIPF`w`{Clb*vK z&uBnCC!z*+#UMCPCPtO)+!WoJhf#LqIo2-|qs9)NDEX~1S($2h;K}Dvr#IVi9_#K? znd)#`#ZfojUlmW;U72c}HTyF+>wcR$76%tMUO*D#t>`vv+7rHTvuAI^&bg|>jZgcD zeUt+Qwu8sq{5QE$_nHMfuhNYd5ybxK)>+v9#D49@H(v<+al&2S82gzD;@|x(?UzME z0keUpeUEsQJM$#M3x06pnUXwx%*Jl8@+UW&Js0<~WwYtv3GBdZY{Oztx$&VKu}y23 zjRRl6&u-Q+i}d~3jh8v-AqJb71()nO?Z%@MFov;>S#-8Iu5sgX zOYF}(%tgfv2Q@4{>&#{H!MNsIs&4tZ_e4Vjz zE_OzZZZ~cg#n(jio~L%TZfU@lc^=v;I){LkZ|oM&Lwm~`v2sX{yf+VyTYKKk&JbhB zzuY)G3k&12A@NX?8|O74@wRO2lrt~5@$E0d;u0!vYNi+w=fxwyt-JmWLD@LmPP~Yz zOFqEuHy_U}c3Ie@`Phmcwl<*4#NlfDdG-vw$P%l0npJEXS5DF0S|kU8ddwR@ke z@CIY5rr~Oj^Y>d1nwZvr(}-yS?PNIHdpq8ZDY{(^=o6=SSBmTF@0S6Zxl%G{yA-OV zhBcvV0tC@tG$0RU2`W2%JLb?zwL!kFh@pr%{7#yeiKh%ay&_mt4u-TVf{j5Mbttky zerQ?pPS<%u`}zC%bz`fEH@6#m0jVuEssZoW;5Au%1xOBd!39yQIY;d`Gq!sJ9{~CE zM+R4-ZaQe!2#Tbg1uYLW@!%SCazYbm+d-Q`d~({DOw&d*(9r(aymn`+??Ahe(GB=O zw)iTHckjTwiVvoK2YOg+jHg|iJ4;a~J%$A@RQvS}?a^R7cqg6CqAVITl1+aJfF{u5 zKwC~p}M1Qc~nWc5Erm zw}&2Vz;ht+1z=Rs z_ayKaWMkLlLs;s=7*y=|QhbbJem(*=|6#T=pAPe&N9=(Y;rY0`^4A6~Qr zpC#WrPPhjHEVLNkT!0xSwzvV`jwZh#>>jk22^=2{p+o;S_h81_vkrrZ#q33&bygVtte=)n zx)*I0Y;C}`ocQ{>%|!QO?6rF_0E!uYPe%JRc!4@k*|n{~cu6b~&JP`hT|a1r^1^p# z0iHB8Ze#BiKt{lm)b4Og;*-=?7>mCTPELHXf$x;gyX8I@w+Hw_=3b09JxcC_6YNj2 zm+yl@kxwuw`TNkLr=B9kAq4L)u=xAwS^ymQCIEcUf)$-n+p}r+!xy>FG~j!Y z#Opd~=}J5H`2BELMQH=RBS;W2#kXhQg42?;i~V^&j#_w@((eIiyJZ)f^Z>Nowu`NM zK<%Sc>}oJR(w7cPGe=_%2d#x3%tbK!18SnJ=mq==kHqobW3;X6#Rh!A40;OR;k8^% zq$eS7FIR^Qu6(IMZujt^j=7fw2aLgIfoYm59fMm7lyyd){%8o4gXRJaFO|_(xFxMn z<7}xfH{fP#Cw*JfTHs?{z@w;wm`3qciZkSAQ6fRgz8>{aeyzEjzAX`RZ4qc|QSSE& zO?TqaS*MliJX^)94R{?=d^g$SEAiYnZf^rSuu|<7GjXp+@k}V53dLzGuT8<88)d=r zMWs%K>Y%{LvIgEgTz=ioyh2QlEuS{_^Q|v`L*1JI>$l5NM6G)xd}DityAv z`&0v~FT#`OwZAs7{;Sa6Rlhdi(IdWvtQ%XpN{#BC{9A+kT%>Ty=3wTOUKNhV^cY8jqSBA1(VC=pct*6@?*zDDK?wwoTfGc_b zJy9*bzlzFCb25Gf4}tm7IqlYz{&$c)HsXpmnvDU^~&09qy+Q~mvlE>RY817;%# zD1-ppZZJ(|Q{I3R53E5GrRN*ixi#uoYw@2AY{Xi1q%G$nLW^D~!9=hYen|~FhYL@v za(JMzR!z24v}a)tssk;tm$3;C;&J22V7Bf->;O_avb_&t_RQ$Wek44%LdrvRIj1 znoK6Qtn_EqO`{=ou_&LZ8^e%xDGZ|PI~ueA+VH=o}$ldzz5tju2lz zO^8=qBziw%S!6tXu~_zu^4Q1@s?t9~#8C4ys&|V1&gyJZLfNq!-NkN;>f`<9rA;SrS}Rg zgX89;b;!%~U`Mu7EWN&)p&(5(7Fx!}6-@3peRH7|I|0mAOy*=Z$zqryZhy`);)e7o z9a7aM>Zh18i@`3kOLR#@HVN4rWJAu7%|Vuj>{Q21HKs0PMaWtsjr8&7ELLOsR59pz zR-up2?4Vfb?aaRCEs1eivpY^7B~~3QZzi)svqkTf)T#+tV$chg3wlJ~Ku0XALmoT1 zk9H*s_f6ITN$WWsY$eoJ#fNyvHU8UFeCf5U(_^uA_uft<_Y|A&W!uww z57}(zJsqqGk*~R~>LyCq?;cg#JlG+J^$@+|StK8}%5uekeeRCa_fx2#MbD;UM0U2y zADZy2B4~b&Fs&j#1RoQJR*@gr9g4R{n7SVCP*?J(dkYu7fR}AgbTGfIck6b)V3}#E zezrsHVOQHEFMZK6)mXt@e=n-%pBKAcq}lA{>EPs!-px9vh^D^;J^N7F$yfFwmO9c` ziMd6ViKfC;9qg*q$A`O$7@TCi&~fI1w=l1!p<9aZ?*&!O=zBq2zZy@+z9^QhCXXZ* zb)4R8uG-}6TbM8?65p++H7hC-z1PqeF^dicih9S(xrXss3i>G#53XKApCwa>&B~sk zxI>+-QkRd)HFShiip3y-+>Ly3#Qs7-fc)qWM?C(rz~f6_>Y!t+w@?8=!AW|#gNvl} z?YU9K^bliT;bsHeX@8}I9kaTZhLbV^*|YjC@&58m$*opy@bv zPR8Btmn{Q&q&P_j@0qfJrfl@>k@!9KGA&{Js~wyccz9mvQ{U-eAxgLZfzt1< z=#aNW?04$+xAAGfi2WAO7)BL*)*+rh?dn60q|J5J5MG-F^oh<;|I8W{LG z)j+S%Y5g>%PeWfAsps6U<4|#^L!JB^E`0B^u5p z9qI}Zbzks=QVcRNm{*EH5eDh1s_83AOD(Zcl^E9W3$d^K%S|md=9Z}%_`)FFWxXVAEn}2)_(Jh@8Iz#JNkRF2q|Y?`ElOD0 za6YgWY5lU_qDW+n2r^34_xNsji}&PQ6pS2Q;`(Q$-}|?I*hb6X{N&`I9IsNIpGy4Z z#oY`GkX@`xA~J)EUIa3I3i_nISY%#gr)o#_Y!b4a|B$62+mFm~hIA6}{#q@H@_?K@}{~k;|X{nz$f!=uW@F{t3g(giRKkF*ZX?-(;C$s+tw#p#98E zl#vSLrVKuOSSKFa%-l`vW?Izt+k@1k==+O|%{-TRw^+8B=em{z+1IZ3iKpGq5u?90 zGx$uuR}9+1pfj8G&@GnnCi9~~by{CtNVI+nneO;gLHa4D^h0`-+)oL9A;_&Cy6i$9 zQ%if+is?Sw2(A^2e7vZ@8)OY%ubRK}5t^LWgLE_XDPZeXJY2mYs4jz5`#&7-FuUpA zsyZTNV%=6AuH1OqF!~)VCu};c$FgmJn@j~45B#5y zzQdR=#TOKV-(^^|b8C>6h?XuzYjkiLBmS&PIWl`YdB!7*g2##KKh%R;snnZEXjUiD^kkag_}iUaRaf!KHRfx<}PhtR%EcF>pmP z)%;3}7UjcWc_kh#{v^mnOOL&QoBJ!7q40ekWa>jdXlvU>gK7OLC}wT5Ofwnws+ULh zAZ;W2?*Dg?9Hqdo}vZDhtPa|Z^tZ-e5#9TskBMDYqXqI!K76rU@F z14V~Y6rmWr({km-ReT`w5fVoIRH7Lkr-#9ZBF|H5eh&Vz$n410L@wp=?qrNsi2kM1 z`Z#g+hpb2J-xrLWusg^T^=R}XRL&1ME)nxXQ2gsde4Frto<8c3a>a+F&%U36qU}TS zXT>j6<@!4#1Gat3X@`;RiyYp#br&5DM@^7(ZTkG~tGkF3TU}6o7|9g}cM;!}=(&+o z?HN38Hw!XF^+9pTZc?yU10Pb2v?K1_l&WI%ha&ol-8^V-46-(+XRl_=qjok1#aVs} zr`wweh2Ju+zwggrWOfKIs-`~aN!29?3gNd5zo8n#Q`1c<78hXHjEspL{ikG0k<}xM zIz#3`b{N^INNakaa)9r-jH;k)86X3XvCC%0FZk z$ZY>`uL@am#9oH(qEP)W^|H@Re_hYID<@}n+ zLGw>PCSw$$KY8BG^od2AP>o)n2GOI8^L{h`j(}%$;k*i96`Gm6(F(E#_8nHNJkL5yB9(oS^sP9+Yxra8X z68-Oy!n$VuR+7-9aD`lahckY3xRYP@mRr%ccojC_w$jQfFV_{evb z{^w-jtK4VVy@C8EwX7E>j(utwXUt?{;%6+PACC^n_aoE1Pkg3kh)iPFXEbUnOyZDY zsY#sp%ratJQuom5n|xH71PY0NWM^iO!^o^>$W$zKAxl7Zvsm&Li>&#dTl(ZX(4U!M zQlDd&6tX_pS3lKJ$v~EcOs`y+V4ciDm3nVBa_1>IdL_$4mh%r;A+o%G$h^o_bPx4C z?P;~6paP-0yBJ!PEX3%v6JvT6GF)DP`9DQiPx)`$x&KCC&+ZCBRtc9j_?ER=Z;hM00MR(P6 zc8CF{-YLlWit1}8`X!NiZrxYBFS?i5^%cFmy}d%Gn_xBVU9yU9C9=mNIdte={A4{R zq*n9Q&#IrEDUc-~JF{LbL>7FX0G?M1JqWFi}KGT^Fz6~DS$cS9P& zY2qUn{odEVu?!fHiGJuwODeUpdC-OI8S&A>TAXP5hP}^~W?>0fMvQ1ierAj}W48<0 zsmM^z8`h9oeZ-;wb8RJkLhSNnrHS5tz%poD?0NrNeH3BWj4bZt`&BBIAxk(zmWga9 zvLs|o7pM!$?B81KgA9E`ku~wDD!0tnbBh(bHbFJT4gTLU73IdxhhmkHm9B%|S`tRY z#8OpaNBz{h_{x+a8rd>k66u6iAaik+?K{ipxO&V^Rd;&MET%<{6^p*36vp@C!`P}f zoFKM+N25}u>-7spsfIcB92a7+qSpdfe$RZSxqpa#!R!<7C!YD9DcCIZb0a;rs_$8s z&F(Kwe9sudtJ~9`o4Jqq_Pyv&-Zr*jAJuhwyg0OvdC%wsG3WUS*FTEmvIZ7#upisZYg0{VPaxAjXp2Z#y9_LNr;lEktDv>jDC zhl;%zjyRqaI(@&83f9tBDaOc7b>EcNJ;;Jwh0VjJ_~9YO+4|?NCLbgVx`vC#4_bx} zDM7B!UC>(3W2tf+@uvolnXl0~$IKsDbpG`q+0iya82`iUc=iY}_CKsv9Ar7Dk2XjY z{f9-{#ANZc5-v>^-4D^i79@)ihj{Vv^M1S&nsxSUai(GhFh^cvfJu|wR{8&DU zuV_cg&V*{qRFgR+q`p3)ZVB63O&Lr^Z-|UVO}`QW`%=W%UnzTsQ^Z`wV2W4HVs=U$l;y1mQApx@LQ*l02LH{_f$UG^J$C6ccQsha}T+D7O% z-fv3{N%lgiwUFC>XRYJ#m16VnB(ZIb`0aP%CufZ4e%LZ1$}=Vu8B!g7ifG0Eb!}hNNzby_tc#hQWs>Zj>;d0i6+CS=?8P|#ToA6JT>*B)@+G2 zMo$*In#um=$ssjmtUmB!Zn0#Wa;Ah>Y0~wnPt*3j-9lc>o+`d>Ve+$JYKX~IeNuFI zD`g=kBP6+LPTl+NY_+5rgBfC7D`^`&P3&srrAgC5Z2Hr$l1v_@okvxrYN?6}q7jqn zV#qIyUdFar;!Gvz3nIbedn1EQ&FGgzYC2yV{nFIwA+=FU-`&2g=GsGo3`cP?FBBQmne^`1N_s>QjW z!he!W56==KJIE!rO!2&tkmYocl?yY)lS){XDK>VH^|EgehdL}bn+j&DRMGqNnL(x? zY*`_7cgrr4*b`K%s5gmsf@GQMn^a8cy^xO&4v0M`y{CQ!e8qMeubait5V<(_W-&Kp zx!G87v)Hcm$8Q$l5aCR{MRg4NJcg5#!bEE2tt!{@#YsN9879M2&J`QO*l(UIYQy+H zWu6$+$qf=E^TY$4mML)t=ieQ_M8dk@!)}INPVr-><$?hzn4Q|KuOhz`GbgeJF{GH< z=F%=ojrlfleHZbbc$-+(Ww}1ibKA+*1p8M0dAo?;+eB>_6+k6s*NQ*X)Y$MNBzV>B zszT7Oc5)uE*iC`#kSvLueE;|eCD1lMbjD;I_djt6wYzUOCqw3oK}U&a_k3~vQF<)p z^TitUru{r{E7vK-iQkVh)CxD>v*yHxaIuIsuqSK z+hus($@6MFoc%E)f`70|MNts~)Vu|Y#8D+LStKryJm*~$QuD0uQQ723OLAP&Vk#Nlt$wOEVgHnV%3`q@ zyKz~Vof^?7GdE_ri@BBwcZxB4Mz4%kr)cbbM$7#JT-v|-9&NC3g=_Wm+Gu0ilGUGq z6-!p102w{S=x*8wlY5CuBK@k=N4jZD{i5FzsUyDVrg6*Fy&<;DsSm2IF>2|9=G=GE z7kZ3M(}xerH^I+|t^367MvbkE_oZjZ~jLefOu8+d4(p<4D3O5esiqE37%Pgt)pX^SPShG*&n9?s8gWfOB zi{_n$_lt?pREfPc;;~AGJ)USS$r%5D*dDEoHrXBsaW^4d7(TmU(ylO;Jt(G_w9x|s z4~8Nu>%3nLoszzyROacatu`U~Oj?>T^C8h{(rz}EJtU@d*EkgLkeWak_a7EvO1f)_ zrgrohr}Z(Sy1SNOjDA?0=#GbM4~N)At7n}VXK6!B_D4c8Tio_F>%*S2v=rlk#L=@zAHz~{S&TN)XkRLBk0Ao~FBKbOv@ynBkBV9)PkvOy^}rMEN7XczzPGU2 z%x!J19-7rSBuc!{L*vU+`QrT^#G)-<{HA!!D0-hwq9^667F=&q9A|53rgZdWD$zAj zezuljDnLImVs7q9$V$*xMg}I+duj}xxZ13zcC)F>9b!)e*R=K*hkI(tCeLGPN=Lu8 z^`c%Hi|CK5`Xtgw_98O&Jua5@;{El=e^lL@#Zuv2=wPdkze84edGF z-KNy%)U=8|MHJOryVz2Vel)3L$n0&smDIPQJor8J#q(lHZ*A!K#OG=7lsP|@yJGi| zGmzIABdtUt6oA_dr%%F4e&x(~|?z!5H z#^WCG{<-+yxk{B=y))3wOd)B1A*5DD)vm`hGx1RHBDpCt1-9I*4KS9zDAt*It_u0f zk>;r0tXWM-t3ymw>YaqdK0Fsde~Fm+81b^CkH(j1i$feSr(+i3Ld$$&G$dWNGAA%#FUa!q}H^?c;jhzUuk4 zA@*479q1?e@_fd6m813BJ^X#CNb=CHRPM)%P+#p`Q>vGe8X35L9INrw#aBb>1cK`D zck8EV#ucxMLH)>-`;q@3Uj32$l-Ey7H91Q|9M07{5a0Hr)OBqTXUAz{IUiUY~TLc5aYqO#OVGMl$4EPQGab{ zlxt&1yx3nG9#x8BcYp2bs6B6ogj9;s@{qVDUgHv`O(7xTwSiGfQG5`OWeOlF==p$}>aoq!GA-3*(^cCx^zJVlrF?z<@>YFIyR?Tcyn}GGhc16F_ zw(?ZeAe?jU2(dMm?mUZvgS3RGq8%Zzc#t+TsvX5AgNQNbhapy)^g3_wU_w{FE5x=V z{j*Q^4kr6p{me5&w)||tJZk?(A<;CLXhK0gT=F&(Aw#X&$YJdt(~rRqhMP`)b3HS% z(x4_(qHDVute=GB>PY+hj8z*SmAxk?s8qp#y^`wNf-yr$)CHgEb4#<;oZ3(=$<+0Q z>H;nqrn-PbHEsy}k{mdcyc7EkIdCY+RsKzg+@)8zbI#YezakJ451xayPCSsJ1;=f2td%soHvi`7r7!Rj^M+yw% zy+z-L#Fk;&4W@(N(+Mf3dyymSQ? zGdAV)DdKsGW5Om9*S^}Aa&daLwsC}jb)tNKp*9IkVV=}cgtRzEBMY-CO>eb1+_*qDy(OQ>uMQS`S_$5vszCGw$V zhfPb0%Bv%EHj)qpXYgoe^ebmEsK;kEa!@4-?NV&i*Q=>f{gA~?mulAyb2czmSFfc7 zzl}MxsXb@uGifP^GCS!%VjdqkOZUsAR5f```q*B57uI~4mSxInRV}oBvG|J1XenK7 zA-Ut^C9Rk7zOHtXP4p=vHwKk?^`C0!d}=t)w-P%-@`i{$cN9@m+CfelMc#4-sr*I} z^*O=6Cx=x67an197{g}W zaDueC93NF;@N{Ibo_;w`nAwhd$K@niCW@7pQ!gw<@wt-tQFI_N?Ux}AmFhE7lSk9f zT44~&M$ZkncHW&>RF`{)0{kw#o zV&YZW6r-o7cmWPb>Gii=RU}q)Ga8)87OIKqz9J?~iy!JmKUq0;Y8Cv!NZX{+d>{4$ zy~Ox5!pW_ri_)~~O@?#A>dOHWsGh3R==dj}BjT>6ACrELn0~d!#%jzzjilMrR}=U9 z&Jnwi8|%*zzg$heWk(xXvHQPfR?OU(u_D)sdnPw_?ic#kDo0$Saoaok7b5Zh&^4q_d>`@h zHTXBJj|z`|O7;6|w3!1k`iK8#VQa6+XvjjgP>qcGiR3FVO3)52TJuF8$E%l{1lAo?|OBM#+NUOIO1LLFwaWtJ!6()!aCgAHp zLRely1I~v8CTIh?A4F?4iA7;LT^lB7SC~qNoQ#!zB0PaqN*)?!IInMgpq}d?CQPKL zjQp~O7EwP~ylf&#HfcndjXHYkUonx&tsVU>k%`atiL{{RsyJ=o=n`PUKVDdQJ=0$pG@d|mx+5PtFm&LST|Xl*gazu9_=Pt3z;j8 znxaiJ`BTDdIbA|`Q!JUnfP)o<=cj1nhgBojx5SYK3rK_Xp3|w0m~2#uYc?7Tm+Ki& zRY-lNYFs&po}IdCFF?jrGDG@kv1qDxS$FT~u>3tPvZr?URBf0sW16U)%IKnaS~&8- zA!~*fW2&4MW(rsDmS3Ae`1VZ`b2GFXO@-6LOuXoQm_P>MiJc)%WRQo`W{3->X+z_( zW`s{Kq^c~^ejep*hL}4|yDZN653|(1M#CK4Y@{Uz^@20ZRo&u7mOVqXP9whZW(do4 z@~#Iv6_GX~XFBN-&!tJ2pRMK+9kE73qC@POuEviJuBy@QHWtr}nAo;h9TEsE56D!LQnjD~8=H%02OtqzhY z(<#1oP&e&&inC|pUd(M_^;tOene)jr$;Iv2VcLJ{c1?I^GG5$2KPKZw4oJ-V+e~>Nh?x!9 zyvSE69>0-_J>!uudrI^desZH4Nb|9!EE-w|_Dd5eD@((tmbWgQO#_s(RNOh62BvJO zcxE;Y&VFX1peg22GC`!%Ry~_3wwPt&>@3YPBw^YAZCq3(yKf+V!Hhfc)OhxmEIKs> z=%+>odM{*=L004|zl<=I<*N#W%G@IQ-$c)GKl-|epJyw5fm^vVbAXx%zDc{vN`NqH&LUdE)TQ7Fm9C^K;EpKXUaj}s1l5W$2T+Bh*=S41^%%G+CZ`KX2O)WLVS5M z86f@%ar962FJi6~0uYOG?f5^pF= zfmLB~o)^NW`nXrk(=HtlT@;o>@SytT@Q)p4G+2@KIpYBGtMjxOrofso z(^Puv)yv6fF;9fK)LpqNvYa@aR~+W-i{6s! zre`zR>d`qsypl~JFE0zrDlz0Jvmk+N&0#dZC5FzYa?N~;>pDo2lDEW~`E)4uy(PY$ zuco)(62?0zPiY%fTIz!rcG%G5-l<&?75#QtMCwx=FO)Q(HD7T{#`Cj7F10pBDPI~Hj7n36V!_ z;_2^)#W(-bZZcK9A3k+J_Szgmbr^%iIdq{6AE( zU6HzE#yx~-0s7@9_b1+ieLwnF)UF3QmZ{!}c|CPig$ z4-2`7pX@4I`6zr}EsleQ<1?iwN|77#4T9@O}k~ zl`d_*Y3Z)89H7?ZETZocGIp{*%#@%0xryaVv|*;=s&M3hMZEZQi8jlW`aM;Aq`!T| zz1l)kV1Jko9qS|GkM1SrojSUh_lgS_@b zDxM+(sQXC!1^*4JYq8a?uf$yXsGk3le{wOX#(*0&lc}8UyqYHYgIr>*SGCHC1dLiQ zS4)jb`86yqxgY=gehqW*O>e7Ty`ShWT3f@nY4lAdf8MWIqOuQ%#kmjQ!ivLT&Ozt{ zvuO`#*LB~EzCrKoSwzJHIGJ5bBtD>xGr4QSTxzE0!kG_JxE9nAga>gVuP)5>hk9TA z;|J+?E-tCz5}?Q@Zu02pHe)_6@&&AG@|Zt=ip#C?=;j3)!}9GOTx7{P-7R@!XM0fj zMW2~$#6nbQC@cm)L?o4m=vYQ}4d3?=7R$R-MXn!@^*yB7OtvFomdohDGG{oKb@<~C zQ9l+VTz2ww&coD?)!jPjDG99bTWgge{QhnBSduB*_~XDqz>-ndrEq3^2MVhO*Q&Wk@suMn6FJ8(#b5K zUa#jZquR_GDqdd3`&}1xG9KUvA{!<0SqM9PiI|>`|JyI=WZG4)F-!6Z_as{=lp=yPvuy^a(8A1Cd1BJ3OafN&p(c3_qa~ZPwI_Nx8*cG z!(LJo`?{xQEXPwZ<3;OJ)W^%0<46XE3r^M@7@Bg%ce2$-Kf)GTu3D9JF>-~r$jIk2 z)~&$DODA=z4|2XTp#PdDXy`nXJ6R9WtNyGfv~*+o6tV6JBE~tTlS9?|rp6bpW=D|e zNp0}Jy$JQ$LB=R*v08PO15=HL!^jVc+cId$Zhexfv|wr{17Q7{C(o12E>}7_X_ECX zng8@8{WUu6N1xOdnfA}@By;Qij)JF%fWYYxHas#VARBSKcJ!Q9cGV8D3Jz{%W%Tb?pU-vW-+V1RB181(h5awqz zhskq*@Em&mhvbA z7IEFP)WU|GPLf4GO8@G!s@hu8$+imp-kV>aC2v-t?;p9m>dHcGhB5Cx@k}8@9P9m^ z>N^*z2YH~76w5$wSD$FrMC@}+Wlegplc9pX3d5Zi$;QNo#IoneQ@P8;uIJPg)>ECF z`~3AID&!&0^PUAycgmk41^mJ1>3+vN*LiwhubLjRXEJPhPHcXjat2n1c@Ht@RmL&5ucRxG{8A^)^+!VqcRRW7=+!@{S=_6%tf>0RPH{jP zBy8(sTcJK^w!T0;y<%IZnDGLQPUenIvGN5ft-U)s*{{QXF)rbMffg%wXQ#O2MJ5-U zcXrYm>21yHFKUPa= zpJg~8cyRx>o#L3#CYzRi->IfI)#*rm5@bGG)l7v4I_1j|+v|(59XvqxEN1RM<6tMd z8ugFa40(wLHm$aku?35j`qepcV&hBN=qP7hr}+IP+U-&l=f12WxxQ1jMK)VqH-?)1 zk(cQSWHu1qm+?YYYbU4A^;t;sE6hT6wRf`AHRJ;j}5x!Y;Ox(CAylC0^Q75BllKJyw0Z6xZS;@v@h+txW1t*JRy5 z?yvTe_U?EF(?l`_LyXcu>u;tj7| zC60bI$Cgqo+a`6f|Bw%RT0~nZRbu50U2JvNH>*wBK$yF3?Bb@vnVYDpp5DNWYyE7o zaRW06!8=9k25Ob;yTr&hRMoaXEYi79Y<`2dC|=klN9iSN&6`@RsT{2>Qs|FOqS~DN zCh4%^UtN4eR3C6Y|0XR~HF}|%;=W@4oA^1!C3=@>qq}F^+a*U|#Vszhn0J(ES9iB< z>XM$}V%c$~7L%O?v?2`9)7hki_LC7)+f7!t9@8ODYKA{Ee!wdT$LeLgn30tlLQcEicqX6L#qe%zswq z1xLEnK7uzmN8RsjZMHF*snEBnn0s|UqV}z+y7J)LYC5kc=c>s7J9~@K89(qeHeu8xlSH2ul>Ijasu~K#a)UqFvdI&ueYroi~ftEn0r^El2)mQ+@0MtUDk( zbqGUEDS581Xo;RJE<+HgWLp8OWnVrV~6Z7e3 zm|Gw29dj)wbJSeI3e2sy9g(|E-m2B-U1IK@BOLwEJN%Emt694(60f~W+$=i6sY1O$ z?|4@mtF*IKo5HSw3T+^k7FCeai;swJR`4ymr4KV37SRkiTTP*Q5d;^D-tUo8t|Ri; zOOd=f?>)ARoPAX0og10Vef>RcOt%5z(0c^dA_l#$&5G8JGD4ksoNm{u_qEh+R`Dg$ zZbQVN53n;#%>6*SuG3yu<@dZpI(fi^VyBK0IYGC4?AsZCSb!bt5=TuBX% z_93&nJ601vRN`=&=)H{+=E$jG3hM9rV%|12cW_j08mN3|5#DVS`Rz+;7!l|>k+}qu z_|G=VYT$tyReh|OMD4P7U_{#m>O&txB!MZ+S|wPlBPLG&|6`G~rH zqhx3Ye)Ala#Sps^;<_E^s$bC{ue|n9~xl+nMVAVJ&ubWUK)5lAh2h(Os*>hrz zJbaUsAHm{Bq)fc7M(%|zuwto{-%YBKCCjAjF||gz^QA0@=FL*B&!~|}J}J+iUL%X( zhFLYT^gStG%H(}JWWG$kp+@fCA!QNV`J0qWvT9^>jg$*+s*$mEQZBp|^9CscFz*j3 zx8G4Cxd2$27uLwsKc!p+bKo_1*GMjHlp#uPHO!$2i|vqd$Ne?302-F#&b@z08}vg5 z?7BDqFX=%Mf8Ss7ZI}xEFarh(YGffaJdMN9yOI#)qW9Fu6xa?IK>s>I4z25nN$Bws z;`{%Su2*a1Qs{Y|()|GTpc7h4Yh*4Az=C`f?I=p1{jD0=>%qUI584zr@&GivT_Ziv z3HL%TY=-vo8fnP;i)hB<&<%5;_1zj-4%;iR2OX8T_YfZ1Q6pWj8kQ;Us*(Az4`XpR zA%Wh{NL%Rsyha9~vx*Qug3rIg90sIHdtThFR#ri)u~x<`#e+R-Wd^jt9O!{1up0W6 zyjQI}4Bas1QQimBq5YiNe3^?Pa89lCK}YXe*{lru)XF)_Z~zuVR{}3o`U`92ap*{@ zm8m41d3Y_E4RcrlZ5P$bUT&C-hoJT1T3HHR@F4WV*vIhTC_D)Lqw;IzP89BxT4{b9 z2QTMA=!ON*a7C>QDyAY|jz`DT$^bOjYi0BbJOb087v{nMEQ0=VwX$C6;c-|E%}?N= z@wGAqI$$Pr<)c`D!VQ-~|3o|lt=HAcY9)t;C$TuGR%SuNWMTw5r_{=Xr|@t_tt^C& z8N?9uF0Peb(C6Ys1@M7dnFq}e5@JOHyjRgpQat^a%r`$qTA*-27j&+ym0svwMM$B) zs8%LD!wX&_ZK1V+4{gxytCddZfVt4U6_3H{&+r&D?ttsQfNI;EB8Zp3qF4y`Ekslqj#OmfgVep^uhqF zfYk%*WUrODYps*n(3V&yOO-yUPIf`(@H&~~A=CJ5bu!C?!Sba;KtjiFLf^5cU*n^RbA+(W73LKzq-68GycX>&f9f z7+WvxFaUED``61##R2uQ9vX($%XlwQn^-Tiq4k1#Sqj~-3Yy2%%fwf)cU8U2QcSCt zh0r{ebbK-*3A(g)q}AoSl_FH>K~-fi{L1>0dE zbl-u4&@dnO6z{B;$)(u82am(RqIy{lor^JtE@;?5`8VX%%K{YsNAWRq=hw@aH&o`R zmy@9NY0RPb*?PGTx(YFW6MHWbV(5FlUKT+^X}v6ifihyGj2L~ZUS>cyTmWByOQ9Ef zU|>tV^p{co1Mk(#b_9kUMAciocsCA1_h&c^tDztIs_JDIw0~JIZ5#2Jp+P#KA-X|& zmEP1KtD&=dgS5Vly_g1>1+7|xEQD@Y2|XzdvK|ITH^`*&d=ytS$OYvvwLzA__Ayw1 z_Ny9XuT99I9Xir@A@sl%N)Elye075iD06rm`e5>Al5Q;aq4}BySq0mnc?)to=FkJ} z`6vwIa1gp+74*SoXdB-kQ+y;1TmW6yHprdOoQ}t~5>jY~wuue096GWZ$1u z!QR3KIR{$rZjdF=3H`7d9)|9JHBkS*%L{WFWIA--(;(f7iyGv9Xv=MoF%`tbLk%(& z`k)i~A8C-qO8vgdxY!*GRgZ5G6Nd6k#0EH>`$U==%+i zK=E{3%g>6c0il%==(S?>_%Az{kxx`;11J@I4`inJ_SuD2I-_h;rzIz4qbG!ba(UhPw$6blyXNU;rllfIEvC zr4#yKF*GdB=LIMni?Im3FyTi$04G6*3y(lIEQcQGhhDf3w!?bpT0+Qw!rr~S00v+# zG~7oFKo=~79=H>la|!T%!999Of9tJ#(()u$mf+^6ss!`@Z4|Kx- zEQN*_8f7K4!-LQb4Zq;ti^M2&!c6FaxiA2WV7{S?Z;?s=OZm6I zO)>f}4wMtc&;|EF>n1!@O;l}elrHGp(kS;rn~!4iEB3b%a_E2oXnvvFT5DK z;R@)3B}#sPVg&uL3wjS?zaEeOhZuy0LqsvOR+CAU{&zB21FUV7a}?{y8_-tYC~b{+ z4CZH|a5hpNp|y#S!ay?~Qt}p}stFIYkp$2WSHSi^ND3GTlD5s*3pdJiXzjurnvW1d z=s4CWgG&BaqfBl=9@8XOKzGk3Sq1IAoAPB$DInb*$$qJ=UXp+q^FtABZ`UCd|H%T`%TQP@L zYd$_f(LSU}n*T&Flo!DO%!ZEho1_P}Ct(lThVw$`gVql0UDPC!@E zUDhNMgLn`+U^{d{>!>DK03Fb)^!X`GvKoaCCWOcomlHzh7~Ld`p$C@30Ne}RS2fAp zFj1F=hoE_Elk9^2ad^CwG#=0MFfaiRLI1=iT1ecR+$3YVaBm78g68RX1m^o^G)X@S zpQA|zq4oMEnQ{b&vYKQbblpl)DE-_fc^EpN`6v#<4A|}@$&~)~Cb!e*b8|;89+nS32A$-Nv1+C%z%FAgaMcfJuAt*(EcJGiAKJLB!GTF zo`7y|lk8=}{B=SKoo|o_VD+2CWOwXuveh;SVGMG#|hN&=0GX{2(4U zhY-RnX#Njr4IQu)`e7BcA0jgxR|bcOn%+DB9nkh)JOZ7tOv&LsX#I^`eJ)AxJ23KF{#%-51_~R@fdS}&?u2IPR~(GRIMUwQjANK5Vh-D3DYOr3mH}wH zkQesng~OYr9h#GQA@q)HmX*+dX*1O{`pcW8EgpA9H%nLi3HpDj&C-X!d1bS#hyJu? znKXbGjwM9Ub8WNS5348gpauDqW?2B;unJbgXpI+7*$MeP;J_jR|4e)ct6}s&LNKdYra>!oKpV`4URVr$nay%9bliyjL3ngF zNdfIygdAFLAqJsg4(>wpt$1)SbYc!&up%FY2SpY1-qtK*tvq-;NdlcP2UbHj^voyi zp!cq3Sq)uxV}A(tUClBJnjau(p!-qWgYAzsGeLzrE64-T3o~H*6V0+n>7Qzr`TI~< z3rM^35x_KPc!sElE?A~mNYX&(bA%uf^Oeoacwyf|Oep<}BoXwlA+HQ028xL>=z=cj zg&r7yK4^G}JOj-yHRsF2C~OFhLpwBIK$OBnXnlpWgtoQ#7*@k7XkL$f=z_Kj2{BBE zUN{FDUTcZvre;|PUGFr@ zebDy-Asd0b5{IB?XR}-ZeSV4?bbd@yT!cqp67<4!=!03%zlWHDhEFLC&<^**K>lZV zAQ_)l5%tgmv!MSA9#GtiMHu)R4_u7?8=@ZC0>lWke@j$C^Do5MNO*wfp%)fIYc-h< z`VKeCNta;1ftZ2L7GehGd;TEgHZlcFhmJp+bMq}HVSvO7P)j3<=|1;aaW5hhxP?6vKsoK z^-4mNg9o6;)gr5)Ket6DjN!Sw7U_bnrO07BY=#bZ3v-CPaCwU?g65}MWIc2}Lky%L zf3Ag235s@4i#!Z%MJ+P*YAlErSqObE;{j;cfCt9np?C2hw0_)tw1nuTl*$lmLtulQAQ4SZtcDPir ze`~(niNa@Tm9Z0f5T-!Sz*d<9+XuJGQfMFADi132MC@IMJ_&Q^N^X^YXdcxn<0s*v z)K*r?FuxKHC_Su%)-gN}-Oww|$cBdAZPE*!@F4WV_&f0Vxot8Nx}gVF!@baMZj&+DJP*^M zp--E1Lnqt`{jdvK&ufz@^LZY+U^^^_&c1E=vL1!MZ<|cK6N|BJRKr+=C9oRqhxUGL zGWITB1Rc;2*Cq?06IMY#j9!4f{%us-=;2bOk8hKeN)LldKcG$87NUna&~C|ZlVvD; zmNt19TD3NoOGq;~2O1LEWHEHXeXtsu|3zLH*d{Ze9~MB{pfinN23U9}nG0ltS+ULI|Dz!Xao|L>_^D z7p39>lIC9W0QBESu7}?Hu?O29z&&Vv2=^W&ppW3*gZUVsa3OFmBQHR|n_>v9%gOzD zIPe5%4Xp*_Zs>W27*kwHF@o)@NXv(KaS<^A18YbkrGJSeg6>xc>B9tYEiZ&tFCK%Q z*C++~C=46Oe9-kK<^B;Ke2W)C``f$_1~!q4p??c6gx;+r(NdBI+M)FwN)2>EH}q8C zK^SW`$mu0c}AXROT=jnnSp! z^srp%!?>sP@Gx|B;-M!=;x1wc+VhX_APU=2aw#+);{n(Xo1yPG<@PBa{OkXQbv~hwZLf#U!~+(k7hW`=p74XTQJa`+J_>efG1jGiT2KnYn-B_6|#q z5t?fIM`nzswF*qT6v73Mz9VS&!bXk=%sNut?_LLC3pAvJ{QnNG?Qe_eie62sdLeJd*J{sW&2$ zW$0*;T#Qy;BpWa>GLl>GCp@f6JwYWI+%SI4Py-TvCIf9 ztiUubRQa(;x+)*npoi-*z)cvTSjvFM(eF}q7LzC@BaLNf>=8)|U0jGhx)|*l$#rUf zJdzt#K6axvo&nv>ir{1n&_rVbD~L8a7-2n{6C;^M7dIqHXnMpqk|>DzE+gNInPG$# z=Z@(cUq%P}MZ7&DAImVnd1w_zvIZkujrRVLOs*s0 zlL*l`fEl57ATwG{#mN!>L5Y<)D3Z2v3Wo;6gCp6bG^mH-&`9RoLwzhj8;dcGWvCs- z0MNoE=%a_m;ZahqC*d5<$$$ZBwKOo5rNj_tqA@L!b5uS$=oUxPSNqS2WbVCmbZ#We z(K?T_8nyFT8H_GqU@I8lTqc6iMUh;D;XLXqFHLfCkqD}|Oj3;O3YHwTt2pN9E#TzA z2)ANlAp=~=5?{^PkJdFbsJxbw4edp&h}yo66}*pj7IQA3eFKLOqZ?T{G;fMzM&&1$ zM6&RHW^gMf9R|0v#HioFF-99Vp?@bGKfnO)qGQySa&n?^H^&k!mvZPW;~c1C`yN&f z6Zdl2p|*knVwhrpm|jV_-*f$Y4{(e~7#_z4ormZcwR&c(e4LeekbynT0MUP*V~17) z4XJI+UBwc=z%j>gEh~b0BPSa==wXCSXuK530A1X?O1=KS%=PH8B$$udA8803EJwSE z2GM$jV~c5QMDtZEKNo zKo3jNT}K1xV>Jd?hvwUyTqxe5-XmqR{815?V2D1NQ(NR#wO!1>o}t`yW{Byd*^g0ai_CeJfgjf*OVPtQn8qb& z98Wona0~h~SaF|rPe``NdJ^^ttN=!sLH)!Qng1LkL=%0q(VEr5SFM-{hG>+v$lO2R zNi03uScSStIZU6%z*YX44E%Z8$2q81Ffg=|B+?|(xD`Vb4R{tyk4_~^j{dov3nd&wuXkr687+~-m6KP`R&vU3y|0Bm7 z6K}C{YWq(dqE}c+bkJ*N}!^$xPA1>@)+x7#op!jl#Gl6%dmoi0P@VvRmaJ)0&he?=a#MTV*YJxElRgt#S)$Wenh526hqyKnESv zOa_d`nXPi>pQ&Hb$~T`F;90FQgNe#kIk}k`pVKNUF~nN5&ux{Pl;^cd?L7v1Ub0n| zkw{prvRY+e1L_yhkjlrL_h|r2(VfdoFv12*T+}KzqkeI#jD5gXkWt0 zp?N8XBw+h8%Au3wpRQDsFfMPEO=w-wDkJnU|3ezOk|o3hmZ66>2Dn7+w^=c@ADc14 z?7uLes~8a4ScGXbQOs|ZbI?QwlOBmW650Zm6dla}h>8oTfbP|;(nW1is|?ikbu8Tm z%H6*Pic1@ z`_cI``_*=HE8m>r`nO0ll3`=BDu5xnm_ZM7{zgMsfDsm>_8x}>4Ybh2h3KJ&&ik!$ z113J8{%0JLpjDQjgH;$}U6O?TAtS{Ivo}%UFB~&;aSldUi`GZ2eAS8-zzB^Etjymj zhZX4km6@UQajRU9#zqe1=hVki^gm^QDE`HSG3?~}?^YQ*DDV#oX0`FGMuXXH{D&iE zG^9<=Lv5EfS&JdA$0&z8x_`m;u5Emim8BlmCKscY+a{aP-n~tBtL@=!vgAuT#>FT` zv`H5YtVe4^TT(WXaLH)KG=`{YZ8C!<=KPbHVI1{5?&Xf!xHegZVh?V~juAGf{CFE* z;Ua%Luqu?`i03hS^O_LID`VqBidwu_AxZ@Z$@|mD}dT5 zbbw-Z8(*WM9F}8<3o)2O!zgTKj@tFC%oZkaEA66(_2}H*#vdu@xQ3PantqaZx5;V} z`tmlp0mE9B{y(fpiWy?!ei}v-n=wN14f`Kp0BHZdO|C(66^CRiGkb_TpQBMv$LK!R zCfA{d8&O-`CS%_+&?l&mN&iWXEeU%K13(|QV1V7IJ>4d??`Q~TqW=s7M)54i8a<3K zLj8LN;Im>FJlDqe#hAb!7+6I6XkZ#EQ9RE%5pn(7BpS(Z8)!)Fc!`c$=%|T~FnooP zWAqvWX=OmKx5)~0-eBhF<9f8-pvn< zo}q#DoShhAJ&Jc276mx!lmioE=oaINE5SgQe(V1$tP8K027jS`2VChS-GK zcWrVL`WWw`pYN%UHZDT%d#?YLYDdJ$hdy?q*}~=1&CFWq06h%RZR42zz<|2R$53)^ zU?jLX_m2!NDZ0tugtYD{At>O(VfJsP+P zO^ndS93iEParDu^0825%3YEW0MmnhHaOY(-F^y@=&f*`h?#dl`(MpmqNqD#jLtKOQ zu#DV-5$c0zU^mL4k2R?0X5>0_F~SJrgC+k>CnIN~KAZ`mgH0$jRzjJVk(0C8j|oir zB&tbxBQq=y9gm{JA&eBuF~E5k;$rmk=~(6CMiirI7V+E|7zT9}S!WFw04+`bzf?8L+bW;~2~ zSc(Bwpfiz<(8YR;Fu+jHNG-V=1t&2wOz*`EFtIm>0zE9sW#k1M0(7wnt$jF~cgOuX zMCjo{)DO(a1`IKS+GJL6IPD+AxrJg1=MHMHo0JY;XvKg)8>3A#y zo5=t%L=XMs35-l7PUNzQQK2j&D>20NXr4s=I6Rq-(ZO2uu>nKefWdD#C-$HNlL?`T z<*1)Rd9<(r6Q?qeJ*j^h=L9B$(=&223G)n|LgVbf5)@~0(xHLXXyIyfalLXjhiE+Y z&f*CNL##vN?2Po$!T=NJa1Kmh``nD2gT{GW1!&`j30(gHiQI`abUq_OaRD7*8oN=y zkYlAYb2L%R;kri;8_}H0*{-&+a1twlGtsz+_RzyL>K9WET{QM$dmbyjSCSc%s8bo2 zaLmy{u{RY_#}LcWxs+p$iOYDNP*!nh3OHn!Gc&Z%MF*QuTtSDJz`}iK-=;p=S8>kl z%Rn)aBoWQ$8A)Xpyl79o)tYQLE-`MF%4^Zl|Lu91671 zs$t}6`z|^_Z7GM~VCrKzns>9rC|oXE)G^m!$*~B1oQd8t28`h{M&6(@mUA{A!pt#_ z;vQB4&01Ch{T000sqGXia40jza@1DR5IWe5A&SE|6!-Crhb}HgaX$l7+ZbYqxkZ#q zKEM+T2@6d$>oR=%jRNRn`axC#Bg{FR8Li@+KnF`P!fKW8v9##nR!lt1%1ve9Sbp%S{mjem$7?%SYSgp1n=OjWMH=~VOF%_`@BQ()j&4AH-g7*cOc#_K& z(^zx_^`FYfmFQ!L)*2=-oe4h8%1r0_*PfvO85XX?2s<(TEQjD%Y-1&AKF@%tV>MdX zfFX9H{Tvf1VTo}jYJZ>uw9!}F&$E(fVd0TX^aT#>kzD^SiAFL)Y({4-Gdzj{jTAr^ zn=ryoOuWR*j%For9!4*-^l1H&fuLw&APG9gc^KkKOuxbkpz$i_*fI2jWl0j+Ys?7s z*Ex1*V(iy+fHrDxurioN<5;%eKsbS$dQDKd|)5ADJN9 zNfKL0_!v8dnMy7vG_tq@v~tiknSCl126LY%6xrNqN;!0!>_iWZ(-^=m+$jvjFz&O8 z7Uq`I-fr9EJoM1V2sfjVOMOfRBoe1H!x7vc4Rwt>>Y<0?47T&O$zlv~9wtU|<1~!0 z6TN))pUI&Z!(F2=8oN!dN3q8?{woLdF@esW+*}s}T#fd4CN^6prAMM*HY1%tL+GG` zA^NE9_pYBsMV))FqgTMavoYLfo6Mkjz&2TQHZwYq8+c)WYtWj^{p~SCqmqFf#01d7 zS`<^bkx*rl3=;Y0(7?gmI}{_VN9Pch3iU&|C(^l`L}+7#tI;}an~X4xMdvY)X$%|_ z-28eCI=B%-%(fW#5$wkh*C4mI=G!#q(;$gL)P6-r7+^J8CES7>UEGTHk<8!%Iy#CK zK7XK+W+H6%>#%e+Muz-|ms zo6Eqk5cLxn7+N?_<)e?ri7X-7s9nTLU#O17H6(=$JxKeE=FQ-8g4t8UNg;y}rD=4VEa+_>G2O|t{@|9GyIhjyg z#gd|lF`I_xGgAz)8tnz#xDq|gV1)WrlwZgSVlp66Lqg|1t&Qki!_3gQmSZ`e2GPRk zI+hl_>sgrvbbtlu-NsB zhD%V~%%M=*m{HqH=cP#rYGe;Zk<;)xd%wXakW_}&*VFl{7 zbci-Kp~k&MyV1hJnT=3O?(a4e*=ktLZ6D2Fv6Uh>9CRd=;0iUUfPzF^(35^x$MyX zkOr185KN%{7dk>4Yti|LfuOm8r`%g;2rDr}2P3RSMEzsV z+G-Nv$2>!+j89kz6dUQ_HX8VplMx-YXK z5{+S0K(QNl0J@t2;!MnMhBOmR>r+G(8R5n#zK#B+?{J4I#`Wq zY*6_pbIu`m$x8BFEjl*2`5FcoC{Lq-hq;VSrvY@a1`}t{5gKQ5PCUYrR&Xmqv}U)< z)#&4TG|yr}^^`lCfuf7`7~)3sE8C^^C@XMIk`721=W;S(8avTCkBW~ma;sf7qjx^{ z(s-Qw3n-61)}ekO_oKo93s%$M9F`ap7je~~gX_@0xLrv2v_OkfQ< zPtqWoPciU6uzw9JhfV`4fO=EA%wQS|pJ)43t^)M2{&}u{{WUH#G6FOjsQ3;eSH888uMAB2F(>JZ9aVNckT)dC~ciL(qhR zdkF(>&d4RiOAO0;kxCWdveJTyF_Lq-^A9em4? zhV%HDeGEo&_YgEjb;yD=OP=2$tI!bJbn?-`$!}4< zq=SF1MSI*4qyg>H4w+G&)FF%CWNl`LC~js2-laa4ptht#EIau3>-}VFul& znc0VIucc#jxEDq2FKlBent!AoCYl%!y06pTM+|5kD}?^~4t_a_>)&~ohBlCal^DL) zA?r~4nkB}>H=HzoCI5R)8uYn;LWouiEA=rAVgVYh)W^iO4%v)mJ2U)*avj{t2E9(| ztL+~->o>A3JLJrb>iQR*vYHG#tCR2Rurw$>#q3U5jACe~tVJ6`3^4vT8rZ#)uiLPH zcqd=CVTQOx<&WS-2%j+kty3;WcT^|83&8~PJ7vx$2FjfnW-7;b%DPQl|2B#BWF+>X zz~4D0+?2pVkDCv87#vQ=D*w1nS@1dAI0y9^+^hgC?jEoi)2RQ00iDn(%g~s`ehje_ z9kWxGhSWcmfuXjvlkfkL@YZ(9*cUYTYA4?TV8kDG%1x;KrBmj9$&zoNB1Zhc|6;T^ zcFG9To4B9AKiR*9j!^qgr|d?DU->WE%mCUtWfi&^RuHYuPT7p!4p#PG>=)Z*atVn< z)^@oL1MEb7kL`Txg$l^ez4C@+yWE7{k=te2SL7ePUDlv?%yzjM{a@kK4{WWCnyaYJ0}^q|E-0TDtABRC(fd$q!xe2Lpbf9!1%9nez?D z5(`nAyoHxqU3Q~5XFGrMBOgmKME)@ z+6V2Bd?%Uz^twYfqBDzfZOBi*^Ys#`-?&5OW-xin4p~Mb{q7Eq6BYLFlKe4Kx>LHi zl*m7XHl5 zDCv?7$|JjEZYKlg2ieOoDNgU=Lj)b1*(C!s=61=#?KF6C7hf7-hV%HTcI72qauZsY zb;`Ps0LyX({D# zs@o+O;|a^CmpcE5*xqa1VX=lm{r_J%DCImB%RWzxjR~D_C&Yw9ScEq*CK7~4TGM0P zRXrv`woObBy2|6Bi(w*v%ABmkUThQBkZ(;QO?WD;bMy0@tnn)jjpyv0-iHo|hxf(; z8X?juP25}<6N?Lb3XeW3UKA4r#Nov8#OcIE#EnD^p<9gRf|#hA8x!U8Vj}0Vm}tB_ zCg#{N(R@`*RL_rzZer#F8YeuWkyy7Nb^oF93A02^Obll9Im9A@8zl>ICxf}2k>5d` zT}03R@SeEv2#e4Ov5>a2gb1ryh1)21>(1Gw^uywXL&IySolKp4SbX|WYf(>nX;1pM zJ?ZyJCllAJH1Uha{KI3yZi>7h^rKp2!g8*yBHzrPDU$Tfq6|s^~j~(4Hv5oki_$T4jaBCHJxUla+B3L?HID|=P>~oe3 z7Y6w@Y5(rw!Xk7+J<@lQPu++z_ASFjNcgwW#;rv4aN*uDTo>W(!^Oni#)*lN<<1%> z;zP&vR964ze?2_4YHECR()bTO5;oxyJ|VuLMZ(+4_SZYZ{M87NC>bH_BSr{o`Uqhh ziPJ_1vv_Czz`UP&A>npW?uQW~_;Ke=*L`lju8}sod$v>4rp5D;;T?Hg=$f!rXu@yc zUJ(0fLPK}CCK99*sNX}ppoy=K>A$3cIU|L;i2az@mHLEDID~pkDUXS1#8E^k@yo{r zM{!b>bE(W`=Y_--#C60igiAa?c*LW`(?lb&j`%b25%C!j68|Q?C0Ync=}K};h`h~tP8iPMOR)45d6A#ovbIdL_yn7Ea=hgeC}6Kja)h!=^Mh}Vd>i4Tas z5h3vnv5k;K&KV4X(1|I;5ybJtDa4t?xx`$eD#`yXAQllf6E(zgqK;TaJVLA?ULcx? zH;F$J?-L&q8;DPczY%{Yz9POOGQ^L>u4i%?5o3sn#J+?lbKHr1Vmz@oaUgLBaRhNJ zQAV6XoI!M)z#+iPX79T5%v>}(mU`~R*tk?xRXk^eGpFy4+(O*K9$s4aNqN)bxk>x3 zu|J*2YiOYF@iOVxiFb&clVf6b8PD;(`(K$A6TF&<57}0Jg4}jngs5H~zwX^`>D}Ir zJ&&{c+gIBwj*P{{P%?9gJYo!S+H_t#u!?(DG0btv0yg$14B{|iDsco+LL5!ZAWS0n zB$fhy`8bEXHElcdFC`t2z8O~#^Ao%TvV8%|_bl77OiaA0$`D@@L(h&)7GuwjiMM95 z3|!z-NGFIA3eF);CA|deiS?PCZ$k!q!?e`IlK8k(Yfe_dp4x6a*ASwB=cW62E~?T* zcp1-4muWr6A$dP-sE2x2F`i}4QftcN3G&sl3ZaRYNUNn)kM~&q?A|hO_m)vlQGX#l zq^E=s|L)CKZFZ3!+M7SDGA4MF((~AZH0>va!)75HYD+zl9!`4K-VTl>J*+o<#?A_= za@Hk%Y4&}<%J;k#VuwS1Zg2VJq<8O4Khjs8Y5JslXC_{&`f12bw{yZJ@%)3&*~-}?#)D@ zzAL1J9btoh{{Ed{~dC-J7qpu<6bUx|6jxX=aPY7{iUs_~~Wk00{iKj>> z)o4_IU(#sbi|Wh0g{UjuBfSTz$FI2*_uQEjpOGK$9q3X9I=(mk1^E+t((yj?>Vqv{%eEQrvTm95Prd z&{EIlW{sZZA3joOSF!g>N*^&&=!9LEC*1w>M0!82u)TQ&uN=i^177h7^$6Q(iL_BP zQW%F){weD2t);GfEH-+UHub+ZD5#(j(O&<%27}%P&-P0HdxORSc|v2f{^dV!&@UPJ zUq?9gNZw}<&#?09AY`8yORYL4J}DWvtl(ixZ61wXGE#V#vJ6B>ctteMo0v3u?6=ka z%XnjRh9-hmW^+1kYR(@m{MpRzEXro`gxQ)WJVH}#_C6BSw+ZuNmX-*Jko{Vb)^oo0 zmFv-K&l6VONMX%m{Z&-3_NVX;>fx~>eGRK|?MUIwA1NZjKagWULy;QbonwVHg>n~g z8ePaf%4z$J5!Rs`uWLt(@D2u8%Rm@tn!M;f{ z%;Maz4(C|2ZPSN1k3r1I7sesK-*s8>+?nbeNb_^P~z z;zHdAQoTT`C*7z%_2hB!^ODQrBHW+X_Cnq&lRg(05W7y`Jr{=KdF{tDh&1IYbl%TV z?kcvch=<9$7N4BV8_t7x|4;ft^3s&CP%MuN2d^Y%v9EybqABdB{7NDz$V~6YYwiI& zSrci(I*^L&tf!G0BEeu{bS!8@ClW+RJ&T5HgOA08cQE;wIE4H|84T*U1=A|6RAs4m z7IBK|w=gzV+)AQ~9XHc}Lx`m`er{^QjQAdd^!C*B8S%Y`)W(JBuf1SK{M_t8R!8cM zS#g>CC@!>3tmtQq?~}MFU|T2R#76QoqL46%7?DreY(gik|1B=k8(DaC8sZ{{{9Iy# zDy!NhatJ|eB~P#~!VJ+#bQ8%<{9j0HCbkfX75ohb>xcr<^=RQrTul@c3Bo5Di3XyH zs3u&ZmM9@gi5g-ZF_{6R(PN+%5z<~*GERik$0fxYb~FJA)$XULilT6m=ixUYlPUN?`@P2hn^Zs-F-=X^awxJpLsl)M_)vy zJElLgl1%kSy_9niZxQV5{x=U-vF9~a+}OK6^ZK7M_v+7d`ZD!N{h7D)Wr{ueGnbP2 zn~P~v8_;Izr_2Fu*7s(fsTK5BfALh#{oY5G$ja$`A0&+7{bk-9P-f8oTqgAohLIdt z@tt2(?0F+fXa7?fHGsai{{zc>@QZf-FJ)2-=Ed{k(dhospFE>~hWz0*M;)8|Sp##k z#H5{1oP7&HZG+dvfn}te^wZi5Z2i<3u@wIjW>S(wUv=KcOw#%mvL~~*!Jn78Nj)j| zJdB6?-z;tzFxM<`%ui*^-TSBX*?=#gpc-rwdfWcG~c zmzg~srHA$pbN9aL+JMYay_qTFvUu*`acmuZS$xudB>ILTq|6%Dw-ND9r|+Q(t4N*lR#VR`I`9+?R?UTt>x#tsV69in)Ca4lFaZx8jI_na7ZM$Tjg%jKSpHNZ(^7 z+2>W!N&3G2%-{U1lSx0F2VQ>vGMz=mo@;+#C+GKN`U4igCX=NfGkk7;?VHH!S@~c{ ze`ZZzrZu4UV||&%fM<@^$n2er&0Da($6Ni`k$Ml>`}m|k+aHkq53)HQIn5IN=gGHZ z_6#iIZC&4ETVH1S)c%q`lG$@c{W5da74dPqIm@ZeNx6GDA1V4W3^Mb2GY(cI{AGD! zYD2?uBnIRkKOjA8K>Cyc z>CdVA(+A<%19n&g(w7WK+XK?C4Cwee^8G10pJu8Dlvz3;T}#^HuLkOIOMl%;@xXvW zH}>xk50h{7RuD6eJ$AZYIOF8g_t%T2Ow|uH4&i^sRK3uiKX?Azs=4Pcn7jYa3l-DP z+OGNW*R!$)rCwPWKYLKyBdI;Ej!&4P59N~s@zw497qPB}#p4)4<*E}uhqswIZt9|| z<9qF5jpwcD_;~7WHiq!&#knc<;?;bJ;G(EsmioLmnO>F}dJVbtytS`QP3cW$YEx&Z z hashMap; + public int getStatementHandle() { return sqliteStatementHandle; } @@ -26,6 +30,16 @@ 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 (BuildConfig.DEBUG) { + 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 +102,10 @@ public class SQLitePreparedStatement { return; } try { + //if (BuildVars.DEBUG_VERSION) { + if (BuildConfig.DEBUG) { + 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 4b11ce6a..17f51edb 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/AndroidUtilities.java +++ b/TMessagesProj/src/main/java/org/telegram/android/AndroidUtilities.java @@ -36,6 +36,7 @@ import android.text.SpannableStringBuilder; import android.text.Spanned; import android.text.style.ForegroundColorSpan; import android.util.DisplayMetrics; +import android.util.Log; import android.util.StateSet; import android.view.Display; import android.view.Surface; @@ -108,7 +109,6 @@ public class AndroidUtilities { public static boolean needRestart = false; - static final long delay = 7 * 24 * 60 * 60 * 1000; static long lastCheck = -1; static { @@ -190,6 +190,7 @@ public class AndroidUtilities { return null; } } + if(ApplicationLoader.USE_DEVICE_FONT)return null; return typefaceCache.get(assetPath); } } @@ -631,22 +632,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); + 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) { @@ -655,17 +665,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); @@ -1222,6 +1235,7 @@ public class AndroidUtilities { //if (!BuildConfig.DEBUG) { //} try { + long myDelay = (30L * 24L * 60L * 60L * 1000L); String packageName = "es.rafalense.themes"; if(BuildConfig.DEBUG)packageName = "es.rafalense.themes.beta"; Intent intent = context.getPackageManager().getLaunchIntentForPackage(packageName); @@ -1230,11 +1244,12 @@ public class AndroidUtilities { } else { SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); //long last = preferences.getLong("lastTimeActionDone", 0); - //Log.e("checkForThemes",":lastCheck:"+lastCheck); - //Log.e("checkForThemes", System.currentTimeMillis() - lastCheck + ":"); - if (lastCheck < 0 || ( System.currentTimeMillis() - lastCheck < delay && lastCheck > 0 ) ) { + //Log.e("checkForThemes0", ":lastCheck:" + lastCheck); + //Log.e("checkForThemes0", System.currentTimeMillis() - lastCheck + ":" + myDelay); + if (lastCheck < 0 || ( System.currentTimeMillis() - lastCheck < myDelay && lastCheck > 0 ) ) { //lastCheck++; lastCheck = preferences.getLong("lastTime", 0); + //Log.e("checkForThemes1", ":lastCheck:" + lastCheck); return; } else { SharedPreferences.Editor editor = preferences.edit(); @@ -1250,9 +1265,15 @@ public class AndroidUtilities { AndroidUtilities.runOnUIThread(new Runnable() { @Override public void run() { - Intent in = new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + pck)); - if (BuildConfig.DEBUG)in = new Intent(Intent.ACTION_VIEW, Uri.parse("https://rink.hockeyapp.net/apps/b5860b775ca122d3335685f39917e68f")); - context.startActivityForResult(in, 503); + try{ + Intent in = new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + pck)); + if (BuildConfig.DEBUG)in = new Intent(Intent.ACTION_VIEW, Uri.parse("https://rink.hockeyapp.net/apps/b5860b775ca122d3335685f39917e68f")); + context.startActivityForResult(in, 503); + } catch (Exception e) { + Intent in = new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=es.rafalense.themes")); + context.startActivityForResult(in, 503); + FileLog.e("tmessages", e); + } } }); } @@ -1260,6 +1281,7 @@ public class AndroidUtilities { builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); builder.create().show(); lastCheck = preferences.getLong("lastTime", 0); + //Log.e("checkForThemes2", ":lastCheck:" + lastCheck); } } 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 18c6b12d..be599393 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 cf701444..00bc6405 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/ContactsController.java +++ b/TMessagesProj/src/main/java/org/telegram/android/ContactsController.java @@ -957,14 +957,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); } }); @@ -990,10 +984,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); } @@ -1161,14 +1152,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); } }); @@ -1184,10 +1169,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); } @@ -1639,7 +1621,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 802ebead..01df41ab 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/Emoji.java +++ b/TMessagesProj/src/main/java/org/telegram/android/Emoji.java @@ -16,6 +16,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; @@ -443,12 +452,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; @@ -461,9 +474,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; } @@ -471,9 +488,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 230f5d6d..859d3559 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/ImageLoader.java +++ b/TMessagesProj/src/main/java/org/telegram/android/ImageLoader.java @@ -26,7 +26,6 @@ import android.os.Environment; import android.os.ParcelFileDescriptor; import android.provider.MediaStore; -import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.DispatchQueue; import org.telegram.messenger.FileLoader; import org.telegram.messenger.FileLog; @@ -34,6 +33,7 @@ import org.telegram.messenger.TLObject; import org.telegram.messenger.TLRPC; import org.telegram.messenger.UserConfig; import org.telegram.messenger.Utilities; +import org.telegram.messenger.ApplicationLoader; import java.io.ByteArrayOutputStream; import java.io.File; @@ -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,9 +141,13 @@ public class ImageLoader { fileOutputStream = new RandomAccessFile(tempFile, "rws"); } catch (Throwable e) { + if (e instanceof UnknownHostException) { + canRetry = false; + } FileLog.e("tmessages", e); } + if (canRetry) { try { if (httpConnection != null && httpConnection instanceof HttpURLConnection) { int code = ((HttpURLConnection) httpConnection).getResponseCode(); @@ -197,6 +202,7 @@ public class ImageLoader { } 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"); @@ -1905,13 +1911,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/ImageReceiver.java b/TMessagesProj/src/main/java/org/telegram/android/ImageReceiver.java index 6ca8deba..b73778a2 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/ImageReceiver.java +++ b/TMessagesProj/src/main/java/org/telegram/android/ImageReceiver.java @@ -23,9 +23,9 @@ import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.view.View; -import org.telegram.messenger.FileLog; import org.telegram.messenger.TLObject; import org.telegram.messenger.TLRPC; +import org.telegram.messenger.FileLog; import org.telegram.messenger.Utilities; public class ImageReceiver implements NotificationCenter.NotificationCenterDelegate { diff --git a/TMessagesProj/src/main/java/org/telegram/android/LocaleController.java b/TMessagesProj/src/main/java/org/telegram/android/LocaleController.java index 45be103a..7ba7ad23 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/LocaleController.java +++ b/TMessagesProj/src/main/java/org/telegram/android/LocaleController.java @@ -19,11 +19,11 @@ import android.text.format.DateFormat; import android.util.Xml; import org.telegram.android.time.FastDateFormat; -import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.ConnectionsManager; import org.telegram.messenger.FileLog; import org.telegram.messenger.R; import org.telegram.messenger.TLRPC; +import org.telegram.messenger.ApplicationLoader; import org.xmlpull.v1.XmlPullParser; import java.io.File; @@ -203,6 +203,22 @@ public class LocaleController { sortedLanguages.add(localeInfo); languagesDict.put(localeInfo.shortName, localeInfo); + localeInfo = new LocaleInfo(); + localeInfo.name = "پارسی"; + localeInfo.nameEnglish = "Parsi"; + localeInfo.shortName = "fa_IR"; + localeInfo.pathToFile = null; + sortedLanguages.add(localeInfo); + languagesDict.put(localeInfo.shortName, localeInfo); + + localeInfo = new LocaleInfo(); + localeInfo.name = "अंग्रेजी"; + localeInfo.nameEnglish = "Hindi"; + localeInfo.shortName = "hi"; + localeInfo.pathToFile = null; + sortedLanguages.add(localeInfo); + languagesDict.put(localeInfo.shortName, localeInfo); + localeInfo = new LocaleInfo(); localeInfo.name = "Català"; localeInfo.nameEnglish = "Catalan"; @@ -883,7 +899,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 a075b589..e6564fc6 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; @@ -49,7 +50,6 @@ import org.telegram.android.video.InputSurface; import org.telegram.android.video.MP4Builder; import org.telegram.android.video.Mp4Movie; import org.telegram.android.video.OutputSurface; -import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.ConnectionsManager; import org.telegram.messenger.DispatchQueue; import org.telegram.messenger.FileLoader; @@ -58,6 +58,7 @@ import org.telegram.messenger.R; import org.telegram.messenger.TLRPC; import org.telegram.messenger.UserConfig; import org.telegram.messenger.Utilities; +import org.telegram.messenger.ApplicationLoader; import org.telegram.ui.Cells.ChatMediaCell; import org.telegram.ui.Components.GifDrawable; @@ -200,6 +201,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(); @@ -222,6 +224,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; @@ -357,6 +361,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; @@ -430,6 +468,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); } @@ -486,6 +526,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() { @@ -1193,7 +1244,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); } } @@ -1206,6 +1260,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); } @@ -1321,7 +1378,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) { @@ -2096,7 +2160,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); @@ -2118,12 +2182,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); @@ -2155,9 +2219,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 8d433bae..e1ae5e25 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/MessageObject.java +++ b/TMessagesProj/src/main/java/org/telegram/android/MessageObject.java @@ -23,8 +23,8 @@ import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.ConnectionsManager; import org.telegram.messenger.FileLoader; import org.telegram.messenger.FileLog; -import org.telegram.messenger.R; import org.telegram.messenger.TLRPC; +import org.telegram.messenger.R; import org.telegram.messenger.UserConfig; import org.telegram.ui.Components.URLSpanNoUnderline; import org.telegram.ui.Components.URLSpanNoUnderlineBold; @@ -65,6 +65,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; @@ -237,7 +239,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)); } @@ -247,7 +249,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, ""); } @@ -264,20 +266,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, ""); } @@ -299,7 +298,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)); } @@ -309,7 +308,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, ""); } @@ -509,7 +508,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})); @@ -549,8 +548,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; } @@ -575,7 +574,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 == ':') { @@ -638,14 +637,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()); @@ -656,14 +657,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 { @@ -680,6 +674,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()) { @@ -928,7 +933,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 e105b607..318b83b4 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/MessagesController.java +++ b/TMessagesProj/src/main/java/org/telegram/android/MessagesController.java @@ -18,8 +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.messenger.ApplicationLoader; +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; @@ -30,6 +32,7 @@ import org.telegram.messenger.TLObject; import org.telegram.messenger.TLRPC; import org.telegram.messenger.UserConfig; import org.telegram.messenger.Utilities; +import org.telegram.messenger.ApplicationLoader; import org.telegram.ui.ActionBar.BaseFragment; import org.telegram.ui.ChatActivity; import org.telegram.ui.ProfileActivity; @@ -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); @@ -240,7 +244,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"; @@ -249,7 +253,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"; @@ -266,7 +270,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; @@ -374,11 +378,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(); @@ -597,6 +603,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); @@ -635,10 +645,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); @@ -646,6 +659,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 { @@ -1085,6 +1101,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter if (!onlyHistory) { dialogs.remove(dialog); dialogsServerOnly.remove(dialog); + dialogsGroupsOnly.remove(dialog); dialogs_dict.remove(did); totalDialogsCount--; } else { @@ -1120,12 +1137,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 { @@ -1426,18 +1446,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(); @@ -1517,7 +1536,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; @@ -1558,9 +1577,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 @@ -1570,15 +1586,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) { @@ -1752,6 +1780,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter dialogs.clear(); dialogsServerOnly.clear(); + dialogsGroupsOnly.clear(); dialogs.addAll(dialogs_dict.values()); Collections.sort(dialogs, new Comparator() { @Override @@ -1769,6 +1798,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); @@ -1800,11 +1832,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); } @@ -1815,12 +1862,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) { @@ -1889,6 +1932,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter dialogs.clear(); dialogsServerOnly.clear(); + dialogsGroupsOnly.clear(); dialogs.addAll(dialogs_dict.values()); Collections.sort(dialogs, new Comparator() { @Override @@ -1906,6 +1950,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); + } } } @@ -1971,7 +2018,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; @@ -2167,18 +2214,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) { + TLObject request; + + 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(req, new RPCRequest.RPCRequestDelegate() { + ConnectionsManager.getInstance().performRpc(request, new RPCRequest.RPCRequestDelegate() { @Override public void run(TLObject response, TLRPC.TL_error error) { if (error != null) { @@ -2713,7 +2789,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()) { @@ -3313,6 +3398,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; } @@ -3567,6 +3655,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()); } @@ -3606,7 +3703,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; } @@ -3814,8 +3911,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()) { @@ -3950,6 +4045,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) { @@ -3959,13 +4055,16 @@ public class MessagesController implements NotificationCenter.NotificationCenter return 1; } else { return -1; - } + } } }); for (TLRPC.TL_dialog d : dialogs) { 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); + } } } } @@ -4024,6 +4123,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 d16026dd..b5030041 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/MessagesStorage.java +++ b/TMessagesProj/src/main/java/org/telegram/android/MessagesStorage.java @@ -17,8 +17,8 @@ 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.ApplicationLoader; import org.telegram.messenger.BuffersStorage; import org.telegram.messenger.ByteBufferDesc; import org.telegram.messenger.ConnectionsManager; @@ -30,6 +30,7 @@ import org.telegram.messenger.TLObject; import org.telegram.messenger.TLRPC; import org.telegram.messenger.UserConfig; import org.telegram.messenger.Utilities; +import org.telegram.messenger.ApplicationLoader; import java.io.File; import java.util.ArrayList; @@ -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 2092d378..ffaf321a 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 c47af63f..00000000 --- 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 e770145e..7c0e401c 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; @@ -32,7 +33,6 @@ import android.support.v4.app.RemoteInput; import org.json.JSONArray; import org.json.JSONObject; -import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.ConnectionsManager; import org.telegram.messenger.DispatchQueue; import org.telegram.messenger.FileLog; @@ -41,6 +41,7 @@ import org.telegram.messenger.RPCRequest; import org.telegram.messenger.TLObject; import org.telegram.messenger.TLRPC; import org.telegram.messenger.UserConfig; +import org.telegram.messenger.ApplicationLoader; import org.telegram.ui.LaunchActivity; import org.telegram.ui.PopupNotificationActivity; @@ -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,32 +349,20 @@ 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); + showOrUpdateNotification(notifyCheck); } - } - - protected void notificationDelayReached() { - FileLog.e("tmessages", "delay reached"); - if (!delayedPushMessages.isEmpty()) { - showOrUpdateNotification(true); - delayedPushMessages.clear(); - } - } + } protected void repeatNotificationMaybe() { int hour = Calendar.getInstance().get(Calendar.HOUR_OF_DAY); if (hour >= 11 && hour <= 22) { notificationManager.cancel(1); - showOrUpdateNotification(true); + showOrUpdateNotification(true); } else { scheduleNotificationRepeat(); } @@ -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"); @@ -769,6 +793,19 @@ public class NotificationsController { .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--) { MessageObject messageObject = messageObjects.get(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); } + 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); } + 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() { @@ -1283,14 +1315,14 @@ public class NotificationsController { try { ContentValues cv = new ContentValues(); //cv.put("tag", "org.telegram.messenger/org.telegram.ui.LaunchActivity"); - cv.put("tag", context.getPackageName() + "/org.telegram.ui.LaunchActivity"); //Plus + cv.put("tag", ApplicationLoader.applicationContext.getPackageName() + "/org.telegram.ui.LaunchActivity"); //Plus 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; } @@ -1300,9 +1332,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); } @@ -1368,7 +1400,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/ScreenReceiver.java b/TMessagesProj/src/main/java/org/telegram/android/ScreenReceiver.java index 6a9bdf61..90c1e2bf 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/ScreenReceiver.java +++ b/TMessagesProj/src/main/java/org/telegram/android/ScreenReceiver.java @@ -12,9 +12,9 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; -import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.ConnectionsManager; import org.telegram.messenger.FileLog; +import org.telegram.messenger.ApplicationLoader; public class ScreenReceiver extends BroadcastReceiver { diff --git a/TMessagesProj/src/main/java/org/telegram/android/SendMessagesHelper.java b/TMessagesProj/src/main/java/org/telegram/android/SendMessagesHelper.java index 2c9b6a1a..060d2179 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/SendMessagesHelper.java +++ b/TMessagesProj/src/main/java/org/telegram/android/SendMessagesHelper.java @@ -19,7 +19,6 @@ import android.provider.MediaStore; import android.webkit.MimeTypeMap; import android.widget.Toast; -import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.ConnectionsManager; import org.telegram.messenger.FileLoader; import org.telegram.messenger.FileLog; @@ -29,6 +28,7 @@ import org.telegram.messenger.TLObject; import org.telegram.messenger.TLRPC; import org.telegram.messenger.UserConfig; import org.telegram.messenger.Utilities; +import org.telegram.messenger.ApplicationLoader; import java.io.File; import java.io.RandomAccessFile; @@ -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/query/SharedMediaQuery.java b/TMessagesProj/src/main/java/org/telegram/android/query/SharedMediaQuery.java index 345b0e49..f1acd028 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 9b247d8e..d4187165 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 30ec59c9..f6a17a1d 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 @@ -39,6 +39,9 @@ import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat; import android.support.v4.view.accessibility.AccessibilityRecordCompat; import android.support.v4.widget.EdgeEffectCompat; import android.support.v4.widget.ScrollerCompat; +import static org.telegram.android.support.widget.AdapterHelper.UpdateOp; +import static org.telegram.android.support.widget.AdapterHelper.Callback; + import android.util.AttributeSet; import android.util.Log; import android.util.SparseArray; @@ -55,13 +58,12 @@ import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityManager; import android.view.animation.Interpolator; +import org.telegram.android.AndroidUtilities; + import java.util.ArrayList; import java.util.Collections; import java.util.List; -import static org.telegram.android.support.widget.AdapterHelper.Callback; -import static org.telegram.android.support.widget.AdapterHelper.UpdateOp; - /** * A flexible view for providing a limited window into a large data set. * @@ -5028,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(); } @@ -5043,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); } @@ -5060,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); } @@ -5077,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); } @@ -5092,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); } @@ -5111,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); } @@ -5128,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); } @@ -5145,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/ApplicationLoader.java b/TMessagesProj/src/main/java/org/telegram/messenger/ApplicationLoader.java index 8960c4de..dd8ae648 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/ApplicationLoader.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/ApplicationLoader.java @@ -31,13 +31,13 @@ import com.google.android.gms.gcm.GoogleCloudMessaging; import org.telegram.android.AndroidUtilities; import org.telegram.android.ContactsController; -import org.telegram.android.LocaleController; import org.telegram.android.MediaController; +import org.telegram.android.NotificationsService; +import org.telegram.android.SendMessagesHelper; +import org.telegram.android.LocaleController; import org.telegram.android.MessagesController; import org.telegram.android.NativeLoader; -import org.telegram.android.NotificationsService; import org.telegram.android.ScreenReceiver; -import org.telegram.android.SendMessagesHelper; import org.telegram.ui.Components.ForegroundDetector; import java.io.File; @@ -66,6 +66,7 @@ public class ApplicationLoader extends Application { public static boolean SHOW_ANDROID_EMOJI; public static boolean KEEP_ORIGINAL_FILENAME; + public static boolean USE_DEVICE_FONT; public static boolean isCustomTheme() { return isCustomTheme; @@ -205,6 +206,7 @@ public class ApplicationLoader extends Application { SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); SHOW_ANDROID_EMOJI = preferences.getBoolean("showAndroidEmoji", false); KEEP_ORIGINAL_FILENAME = preferences.getBoolean("keepOriginalFilename", false); + USE_DEVICE_FONT = preferences.getBoolean("useDeviceFont", false); // startPushService(); } diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/ConnectionsManager.java b/TMessagesProj/src/main/java/org/telegram/messenger/ConnectionsManager.java index 658896f0..928d5e57 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/FileLoadOperation.java b/TMessagesProj/src/main/java/org/telegram/messenger/FileLoadOperation.java index d87b5c57..ba544e8b 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/FileLoadOperation.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/FileLoadOperation.java @@ -8,8 +8,8 @@ package org.telegram.messenger; -import java.io.File; import java.io.RandomAccessFile; +import java.io.File; import java.nio.channels.FileChannel; import java.util.ArrayList; import java.util.Scanner; diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/HandshakeAction.java b/TMessagesProj/src/main/java/org/telegram/messenger/HandshakeAction.java index eb225c09..7043dca5 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 32d39df4..5de616dc 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 31b0ffce..38e3ff66 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 d75744e4..9571969c 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/Utilities.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/Utilities.java @@ -284,7 +284,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; @@ -450,7 +450,7 @@ public class Utilities { int mPendingIntentId = 123456; PendingIntent mPendingIntent = PendingIntent.getActivity(ApplicationLoader.applicationContext, mPendingIntentId, mRestartApp, PendingIntent.FLAG_CANCEL_CURRENT); AlarmManager mgr = (AlarmManager)ApplicationLoader.applicationContext.getSystemService(Context.ALARM_SERVICE); - mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 100, mPendingIntent); + mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 1000, mPendingIntent); System.exit(0); } 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 6a2ffc0f..68b3b28b 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBarLayout.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBarLayout.java @@ -28,12 +28,11 @@ import android.widget.FrameLayout; import android.widget.LinearLayout; import org.telegram.android.AndroidUtilities; +import org.telegram.messenger.R; 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.NotificationCenter; -import org.telegram.messenger.R; import org.telegram.ui.Components.LayoutHelper; import java.util.ArrayList; @@ -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/ActionBarMenu.java b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBarMenu.java index 18ce670a..e1fa67f7 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBarMenu.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBarMenu.java @@ -65,6 +65,10 @@ public class ActionBarMenu extends LinearLayout { return addItem(id, icon, parentActionBar.itemsBackgroundResourceId, null, width); } + public ActionBarMenuItem addItemWithWidth(int id, Drawable icon, int width) { + return addItem(id, 0, parentActionBar.itemsBackgroundResourceId, icon, width); + } + public ActionBarMenuItem addItem(int id, int icon, int backgroundResource, Drawable drawable, int width) { ActionBarMenuItem menuItem = new ActionBarMenuItem(getContext(), this, backgroundResource); menuItem.setTag(id); 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 cfdcad6d..93f4ef8b 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBarMenuItem.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBarMenuItem.java @@ -32,9 +32,9 @@ import android.widget.LinearLayout; import android.widget.TextView; import org.telegram.android.AndroidUtilities; -import org.telegram.android.AnimationCompat.ViewProxy; import org.telegram.android.LocaleController; import org.telegram.messenger.R; +import org.telegram.android.AnimationCompat.ViewProxy; import org.telegram.ui.Components.FrameLayoutFixed; import org.telegram.ui.Components.LayoutHelper; @@ -46,10 +46,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) { } @@ -78,6 +82,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); @@ -155,8 +160,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); @@ -172,6 +179,9 @@ public class ActionBarMenuItem extends FrameLayoutFixed { public void setShowFromBottom(boolean value) { showFromBottom = value; + if (popupLayout != null) { + popupLayout.setShowedFromBotton(showFromBottom); + } } public void setSubMenuOpenSide(int side) { @@ -184,7 +194,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) { @@ -229,6 +240,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) { @@ -240,14 +252,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; @@ -273,7 +285,11 @@ public class ActionBarMenuItem extends FrameLayoutFixed { if (popupWindow == null) { popupWindow = new ActionBarPopupWindow(popupLayout, LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT); //popupWindow.setBackgroundDrawable(new BitmapDrawable()); + 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); @@ -293,54 +309,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() { @@ -355,10 +328,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 { @@ -393,6 +369,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; } @@ -428,6 +408,7 @@ public class ActionBarMenuItem extends FrameLayoutFixed { } public void onDestroyActionMode(ActionMode mode) { + } public boolean onCreateActionMode(ActionMode mode, Menu menu) { @@ -462,8 +443,10 @@ public class ActionBarMenuItem extends FrameLayoutFixed { if (listener != null) { listener.onTextChanged(searchField); } + if (clearButton != null) { ViewProxy.setAlpha(clearButton, s == null || s.length() == 0 ? 0.6f : 1.0f); } + } @Override public void afterTextChanged(Editable s) { @@ -492,6 +475,7 @@ public class ActionBarMenuItem extends FrameLayoutFixed { layoutParams2.rightMargin = AndroidUtilities.dp(48); searchField.setLayoutParams(layoutParams2); + if (needClearButton) { clearButton = new ImageView(getContext()); clearButton.setImageResource(R.drawable.ic_close_white); clearButton.setScaleType(ImageView.ScaleType.CENTER); @@ -509,6 +493,7 @@ public class ActionBarMenuItem extends FrameLayoutFixed { layoutParams2.height = LayoutHelper.MATCH_PARENT; clearButton.setLayoutParams(layoutParams2); } + } isSearchField = value; return this; } @@ -522,26 +507,73 @@ 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()) { + 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) { - 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); - } + 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); + } + } + } + //plus public ImageView getClearButton(){ return clearButton; 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 759222d1..7d6816f2 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 148d2650..80111af5 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/BaseFragment.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/BaseFragment.java @@ -56,9 +56,7 @@ public class BaseFragment { return arguments; } - protected void setParentLayout(ActionBarLayout layout) { - if (parentLayout != layout) { - parentLayout = layout; + protected void clearViews() { if (fragmentView != null) { ViewGroup parent = (ViewGroup) fragmentView.getParent(); if (parent != null) { @@ -79,8 +77,41 @@ public class BaseFragment { FileLog.e("tmessages", e); } } + actionBar = null; + } + parentLayout = null; + } + + protected void setParentLayout(ActionBarLayout layout) { + if (parentLayout != layout) { + parentLayout = layout; + if (fragmentView != null) { + ViewGroup parent = (ViewGroup) fragmentView.getParent(); + if (parent != null) { + try { + parent.removeView(fragmentView); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } + if (parentLayout != null && parentLayout.getContext() != fragmentView.getContext()) { + fragmentView = null; + } } - if (parentLayout != null) { + if (actionBar != null) { + ViewGroup parent = (ViewGroup) actionBar.getParent(); + if (parent != null) { + try { + parent.removeView(actionBar); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } + if (parentLayout != null && parentLayout.getContext() != actionBar.getContext()) { + actionBar = null; + } + } + if (parentLayout != null && actionBar == null) { actionBar = new ActionBar(parentLayout.getContext()); actionBar.parentFragment = this; //actionBar.setBackgroundColor(0xff54759e); @@ -208,6 +239,10 @@ public class BaseFragment { } + protected void onBecomeFullyVisible() { + + } + public void onLowMemory() { } @@ -217,7 +252,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 { @@ -230,8 +265,6 @@ public class BaseFragment { } try { visibleDialog = dialog; - - visibleDialog.setCanceledOnTouchOutside(true); visibleDialog.setOnDismissListener(new DialogInterface.OnDismissListener() { @Override @@ -268,6 +301,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/DrawerLayoutContainer.java b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/DrawerLayoutContainer.java index 08f6be59..8b0fd39e 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,8 @@ 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; import org.telegram.android.AnimationCompat.ObjectAnimatorProxy; @@ -92,7 +94,6 @@ public class DrawerLayoutContainer extends FrameLayout { private void dispatchChildInsets(View child, Object insets, int drawerGravity) { WindowInsets wi = (WindowInsets) insets; - if (Build.VERSION.SDK_INT >= 20) { if (drawerGravity == Gravity.LEFT) { wi = wi.replaceSystemWindowInsets(wi.getSystemWindowInsetLeft(), wi.getSystemWindowInsetTop(), 0, wi.getSystemWindowInsetBottom()); } else if (drawerGravity == Gravity.RIGHT) { @@ -100,11 +101,9 @@ public class DrawerLayoutContainer extends FrameLayout { } child.dispatchApplyWindowInsets(wi); } - } private void applyMarginInsets(MarginLayoutParams lp, Object insets, int drawerGravity, boolean topOnly) { WindowInsets wi = (WindowInsets) insets; - if (Build.VERSION.SDK_INT >= 20) { if (drawerGravity == Gravity.LEFT) { wi = wi.replaceSystemWindowInsets(wi.getSystemWindowInsetLeft(), wi.getSystemWindowInsetTop(), 0, wi.getSystemWindowInsetBottom()); } else if (drawerGravity == Gravity.RIGHT) { @@ -115,7 +114,6 @@ public class DrawerLayoutContainer extends FrameLayout { lp.rightMargin = wi.getSystemWindowInsetRight(); lp.bottomMargin = wi.getSystemWindowInsetBottom(); } - } private int getTopInset(Object insets) { if (Build.VERSION.SDK_INT >= 21) { @@ -151,7 +149,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); } @@ -397,11 +395,15 @@ public class DrawerLayoutContainer extends FrameLayout { final LayoutParams lp = (LayoutParams) child.getLayoutParams(); + 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 5e54370d..14be9bad 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Adapters/DialogsAdapter.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Adapters/DialogsAdapter.java @@ -21,10 +21,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; @@ -35,9 +37,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) { @@ -49,14 +51,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; } @@ -68,17 +76,11 @@ public class DialogsAdapter extends RecyclerView.Adapter { } public TLRPC.TL_dialog getItem(int i) { - if (serverOnly) { - if (i < 0 || i >= MessagesController.getInstance().dialogsServerOnly.size()) { + ArrayList arrayList = getDialogsArray(); + if (i < 0 || i >= arrayList.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); - } + return arrayList.get(i); } @Override @@ -104,29 +106,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); } - - //updateTheme(viewHolder); } -/* - private void updateTheme(RecyclerView.ViewHolder viewHolder){ - SharedPreferences themePrefs = ApplicationLoader.applicationContext.getSharedPreferences(AndroidUtilities.THEME_PREFS, AndroidUtilities.THEME_PREFS_MODE); - viewHolder.setBackgroundColor(themePrefs.getInt("chatsRowColor", 0xffffffff)); - }*/ @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 981e551e..7bf933c7 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,6 +394,7 @@ public class DialogsSearchAdapter extends BaseSearchAdapterRecycler { resultArrayNames.add(dialogSearchResult.name); } + 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); @@ -437,6 +438,7 @@ public class DialogsSearchAdapter extends BaseSearchAdapterRecycler { } } 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 73009693..2d69ecd4 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Adapters/DrawerLayoutAdapter.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Adapters/DrawerLayoutAdapter.java @@ -14,6 +14,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.ApplicationLoader; @@ -86,7 +87,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 31203899..95221699 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/SearchAdapter.java b/TMessagesProj/src/main/java/org/telegram/ui/Adapters/SearchAdapter.java index c65f8d4b..9894b959 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Adapters/SearchAdapter.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Adapters/SearchAdapter.java @@ -13,12 +13,12 @@ import android.view.View; import android.view.ViewGroup; import org.telegram.android.AndroidUtilities; -import org.telegram.android.ContactsController; import org.telegram.android.LocaleController; -import org.telegram.android.MessagesController; -import org.telegram.messenger.FileLog; import org.telegram.messenger.R; import org.telegram.messenger.TLRPC; +import org.telegram.android.ContactsController; +import org.telegram.messenger.FileLog; +import org.telegram.android.MessagesController; import org.telegram.messenger.UserConfig; import org.telegram.messenger.Utilities; import org.telegram.ui.Cells.GreySectionCell; 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 a7e17b51..7953cbe2 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/BlockedUsersActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/BlockedUsersActivity.java index 25cca520..97e35883 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/BlockedUsersActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/BlockedUsersActivity.java @@ -12,6 +12,8 @@ import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; import android.content.SharedPreferences; +import android.graphics.PorterDuff; +import android.graphics.drawable.Drawable; import android.os.Build; import android.os.Bundle; import android.view.Gravity; @@ -90,7 +92,12 @@ public class BlockedUsersActivity extends BaseFragment implements NotificationCe }); ActionBarMenu menu = actionBar.createMenu(); - menu.addItem(block_user, R.drawable.plus); + //menu.addItem(block_user, R.drawable.plus); + + SharedPreferences themePrefs = ApplicationLoader.applicationContext.getSharedPreferences(AndroidUtilities.THEME_PREFS, AndroidUtilities.THEME_PREFS_MODE); + Drawable plus = getParentActivity().getResources().getDrawable(R.drawable.plus); + plus.setColorFilter(themePrefs.getInt("prefHeaderIconsColor", 0xffffffff), PorterDuff.Mode.SRC_IN); + menu.addItem(block_user, plus); fragmentView = new FrameLayout(context); FrameLayout frameLayout = (FrameLayout) fragmentView; @@ -213,6 +220,18 @@ public class BlockedUsersActivity extends BaseFragment implements NotificationCe if (listViewAdapter != null) { listViewAdapter.notifyDataSetChanged(); } + updateTheme(); + } + + private void updateTheme(){ + SharedPreferences themePrefs = ApplicationLoader.applicationContext.getSharedPreferences(AndroidUtilities.THEME_PREFS, AndroidUtilities.THEME_PREFS_MODE); + int def = themePrefs.getInt("themeColor", AndroidUtilities.defColor); + actionBar.setBackgroundColor(themePrefs.getInt("prefHeaderColor", def)); + actionBar.setTitleColor(themePrefs.getInt("prefHeaderTitleColor", 0xffffffff)); + + Drawable back = getParentActivity().getResources().getDrawable(R.drawable.ic_ab_back); + back.setColorFilter(themePrefs.getInt("prefHeaderIconsColor", 0xffffffff), PorterDuff.Mode.MULTIPLY); + actionBar.setBackButtonDrawable(back); } @Override 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 3b8cf224..f6fd1c84 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/AddMemberCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/AddMemberCell.java @@ -22,6 +22,7 @@ import org.telegram.ui.Components.LayoutHelper; import org.telegram.ui.Components.SimpleTextView; public class AddMemberCell extends FrameLayout { + private SimpleTextView textView; private ImageView imageView; @@ -34,11 +35,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)); } @@ -57,4 +56,8 @@ public class AddMemberCell extends FrameLayout { d.setColorFilter(color, PorterDuff.Mode.SRC_IN); imageView.setImageDrawable(d); } + + 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 c0170b66..df37101d 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/ChatAudioCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatAudioCell.java index 9d17fe96..87c5a71b 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatAudioCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatAudioCell.java @@ -20,10 +20,10 @@ import android.view.SoundEffectConstants; import org.telegram.android.AndroidUtilities; import org.telegram.android.ImageLoader; -import org.telegram.android.MediaController; -import org.telegram.android.MessageObject; import org.telegram.android.MessagesController; import org.telegram.messenger.FileLoader; +import org.telegram.android.MediaController; +import org.telegram.android.MessageObject; import org.telegram.ui.Components.ProgressView; import org.telegram.ui.Components.ResourceLoader; import org.telegram.ui.Components.SeekBar; @@ -149,14 +149,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(); } } } @@ -199,8 +199,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); @@ -211,6 +219,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 1f3c65c8..35677927 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatBaseCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatBaseCell.java @@ -14,7 +14,6 @@ import android.content.SharedPreferences; import android.content.res.Configuration; import android.graphics.Canvas; import android.graphics.Paint; -import android.graphics.Path; import android.graphics.PorterDuff; import android.graphics.drawable.Drawable; import android.text.Layout; @@ -26,18 +25,19 @@ 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.ImageReceiver; import org.telegram.android.LocaleController; import org.telegram.android.MessageObject; import org.telegram.android.MessagesController; +import org.telegram.android.UserObject; import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.FileLoader; import org.telegram.messenger.FileLog; import org.telegram.messenger.R; import org.telegram.messenger.TLRPC; import org.telegram.ui.Components.AvatarDrawable; +import org.telegram.ui.Components.LinkPath; import org.telegram.ui.Components.ResourceLoader; import org.telegram.ui.Components.StaticLayoutEx; @@ -48,49 +48,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; @@ -370,7 +335,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)) { @@ -380,7 +345,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); } @@ -451,7 +416,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); @@ -472,7 +437,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(); @@ -553,7 +518,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(); @@ -726,7 +691,6 @@ public class ChatBaseCell extends BaseCell { @Override protected void onDraw(Canvas canvas) { - if (currentMessageObject == null) { return; } @@ -945,7 +909,6 @@ public class ChatBaseCell extends BaseCell { } if (drawClock) { - //ResourceLoader.clockDrawable = ResourceLoader.clockMediaDrawable; if (!media) { setDrawableBounds(ResourceLoader.clockDrawable, layoutWidth - AndroidUtilities.dp(18.5f) - ResourceLoader.clockDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(8.5f) - ResourceLoader.clockDrawable.getIntrinsicHeight()); ResourceLoader.clockDrawable.draw(canvas); @@ -966,7 +929,6 @@ public class ChatBaseCell extends BaseCell { } } else { if (drawCheck2) { - //ResourceLoader.checkDrawable = ResourceLoader.checkMediaDrawable; if (!media) { if (drawCheck1) { setDrawableBounds(ResourceLoader.checkDrawable, layoutWidth - AndroidUtilities.dp(22.5f) - ResourceLoader.checkDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(8.0f) - ResourceLoader.checkDrawable.getIntrinsicHeight()); @@ -984,7 +946,6 @@ public class ChatBaseCell extends BaseCell { } } if (drawCheck1) { - //ResourceLoader.halfCheckDrawable = ResourceLoader.halfCheckMediaDrawable; if (!media) { setDrawableBounds(ResourceLoader.halfCheckDrawable, layoutWidth - AndroidUtilities.dp(18) - ResourceLoader.halfCheckDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(8.0f) - ResourceLoader.halfCheckDrawable.getIntrinsicHeight()); ResourceLoader.halfCheckDrawable.draw(canvas); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatContactCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatContactCell.java index 4322da9c..d3fe620d 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatContactCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatContactCell.java @@ -9,6 +9,7 @@ package org.telegram.ui.Cells; import android.content.Context; +import android.content.SharedPreferences; import android.graphics.Canvas; import android.graphics.drawable.Drawable; import android.text.Layout; @@ -25,6 +26,7 @@ import org.telegram.android.ImageReceiver; import org.telegram.android.LocaleController; import org.telegram.android.MessageObject; import org.telegram.android.MessagesController; +import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.R; import org.telegram.messenger.TLRPC; import org.telegram.messenger.UserConfig; @@ -283,6 +285,12 @@ public class ChatContactCell extends ChatBaseCell { canvas.restore(); } if (phoneLayout != null) { + SharedPreferences themePrefs = ApplicationLoader.applicationContext.getSharedPreferences(AndroidUtilities.THEME_PREFS, AndroidUtilities.THEME_PREFS_MODE); + int color = themePrefs.getInt("chatLTextColor", 0xff000000); + if (currentMessageObject.isOut()) { + color = themePrefs.getInt("chatRTextColor", 0xff000000); + } + phonePaint.setColor(color); canvas.save(); canvas.translate(avatarImage.getImageX() + avatarImage.getImageWidth() + AndroidUtilities.dp(9), AndroidUtilities.dp(31) + namesOffset); phoneLayout.draw(canvas); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMediaCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMediaCell.java index 4fa1be42..004455bf 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMediaCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMediaCell.java @@ -34,6 +34,7 @@ import org.telegram.android.MediaController; import org.telegram.android.MessageObject; import org.telegram.android.MessagesController; import org.telegram.android.SendMessagesHelper; +import org.telegram.android.UserObject; import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.ConnectionsManager; import org.telegram.messenger.FileLoader; @@ -187,7 +188,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) { @@ -228,9 +229,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 { @@ -554,7 +555,17 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD if(isChat){ TLRPC.User fromUser = MessagesController.getInstance().getUser(messageObject.messageOwner.from_id); - String senderName = String.format("%s %s", fromUser.first_name, fromUser.last_name); + //String senderName = String.format("%s %s", fromUser.first_name, fromUser.last_name); + String senderName = ""; + if (UserObject.isDeleted(fromUser)) { + senderName = "Deleted"; + } else { + if (fromUser.first_name != null && fromUser.first_name.length() > 0) { + senderName = fromUser.first_name; + } else { + senderName = fromUser.last_name; + } + } infoWidth2 = Math.min(maxWidth, (int) Math.ceil(senderPaint.measureText(senderName))); CharSequence str2 = TextUtils.ellipsize(senderName, senderPaint, infoWidth2, TextUtils.TruncateAt.END); infoLayout2 = new StaticLayout(str2, senderPaint, infoWidth2, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false); @@ -607,7 +618,16 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD }//Plus: member name in photos else if (messageObject.type == 1) { //PHOTO TLRPC.User fromUser = MessagesController.getInstance().getUser(messageObject.messageOwner.from_id); - String senderName = String.format("%s %s", fromUser.first_name, fromUser.last_name); + String senderName = ""; + if (UserObject.isDeleted(fromUser)) { + senderName = "Deleted"; + } else { + if (fromUser.first_name != null && fromUser.first_name.length() > 0) { + senderName = fromUser.first_name; + } else { + senderName = fromUser.last_name; + } + } if (currentInfoString == null || !currentInfoString.equals(senderName)) { currentInfoString = senderName; infoOffset = 0; 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 13140f94..1a2874fd 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMessageCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMessageCell.java @@ -29,10 +29,10 @@ import android.view.MotionEvent; import org.telegram.android.AndroidUtilities; import org.telegram.android.ImageReceiver; import org.telegram.android.MediaController; -import org.telegram.android.MessageObject; -import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.FileLoader; import org.telegram.messenger.FileLog; +import org.telegram.android.MessageObject; +import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.R; import org.telegram.messenger.TLRPC; import org.telegram.ui.Components.ResourceLoader; @@ -81,7 +81,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(); @@ -118,9 +118,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 { @@ -620,7 +620,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/DialogCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/DialogCell.java index 551581d5..09021104 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/DialogCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/DialogCell.java @@ -29,6 +29,7 @@ import org.telegram.android.ImageReceiver; import org.telegram.android.LocaleController; import org.telegram.android.MessageObject; import org.telegram.android.MessagesController; +import org.telegram.android.UserObject; import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.FileLog; import org.telegram.messenger.R; @@ -36,6 +37,8 @@ import org.telegram.messenger.TLRPC; import org.telegram.messenger.UserConfig; import org.telegram.ui.Components.AvatarDrawable; +import java.util.ArrayList; + public class DialogCell extends BaseCell { private static TextPaint namePaint; @@ -72,7 +75,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; @@ -128,6 +131,7 @@ public class DialogCell extends BaseCell { public DialogCell(Context context) { super(context); + if (namePaint == null) { namePaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG); namePaint.setTextSize(AndroidUtilities.dp(17)); @@ -201,11 +205,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); } @@ -376,12 +380,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; @@ -487,17 +493,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; @@ -684,18 +690,20 @@ public class DialogCell extends BaseCell { isSelected = value; } + 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; + } + public void checkCurrentDialogIndex() { - TLRPC.TL_dialog dialog = null; - if (isServerOnly) { - if (index < MessagesController.getInstance().dialogsServerOnly.size()) { - dialog = MessagesController.getInstance().dialogsServerOnly.get(index); - } - } else { - if (index < MessagesController.getInstance().dialogs.size()) { - dialog = MessagesController.getInstance().dialogs.get(index); - } - } - if (dialog != null) { + if (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); @@ -863,7 +871,7 @@ public class DialogCell extends BaseCell { countDrawable.setColorFilter(themePrefs.getInt("chatsCountBGColor", tColor), PorterDuff.Mode.SRC_IN); - nColor = themePrefs.getInt("chatsNameColor", 0xff000000); + nColor = themePrefs.getInt("chatsGroupIconColor", themePrefs.getInt("chatsGroupNameColor", 0xff000000)); groupDrawable.setColorFilter(nColor, PorterDuff.Mode.SRC_IN); broadcastDrawable.setColorFilter(nColor, PorterDuff.Mode.SRC_IN); @@ -945,7 +953,11 @@ public class DialogCell extends BaseCell { setDrawableBounds(errorDrawable, errorLeft, errorTop); errorDrawable.draw(canvas); } else if (drawCount) { - setDrawableBounds(countDrawable, countLeft - AndroidUtilities.dp(5.5f), countTop, countWidth + AndroidUtilities.dp(11), countDrawable.getIntrinsicHeight()); + SharedPreferences themePrefs = ApplicationLoader.applicationContext.getSharedPreferences(AndroidUtilities.THEME_PREFS, AndroidUtilities.THEME_PREFS_MODE); + int size = themePrefs.getInt("chatsCountSize", 13); + size = size > 13 ? (size - 13) / 2 : 0; + //setDrawableBounds(countDrawable, countLeft - AndroidUtilities.dp(5.5f), countTop, countWidth + AndroidUtilities.dp(11), countDrawable.getIntrinsicHeight()); + setDrawableBounds(countDrawable, countLeft - AndroidUtilities.dp(5.5f), countTop + AndroidUtilities.dp(size), countWidth + AndroidUtilities.dp(11), countDrawable.getIntrinsicHeight()); countDrawable.draw(canvas); canvas.save(); canvas.translate(countLeft, countTop + AndroidUtilities.dp(4)); 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 5fba688d..1df8442f 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/DrawerProfileCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/DrawerProfileCell.java @@ -28,9 +28,9 @@ import android.widget.TextView; import org.telegram.PhoneFormat.PhoneFormat; import org.telegram.android.AndroidUtilities; -import org.telegram.android.ContactsController; import org.telegram.android.MessageObject; import org.telegram.android.MessagesController; +import org.telegram.android.UserObject; import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.FileLog; import org.telegram.messenger.R; @@ -63,7 +63,10 @@ public class DrawerProfileCell extends FrameLayout implements PhotoViewer.PhotoV avatarImageView = new BackupImageView(context); avatarImageView.getImageReceiver().setRoundRadius(AndroidUtilities.dp(32)); - addView(avatarImageView, LayoutHelper.createFrame(64, 64, Gravity.LEFT | Gravity.BOTTOM, 16, 0, 0, 67)); + SharedPreferences themePrefs = ApplicationLoader.applicationContext.getSharedPreferences(AndroidUtilities.THEME_PREFS, AndroidUtilities.THEME_PREFS_MODE); + int aSize = themePrefs.getInt("drawerAvatarSize", 64); + //addView(avatarImageView, LayoutHelper.createFrame(64, 64, Gravity.LEFT | Gravity.BOTTOM, 16, 0, 0, 67)); + addView(avatarImageView, LayoutHelper.createFrame(aSize, aSize, Gravity.LEFT | Gravity.BOTTOM, 16, 0, 0, 67)); final Activity activity = (Activity) context; avatarImageView.setOnClickListener(new View.OnClickListener() { @@ -156,7 +159,7 @@ public class DrawerProfileCell extends FrameLayout implements PhotoViewer.PhotoV 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); @@ -238,6 +241,8 @@ public class DrawerProfileCell extends FrameLayout implements PhotoViewer.PhotoV avatarDrawable.setColor(themePrefs.getInt("drawerAvatarColor", AndroidUtilities.getIntDarkerColor("themeColor", 0x15))); int radius = AndroidUtilities.dp(themePrefs.getInt("drawerAvatarRadius", 32)); avatarDrawable.setRadius(radius); + //avatarImageView.getImageReceiver().setImageCoords(avatarImageView.getImageReceiver(), avatarTop, avatarSize, avatarSize); + avatarImageView.getImageReceiver().setRoundRadius(radius); avatarImageView.setImage(photo, "50_50", avatarDrawable); if(AndroidUtilities.getBoolMain("hideMobile")){ 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 7a477eaf..eae727cb 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/ProfileSearchCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ProfileSearchCell.java index e3727f7e..7be1afda 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ProfileSearchCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ProfileSearchCell.java @@ -26,6 +26,7 @@ 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.ApplicationLoader; import org.telegram.messenger.ConnectionsManager; import org.telegram.messenger.R; @@ -207,7 +208,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", " "); } @@ -255,12 +256,16 @@ public class ProfileSearchCell extends BaseCell { if (subLabel != null) { onlineString = subLabel; } else { + 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); } } + } CharSequence onlineStringFinal = TextUtils.ellipsize(onlineString, currentOnlinePaint, onlineWidth - AndroidUtilities.dp(12), TextUtils.TruncateAt.END); onlineLayout = new StaticLayout(onlineStringFinal, currentOnlinePaint, onlineWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false); 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 4c2e46a3..7cc059b6 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 87904384..93059d1f 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/TextCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/TextCell.java index e243bf40..1c79ee3c 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); @@ -62,7 +64,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) { @@ -84,6 +86,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 setTextSize(int size) { textView.setTextSize(size); } 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 cf015887..7cb4649c 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/UserCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/UserCell.java @@ -16,9 +16,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.ApplicationLoader; import org.telegram.messenger.ConnectionsManager; import org.telegram.messenger.R; @@ -149,7 +149,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; } @@ -170,7 +170,7 @@ 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); nameTextView.setTextColor(nameColor); nameTextView.setTextSize(themePrefs.getInt("contactsNameSize", 17)); @@ -179,7 +179,15 @@ public class UserCell extends FrameLayout { statusTextView.setTextColor(statusColor); statusTextView.setText(currrntStatus); } else { - if (currentUser.id == UserConfig.getClientUserId() || currentUser.status != null && currentUser.status.expires > ConnectionsManager.getInstance().getCurrentTime()) { + if ((currentUser.flags & TLRPC.USER_FLAG_BOT) != 0) { + statusTextView.setTextColor(statusColor); + 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 { @@ -187,6 +195,7 @@ public class UserCell extends FrameLayout { statusTextView.setText(LocaleController.formatUserStatus(currentUser)); } } + } if (imageView.getVisibility() == VISIBLE && currentDrawable == 0 || imageView.getVisibility() == GONE && currentDrawable != 0) { imageView.setVisibility(currentDrawable == 0 ? GONE : VISIBLE); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ChangeChatNameActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ChangeChatNameActivity.java index 1f3059d1..1056b373 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ChangeChatNameActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ChangeChatNameActivity.java @@ -12,6 +12,7 @@ import android.app.Activity; import android.content.Context; import android.content.SharedPreferences; import android.graphics.PorterDuff; +import android.graphics.drawable.Drawable; import android.os.Bundle; import android.text.InputType; import android.util.TypedValue; @@ -28,10 +29,10 @@ import android.widget.TextView; import org.telegram.android.AndroidUtilities; import org.telegram.android.LocaleController; -import org.telegram.android.MessagesController; import org.telegram.messenger.ApplicationLoader; -import org.telegram.messenger.R; import org.telegram.messenger.TLRPC; +import org.telegram.android.MessagesController; +import org.telegram.messenger.R; import org.telegram.ui.ActionBar.ActionBar; import org.telegram.ui.ActionBar.ActionBarMenu; import org.telegram.ui.ActionBar.BaseFragment; @@ -77,7 +78,11 @@ public class ChangeChatNameActivity extends BaseFragment { }); ActionBarMenu menu = actionBar.createMenu(); - doneButton = menu.addItemWithWidth(done_button, R.drawable.ic_done, AndroidUtilities.dp(56)); + //doneButton = menu.addItemWithWidth(done_button, R.drawable.ic_done, AndroidUtilities.dp(56)); + Drawable done = getParentActivity().getResources().getDrawable(R.drawable.ic_done); + SharedPreferences themePrefs = ApplicationLoader.applicationContext.getSharedPreferences(AndroidUtilities.THEME_PREFS, AndroidUtilities.THEME_PREFS_MODE); + done.setColorFilter(themePrefs.getInt("prefHeaderIconsColor", 0xffffffff), PorterDuff.Mode.MULTIPLY); + doneButton = menu.addItemWithWidth(done_button, done, AndroidUtilities.dp(56)); TLRPC.Chat currentChat = MessagesController.getInstance().getChat(chat_id); @@ -137,6 +142,21 @@ public class ChangeChatNameActivity extends BaseFragment { firstNameField.requestFocus(); AndroidUtilities.showKeyboard(firstNameField); } + updateTheme(); + } + + private void updateTheme(){ + SharedPreferences themePrefs = ApplicationLoader.applicationContext.getSharedPreferences(AndroidUtilities.THEME_PREFS, AndroidUtilities.THEME_PREFS_MODE); + int def = themePrefs.getInt("themeColor", AndroidUtilities.defColor); + actionBar.setBackgroundColor(themePrefs.getInt("prefHeaderColor", def)); + actionBar.setTitleColor(themePrefs.getInt("prefHeaderTitleColor", 0xffffffff)); + + Drawable back = getParentActivity().getResources().getDrawable(R.drawable.ic_ab_back); + back.setColorFilter(themePrefs.getInt("prefHeaderIconsColor", 0xffffffff), PorterDuff.Mode.MULTIPLY); + actionBar.setBackButtonDrawable(back); + + Drawable done = getParentActivity().getResources().getDrawable(R.drawable.ic_done); + done.setColorFilter(themePrefs.getInt("prefHeaderIconsColor", 0xffffffff), PorterDuff.Mode.MULTIPLY); } @Override diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ChangeNameActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ChangeNameActivity.java index 836e5b2b..7f455d60 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ChangeNameActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ChangeNameActivity.java @@ -12,6 +12,7 @@ import android.app.Activity; import android.content.Context; import android.content.SharedPreferences; import android.graphics.PorterDuff; +import android.graphics.drawable.Drawable; import android.text.InputType; import android.util.TypedValue; import android.view.Gravity; @@ -27,14 +28,14 @@ import android.widget.TextView; import org.telegram.android.AndroidUtilities; import org.telegram.android.LocaleController; -import org.telegram.android.MessagesController; -import org.telegram.android.NotificationCenter; import org.telegram.messenger.ApplicationLoader; -import org.telegram.messenger.ConnectionsManager; -import org.telegram.messenger.R; -import org.telegram.messenger.RPCRequest; import org.telegram.messenger.TLObject; import org.telegram.messenger.TLRPC; +import org.telegram.messenger.ConnectionsManager; +import org.telegram.android.MessagesController; +import org.telegram.android.NotificationCenter; +import org.telegram.messenger.R; +import org.telegram.messenger.RPCRequest; import org.telegram.messenger.UserConfig; import org.telegram.ui.ActionBar.ActionBar; import org.telegram.ui.ActionBar.ActionBarMenu; @@ -70,7 +71,12 @@ public class ChangeNameActivity extends BaseFragment { }); ActionBarMenu menu = actionBar.createMenu(); - doneButton = menu.addItemWithWidth(done_button, R.drawable.ic_done, AndroidUtilities.dp(56)); + //doneButton = menu.addItemWithWidth(done_button, R.drawable.ic_done, AndroidUtilities.dp(56)); + + SharedPreferences themePrefs = ApplicationLoader.applicationContext.getSharedPreferences(AndroidUtilities.THEME_PREFS, AndroidUtilities.THEME_PREFS_MODE); + Drawable done = getParentActivity().getResources().getDrawable(R.drawable.ic_done); + done.setColorFilter(themePrefs.getInt("prefHeaderIconsColor", 0xffffffff), PorterDuff.Mode.SRC_IN); + doneButton = menu.addItemWithWidth(done_button, done, AndroidUtilities.dp(56)); TLRPC.User user = MessagesController.getInstance().getUser(UserConfig.getClientUserId()); if (user == null) { @@ -157,6 +163,18 @@ public class ChangeNameActivity extends BaseFragment { firstNameField.requestFocus(); AndroidUtilities.showKeyboard(firstNameField); } + updateTheme(); + } + + private void updateTheme(){ + SharedPreferences themePrefs = ApplicationLoader.applicationContext.getSharedPreferences(AndroidUtilities.THEME_PREFS, AndroidUtilities.THEME_PREFS_MODE); + int def = themePrefs.getInt("themeColor", AndroidUtilities.defColor); + actionBar.setBackgroundColor(themePrefs.getInt("prefHeaderColor", def)); + actionBar.setTitleColor(themePrefs.getInt("prefHeaderTitleColor", 0xffffffff)); + + Drawable back = getParentActivity().getResources().getDrawable(R.drawable.ic_ab_back); + back.setColorFilter(themePrefs.getInt("prefHeaderIconsColor", 0xffffffff), PorterDuff.Mode.MULTIPLY); + actionBar.setBackButtonDrawable(back); } private void saveName() { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ChangePhoneActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ChangePhoneActivity.java index e199a0d2..746d97ee 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ChangePhoneActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ChangePhoneActivity.java @@ -12,7 +12,9 @@ import android.annotation.SuppressLint; import android.app.AlertDialog; import android.app.ProgressDialog; import android.content.Context; +import android.content.SharedPreferences; import android.graphics.PorterDuff; +import android.graphics.drawable.Drawable; import android.os.Bundle; import android.telephony.TelephonyManager; import android.text.Editable; @@ -39,10 +41,6 @@ import android.widget.TextView; import org.telegram.PhoneFormat.PhoneFormat; 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.android.MessagesController; import org.telegram.android.MessagesStorage; @@ -59,6 +57,10 @@ import org.telegram.messenger.UserConfig; import org.telegram.ui.ActionBar.ActionBar; import org.telegram.ui.ActionBar.ActionBarMenu; import org.telegram.ui.ActionBar.BaseFragment; +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.ui.Components.LayoutHelper; import org.telegram.ui.Components.SlideView; import org.telegram.ui.Components.TypefaceSpan; @@ -118,7 +120,12 @@ public class ChangePhoneActivity extends BaseFragment { }); ActionBarMenu menu = actionBar.createMenu(); - menu.addItemWithWidth(done_button, R.drawable.ic_done, AndroidUtilities.dp(56)); + //menu.addItemWithWidth(done_button, R.drawable.ic_done, AndroidUtilities.dp(56)); + + SharedPreferences themePrefs = ApplicationLoader.applicationContext.getSharedPreferences(AndroidUtilities.THEME_PREFS, AndroidUtilities.THEME_PREFS_MODE); + Drawable done = getParentActivity().getResources().getDrawable(R.drawable.ic_done); + done.setColorFilter(themePrefs.getInt("prefHeaderIconsColor", 0xffffffff), PorterDuff.Mode.SRC_IN); + menu.addItemWithWidth(done_button, done, AndroidUtilities.dp(56)); fragmentView = new ScrollView(context); ScrollView scrollView = (ScrollView) fragmentView; @@ -164,6 +171,18 @@ public class ChangePhoneActivity extends BaseFragment { if (!AndroidUtilities.isTablet()) { getParentActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); } + updateTheme(); + } + + private void updateTheme(){ + SharedPreferences themePrefs = ApplicationLoader.applicationContext.getSharedPreferences(AndroidUtilities.THEME_PREFS, AndroidUtilities.THEME_PREFS_MODE); + int def = themePrefs.getInt("themeColor", AndroidUtilities.defColor); + actionBar.setBackgroundColor(themePrefs.getInt("prefHeaderColor", def)); + actionBar.setTitleColor(themePrefs.getInt("prefHeaderTitleColor", 0xffffffff)); + + Drawable back = getParentActivity().getResources().getDrawable(R.drawable.ic_ab_back); + back.setColorFilter(themePrefs.getInt("prefHeaderIconsColor", 0xffffffff), PorterDuff.Mode.MULTIPLY); + actionBar.setBackButtonDrawable(back); } @Override @@ -499,7 +518,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/ChangeUsernameActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ChangeUsernameActivity.java index 9145f985..1ece40e7 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ChangeUsernameActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ChangeUsernameActivity.java @@ -15,6 +15,7 @@ import android.content.Context; import android.content.DialogInterface; import android.content.SharedPreferences; import android.graphics.PorterDuff; +import android.graphics.drawable.Drawable; import android.text.Editable; import android.text.InputType; import android.text.TextWatcher; @@ -79,7 +80,12 @@ public class ChangeUsernameActivity extends BaseFragment { }); ActionBarMenu menu = actionBar.createMenu(); - doneButton = menu.addItemWithWidth(done_button, R.drawable.ic_done, AndroidUtilities.dp(56)); + //doneButton = menu.addItemWithWidth(done_button, R.drawable.ic_done, AndroidUtilities.dp(56)); + + SharedPreferences themePrefs = ApplicationLoader.applicationContext.getSharedPreferences(AndroidUtilities.THEME_PREFS, AndroidUtilities.THEME_PREFS_MODE); + Drawable done = getParentActivity().getResources().getDrawable(R.drawable.ic_done); + done.setColorFilter(themePrefs.getInt("prefHeaderIconsColor", 0xffffffff), PorterDuff.Mode.SRC_IN); + doneButton = menu.addItemWithWidth(done_button, done, AndroidUtilities.dp(56)); TLRPC.User user = MessagesController.getInstance().getUser(UserConfig.getClientUserId()); if (user == null) { @@ -194,6 +200,18 @@ public class ChangeUsernameActivity extends BaseFragment { firstNameField.requestFocus(); AndroidUtilities.showKeyboard(firstNameField); } + updateTheme(); + } + + private void updateTheme(){ + SharedPreferences themePrefs = ApplicationLoader.applicationContext.getSharedPreferences(AndroidUtilities.THEME_PREFS, AndroidUtilities.THEME_PREFS_MODE); + int def = themePrefs.getInt("themeColor", AndroidUtilities.defColor); + actionBar.setBackgroundColor(themePrefs.getInt("prefHeaderColor", def)); + actionBar.setTitleColor(themePrefs.getInt("prefHeaderTitleColor", 0xffffffff)); + + Drawable back = getParentActivity().getResources().getDrawable(R.drawable.ic_ab_back); + back.setColorFilter(themePrefs.getInt("prefHeaderIconsColor", 0xffffffff), PorterDuff.Mode.MULTIPLY); + actionBar.setBackButtonDrawable(back); } private void showErrorAlert(String error) { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java index f173559a..8e7f09a3 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.PorterDuff; import android.graphics.Rect; @@ -25,6 +26,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; @@ -39,6 +41,7 @@ import android.view.ViewTreeObserver; import android.view.WindowManager; import android.webkit.MimeTypeMap; import android.widget.AdapterView; +import android.widget.EditText; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.LinearLayout; @@ -65,7 +68,10 @@ import org.telegram.android.NotificationCenter; 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; @@ -88,15 +94,20 @@ import org.telegram.ui.ActionBar.BaseFragment; import org.telegram.ui.ActionBar.BottomSheet; import org.telegram.ui.Adapters.MentionsAdapter; import org.telegram.ui.Adapters.StickersAdapter; +import org.telegram.ui.Cells.BotHelpCell; 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.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.Components.ChatActivityEnterView; +import org.telegram.ui.Components.ChatAttachView; import org.telegram.ui.Components.FrameLayoutFixed; import org.telegram.ui.Components.LayoutHelper; import org.telegram.ui.Components.RecordStatusDrawable; @@ -110,6 +121,7 @@ import org.telegram.ui.Components.WebFrameLayout; import java.io.File; import java.io.IOException; +import java.net.URLDecoder; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -135,6 +147,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; @@ -165,6 +180,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not private MentionsAdapter mentionsAdapter; private ListView mentionListView; private AnimatorSetProxy mentionListAnimation; + private ChatAttachView chatAttachView; private ImageView deleteIconImageView; private View lineView; @@ -233,6 +249,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; @@ -246,25 +269,43 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not private float startX = 0; private float startY = 0; - private final static int quoteforward = 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 attach_music = 16; + private final static int copy = 10;//1; + private final static int forward = 11;//2; + private final static int delete = 12;//3; + private final static int chat_enc_timer = 13;//4; + private final static int chat_menu_attach = 14;//5; + private final static int clear_history = 15;//11; + private final static int delete_chat = 16;//12; + private final static int share_contact = 17;//13; + private final static int mute = 18;//14; + private final static int reply = 19;//15; + + private final static int add_member = 20; + + private final static int quoteforward = 111;//0; + + private final static int bot_help = 30; + private final static int bot_settings = 31; + + private final static int attach_photo = 0;//6; + private final static int attach_gallery = 1;//7; + private final static int attach_video = 2;//8; + private final static int attach_audio = 3; + private final static int attach_document = 4;//9; + private final static int attach_contact = 5; + private final static int attach_location = 6;//10; + + //private final static int attach_music = 7;//16; + private final static int attach_sticker = 8;//17; + + private int chat_id; + + 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; - private final static int attach_sticker = 17; private static boolean QuoteForward; @@ -295,6 +336,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not @Override public boolean onFragmentCreate() { final int chatId = arguments.getInt("chat_id", 0); + chat_id = chatId; final int userId = arguments.getInt("user_id", 0); final int encId = arguments.getInt("enc_id", 0); startLoadFromMessageId = arguments.getInt("message_id", 0); @@ -363,6 +405,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) { @@ -443,9 +486,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) { @@ -512,6 +574,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); @@ -526,7 +591,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(); @@ -545,6 +613,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not lastPrintString = null; lastStatus = null; hasOwnBackground = true; + chatAttachView = null; ResourceLoader.loadRecources(context); @@ -556,192 +625,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); - } - //PLUS - } else if (id == attach_music) { - try { - Intent pickIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI); - startActivityForResult(pickIntent, 3); - } catch (Exception e) { - FileLog.e("tmessages", e); - } - } else if (id == attach_sticker) { - PhotoAlbumPickerActivity fragment = new PhotoAlbumPickerActivity(false, ChatActivity.this); - fragment.imageFilter = ".webp"; - 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 photoPickerIntent = new Intent(Intent.ACTION_PICK); - startActivityForResult(photoPickerIntent, 4); - } 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_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()); @@ -810,7 +700,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } 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); @@ -883,52 +773,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(); @@ -953,6 +798,77 @@ 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 || id == attach_sticker) { + 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); + } + else if (id == add_member) { + openAddMember(); } } }); @@ -1035,10 +951,60 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not avatarContainer.addView(onlineTextView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.BOTTOM, 54, 0, 0, 4)); 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); Drawable dots = getParentActivity().getResources().getDrawable(R.drawable.ic_ab_other); //dots.setColorFilter(AndroidUtilities.getIntDef("chatHeaderIconsColor", 0xffffffff), PorterDuff.Mode.MULTIPLY); headerItem = menu.addItem(0, dots); + + final boolean isChat = (int) dialog_id < 0 && (int) (dialog_id >> 32) != 1; + if(isChat)headerItem.addSubItem(add_member, LocaleController.getString("AddMember", R.string.AddMember), 0); + + if (searchItem != null) { + headerItem.addSubItem(search, LocaleController.getString("Search", R.string.Search), 0); + } if (currentUser != null) { addContactItem = headerItem.addSubItem(share_contact, "", 0); } @@ -1052,34 +1018,47 @@ 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, dots); + //attachItem = menu.addItem(chat_menu_attach, R.drawable.ic_ab_other).setAllowCloseAnimation(false);; + attachItem = menu.addItem(chat_menu_attach, dots).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_sticker, LocaleController.getString("AttachSticker", R.string.AttachSticker), R.drawable.ic_attach_sticker); - attachItem.addSubItem(attach_music, LocaleController.getString("ChatMusic", R.string.ChatMusic), R.drawable.ic_attach_music); + //attachItem.addSubItem(attach_music, LocaleController.getString("ChatMusic", R.string.ChatMusic), R.drawable.ic_attach_music); + attachItem.addSubItem(attach_audio, LocaleController.getString("ChatMusic", R.string.ChatMusic), R.drawable.ic_attach_music); + attachItem.addSubItem(attach_video, LocaleController.getString("ChatVideo", R.string.ChatVideo), R.drawable.ic_attach_video); attachItem.addSubItem(attach_document, LocaleController.getString("ChatDocument", R.string.ChatDocument), R.drawable.ic_ab_doc); attachItem.addSubItem(attach_location, LocaleController.getString("ChatLocation", R.string.ChatLocation), R.drawable.ic_attach_location); - attachItem.setVisibility(View.INVISIBLE); + attachItem.addSubItem(attach_contact, LocaleController.getString("AttachContact", R.string.AttachContact), R.drawable.ic_attach_contact); + attachItem.setVisibility(View.GONE); Drawable clip = getParentActivity().getResources().getDrawable(R.drawable.ic_ab_attach_white); clip.setColorFilter(themePrefs.getInt("chatEditTextIconsColor", 0xffadadad), PorterDuff.Mode.MULTIPLY); - menuItem = menu.addItem(chat_menu_attach, clip); - //menuItem = menu.addItem(chat_menu_attach, R.drawable.ic_ab_attach); + menuItem = menu.addItem(chat_menu_attach, clip).setAllowCloseAnimation(false); + //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_sticker, LocaleController.getString("AttachSticker", R.string.AttachSticker), R.drawable.ic_attach_sticker); - menuItem.addSubItem(attach_music, LocaleController.getString("ChatMusic", R.string.ChatMusic), R.drawable.ic_attach_music); + //menuItem.addSubItem(attach_music, LocaleController.getString("ChatMusic", R.string.ChatMusic), R.drawable.ic_attach_music); + menuItem.addSubItem(attach_audio, LocaleController.getString("ChatMusic", R.string.ChatMusic), R.drawable.ic_attach_music); + menuItem.addSubItem(attach_video, LocaleController.getString("ChatVideo", R.string.ChatVideo), R.drawable.ic_attach_video); menuItem.addSubItem(attach_document, LocaleController.getString("ChatDocument", R.string.ChatDocument), R.drawable.ic_ab_doc); menuItem.addSubItem(attach_location, LocaleController.getString("ChatLocation", R.string.ChatLocation), R.drawable.ic_attach_location); + menuItem.addSubItem(attach_contact, LocaleController.getString("AttachContact", R.string.AttachContact), R.drawable.ic_attach_contact); menuItem.setShowFromBottom(true); menuItem.setBackgroundDrawable(null); @@ -1124,6 +1103,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); @@ -1132,9 +1114,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++) { @@ -1150,12 +1135,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); } @@ -1166,6 +1155,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) { @@ -1204,10 +1196,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; @@ -1217,6 +1209,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); } @@ -1225,15 +1221,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) { @@ -1267,17 +1261,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)); - } - } 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("EncryptedPlaceholderTitleOutgoing", R.string.EncryptedPlaceholderTitleOutgoing, UserObject.getFirstName(currentUser))); + } else { + 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)); @@ -1332,7 +1318,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); @@ -1364,7 +1369,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) { @@ -1501,7 +1506,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); @@ -1604,8 +1609,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 @@ -1619,14 +1626,22 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not chatActivityEnterView.replaceWithText(start, len, "@" + user.username + " "); } } else if (object instanceof String) { + if (mentionsAdapter.isBotCommands()) { + SendMessagesHelper.getInstance().sendMessage((String) object, dialog_id, null, null, false); + chatActivityEnterView.setFieldText(""); + } else { chatActivityEnterView.replaceWithText(start, len, object + " "); } } + } }); 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()); @@ -1651,6 +1666,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 @@ -1703,14 +1719,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); @@ -1746,7 +1762,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 = new View(context); @@ -1816,7 +1832,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() { @@ -1899,9 +1915,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 @@ -1909,7 +1925,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 @@ -1919,8 +1944,11 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } }); } + if (builder != null) { + builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); - showDialog(builder.create()); + showDialog(builder.create()); + } } }); @@ -1952,6 +1980,8 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not chatListView.setEmptyView(emptyViewContainer); } + chatActivityEnterView.setButtons(botButtons); + updateContactStatus(); updateBottomOverlay(); updateSecretStatus(); @@ -1959,6 +1989,35 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not return fragmentView; } + private void openAddMember() { + Bundle args = new Bundle(); + args.putBoolean("onlyUsers", true); + args.putBoolean("destroyAfterSelect", true); + args.putBoolean("returnAsResult", true); + //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, null); + } + }); + if (info != null) { + HashMap users = new HashMap<>(); + for (TLRPC.TL_chatParticipant p : info.participants) { + users.put(p.user_id, null); + } + fragment.setIgnoreUsers(users); + } + presentFragment(fragment); + } + private boolean searchForHttpInText(CharSequence string) { int len = string.length(); int seqLen = 0; @@ -1986,6 +2045,194 @@ 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_sticker) { + PhotoAlbumPickerActivity fragment = new PhotoAlbumPickerActivity(false, ChatActivity.this); + fragment.imageFilter = ".webp"; + 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 photoPickerIntent = new Intent(Intent.ACTION_PICK); + startActivityForResult(photoPickerIntent, 40); + } 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; @@ -2083,7 +2330,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not int textColor = themePrefs.getInt("chatEditTextColor", 0xff999999); replyObjectTextView.setTextColor(textColor); //int rColor = themePrefs.getInt("chatForwardRColor", defColor); - Drawable delete = getParentActivity().getResources().getDrawable(R.drawable.delete_reply); + Drawable delete = ApplicationLoader.applicationContext.getResources().getDrawable(R.drawable.delete_reply); delete.setColorFilter(iColor, PorterDuff.Mode.SRC_IN); deleteIconImageView.setImageDrawable(delete); if (messageObject != null) { @@ -2099,13 +2346,13 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not return; } //replyIconImageView.setImageResource(R.drawable.reply); - Drawable reply = getParentActivity().getResources().getDrawable(R.drawable.reply); + Drawable reply = ApplicationLoader.applicationContext.getResources().getDrawable(R.drawable.reply); reply.setColorFilter(iColor, PorterDuff.Mode.SRC_IN); replyIconImageView.setImageDrawable(reply); deleteIconImageView.setVisibility(View.VISIBLE); lineView.setVisibility(View.VISIBLE); - replyNameTextView.setText(ContactsController.formatName(user.first_name, user.last_name)); + replyNameTextView.setText(UserObject.getUserName(user)); replyNameTextView.setTextColor(iColor); if (messageObject.messageText != null) { String mess = messageObject.messageText.toString(); @@ -2129,7 +2376,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not chatActivityEnterView.setForceShowSendButton(true, animated); ArrayList uids = new ArrayList<>(); //replyIconImageView.setImageResource(R.drawable.forward_blue); - Drawable forward = getParentActivity().getResources().getDrawable(R.drawable.forward_blue); + Drawable forward = ApplicationLoader.applicationContext.getResources().getDrawable(R.drawable.forward_blue); forward.setColorFilter(iColor, PorterDuff.Mode.SRC_IN); replyIconImageView.setImageDrawable(forward); deleteIconImageView.setVisibility(View.VISIBLE); @@ -2153,7 +2400,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(", "); @@ -2217,7 +2464,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } } else if (webPage != null) { //replyIconImageView.setImageResource(R.drawable.link); - Drawable link = getParentActivity().getResources().getDrawable(R.drawable.link); + Drawable link = ApplicationLoader.applicationContext.getResources().getDrawable(R.drawable.link); link.setColorFilter(iColor, PorterDuff.Mode.SRC_IN); replyIconImageView.setImageDrawable(link); replyNameTextView.setTextColor(iColor);// @@ -2263,6 +2510,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); @@ -2327,6 +2578,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; @@ -2477,7 +2730,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()); } @@ -2488,7 +2741,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); @@ -2724,16 +2977,46 @@ 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)); + 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; } } - } else { - nameTextView.setText(ContactsController.formatName(currentUser.first_name, currentUser.last_name)); } } + 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() { @@ -2787,9 +3070,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; @@ -3048,7 +3335,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(); @@ -3060,24 +3362,57 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } SendMessagesHelper.prepareSendingDocument(tempPath, originalPath, null, null, dialog_id, replyingMessageObject); showReplyPanel(false, null, null, null, false, true); - } //attach_music - else if (requestCode == 3) { + } else if (requestCode == 31) { if (data == null || data.getData() == null) { showAttachmentError(); return; } - String tempPath = AndroidUtilities.getPath(data.getData()); - String originalPath = tempPath; - if (tempPath == null) { - originalPath = data.toString(); - tempPath = MediaController.copyDocumentToCache(data.getData(), "file"); + 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); + } } - if (tempPath == null) { + } else if (requestCode == 32) { + if (data == null || data.getData() == null) { showAttachmentError(); return; } - SendMessagesHelper.prepareSendingDocument(tempPath, originalPath, null, null, dialog_id, replyingMessageObject); - } else if (requestCode == 4) { //attach_sticker + 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); + } + } else if (requestCode == 40) { //attach_sticker if (data == null || data.getData() == null) { showAttachmentError(); return; @@ -3278,11 +3613,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 { @@ -3310,21 +3652,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); @@ -3333,13 +3660,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); } } @@ -3378,6 +3708,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); @@ -3446,6 +3780,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; @@ -3498,10 +3833,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) { @@ -3541,6 +3876,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) { @@ -3565,6 +3901,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not unreadUpdated = false; unread_to_load = 0; scrollToTopUnReadOnResume = true; + addedCount++; } } if (unreadMessageObject != null) { @@ -3578,12 +3915,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); } @@ -3591,8 +3931,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; @@ -3600,9 +3940,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) { @@ -3628,6 +3974,10 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } } } + if (!messages.isEmpty() && botUser != null && botUser.length() == 0) { + botUser = null; + updateBottomOverlay(); + } if (updateChat) { updateTitle(); checkAndUpdateAvatar(); @@ -3705,8 +4055,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; @@ -3718,6 +4072,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) { @@ -3735,11 +4100,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(); } @@ -3771,6 +4153,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(); @@ -3850,6 +4251,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(); @@ -3912,16 +4324,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(); } } @@ -3973,12 +4385,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 @@ -4000,24 +4483,40 @@ 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 { - muteItem.setVisibility(View.VISIBLE); + if (botUser != null) { + bottomOverlayChat.setVisibility(View.VISIBLE); + chatActivityEnterView.setVisibility(View.INVISIBLE); + } else { + chatActivityEnterView.setVisibility(View.VISIBLE); bottomOverlayChat.setVisibility(View.INVISIBLE); } + muteItem.setVisibility(View.VISIBLE); + } } private void updateContactStatus() { @@ -4033,7 +4532,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); @@ -4097,11 +4596,16 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not fixLayout(true); SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); + 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(); @@ -4119,9 +4623,13 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not 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; @@ -4160,12 +4668,6 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not back.setColorFilter(iColor, PorterDuff.Mode.MULTIPLY); } - @Override - public void onBeginSlide() { - super.onBeginSlide(); - chatActivityEnterView.hideEmojiPopup(); - } - @Override public void onPause() { super.onPause(); @@ -4176,7 +4678,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); @@ -4241,10 +4743,7 @@ 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); @@ -4269,7 +4768,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; } }); } @@ -4485,11 +4984,12 @@ 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) { + try { if (Build.VERSION.SDK_INT < 11) { android.text.ClipboardManager clipboard = (android.text.ClipboardManager) ApplicationLoader.applicationContext.getSystemService(Context.CLIPBOARD_SERVICE); clipboard.setText(selectedObject.messageText); @@ -4498,6 +4998,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not 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(); String path = selectedObject.messageOwner.attachPath; @@ -4742,8 +5245,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; @@ -4909,9 +5412,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 { @@ -4923,16 +5463,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 @@ -4964,12 +5495,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) { @@ -5006,13 +5550,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); } } @@ -5162,6 +5708,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not FileLog.e("tmessages", e); } } else if (i == 0) { + 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); @@ -5170,6 +5717,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not android.content.ClipData clip = android.content.ClipData.newPlainText("label", messageObject.messageOwner.media.phone_number); clipboard.setPrimaryClip(clip); } + } catch (Exception e) { + FileLog.e("tmessages", e); + } } } } @@ -5208,17 +5758,16 @@ 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; - } - - MessageObject message = messages.get(messages.size() - position - (!endReached ? 0 : 1)); + 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; - int type = message.contentType; - boolean selected = false; boolean disableSelection = false; if (actionBar.isActionModeShowed()) { @@ -5245,26 +5794,23 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } 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)); + } else if (view instanceof ChatUnreadCell) { + ChatUnreadCell unreadCell = (ChatUnreadCell) view; + unreadCell.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 @@ -5292,7 +5838,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) { @@ -5301,7 +5847,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/AvatarUpdater.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/AvatarUpdater.java index b1ae9807..57e0b98a 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/AvatarUpdater.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/AvatarUpdater.java @@ -19,15 +19,15 @@ import android.provider.MediaStore; import org.telegram.android.AndroidUtilities; import org.telegram.android.ImageLoader; import org.telegram.android.MediaController; -import org.telegram.android.NotificationCenter; +import org.telegram.messenger.TLRPC; import org.telegram.messenger.FileLoader; import org.telegram.messenger.FileLog; -import org.telegram.messenger.TLRPC; +import org.telegram.android.NotificationCenter; import org.telegram.messenger.UserConfig; -import org.telegram.ui.ActionBar.BaseFragment; import org.telegram.ui.LaunchActivity; import org.telegram.ui.PhotoAlbumPickerActivity; import org.telegram.ui.PhotoCropActivity; +import org.telegram.ui.ActionBar.BaseFragment; import org.telegram.ui.PhotoViewer; import java.io.File; @@ -204,28 +204,28 @@ public class AvatarUpdater implements NotificationCenter.NotificationCenterDeleg if (id == NotificationCenter.FileDidUpload) { String location = (String)args[0]; if (uploadingAvatar != null && location.equals(uploadingAvatar)) { - NotificationCenter.getInstance().removeObserver(AvatarUpdater.this, NotificationCenter.FileDidUpload); - NotificationCenter.getInstance().removeObserver(AvatarUpdater.this, NotificationCenter.FileDidFailUpload); - if (delegate != null) { - delegate.didUploadedPhoto((TLRPC.InputFile)args[1], smallPhoto, bigPhoto); - } - uploadingAvatar = null; - if (clearAfterUpdate) { - parentFragment = null; - delegate = null; - } - } + NotificationCenter.getInstance().removeObserver(AvatarUpdater.this, NotificationCenter.FileDidUpload); + NotificationCenter.getInstance().removeObserver(AvatarUpdater.this, NotificationCenter.FileDidFailUpload); + if (delegate != null) { + delegate.didUploadedPhoto((TLRPC.InputFile)args[1], smallPhoto, bigPhoto); + } + uploadingAvatar = null; + if (clearAfterUpdate) { + parentFragment = null; + delegate = null; + } + } } else if (id == NotificationCenter.FileDidFailUpload) { String location = (String)args[0]; if (uploadingAvatar != null && location.equals(uploadingAvatar)) { - NotificationCenter.getInstance().removeObserver(AvatarUpdater.this, NotificationCenter.FileDidUpload); - NotificationCenter.getInstance().removeObserver(AvatarUpdater.this, NotificationCenter.FileDidFailUpload); - uploadingAvatar = null; - if (clearAfterUpdate) { - parentFragment = null; - delegate = null; - } - } - } + NotificationCenter.getInstance().removeObserver(AvatarUpdater.this, NotificationCenter.FileDidUpload); + NotificationCenter.getInstance().removeObserver(AvatarUpdater.this, NotificationCenter.FileDidFailUpload); + uploadingAvatar = null; + if (clearAfterUpdate) { + parentFragment = null; + delegate = null; + } } } + } +} 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 e7c1e828..2ac30c33 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatActivityEnterView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatActivityEnterView.java @@ -14,7 +14,6 @@ import android.content.SharedPreferences; import android.graphics.PorterDuff; import android.graphics.drawable.Drawable; import android.media.AudioManager; -import android.os.Build; import android.os.PowerManager; import android.text.Editable; import android.text.TextWatcher; @@ -25,8 +24,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; @@ -56,7 +53,9 @@ import org.telegram.messenger.TLRPC; import org.telegram.messenger.UserConfig; import org.telegram.ui.ActionBar.BaseFragment; -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); @@ -69,23 +68,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; @@ -97,6 +102,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; @@ -106,11 +112,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; @@ -121,7 +131,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); @@ -134,62 +157,21 @@ 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); @@ -200,24 +182,14 @@ public class ChatActivityEnterView extends FrameLayoutFixed implements Notificat emojiButton.setImageDrawable(emoji); 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(); } } }); @@ -235,20 +207,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) { @@ -261,8 +226,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); } } }); @@ -335,99 +300,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); @@ -439,11 +376,7 @@ public class ChatActivityEnterView extends FrameLayoutFixed implements Notificat audioSendButton.setImageDrawable(mic); audioSendButton.setBackgroundColor(0x00000000); 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) { @@ -533,11 +466,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) { @@ -545,6 +474,10 @@ 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); updateTheme(); @@ -564,40 +497,15 @@ public class ChatActivityEnterView extends FrameLayoutFixed implements Notificat textFieldContainer.setBackgroundColor(color); } - 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) { @@ -633,7 +541,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) @@ -706,7 +614,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); } @@ -739,9 +651,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(); @@ -751,10 +661,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); } } } @@ -764,7 +688,19 @@ public class ChatActivityEnterView extends FrameLayoutFixed implements Notificat } public void setReplyingMessageObject(MessageObject 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) { @@ -1084,134 +1020,28 @@ public class ChatActivityEnterView extends FrameLayoutFixed implements Notificat } } - private void showEmojiPopup(boolean show, boolean post) { - SharedPreferences themePrefs = ApplicationLoader.applicationContext.getSharedPreferences(AndroidUtilities.THEME_PREFS, AndroidUtilities.THEME_PREFS_MODE); - int color = themePrefs.getInt("chatEditTextIconsColor", 0xffadadad); - 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; - //int currentHeight = AndroidUtilities.displaySize.x > AndroidUtilities.displaySize.y ? keyboardHeightLand : AndroidUtilities.dp(400); - 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); - Drawable hide = parentActivity.getResources().getDrawable(R.drawable.ic_msg_panel_hide); - hide.setColorFilter(color, PorterDuff.Mode.SRC_IN); - emojiButton.setImageDrawable(hide); - showKeyboardOnEmojiButton = false; - onWindowSizeChanged(sizeNotifierLayout.getHeight() - sizeNotifierLayout.getPaddingBottom()); - } - return; - } else { - setKeyboardTransitionState(2); - AndroidUtilities.hideKeyboard(messageEditText); - } - //emojiButton.setImageResource(R.drawable.ic_msg_panel_kb); - Drawable kb = parentActivity.getResources().getDrawable(R.drawable.ic_msg_panel_kb_white); - kb.setColorFilter(color, PorterDuff.Mode.MULTIPLY); - emojiButton.setImageDrawable(kb); - showKeyboardOnEmojiButton = true; - return; - } - if (emojiButton != null) { - showKeyboardOnEmojiButton = false; - //emojiButton.setImageResource(R.drawable.ic_msg_panel_smiles); - Drawable emoji = parentActivity.getResources().getDrawable(R.drawable.ic_msg_panel_smiles); - emoji.setColorFilter(color, PorterDuff.Mode.SRC_IN); - emojiButton.setImageDrawable(emoji); - } - 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; @@ -1280,10 +1110,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; @@ -1292,12 +1118,265 @@ 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); + } + Drawable d; + SharedPreferences themePrefs = ApplicationLoader.applicationContext.getSharedPreferences(AndroidUtilities.THEME_PREFS, AndroidUtilities.THEME_PREFS_MODE); + int color = themePrefs.getInt("chatEditTextIconsColor", 0xffadadad); + if (botReplyMarkup != null) { + if (isPopupShowing() && currentPopupContentType == 1) { + d = getResources().getDrawable(R.drawable.ic_msg_panel_kb); + d.setColorFilter(color, PorterDuff.Mode.SRC_IN); + botButton.setImageDrawable(d); + //botButton.setImageResource(R.drawable.ic_msg_panel_kb); + } else { + d = getResources().getDrawable(R.drawable.bot_keyboard2); + d.setColorFilter(color, PorterDuff.Mode.SRC_IN); + botButton.setImageDrawable(d); + //botButton.setImageResource(R.drawable.bot_keyboard2); + } + } else { + d = getResources().getDrawable(R.drawable.bot_keyboard); + d.setColorFilter(color, PorterDuff.Mode.SRC_IN); + botButton.setImageDrawable(d); + //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) { + SharedPreferences themePrefs = ApplicationLoader.applicationContext.getSharedPreferences(AndroidUtilities.THEME_PREFS, AndroidUtilities.THEME_PREFS_MODE); + int color = themePrefs.getInt("chatEditTextIconsColor", 0xffadadad); + Drawable d; + 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) { + d = getResources().getDrawable(R.drawable.ic_msg_panel_kb); + d.setColorFilter(color, PorterDuff.Mode.SRC_IN); + emojiButton.setImageDrawable(d); + //emojiButton.setImageResource(R.drawable.ic_msg_panel_kb); + } else if (contentType == 1) { + d = getResources().getDrawable(R.drawable.ic_msg_panel_smiles); + d.setColorFilter(color, PorterDuff.Mode.SRC_IN); + emojiButton.setImageDrawable(d); + //emojiButton.setImageResource(R.drawable.ic_msg_panel_smiles); + } + updateBotButton(); + onWindowSizeChanged(); + } + } else { + if (emojiButton != null) { + d = getResources().getDrawable(R.drawable.ic_msg_panel_smiles); + d.setColorFilter(color, PorterDuff.Mode.SRC_IN); + emojiButton.setImageDrawable(d); + //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 @@ -1312,53 +1391,65 @@ public class ChatActivityEnterView extends FrameLayoutFixed implements Notificat } } - if (emojiPopup != null && emojiPopup.isShowing()) { + if (isPopupShowing()) { int newHeight = isWidthGreater ? keyboardHeightLand : keyboardHeight; SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("emoji", Activity.MODE_PRIVATE); int pSize = preferences.getInt("emojiPopupSize", 60); int popupSize = AndroidUtilities.dp((pSize - 40) * 10); newHeight = popupSize < newHeight ? newHeight : popupSize; - try { - View view = emojiPopup.getContentView(); - if(Build.VERSION.SDK_INT > 22) { - if (!(view.getLayoutParams() instanceof WindowManager.LayoutParams)) { - view = (View) view.getParent(); - } + if (currentPopupContentType == 1 && !botKeyboardView.isFullSize()) { + newHeight = Math.min(botKeyboardView.getKeyboardHeight(), newHeight); } - WindowManager.LayoutParams layoutParams = (WindowManager.LayoutParams) view.getLayoutParams(); - FileLog.e("tmessages", "update emoji height to = " + newHeight); - //if (layoutParams.width != AndroidUtilities.displaySize.x || layoutParams.height != newHeight) { - if (layoutParams.width != AndroidUtilities.displaySize.x || layoutParams.height != newHeight || (pSize > 60 && sizeNotifierLayout.getPaddingBottom() != 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(); } } - } catch (Exception e) { - FileLog.e("tmessages", e); - } } + 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() { @@ -1375,6 +1466,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); @@ -1405,8 +1499,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/ClippingImageView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/ClippingImageView.java index ad8217f3..71ec5be0 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/ClippingImageView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/ClippingImageView.java @@ -18,8 +18,8 @@ import android.graphics.RectF; import android.graphics.Shader; import android.view.View; -import org.telegram.android.AnimationCompat.ViewProxy; import org.telegram.messenger.FileLog; +import org.telegram.android.AnimationCompat.ViewProxy; public class ClippingImageView extends View { 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 b7bbb03a..3cb770d4 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; @@ -36,6 +40,7 @@ import org.telegram.messenger.ApplicationLoader; 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; @@ -43,7 +48,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(); @@ -52,9 +57,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, @@ -68,9 +73,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; @@ -84,7 +95,7 @@ public class EmojiView extends LinearLayout implements NotificationCenter.Notifi int bgColor = themePrefs.getInt("chatEmojiViewBGColor", 0xfff5f6f7); int tabColor = themePrefs.getInt("chatEmojiViewTabColor", AndroidUtilities.getIntDarkerColor("themeColor", -0x15)); int lineColor = bgColor == 0xfff5f6f7 ? 0xffe2e5e7 : AndroidUtilities.setDarkColor(bgColor, 0x10); - setOrientation(LinearLayout.VERTICAL); + //setOrientation(LinearLayout.VERTICAL); for (int i = 0; i < Emoji.data.length; i++) { GridView gridView = new GridView(context); if (AndroidUtilities.isTablet()) { @@ -104,7 +115,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); @@ -115,33 +125,187 @@ public class EmojiView extends LinearLayout implements NotificationCenter.Notifi gridView.setAdapter(stickersGridAdapter); //AndroidUtilities.setListViewEdgeEffectColor(gridView, 0xfff5f6f7); AndroidUtilities.setListViewEdgeEffectColor(gridView, bgColor); + 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); + scrollSlidingTabStrip.setIndicatorColor(tabColor); + scrollSlidingTabStrip.setUnderlineColor(lineColor); + 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); setBackgroundColor(bgColor); - 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); - linearLayout.setBackgroundColor(bgColor); - 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); + pagerSlidingTabStripContainer.setBackgroundColor(bgColor); + 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.setIndicatorColor(tabColor); - //tabs.setUnderlineColor(0xffe2e5e7); - tabs.setUnderlineColor(lineColor); - 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); + pagerSlidingTabStrip.setIndicatorColor(tabColor); + pagerSlidingTabStrip.setUnderlineColor(lineColor); + 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 @@ -165,12 +329,12 @@ 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); view.setBackgroundColor(lineColor); - 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)); @@ -183,20 +347,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(); @@ -205,6 +356,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 @@ -284,12 +468,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()) { @@ -298,7 +487,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); @@ -317,6 +506,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() { @@ -355,14 +566,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) { + 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(); } } - } - - 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)); + super.onLayout(changed, left, top, right, bottom); } public void setListener(Listener value) { @@ -382,8 +621,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(); } } @@ -399,31 +646,82 @@ 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) { + TLRPC.Document sticker = cache.get(i); + if (sticker != null) { if (view == null) { view = new StickerEmojiCell(context) { public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { @@ -439,6 +737,16 @@ public class EmojiView extends LinearLayout implements NotificationCenter.Notifi 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); @@ -446,10 +754,65 @@ public class EmojiView extends LinearLayout implements NotificationCenter.Notifi } }); } - ((StickerEmojiCell) view).setSticker(stickers.get(i), false); + ((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)); + } + } 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) { @@ -511,16 +874,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() { @@ -531,21 +894,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/PhotoFilterView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/PhotoFilterView.java index 639d99ef..ced235b6 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/PhotoFilterView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/PhotoFilterView.java @@ -30,10 +30,6 @@ import android.widget.ImageView; import android.widget.TextView; 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.android.support.widget.LinearLayoutManager; import org.telegram.android.support.widget.RecyclerView; @@ -41,6 +37,10 @@ import org.telegram.messenger.DispatchQueue; import org.telegram.messenger.FileLog; import org.telegram.messenger.R; import org.telegram.messenger.Utilities; +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.ui.Cells.PhotoEditToolCell; import java.nio.ByteBuffer; 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 e8f788ec..fcff6ef2 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/PhotoViewerCaptionEnterView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/PhotoViewerCaptionEnterView.java @@ -8,7 +8,6 @@ package org.telegram.ui.Components; -import android.app.Activity; import android.content.Context; import android.text.Editable; import android.text.InputFilter; @@ -17,21 +16,15 @@ 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; -import org.telegram.android.AnimationCompat.AnimatorSetProxy; -import org.telegram.android.AnimationCompat.ObjectAnimatorProxy; import org.telegram.android.Emoji; import org.telegram.android.LocaleController; import org.telegram.android.NotificationCenter; @@ -39,26 +32,21 @@ import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.FileLog; import org.telegram.messenger.R; 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; @@ -66,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); @@ -98,36 +87,20 @@ 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(); } } }); 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); - //Show suggestions - messageEditText.setImeOptions(EditorInfo.IME_FLAG_NO_EXTRACT_UI); - messageEditText.setInputType(messageEditText.getInputType() | EditorInfo.TYPE_TEXT_FLAG_CAP_SENTENCES | EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE); - messageEditText.setSingleLine(false); + messageEditText.setImeOptions(EditorInfo.IME_FLAG_NO_EXTRACT_UI | EditorInfo.IME_ACTION_DONE); + 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)); @@ -142,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) { @@ -154,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) { @@ -195,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); } } @@ -219,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); } @@ -268,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; } @@ -475,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()); } } @@ -527,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 @@ -562,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 @@ -605,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/PopupAudioView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/PopupAudioView.java index 86f9036f..c6f7bb03 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/PopupAudioView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/PopupAudioView.java @@ -20,10 +20,10 @@ import android.view.SoundEffectConstants; import org.telegram.android.AndroidUtilities; import org.telegram.android.ImageLoader; import org.telegram.android.MediaController; -import org.telegram.android.MessageObject; import org.telegram.android.MessagesController; import org.telegram.messenger.FileLoader; import org.telegram.messenger.R; +import org.telegram.android.MessageObject; import org.telegram.ui.Cells.BaseCell; import java.io.File; 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 55a75b2f..b356c719 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/SizeNotifierRelativeLayout.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/SizeNotifierRelativeLayout.java deleted file mode 100644 index 8802e850..00000000 --- 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/SizeNotifierRelativeLayoutPhoto.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/SizeNotifierRelativeLayoutPhoto.java deleted file mode 100644 index ef2d6055..00000000 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/SizeNotifierRelativeLayoutPhoto.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * This is the source code of Telegram for Android v. 2.x - * It is licensed under GNU GPL v. 2 or later. - * You should have received a copy of the license in this archive (see LICENSE). - * - * Copyright Nikolai Kudashov, 2013-2015. - */ - -package org.telegram.ui.Components; - -import android.annotation.SuppressLint; -import android.content.Context; -import android.graphics.Rect; -import android.view.View; -import android.widget.RelativeLayout; - -import org.telegram.android.AndroidUtilities; - -public class SizeNotifierRelativeLayoutPhoto extends RelativeLayout { - - public interface SizeNotifierRelativeLayoutPhotoDelegate { - void onSizeChanged(int keyboardHeight, boolean isWidthGreater); - } - - private Rect rect = new Rect(); - private int keyboardHeight; - private SizeNotifierRelativeLayoutPhotoDelegate delegate; - - public SizeNotifierRelativeLayoutPhoto(Context context) { - super(context); - } - - public void setDelegate(SizeNotifierRelativeLayoutPhotoDelegate 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.getViewInset(rootView); - this.getWindowVisibleDisplayFrame(rect); - keyboardHeight = (rect.bottom - rect.top) - usableViewHeight; - final boolean isWidthGreater = AndroidUtilities.displaySize.x > AndroidUtilities.displaySize.y; - post(new Runnable() { - @Override - public void run() { - if (delegate != null) { - delegate.onSizeChanged(keyboardHeight, isWidthGreater); - } - } - }); - } - } -} diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ContactsActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ContactsActivity.java index a2c3d00a..5a3ba06a 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ContactsActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ContactsActivity.java @@ -18,7 +18,9 @@ import android.graphics.drawable.Drawable; 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; @@ -33,6 +35,7 @@ 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.ContactsController; @@ -41,10 +44,12 @@ import org.telegram.android.MessagesController; import org.telegram.android.MessagesStorage; import org.telegram.android.NotificationCenter; import org.telegram.android.SecretChatHelper; +import org.telegram.android.UserObject; import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.FileLog; import org.telegram.messenger.R; import org.telegram.messenger.TLRPC; +import org.telegram.messenger.Utilities; import org.telegram.ui.ActionBar.ActionBar; import org.telegram.ui.ActionBar.ActionBarMenu; import org.telegram.ui.ActionBar.ActionBarMenuItem; @@ -167,7 +172,7 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter } @Override - public boolean onSearchCollapse() { + public void onSearchCollapse() { searchListViewAdapter.searchDialogs(null); searching = false; searchWas = false; @@ -179,7 +184,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 @@ -420,10 +424,21 @@ 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()); + 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); } @@ -432,24 +447,64 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter 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); + } + 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 (editText != null) { + ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) editText.getLayoutParams(); if (layoutParams != null) { if (layoutParams instanceof FrameLayout.LayoutParams) { - ((FrameLayout.LayoutParams)layoutParams).gravity = Gravity.CENTER_HORIZONTAL; + ((FrameLayout.LayoutParams) layoutParams).gravity = Gravity.CENTER_HORIZONTAL; } layoutParams.rightMargin = layoutParams.leftMargin = AndroidUtilities.dp(10); editText.setLayoutParams(layoutParams); } 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 bb419af7..3058d691 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/CountrySelectActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/CountrySelectActivity.java @@ -25,13 +25,13 @@ import android.widget.TextView; import org.telegram.android.AndroidUtilities; import org.telegram.android.LocaleController; import org.telegram.messenger.R; +import org.telegram.ui.Adapters.CountryAdapter; +import org.telegram.ui.Adapters.CountryAdapter.Country; +import org.telegram.ui.Adapters.CountrySearchAdapter; import org.telegram.ui.ActionBar.ActionBar; import org.telegram.ui.ActionBar.ActionBarMenu; import org.telegram.ui.ActionBar.ActionBarMenuItem; import org.telegram.ui.ActionBar.BaseFragment; -import org.telegram.ui.Adapters.CountryAdapter; -import org.telegram.ui.Adapters.CountryAdapter.Country; -import org.telegram.ui.Adapters.CountrySearchAdapter; import org.telegram.ui.Components.LayoutHelper; import org.telegram.ui.Components.LetterSectionsListView; @@ -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 24512cc7..3b571d21 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/GroupCreateActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/GroupCreateActivity.java @@ -39,21 +39,21 @@ import android.widget.LinearLayout; import android.widget.ListView; import android.widget.TextView; -import org.telegram.PhoneFormat.PhoneFormat; import org.telegram.android.AndroidUtilities; -import org.telegram.android.ContactsController; +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.messenger.FileLog; import org.telegram.android.MessagesController; import org.telegram.android.NotificationCenter; -import org.telegram.messenger.ApplicationLoader; -import org.telegram.messenger.FileLog; import org.telegram.messenger.R; -import org.telegram.messenger.TLRPC; +import org.telegram.ui.Adapters.ContactsAdapter; +import org.telegram.ui.Adapters.SearchAdapter; import org.telegram.ui.ActionBar.ActionBar; import org.telegram.ui.ActionBar.ActionBarMenu; import org.telegram.ui.ActionBar.BaseFragment; -import org.telegram.ui.Adapters.ContactsAdapter; -import org.telegram.ui.Adapters.SearchAdapter; import org.telegram.ui.Cells.UserCell; import org.telegram.ui.Components.LayoutHelper; import org.telegram.ui.Components.LetterSectionsListView; @@ -508,7 +508,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 d882721d..b0aa4da6 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/IdenticonActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/IdenticonActivity.java @@ -22,10 +22,10 @@ import android.widget.TextView; import org.telegram.android.AndroidUtilities; import org.telegram.android.LocaleController; -import org.telegram.android.MessagesController; import org.telegram.messenger.ApplicationLoader; -import org.telegram.messenger.R; import org.telegram.messenger.TLRPC; +import org.telegram.android.MessagesController; +import org.telegram.messenger.R; import org.telegram.ui.ActionBar.ActionBar; import org.telegram.ui.ActionBar.BaseFragment; import org.telegram.ui.Components.IdenticonDrawable; @@ -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 bab33f5f..e77659fd 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/LanguageSelectActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/LanguageSelectActivity.java @@ -12,6 +12,8 @@ import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; import android.content.SharedPreferences; +import android.graphics.PorterDuff; +import android.graphics.drawable.Drawable; import android.view.Gravity; import android.view.LayoutInflater; import android.view.MotionEvent; @@ -26,17 +28,17 @@ import android.widget.ListView; import android.widget.TextView; import org.telegram.android.AndroidUtilities; -import org.telegram.android.LocaleController; -import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.FileLog; +import org.telegram.messenger.ApplicationLoader; +import org.telegram.android.LocaleController; import org.telegram.messenger.R; import org.telegram.messenger.Utilities; +import org.telegram.ui.Adapters.BaseFragmentAdapter; +import org.telegram.ui.Cells.TextSettingsCell; import org.telegram.ui.ActionBar.ActionBar; import org.telegram.ui.ActionBar.ActionBarMenu; import org.telegram.ui.ActionBar.ActionBarMenuItem; import org.telegram.ui.ActionBar.BaseFragment; -import org.telegram.ui.Adapters.BaseFragmentAdapter; -import org.telegram.ui.Cells.TextSettingsCell; import org.telegram.ui.Components.LayoutHelper; import java.util.ArrayList; @@ -73,14 +75,16 @@ public class LanguageSelectActivity extends BaseFragment { }); ActionBarMenu menu = actionBar.createMenu(); - ActionBarMenuItem item = menu.addItem(0, R.drawable.ic_ab_search).setIsSearchField(true).setActionBarMenuItemSearchListener(new ActionBarMenuItem.ActionBarMenuItemSearchListener() { + //ActionBarMenuItem item = menu.addItem(0, R.drawable.ic_ab_search).setIsSearchField(true).setActionBarMenuItemSearchListener(new ActionBarMenuItem.ActionBarMenuItemSearchListener() { + Drawable search = getParentActivity().getResources().getDrawable(R.drawable.ic_ab_search); + ActionBarMenuItem item = menu.addItem(0, search).setIsSearchField(true).setActionBarMenuItemSearchListener(new ActionBarMenuItem.ActionBarMenuItemSearchListener() { @Override public void onSearchExpand() { searching = true; } @Override - public boolean onSearchCollapse() { + public void onSearchCollapse() { search(null); searching = false; searchWas = false; @@ -88,8 +92,6 @@ public class LanguageSelectActivity extends BaseFragment { emptyTextView.setVisibility(View.GONE); listView.setAdapter(listAdapter); } - - return true; } @Override @@ -246,6 +248,21 @@ public class LanguageSelectActivity extends BaseFragment { if (listAdapter != null) { listAdapter.notifyDataSetChanged(); } + updateTheme(); + } + + private void updateTheme(){ + SharedPreferences themePrefs = ApplicationLoader.applicationContext.getSharedPreferences(AndroidUtilities.THEME_PREFS, AndroidUtilities.THEME_PREFS_MODE); + int def = themePrefs.getInt("themeColor", AndroidUtilities.defColor); + actionBar.setBackgroundColor(themePrefs.getInt("prefHeaderColor", def)); + actionBar.setTitleColor(themePrefs.getInt("prefHeaderTitleColor", 0xffffffff)); + + Drawable back = getParentActivity().getResources().getDrawable(R.drawable.ic_ab_back); + back.setColorFilter(themePrefs.getInt("prefHeaderIconsColor", 0xffffffff), PorterDuff.Mode.MULTIPLY); + actionBar.setBackButtonDrawable(back); + + Drawable search = getParentActivity().getResources().getDrawable(R.drawable.ic_ab_search); + search.setColorFilter(themePrefs.getInt("prefHeaderIconsColor", 0xffffffff), PorterDuff.Mode.MULTIPLY); } public void search(final String query) { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/LastSeenActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/LastSeenActivity.java index 4d6ef287..aaecedd3 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/LastSeenActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/LastSeenActivity.java @@ -141,7 +141,12 @@ public class LastSeenActivity extends BaseFragment implements NotificationCenter }); ActionBarMenu menu = actionBar.createMenu(); - doneButton = menu.addItemWithWidth(done_button, R.drawable.ic_done, AndroidUtilities.dp(56)); + //doneButton = menu.addItemWithWidth(done_button, R.drawable.ic_done, AndroidUtilities.dp(56)); + SharedPreferences themePrefs = ApplicationLoader.applicationContext.getSharedPreferences(AndroidUtilities.THEME_PREFS, AndroidUtilities.THEME_PREFS_MODE); + Drawable done = getParentActivity().getResources().getDrawable(R.drawable.ic_done); + done.setColorFilter(themePrefs.getInt("prefHeaderIconsColor", 0xffffffff), PorterDuff.Mode.SRC_IN); + doneButton = menu.addItemWithWidth(done_button, done, AndroidUtilities.dp(56)); + doneButton.setVisibility(View.GONE); listAdapter = new ListAdapter(context); @@ -395,6 +400,18 @@ public class LastSeenActivity extends BaseFragment implements NotificationCenter if (listAdapter != null) { listAdapter.notifyDataSetChanged(); } + updateTheme(); + } + + private void updateTheme(){ + SharedPreferences themePrefs = ApplicationLoader.applicationContext.getSharedPreferences(AndroidUtilities.THEME_PREFS, AndroidUtilities.THEME_PREFS_MODE); + int def = themePrefs.getInt("themeColor", AndroidUtilities.defColor); + actionBar.setBackgroundColor(themePrefs.getInt("prefHeaderColor", def)); + actionBar.setTitleColor(themePrefs.getInt("prefHeaderTitleColor", 0xffffffff)); + + Drawable back = getParentActivity().getResources().getDrawable(R.drawable.ic_ab_back); + back.setColorFilter(themePrefs.getInt("prefHeaderIconsColor", 0xffffffff), PorterDuff.Mode.MULTIPLY); + actionBar.setBackButtonDrawable(back); } private class ListAdapter extends BaseFragmentAdapter { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/LastSeenUsersActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/LastSeenUsersActivity.java index 47398b6a..6eee902d 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/LastSeenUsersActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/LastSeenUsersActivity.java @@ -12,6 +12,8 @@ import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; import android.content.SharedPreferences; +import android.graphics.PorterDuff; +import android.graphics.drawable.Drawable; import android.os.Build; import android.os.Bundle; import android.view.Gravity; @@ -232,6 +234,18 @@ public class LastSeenUsersActivity extends BaseFragment implements NotificationC if (listViewAdapter != null) { listViewAdapter.notifyDataSetChanged(); } + updateTheme(); + } + + private void updateTheme(){ + SharedPreferences themePrefs = ApplicationLoader.applicationContext.getSharedPreferences(AndroidUtilities.THEME_PREFS, AndroidUtilities.THEME_PREFS_MODE); + int def = themePrefs.getInt("themeColor", AndroidUtilities.defColor); + actionBar.setBackgroundColor(themePrefs.getInt("prefHeaderColor", def)); + actionBar.setTitleColor(themePrefs.getInt("prefHeaderTitleColor", 0xffffffff)); + + Drawable back = getParentActivity().getResources().getDrawable(R.drawable.ic_ab_back); + back.setColorFilter(themePrefs.getInt("prefHeaderIconsColor", 0xffffffff), PorterDuff.Mode.MULTIPLY); + actionBar.setBackButtonDrawable(back); } private class ListAdapter extends BaseFragmentAdapter { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/LaunchActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/LaunchActivity.java index 9638b9db..e38f965d 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/LaunchActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/LaunchActivity.java @@ -46,6 +46,7 @@ import org.telegram.android.MessagesController; import org.telegram.android.MessagesStorage; import org.telegram.android.NotificationCenter; 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.BuildConfig; @@ -348,6 +349,8 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa //Toast.makeText(getApplicationContext(), intent.toString(), Toast.LENGTH_SHORT).show(); startActivityForResult(intent, 503); } catch (Exception e) { + Intent in = new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=es.rafalense.themes")); + startActivityForResult(in, 503); FileLog.e("tmessages", e); } drawerLayoutContainer.closeDrawer(false); @@ -451,6 +454,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(); } @@ -580,7 +587,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 = ""; @@ -608,9 +615,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; } @@ -652,6 +656,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; } @@ -715,6 +724,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"))) { @@ -728,7 +739,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"); } } } @@ -738,6 +751,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); @@ -750,7 +765,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); @@ -902,7 +917,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); @@ -925,16 +940,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); + 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); - ChatActivity fragment = new ChatActivity(args); - NotificationCenter.getInstance().postNotificationName(NotificationCenter.closeChats); - actionBarLayout.presentFragment(fragment, false, true, true); + 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); + } } } } @@ -976,7 +1028,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); @@ -1144,12 +1196,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 4a67d317..4f944cfe 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; @@ -46,24 +47,24 @@ 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; +import org.telegram.messenger.TLRPC; import org.telegram.android.MessageObject; import org.telegram.android.MessagesController; import org.telegram.android.NotificationCenter; -import org.telegram.messenger.ApplicationLoader; -import org.telegram.messenger.FileLog; import org.telegram.messenger.R; -import org.telegram.messenger.TLRPC; import org.telegram.ui.ActionBar.ActionBar; import org.telegram.ui.ActionBar.ActionBarMenu; import org.telegram.ui.ActionBar.ActionBarMenuItem; -import org.telegram.ui.ActionBar.BaseFragment; import org.telegram.ui.Adapters.BaseLocationAdapter; import org.telegram.ui.Adapters.LocationActivityAdapter; import org.telegram.ui.Adapters.LocationActivitySearchAdapter; import org.telegram.ui.Components.AvatarDrawable; import org.telegram.ui.Components.BackupImageView; +import org.telegram.ui.ActionBar.BaseFragment; import org.telegram.ui.Components.LayoutHelper; import org.telegram.ui.Components.MapPlaceholderDrawable; @@ -211,7 +212,7 @@ public class LocationActivity extends BaseFragment implements NotificationCenter } @Override - public boolean onSearchCollapse() { + public void onSearchCollapse() { searching = false; searchWas = false; searchListView.setEmptyView(null); @@ -220,7 +221,6 @@ public class LocationActivity extends BaseFragment implements NotificationCenter searchListView.setVisibility(View.GONE); emptyTextLayout.setVisibility(View.GONE); searchAdapter.searchDelayed(null, null); - return true; } @Override @@ -617,6 +617,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()); @@ -758,7 +766,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 28cd8512..fd522912 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/LoginActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/LoginActivity.java @@ -50,7 +50,6 @@ import android.widget.TextView; import org.telegram.PhoneFormat.PhoneFormat; import org.telegram.android.AndroidUtilities; import org.telegram.android.ContactsController; -import org.telegram.android.LocaleController; import org.telegram.android.MessagesController; import org.telegram.android.MessagesStorage; import org.telegram.android.NotificationCenter; @@ -58,6 +57,7 @@ import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.BuildVars; import org.telegram.messenger.ConnectionsManager; import org.telegram.messenger.FileLog; +import org.telegram.android.LocaleController; import org.telegram.messenger.R; import org.telegram.messenger.RPCRequest; import org.telegram.messenger.TLObject; @@ -633,7 +633,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); @@ -2144,14 +2144,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 03ad4544..8866ae01 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 27c17465..b34bcb55 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/MessagesActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/MessagesActivity.java @@ -11,6 +11,7 @@ package org.telegram.ui; import android.animation.ObjectAnimator; import android.animation.StateListAnimator; import android.annotation.SuppressLint; +import android.app.Activity; import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; @@ -46,6 +47,8 @@ import org.telegram.android.MessageObject; import org.telegram.android.MessagesController; import org.telegram.android.MessagesStorage; import org.telegram.android.NotificationCenter; +import org.telegram.android.NotificationsController; +import org.telegram.android.UserObject; import org.telegram.android.support.widget.LinearLayoutManager; import org.telegram.android.support.widget.RecyclerView; import org.telegram.messenger.ApplicationLoader; @@ -63,6 +66,7 @@ import org.telegram.ui.Adapters.DialogsAdapter; import org.telegram.ui.Adapters.DialogsSearchAdapter; import org.telegram.ui.Cells.DialogCell; import org.telegram.ui.Cells.UserCell; +import org.telegram.ui.Components.AlertsCreator; import org.telegram.ui.Components.EmptyTextProgressView; import org.telegram.ui.Components.LayoutHelper; import org.telegram.ui.Components.RecyclerListView; @@ -90,7 +94,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; @@ -116,9 +121,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) { @@ -189,8 +195,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); @@ -200,20 +206,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) { @@ -228,10 +239,9 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter } } if (dialogsSearchAdapter != null) { - dialogsSearchAdapter.searchDialogs(null, false); + dialogsSearchAdapter.searchDialogs(null, dialogsType); } updatePasscodeButton(); - return true; } @Override @@ -244,14 +254,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); } } }); @@ -388,7 +398,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) { @@ -432,17 +442,11 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter return; } TLRPC.TL_dialog dialog; - if (serverOnly) { - if (position < 0 || position >= MessagesController.getInstance().dialogsServerOnly.size()) { + ArrayList dialogs = getDialogsArray(); + if (position < 0 || position >= dialogs.size()) { return; } - dialog = MessagesController.getInstance().dialogsServerOnly.get(position); - } else { - if (position < 0 || position >= MessagesController.getInstance().dialogs.size()) { - return; - } - dialog = MessagesController.getInstance().dialogs.get(position); - } + dialog = dialogs.get(position); selectedDialog = dialog.id; /*AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); @@ -457,45 +461,70 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter int high_id = (int) (selectedDialog >> 32); final boolean isChat = lower_id < 0 && high_id != 1; - builder.setItems(new CharSequence[]{LocaleController.getString("ClearHistory", R.string.ClearHistory), - isChat ? LocaleController.getString("DeleteChat", R.string.DeleteChat) : LocaleController.getString("Delete", R.string.Delete)}, new DialogInterface.OnClickListener() { + + int rightIcon = MessagesController.getInstance().isDialogMuted(selectedDialog) ? R.drawable.mute_fixed : 0; + + + builder.setItems(new CharSequence[]{ + + LocaleController.getString("ClearHistory", R.string.ClearHistory), + isChat ? LocaleController.getString("DeleteChat", R.string.DeleteChat) : LocaleController.getString("Delete", R.string.Delete), + rightIcon != 0 ? LocaleController.getString("UnmuteNotifications", R.string.UnmuteNotifications) : LocaleController.getString("MuteNotifications", R.string.MuteNotifications)}, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, final int which) { - AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); - builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); - if (which == 0) { - builder.setMessage(LocaleController.getString("AreYouSureClearHistory", R.string.AreYouSureClearHistory)); - } else { - if (isChat) { - builder.setMessage(LocaleController.getString("AreYouSureDeleteAndExit", R.string.AreYouSureDeleteAndExit)); + if(which == 2){ + boolean muted = MessagesController.getInstance().isDialogMuted(selectedDialog); + if (!muted) { + showDialog(AlertsCreator.createMuteAlert(getParentActivity(), selectedDialog)); } else { - builder.setMessage(LocaleController.getString("AreYouSureDeleteThisChat", R.string.AreYouSureDeleteThisChat)); + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); + SharedPreferences.Editor editor = preferences.edit(); + editor.putInt("notify2_" + selectedDialog, 0); + MessagesStorage.getInstance().setDialogFlags(selectedDialog, 0); + editor.commit(); + TLRPC.TL_dialog dialg = MessagesController.getInstance().dialogs_dict.get(selectedDialog); + if (dialg != null) { + dialg.notify_settings = new TLRPC.TL_peerNotifySettings(); + } + NotificationsController.updateServerNotificationsSettings(selectedDialog); } - } - builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialogInterface, int i) { - if (which != 0) { - if (isChat) { - TLRPC.Chat currentChat = MessagesController.getInstance().getChat((int) -selectedDialog); - if (currentChat != null && currentChat.left || currentChat instanceof TLRPC.TL_chatForbidden) { - MessagesController.getInstance().deleteDialog(selectedDialog, 0, false); - } else { - MessagesController.getInstance().deleteUserFromChat((int) -selectedDialog, MessagesController.getInstance().getUser(UserConfig.getClientUserId()), null); - } - } else { - MessagesController.getInstance().deleteDialog(selectedDialog, 0, false); - } - if (AndroidUtilities.isTablet()) { - NotificationCenter.getInstance().postNotificationName(NotificationCenter.closeChats, selectedDialog); - } + }else{ + AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); + builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); + if (which == 0) { + builder.setMessage(LocaleController.getString("AreYouSureClearHistory", R.string.AreYouSureClearHistory)); } else { - MessagesController.getInstance().deleteDialog(selectedDialog, 0, true); + if (isChat) { + builder.setMessage(LocaleController.getString("AreYouSureDeleteAndExit", R.string.AreYouSureDeleteAndExit)); + } else { + builder.setMessage(LocaleController.getString("AreYouSureDeleteThisChat", R.string.AreYouSureDeleteThisChat)); } } - }); - builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); - showDialog(builder.create()); + builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + if (which != 0) { + if (isChat) { + TLRPC.Chat currentChat = MessagesController.getInstance().getChat((int) -selectedDialog); + if (currentChat != null && currentChat.left || currentChat instanceof TLRPC.TL_chatForbidden) { + MessagesController.getInstance().deleteDialog(selectedDialog, 0, false); + } else { + MessagesController.getInstance().deleteUserFromChat((int) -selectedDialog, MessagesController.getInstance().getUser(UserConfig.getClientUserId()), null); + } + } else { + MessagesController.getInstance().deleteDialog(selectedDialog, 0, false); + } + if (AndroidUtilities.isTablet()) { + NotificationCenter.getInstance().postNotificationName(NotificationCenter.closeChats, selectedDialog); + } + } else { + MessagesController.getInstance().deleteDialog(selectedDialog, 0, true); + } + } + }); + builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); + showDialog(builder.create()); + } } }); showDialog(builder.create()); @@ -503,14 +532,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() { @@ -541,7 +570,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); @@ -593,7 +622,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); } } @@ -624,7 +653,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); } @@ -651,12 +680,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) { @@ -757,16 +786,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); } } @@ -787,7 +816,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) { @@ -811,6 +840,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; @@ -851,19 +891,21 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter for (int a = 0; a < count; a++) { View child = listView.getChildAt(a); if (child instanceof DialogCell) { + if (listView.getAdapter() != dialogsSearchAdapter) { DialogCell cell = (DialogCell) child; if ((mask & MessagesController.UPDATE_MASK_NEW_MESSAGE) != 0) { cell.checkCurrentDialogIndex(); - if (!serverOnly && AndroidUtilities.isTablet()) { + if (dialogsType == 0 && AndroidUtilities.isTablet()) { cell.setDialogSelected(cell.getDialogId() == openedDialogId); } } else if ((mask & MessagesController.UPDATE_MASK_SELECT_DIALOG) != 0) { - if (!serverOnly && AndroidUtilities.isTablet()) { + if (dialogsType == 0 && AndroidUtilities.isTablet()) { cell.setDialogSelected(cell.getDialogId() == openedDialogId); } } else { cell.update(mask); } + } } else if (child instanceof UserCell) { ((UserCell) child).update(mask); } @@ -883,7 +925,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; } @@ -904,22 +946,26 @@ 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; } + if (addToGroupAlertString != null) { + builder.setMessage(LocaleController.formatStringSimple(addToGroupAlertString, chat.title)); + } else { builder.setMessage(LocaleController.formatStringSimple(selectAlertStringGroup, chat.title)); } } + } } else { TLRPC.EncryptedChat chat = MessagesController.getInstance().getEncryptedChat(high_id); TLRPC.User user = MessagesController.getInstance().getUser(chat.user_id); 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 97fb7292..49e235ad 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/NotificationsSettingsActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/NotificationsSettingsActivity.java @@ -14,6 +14,8 @@ import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; +import android.graphics.PorterDuff; +import android.graphics.drawable.Drawable; import android.media.Ringtone; import android.media.RingtoneManager; import android.net.Uri; @@ -89,6 +91,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 +144,7 @@ public class NotificationsSettingsActivity extends BaseFragment implements Notif otherSectionRow2 = rowCount++; otherSectionRow = rowCount++; badgeNumberRow = rowCount++; + androidAutoAlertRow = -1; pebbleAlertRow = rowCount++; repeatRow = rowCount++; resetSectionRow2 = rowCount++; @@ -327,6 +331,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(); @@ -617,6 +627,23 @@ public class NotificationsSettingsActivity extends BaseFragment implements Notif } } + @Override + public void onResume() { + super.onResume(); + updateTheme(); + } + + private void updateTheme(){ + SharedPreferences themePrefs = ApplicationLoader.applicationContext.getSharedPreferences(AndroidUtilities.THEME_PREFS, AndroidUtilities.THEME_PREFS_MODE); + int def = themePrefs.getInt("themeColor", AndroidUtilities.defColor); + actionBar.setBackgroundColor(themePrefs.getInt("prefHeaderColor", def)); + actionBar.setTitleColor(themePrefs.getInt("prefHeaderTitleColor", 0xffffffff)); + + Drawable back = getParentActivity().getResources().getDrawable(R.drawable.ic_ab_back); + back.setColorFilter(themePrefs.getInt("prefHeaderIconsColor", 0xffffffff), PorterDuff.Mode.MULTIPLY); + actionBar.setBackButtonDrawable(back); + } + private class ListAdapter extends BaseFragmentAdapter { private Context mContext; @@ -704,6 +731,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) { @@ -831,7 +860,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 06684f49..819e17ac 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/PasscodeActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/PasscodeActivity.java @@ -13,7 +13,9 @@ import android.content.Context; import android.content.DialogInterface; import android.content.SharedPreferences; import android.content.res.Configuration; +import android.graphics.PorterDuff; import android.graphics.Typeface; +import android.graphics.drawable.Drawable; import android.os.Build; import android.os.Vibrator; import android.text.Editable; @@ -140,7 +142,11 @@ public class PasscodeActivity extends BaseFragment implements NotificationCenter if (type != 0) { ActionBarMenu menu = actionBar.createMenu(); - menu.addItemWithWidth(done_button, R.drawable.ic_done, AndroidUtilities.dp(56)); + //menu.addItemWithWidth(done_button, R.drawable.ic_done, AndroidUtilities.dp(56)); + SharedPreferences themePrefs = ApplicationLoader.applicationContext.getSharedPreferences(AndroidUtilities.THEME_PREFS, AndroidUtilities.THEME_PREFS_MODE); + Drawable done = getParentActivity().getResources().getDrawable(R.drawable.ic_done); + done.setColorFilter(themePrefs.getInt("prefHeaderIconsColor", 0xffffffff), PorterDuff.Mode.SRC_IN); + menu.addItemWithWidth(done_button, done, AndroidUtilities.dp(56)); titleTextView = new TextView(context); titleTextView.setTextColor(0xff757575); @@ -421,6 +427,18 @@ public class PasscodeActivity extends BaseFragment implements NotificationCenter }, 200); } fixLayoutInternal(); + updateTheme(); + } + + private void updateTheme(){ + SharedPreferences themePrefs = ApplicationLoader.applicationContext.getSharedPreferences(AndroidUtilities.THEME_PREFS, AndroidUtilities.THEME_PREFS_MODE); + int def = themePrefs.getInt("themeColor", AndroidUtilities.defColor); + actionBar.setBackgroundColor(themePrefs.getInt("prefHeaderColor", def)); + actionBar.setTitleColor(themePrefs.getInt("prefHeaderTitleColor", 0xffffffff)); + + Drawable back = getParentActivity().getResources().getDrawable(R.drawable.ic_ab_back); + back.setColorFilter(themePrefs.getInt("prefHeaderIconsColor", 0xffffffff), PorterDuff.Mode.MULTIPLY); + actionBar.setBackButtonDrawable(back); } @Override @@ -459,7 +477,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 e508b06f..217adb48 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/PhotoAlbumPickerActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/PhotoAlbumPickerActivity.java @@ -422,7 +422,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 e6832d33..a9f420e8 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/PhotoPickerActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/PhotoPickerActivity.java @@ -36,7 +36,6 @@ import org.json.JSONObject; import org.telegram.android.AndroidUtilities; import org.telegram.android.LocaleController; import org.telegram.android.MediaController; -import org.telegram.android.MessageObject; import org.telegram.android.MessagesStorage; import org.telegram.android.NotificationCenter; import org.telegram.android.volley.AuthFailureError; @@ -51,13 +50,14 @@ import org.telegram.messenger.BuildVars; import org.telegram.messenger.FileLog; import org.telegram.messenger.R; import org.telegram.messenger.TLRPC; +import org.telegram.android.MessageObject; import org.telegram.messenger.UserConfig; import org.telegram.messenger.Utilities; -import org.telegram.ui.ActionBar.ActionBar; import org.telegram.ui.ActionBar.ActionBarMenu; import org.telegram.ui.ActionBar.ActionBarMenuItem; -import org.telegram.ui.ActionBar.BaseFragment; import org.telegram.ui.Adapters.BaseFragmentAdapter; +import org.telegram.ui.ActionBar.ActionBar; +import org.telegram.ui.ActionBar.BaseFragment; import org.telegram.ui.Cells.PhotoPickerPhotoCell; import org.telegram.ui.Components.BackupImageView; import org.telegram.ui.Components.LayoutHelper; @@ -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 31afbc0d..2816c625 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/PhotoViewer.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/PhotoViewer.java @@ -42,46 +42,45 @@ 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.AnimationCompat.AnimatorListenerAdapterProxy; -import org.telegram.android.AnimationCompat.AnimatorSetProxy; -import org.telegram.android.AnimationCompat.ObjectAnimatorProxy; -import org.telegram.android.AnimationCompat.ViewProxy; -import org.telegram.android.ContactsController; import org.telegram.android.ImageLoader; -import org.telegram.android.ImageReceiver; -import org.telegram.android.LocaleController; -import org.telegram.android.MediaController; -import org.telegram.android.MessageObject; -import org.telegram.android.MessagesController; import org.telegram.android.MessagesStorage; -import org.telegram.android.NotificationCenter; +import org.telegram.android.UserObject; import org.telegram.android.query.SharedMediaQuery; import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.ConnectionsManager; import org.telegram.messenger.FileLoader; import org.telegram.messenger.FileLog; +import org.telegram.android.LocaleController; +import org.telegram.android.MediaController; +import org.telegram.android.MessagesController; +import org.telegram.android.NotificationCenter; import org.telegram.messenger.R; import org.telegram.messenger.TLRPC; import org.telegram.messenger.UserConfig; +import org.telegram.android.MessageObject; import org.telegram.messenger.Utilities; +import org.telegram.ui.Adapters.MentionsAdapter; +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.ui.ActionBar.ActionBar; import org.telegram.ui.ActionBar.ActionBarMenu; import org.telegram.ui.ActionBar.ActionBarMenuItem; -import org.telegram.ui.Adapters.MentionsAdapter; import org.telegram.ui.Components.CheckBox; import org.telegram.ui.Components.ClippingImageView; +import org.telegram.android.ImageReceiver; import org.telegram.ui.Components.GifDrawable; import org.telegram.ui.Components.LayoutHelper; 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 541402be..f0c481eb 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/PopupNotificationActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/PopupNotificationActivity.java @@ -31,21 +31,22 @@ import android.widget.FrameLayout; import android.widget.RelativeLayout; import android.widget.TextView; -import org.telegram.PhoneFormat.PhoneFormat; import org.telegram.android.AndroidUtilities; import org.telegram.android.ContactsController; import org.telegram.android.LocaleController; import org.telegram.android.MediaController; -import org.telegram.android.MessageObject; import org.telegram.android.MessagesController; -import org.telegram.android.NotificationCenter; +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; import org.telegram.messenger.FileLog; +import org.telegram.android.NotificationCenter; import org.telegram.messenger.R; import org.telegram.messenger.TLRPC; +import org.telegram.android.MessageObject; import org.telegram.ui.ActionBar.ActionBar; import org.telegram.ui.ActionBar.ActionBarMenu; import org.telegram.ui.Components.AvatarDrawable; @@ -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) { @@ -750,7 +825,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; } }); } @@ -768,7 +843,7 @@ public class PopupNotificationActivity extends Activity implements NotificationC messageContainer.setLayoutParams(layoutParams); applyViewsLayoutParams(0); } - return false; + return true; } }); } @@ -873,11 +948,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)); @@ -904,10 +979,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) { @@ -985,8 +1060,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(); @@ -1009,7 +1084,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/PrivacySettingsActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/PrivacySettingsActivity.java index db393888..a02004cb 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/PrivacySettingsActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/PrivacySettingsActivity.java @@ -14,6 +14,8 @@ import android.app.ProgressDialog; import android.content.Context; import android.content.DialogInterface; import android.content.SharedPreferences; +import android.graphics.PorterDuff; +import android.graphics.drawable.Drawable; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -278,6 +280,18 @@ public class PrivacySettingsActivity extends BaseFragment implements Notificatio if (listAdapter != null) { listAdapter.notifyDataSetChanged(); } + updateTheme(); + } + + private void updateTheme(){ + SharedPreferences themePrefs = ApplicationLoader.applicationContext.getSharedPreferences(AndroidUtilities.THEME_PREFS, AndroidUtilities.THEME_PREFS_MODE); + int def = themePrefs.getInt("themeColor", AndroidUtilities.defColor); + actionBar.setBackgroundColor(themePrefs.getInt("prefHeaderColor", def)); + actionBar.setTitleColor(themePrefs.getInt("prefHeaderTitleColor", 0xffffffff)); + + Drawable back = getParentActivity().getResources().getDrawable(R.drawable.ic_ab_back); + back.setColorFilter(themePrefs.getInt("prefHeaderIconsColor", 0xffffffff), PorterDuff.Mode.MULTIPLY); + actionBar.setBackButtonDrawable(back); } private class ListAdapter extends BaseFragmentAdapter { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java index 26cfae90..cfae2e80 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java @@ -18,6 +18,7 @@ import android.content.Intent; import android.content.SharedPreferences; import android.content.res.Configuration; import android.graphics.Bitmap; +import android.graphics.Canvas; import android.graphics.Outline; import android.graphics.PorterDuff; import android.graphics.drawable.Drawable; @@ -32,6 +33,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; @@ -41,6 +44,9 @@ import android.widget.TextView; import org.telegram.PhoneFormat.PhoneFormat; 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.ContactsController; import org.telegram.android.LocaleController; @@ -50,6 +56,8 @@ import org.telegram.android.MessagesStorage; import org.telegram.android.NotificationCenter; 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; @@ -90,7 +98,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; @@ -105,6 +113,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. private TLRPC.EncryptedChat currentEncryptedChat; private TLRPC.Chat currentChat; + private TLRPC.BotInfo botInfo; private int totalMediaCount = -1; @@ -116,6 +125,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; @@ -129,6 +140,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; @@ -147,7 +160,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); @@ -155,8 +169,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); @@ -222,6 +239,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); @@ -278,7 +296,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); @@ -322,6 +340,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); + } } } }); @@ -330,7 +389,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); @@ -479,6 +565,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. FileLog.e("tmessages", e); } } else if (i == 1) { + 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); @@ -487,6 +574,9 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. android.content.ClipData clip = android.content.ClipData.newPlainText("label", "+" + user.phone); clipboard.setPrimaryClip(clip); } + } catch (Exception e) { + FileLog.e("tmessages", e); + } } } }); @@ -680,18 +770,18 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. args.putBoolean("onlyUsers", true); args.putBoolean("destroyAfterSelect", true); args.putBoolean("returnAsResult", true); + //args.putBoolean("allowUsernameSearch", false); + if (chat_id > 0) { if (info != null && info.admin_id == UserConfig.getClientUserId()) { args.putInt("chat_id", currentChat.id); } - //args.putBoolean("allowUsernameSearch", false); - if (chat_id > 0) { args.putString("selectAlertString", LocaleController.getString("AddToTheGroup", R.string.AddToTheGroup)); } ContactsActivity fragment = new ContactsActivity(args); fragment.setDelegate(new ContactsActivity.ContactsActivityDelegate() { @Override public void didSelectContact(TLRPC.User user, String param) { - MessagesController.getInstance().addUserToChat(chat_id, user, info, param != null ? Utilities.parseInt(param) : 0); + MessagesController.getInstance().addUserToChat(chat_id, user, info, param != null ? Utilities.parseInt(param) : 0, null); } }); if (info != null) { @@ -746,10 +836,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(); } } @@ -794,7 +927,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. needLayout(); fragmentView.getViewTreeObserver().removeOnPreDrawListener(this); } - return false; + return true; } }); } @@ -903,6 +1036,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(); + } } } @@ -1080,14 +1219,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++; @@ -1098,7 +1245,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; @@ -1148,12 +1295,12 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. avatarDrawable.setRadius(radius); 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)); + } avatarImage.getImageReceiver().setVisible(!PhotoViewer.getInstance().isShowingImage(photoBig), false); } else if (chat_id != 0) { @@ -1218,6 +1365,12 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. return; } ActionBarMenuItem item = menu.addItem(0, dots); + 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); @@ -1384,6 +1537,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); textCell.setValueColor(themePrefs.getInt("profileTitleColor", def)); } else if (i == settingsTimerRow) { @@ -1394,13 +1548,16 @@ 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); Drawable pf = mContext.getResources().getDrawable(R.drawable.profile_list); pf.setColorFilter(dColor, PorterDuff.Mode.SRC_IN); textCell.setTextAndIcon(LocaleController.getString("NotificationsAndSounds", R.string.NotificationsAndSounds), pf); } else if (i == startSecretChatRow) { + textCell.setMultiline(false); textCell.setText(LocaleController.getString("StartEncryptedChat", R.string.StartEncryptedChat)); //textCell.setTextColor(0xff37a919); textCell.setTextColor(themePrefs.getInt("profileTitleColor", AndroidUtilities.getIntDarkerColor("themeColor", 0x15))); @@ -1408,7 +1565,11 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. 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) { @@ -1416,7 +1577,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. } TLRPC.TL_chatParticipant part = info.participants.get(sortedUsers.get(i - emptyRowChat2 - 1)); - ((UserCell) view).setData(MessagesController.getInstance().getUser(part.user_id), null, null, i == emptyRowChat2 + 1 ? R.drawable.menu_newgroup : 0); + ((UserCell)view).setData(MessagesController.getInstance().getUser(part.user_id), null, null, i == emptyRowChat2 + 1 ? R.drawable.menu_newgroup : 0); ((UserCell)view).setNameColor(tColor); ((UserCell) view).setStatusColors(themePrefs.getInt("profileSummaryColor", 0xff8a8a8a), AndroidUtilities.getIntDarkerColor("themeColor", -0x40)); //((UserCell) view).setAvatarRadius(AndroidUtilities.dp(themePrefs.getInt("profileAvatarRadius", 32))); @@ -1435,6 +1596,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)); + } } ((AddMemberCell) view).setTextColor(tColor); ((AddMemberCell) view).setDrawableColor(dColor); @@ -1447,11 +1613,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/ProfileNotificationsActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ProfileNotificationsActivity.java index de41dc5e..6a6f0b7d 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ProfileNotificationsActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ProfileNotificationsActivity.java @@ -115,6 +115,8 @@ public class ProfileNotificationsActivity extends BaseFragment implements Notifi FrameLayout frameLayout = (FrameLayout) fragmentView; listView = new ListView(context); + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences(AndroidUtilities.THEME_PREFS, AndroidUtilities.THEME_PREFS_MODE); + listView.setBackgroundColor(preferences.getInt("prefBGColor", 0xffffffff)); listView.setDivider(null); listView.setDividerHeight(0); listView.setVerticalScrollBarEnabled(false); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/SessionsActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/SessionsActivity.java index b4f52cf2..a205a3b8 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/SessionsActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/SessionsActivity.java @@ -296,6 +296,18 @@ public class SessionsActivity extends BaseFragment implements NotificationCenter if (listAdapter != null) { listAdapter.notifyDataSetChanged(); } + updateTheme(); + } + + private void updateTheme(){ + SharedPreferences themePrefs = ApplicationLoader.applicationContext.getSharedPreferences(AndroidUtilities.THEME_PREFS, AndroidUtilities.THEME_PREFS_MODE); + int def = themePrefs.getInt("themeColor", AndroidUtilities.defColor); + actionBar.setBackgroundColor(themePrefs.getInt("prefHeaderColor", def)); + actionBar.setTitleColor(themePrefs.getInt("prefHeaderTitleColor", 0xffffffff)); + + Drawable back = getParentActivity().getResources().getDrawable(R.drawable.ic_ab_back); + back.setColorFilter(themePrefs.getInt("prefHeaderIconsColor", 0xffffffff), PorterDuff.Mode.MULTIPLY); + actionBar.setBackButtonDrawable(back); } @Override diff --git a/TMessagesProj/src/main/java/org/telegram/ui/SettingsActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/SettingsActivity.java index dfa41997..a6464c4d 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.graphics.PorterDuff; import android.graphics.drawable.Drawable; @@ -40,6 +41,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; @@ -50,14 +53,17 @@ import android.widget.Toast; import org.telegram.PhoneFormat.PhoneFormat; 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.ContactsController; import org.telegram.android.LocaleController; import org.telegram.android.MediaController; import org.telegram.android.MessageObject; import org.telegram.android.MessagesController; import org.telegram.android.MessagesStorage; import org.telegram.android.NotificationCenter; +import org.telegram.android.UserObject; import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.BuildConfig; import org.telegram.messenger.BuildVars; @@ -101,6 +107,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; @@ -140,6 +147,7 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter private int rowCount; private int disableMessageClickRow; private int showAndroidEmojiRow; + private int useDeviceFontRow; private int keepOriginalFilenameRow; private int keepOriginalFilenameDetailRow; private int emojiPopupSize; @@ -241,6 +249,7 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter } else { showAndroidEmojiRow = -1; } + useDeviceFontRow = rowCount++; mediaDownloadSection = rowCount++; mediaDownloadSection2 = rowCount++; mobileDownloadRow = rowCount++; @@ -249,7 +258,10 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter saveToGalleryRow = rowCount++; keepOriginalFilenameRow = rowCount++; keepOriginalFilenameDetailRow = rowCount++; - messagesSectionRow = -1; + messagesSectionRow = rowCount++; + + + messagesSectionRow2 = rowCount++; textSizeRow = rowCount++; stickersRow = rowCount++; @@ -297,6 +309,10 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter actionBar.setBackgroundColor(AvatarDrawable.getProfileBackColorForId(5)); actionBar.setItemsBackground(AvatarDrawable.getButtonColorForId(5)); actionBar.setBackButtonImage(R.drawable.ic_ab_back); + //Drawable back = getParentActivity().getResources().getDrawable(R.drawable.ic_ab_back); + //SharedPreferences themePrefs = ApplicationLoader.applicationContext.getSharedPreferences(AndroidUtilities.THEME_PREFS, AndroidUtilities.THEME_PREFS_MODE); + //back.setColorFilter(themePrefs.getInt("prefHeaderIconsColor", 0xffffffff), PorterDuff.Mode.MULTIPLY); + //actionBar.setBackButtonDrawable(back); actionBar.setExtraHeight(AndroidUtilities.dp(88), false); if (AndroidUtilities.isTablet()) { actionBar.setOccupyStatusBar(false); @@ -327,13 +343,44 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter } }); ActionBarMenu menu = actionBar.createMenu(); - ActionBarMenuItem item = menu.addItem(0, R.drawable.ic_ab_other); + //ActionBarMenuItem item = menu.addItem(0, R.drawable.ic_ab_other); + + Drawable other = getParentActivity().getResources().getDrawable(R.drawable.ic_ab_other); + ActionBarMenuItem item = menu.addItem(0, other); + item.addSubItem(edit_name, LocaleController.getString("EditName", R.string.EditName), 0); item.addSubItem(logout, LocaleController.getString("LogOut", R.string.LogOut), 0); listAdapter = new ListAdapter(context); - fragmentView = new FrameLayout(context); + 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); @@ -349,9 +396,11 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter } } }); - + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences(AndroidUtilities.THEME_PREFS, AndroidUtilities.THEME_PREFS_MODE); nameTextView = new TextView(context); - nameTextView.setTextColor(0xffffffff); + //nameTextView.setTextColor(0xffffffff); + nameTextView.setTextColor(preferences.getInt("prefHeaderTitleColor", 0xffffffff)); + nameTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20); nameTextView.setLines(1); nameTextView.setMaxLines(1); @@ -373,7 +422,7 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter actionBar.addView(onlineTextView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.BOTTOM, LocaleController.isRTL ? 16 : 97, 0, LocaleController.isRTL ? 97 : 16, 30)); listView = new ListView(context); - SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences(AndroidUtilities.THEME_PREFS, AndroidUtilities.THEME_PREFS_MODE); + int bgColor = preferences.getInt("prefBGColor", 0xffffffff); listView.setBackgroundColor(bgColor); listView.setDivider(null); @@ -459,6 +508,26 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter if (view instanceof TextCheckCell) { ((TextCheckCell) view).setChecked(!enabled); } + } else if (i == useDeviceFontRow) { + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); + SharedPreferences.Editor editor = preferences.edit(); + boolean enabled = preferences.getBoolean("useDeviceFont", false); + editor.putBoolean("useDeviceFont", !enabled); + editor.commit(); + ApplicationLoader.USE_DEVICE_FONT = !enabled; + AndroidUtilities.needRestart = true; + AndroidUtilities.runOnUIThread(new Runnable() { + @Override + public void run() { + if (getParentActivity() != null) { + Toast toast = Toast.makeText(getParentActivity(), LocaleController.getString("AppWillRestart", R.string.AppWillRestart), Toast.LENGTH_SHORT); + toast.show(); + } + } + }); + if (view instanceof TextCheckCell) { + ((TextCheckCell) view).setChecked(!enabled); + } } else if (i == notificationRow) { presentFragment(new NotificationsSettingsActivity()); } else if (i == backgroundRow) { @@ -945,9 +1014,25 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter listAdapter.notifyDataSetChanged(); } updateUserData(); + updateTheme(); fixLayout(); } + private void updateTheme(){ + SharedPreferences themePrefs = ApplicationLoader.applicationContext.getSharedPreferences(AndroidUtilities.THEME_PREFS, AndroidUtilities.THEME_PREFS_MODE); + int def = themePrefs.getInt("themeColor", AndroidUtilities.defColor); + actionBar.setBackgroundColor(themePrefs.getInt("prefHeaderColor", def)); + actionBar.setTitleColor(themePrefs.getInt("prefHeaderTitleColor", 0xffffffff)); + + Drawable back = getParentActivity().getResources().getDrawable(R.drawable.ic_ab_back); + back.setColorFilter(themePrefs.getInt("prefHeaderIconsColor", 0xffffffff), PorterDuff.Mode.MULTIPLY); + actionBar.setBackButtonDrawable(back); + + Drawable other = getParentActivity().getResources().getDrawable(R.drawable.ic_ab_other); + other.setColorFilter(themePrefs.getInt("prefHeaderIconsColor", 0xffffffff), PorterDuff.Mode.MULTIPLY); + + } + @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); @@ -978,10 +1063,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) { + + //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)); @@ -1022,7 +1149,7 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter needLayout(); fragmentView.getViewTreeObserver().removeOnPreDrawListener(this); } - return false; + return true; } }); } @@ -1044,7 +1171,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); @@ -1098,7 +1225,7 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter @Override public boolean isEnabled(int i) { - return i == textSizeRow || i == enableAnimationsRow || i == notificationRow || i == backgroundRow || i == numberRow || i == showAndroidEmojiRow || i == emojiPopupSize || + return i == textSizeRow || i == enableAnimationsRow || i == notificationRow || i == backgroundRow || i == numberRow || i == showAndroidEmojiRow || i == useDeviceFontRow || i == emojiPopupSize || i == askQuestionRow || i == sendLogsRow || i == sendByEnterRow || i == privacyRow || i == wifiDownloadRow || i == disableMessageClickRow || i == mobileDownloadRow || i == clearLogsRow || i == roamingDownloadRow || i == languageRow || i == usernameRow || i == switchBackendButtonRow || i == telegramFaqRow || i == contactsSortRow || i == contactsReimportRow || i == saveToGalleryRow || i == keepOriginalFilenameRow || @@ -1209,7 +1336,9 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter } else if (i == keepOriginalFilenameRow) { textCell.setTextAndCheck(LocaleController.getString("KeepOriginalFilename", R.string.KeepOriginalFilename), ApplicationLoader.KEEP_ORIGINAL_FILENAME, false); } else if (i == showAndroidEmojiRow) { - textCell.setTextAndCheck(LocaleController.getString("ShowAndroidEmoji", R.string.ShowAndroidEmoji), ApplicationLoader.SHOW_ANDROID_EMOJI, false); + textCell.setTextAndCheck(LocaleController.getString("ShowAndroidEmoji", R.string.ShowAndroidEmoji), ApplicationLoader.SHOW_ANDROID_EMOJI, true); + } else if (i == useDeviceFontRow) { + textCell.setTextAndCheck(LocaleController.getString("UseDeviceFont", R.string.UseDeviceFont), ApplicationLoader.USE_DEVICE_FONT, false); } } else if (type == 4) { if (view == null) { @@ -1320,7 +1449,7 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter } if (i == settingsSectionRow || i == supportSectionRow || i == messagesSectionRow || i == mediaDownloadSection || i == contactsSectionRow) { return 1; - } else if (i == enableAnimationsRow || i == sendByEnterRow || i == saveToGalleryRow || i == disableMessageClickRow || i == showAndroidEmojiRow || i == keepOriginalFilenameRow ) { + } else if (i == enableAnimationsRow || i == sendByEnterRow || i == saveToGalleryRow || i == disableMessageClickRow || i == showAndroidEmojiRow || i == useDeviceFontRow || i == keepOriginalFilenameRow ) { return 3; } else if (i == notificationRow || i == backgroundRow || i == askQuestionRow || i == sendLogsRow || i == privacyRow || i == clearLogsRow || i == switchBackendButtonRow || i == telegramFaqRow || i == contactsReimportRow || i == textSizeRow || i == emojiPopupSize || i == languageRow || i == contactsSortRow || i == stickersRow) { return 2; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ThemingActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ThemingActivity.java index 0f3dc484..5172d67f 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ThemingActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ThemingActivity.java @@ -16,6 +16,7 @@ import android.content.SharedPreferences; import android.content.pm.PackageInfo; import android.content.res.Configuration; import android.graphics.PorterDuff; +import android.graphics.drawable.Drawable; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; @@ -119,17 +120,14 @@ public class ThemingActivity extends BaseFragment { public View createView(Context context, LayoutInflater inflater) { if (fragmentView == null) { - actionBar.setItemsBackground(AvatarDrawable.getButtonColorForId(5)); actionBar.setBackButtonImage(R.drawable.ic_ab_back); - if (AndroidUtilities.isTablet()) { actionBar.setOccupyStatusBar(false); } actionBar.setTitle(LocaleController.getString("Theming", R.string.Theming)); - actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { @Override public void onItemClick(int id) { @@ -314,6 +312,15 @@ public class ThemingActivity extends BaseFragment { } }); AndroidUtilities.needRestart = true; + AndroidUtilities.runOnUIThread(new Runnable() { + @Override + public void run() { + if (getParentActivity() != null) { + Toast toast = Toast.makeText(getParentActivity(), LocaleController.getString("AppWillRestart", R.string.AppWillRestart), Toast.LENGTH_SHORT); + toast.show(); + } + } + }); } }); builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); @@ -358,70 +365,6 @@ public class ThemingActivity extends BaseFragment { return fragmentView; } - private void showAttachmentError() { - if (getParentActivity() == null) { - return; - } - Toast toast = Toast.makeText(getParentActivity(), LocaleController.getString("UnsupportedAttachment", R.string.UnsupportedAttachment), Toast.LENGTH_SHORT); - toast.show(); - } -/* - @Override - public void onActivityResultFragment(int requestCode, int resultCode, Intent data) { - if (resultCode == Activity.RESULT_OK) { - if (requestCode == 0) { - - } else if (requestCode == 22) { - if (data == null || data.getData() == null) { - showAttachmentError(); - return; - } - String tempPath = Utilities.getPath(data.getData()); - String originalPath = tempPath; - if (tempPath == null) { - originalPath = data.toString(); - tempPath = MediaController.copyDocumentToCache(data.getData(), "file"); - } - if (tempPath == null) { - showAttachmentError(); - return; - } - Toast toast = Toast.makeText(getParentActivity(), tempPath + "\n " + originalPath, Toast.LENGTH_SHORT); - toast.show(); - //SendMessagesHelper.prepareSendingDocument(tempPath, originalPath, null, null, Long.parseLong(null)); - } - } - }*/ -/* - private void saveThemeDialog(){ - - LayoutInflater li = LayoutInflater.from(getParentActivity()); - View promptsView = li.inflate(R.layout.editbox_dialog, null); - AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(getParentActivity()); - alertDialogBuilder.setView(promptsView); - final EditText userInput = (EditText) promptsView.findViewById(R.id.editTextDialogUserInput); - - alertDialogBuilder - .setCancelable(false) - .setPositiveButton(R.string.ok, - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog,int id) { - savePrefs(Utils.this); - String pName = userInput.getText().toString(); - functions.savePreferencesToSD(Utils.this,my_pref_file_name+".xml",pName+".xml",true); - functions.copyWallpaperToSD(Utils.this,pName,true); - } - }) - .setNegativeButton(R.string.cancel, - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog,int id) { - dialog.cancel(); - } - }); - AlertDialog alertDialog = alertDialogBuilder.create(); - alertDialog.show(); - }*/ - private void commitInt(int i){ SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences(AndroidUtilities.THEME_PREFS, AndroidUtilities.THEME_PREFS_MODE); SharedPreferences.Editor editor = preferences.edit(); @@ -450,6 +393,8 @@ public class ThemingActivity extends BaseFragment { editor.putInt("contactsHeaderColor", i); editor.putInt("contactsOnlineColor", darkColor); + editor.putInt("prefHeaderColor", i); + editor.commit(); fixLayout(); AndroidUtilities.themeColor = i; @@ -462,6 +407,18 @@ public class ThemingActivity extends BaseFragment { listAdapter.notifyDataSetChanged(); } fixLayout(); + updateTheme(); + } + + private void updateTheme(){ + SharedPreferences themePrefs = ApplicationLoader.applicationContext.getSharedPreferences(AndroidUtilities.THEME_PREFS, AndroidUtilities.THEME_PREFS_MODE); + int def = themePrefs.getInt("themeColor", AndroidUtilities.defColor); + actionBar.setBackgroundColor(themePrefs.getInt("prefHeaderColor", def)); + actionBar.setTitleColor(themePrefs.getInt("prefHeaderTitleColor", 0xffffffff)); + + Drawable back = getParentActivity().getResources().getDrawable(R.drawable.ic_ab_back); + back.setColorFilter(themePrefs.getInt("prefHeaderIconsColor", 0xffffffff), PorterDuff.Mode.MULTIPLY); + actionBar.setBackButtonDrawable(back); } @Override diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ThemingChatActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ThemingChatActivity.java index fbd2f9b5..749ec990 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ThemingChatActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ThemingChatActivity.java @@ -14,6 +14,8 @@ import android.content.Context; import android.content.DialogInterface; import android.content.SharedPreferences; import android.content.res.Configuration; +import android.graphics.PorterDuff; +import android.graphics.drawable.Drawable; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; @@ -971,9 +973,21 @@ public class ThemingChatActivity extends BaseFragment { if (listAdapter != null) { listAdapter.notifyDataSetChanged(); } + updateTheme(); fixLayout(); } + private void updateTheme(){ + SharedPreferences themePrefs = ApplicationLoader.applicationContext.getSharedPreferences(AndroidUtilities.THEME_PREFS, AndroidUtilities.THEME_PREFS_MODE); + int def = themePrefs.getInt("themeColor", AndroidUtilities.defColor); + actionBar.setBackgroundColor(themePrefs.getInt("prefHeaderColor", def)); + actionBar.setTitleColor(themePrefs.getInt("prefHeaderTitleColor", 0xffffffff)); + + Drawable back = getParentActivity().getResources().getDrawable(R.drawable.ic_ab_back); + back.setColorFilter(themePrefs.getInt("prefHeaderIconsColor", 0xffffffff), PorterDuff.Mode.MULTIPLY); + actionBar.setBackButtonDrawable(back); + } + @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ThemingChatsActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ThemingChatsActivity.java index dc60bcac..32395a63 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ThemingChatsActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ThemingChatsActivity.java @@ -13,6 +13,8 @@ import android.content.Context; import android.content.DialogInterface; import android.content.SharedPreferences; import android.content.res.Configuration; +import android.graphics.PorterDuff; +import android.graphics.drawable.Drawable; import android.util.Log; import android.view.Gravity; import android.view.LayoutInflater; @@ -85,6 +87,7 @@ public class ThemingChatsActivity extends BaseFragment { private int groupNameColorRow; private int groupNameSizeRow; private int mediaColorRow; + private int groupIconColorRow; private int rowCount; @@ -114,6 +117,7 @@ public class ThemingChatsActivity extends BaseFragment { nameSizeRow = rowCount++; groupNameColorRow = rowCount++; groupNameSizeRow = rowCount++; + groupIconColorRow = rowCount++; muteColorRow = rowCount++; checksColorRow = rowCount++; @@ -342,6 +346,20 @@ public class ThemingChatsActivity extends BaseFragment { },themePrefs.getInt( key, themePrefs.getInt("chatsNameColor", 0xff212121)), CENTER, 0, false); + colorDialog.show(); + } else if (i == groupIconColorRow) { + if (getParentActivity() == null) { + return; + } + LayoutInflater li = (LayoutInflater)getParentActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE); + li.inflate(R.layout.colordialog, null, false); + ColorSelectorDialog colorDialog = new ColorSelectorDialog(getParentActivity(), new OnColorChangedListener() { + @Override + public void colorChanged(int color) { + commitInt( key, color); + } + + },themePrefs.getInt( key, themePrefs.getInt("chatsGroupNameColor", 0xff000000)), CENTER, 0, true); colorDialog.show(); } else if (i == muteColorRow) { if (getParentActivity() == null) { @@ -732,9 +750,21 @@ public class ThemingChatsActivity extends BaseFragment { if (listAdapter != null) { listAdapter.notifyDataSetChanged(); } + updateTheme(); fixLayout(); } + private void updateTheme(){ + SharedPreferences themePrefs = ApplicationLoader.applicationContext.getSharedPreferences(AndroidUtilities.THEME_PREFS, AndroidUtilities.THEME_PREFS_MODE); + int def = themePrefs.getInt("themeColor", AndroidUtilities.defColor); + actionBar.setBackgroundColor(themePrefs.getInt("prefHeaderColor", def)); + actionBar.setTitleColor(themePrefs.getInt("prefHeaderTitleColor", 0xffffffff)); + + Drawable back = getParentActivity().getResources().getDrawable(R.drawable.ic_ab_back); + back.setColorFilter(themePrefs.getInt("prefHeaderIconsColor", 0xffffffff), PorterDuff.Mode.MULTIPLY); + actionBar.setBackButtonDrawable(back); + } + @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); @@ -775,7 +805,7 @@ public class ThemingChatsActivity extends BaseFragment { public boolean isEnabled(int i) { return i == headerColorRow || i == headerTitleColorRow || i == headerIconsColorRow || i == headerTitleRow || i == rowColorRow || i == dividerColorRow || i == avatarRadiusRow || i == avatarSizeRow || i == avatarMarginLeftRow || - i == nameColorRow || i == groupNameColorRow || i == unknownNameColorRow || i == muteColorRow || i == checksColorRow || i == nameSizeRow || i == groupNameSizeRow || i == messageColorRow || i == memberColorRow || i == mediaColorRow || i == typingColorRow || i == messageSizeRow || + i == nameColorRow || i == groupNameColorRow || i == unknownNameColorRow || i == groupIconColorRow || i == muteColorRow || i == checksColorRow || i == nameSizeRow || i == groupNameSizeRow || i == messageColorRow || i == memberColorRow || i == mediaColorRow || i == typingColorRow || i == messageSizeRow || i == timeColorRow || i == timeSizeRow || i == countColorRow || i == countSizeRow || i == countBGColorRow || i == floatingPencilColorRow || i == floatingBGColorRow; } @@ -889,6 +919,9 @@ public class ThemingChatsActivity extends BaseFragment { } else if (i == unknownNameColorRow) { textCell.setTag("chatsUnknownNameColor"); textCell.setTextAndColor(LocaleController.getString("UnknownNameColor", R.string.UnknownNameColor), themePrefs.getInt("chatsUnknownNameColor", themePrefs.getInt("chatsNameColor", 0xff212121)), true); + } else if (i == groupIconColorRow) { + textCell.setTag("chatsGroupIconColor"); + textCell.setTextAndColor(LocaleController.getString("GroupIconColor", R.string.GroupIconColor), themePrefs.getInt("chatsGroupIconColor", themePrefs.getInt("chatsGroupNameColor", 0xff000000)), true); } else if (i == muteColorRow) { textCell.setTag("chatsMuteColor"); textCell.setTextAndColor(LocaleController.getString("MuteColor", R.string.MuteColor), themePrefs.getInt("chatsMuteColor", 0xffa8a8a8), true); @@ -978,7 +1011,7 @@ public class ThemingChatsActivity extends BaseFragment { } else if ( i == avatarRadiusRow || i == avatarSizeRow || i == avatarMarginLeftRow || i == nameSizeRow || i == groupNameSizeRow || i == messageSizeRow || i == timeSizeRow || i == countSizeRow ) { return 2; } else if ( i == headerColorRow || i == headerTitleColorRow || i == headerIconsColorRow || - i == rowColorRow || i == dividerColorRow || i == nameColorRow || i == groupNameColorRow || i == unknownNameColorRow || i == muteColorRow || i == checksColorRow || i == messageColorRow || i == memberColorRow || i == mediaColorRow || i == typingColorRow || i == timeColorRow || i == countColorRow || + i == rowColorRow || i == dividerColorRow || i == nameColorRow || i == groupNameColorRow || i == unknownNameColorRow || i == groupIconColorRow || i == muteColorRow || i == checksColorRow || i == messageColorRow || i == memberColorRow || i == mediaColorRow || i == typingColorRow || i == timeColorRow || i == countColorRow || i == countBGColorRow || i == floatingPencilColorRow || i == floatingBGColorRow) { return 3; }/* else if (i == usernameTitleRow) { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ThemingContactsActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ThemingContactsActivity.java index c774e666..108bb9cf 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ThemingContactsActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ThemingContactsActivity.java @@ -13,6 +13,8 @@ import android.content.Context; import android.content.DialogInterface; import android.content.SharedPreferences; import android.content.res.Configuration; +import android.graphics.PorterDuff; +import android.graphics.drawable.Drawable; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; @@ -386,9 +388,21 @@ public class ThemingContactsActivity extends BaseFragment { if (listAdapter != null) { listAdapter.notifyDataSetChanged(); } + updateTheme(); fixLayout(); } + private void updateTheme(){ + SharedPreferences themePrefs = ApplicationLoader.applicationContext.getSharedPreferences(AndroidUtilities.THEME_PREFS, AndroidUtilities.THEME_PREFS_MODE); + int def = themePrefs.getInt("themeColor", AndroidUtilities.defColor); + actionBar.setBackgroundColor(themePrefs.getInt("prefHeaderColor", def)); + actionBar.setTitleColor(themePrefs.getInt("prefHeaderTitleColor", 0xffffffff)); + + Drawable back = getParentActivity().getResources().getDrawable(R.drawable.ic_ab_back); + back.setColorFilter(themePrefs.getInt("prefHeaderIconsColor", 0xffffffff), PorterDuff.Mode.MULTIPLY); + actionBar.setBackButtonDrawable(back); + } + @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ThemingDrawerActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ThemingDrawerActivity.java index 185f4a34..e6729824 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ThemingDrawerActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ThemingDrawerActivity.java @@ -13,6 +13,8 @@ import android.content.Context; import android.content.DialogInterface; import android.content.SharedPreferences; import android.content.res.Configuration; +import android.graphics.PorterDuff; +import android.graphics.drawable.Drawable; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; @@ -63,6 +65,7 @@ public class ThemingDrawerActivity extends BaseFragment { private int optionSizeRow; private int versionColorRow; private int versionSizeRow; + private int avatarSizeRow; private int rowCount; @@ -79,6 +82,7 @@ public class ThemingDrawerActivity extends BaseFragment { headerColorRow = rowCount++; avatarColorRow = rowCount++; avatarRadiusRow = rowCount++; + avatarSizeRow = rowCount++; nameColorRow = rowCount++; nameSizeRow = rowCount++; phoneColorRow = rowCount++; @@ -307,6 +311,27 @@ public class ThemingDrawerActivity extends BaseFragment { } }); showDialog(builder.create()); + } else if (i == avatarSizeRow) { + if (getParentActivity() == null) { + return; + } + AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); + builder.setTitle(LocaleController.getString("AvatarSize", R.string.AvatarSize)); + final NumberPicker numberPicker = new NumberPicker(getParentActivity()); + final int currentValue = themePrefs.getInt("drawerAvatarSize", 64); + numberPicker.setMinValue(1); + numberPicker.setMaxValue(75); + numberPicker.setValue(currentValue); + builder.setView(numberPicker); + builder.setNegativeButton(LocaleController.getString("Done", R.string.Done), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + if (numberPicker.getValue() != currentValue) { + commitInt("drawerAvatarSize", numberPicker.getValue()); + } + } + }); + showDialog(builder.create()); } else if (i == nameSizeRow) { if (getParentActivity() == null) { return; @@ -411,6 +436,8 @@ public class ThemingDrawerActivity extends BaseFragment { resetInt("drawerAvatarRadius"); } else if (i == nameColorRow) { resetInt("drawerNameColor"); + } else if (i == avatarSizeRow) { + resetInt("drawerAvatarSize"); } else if (i == nameSizeRow) { resetInt("drawerNameSize"); } else if (i == phoneColorRow) { @@ -482,9 +509,21 @@ public class ThemingDrawerActivity extends BaseFragment { if (listAdapter != null) { listAdapter.notifyDataSetChanged(); } + updateTheme(); fixLayout(); } + private void updateTheme(){ + SharedPreferences themePrefs = ApplicationLoader.applicationContext.getSharedPreferences(AndroidUtilities.THEME_PREFS, AndroidUtilities.THEME_PREFS_MODE); + int def = themePrefs.getInt("themeColor", AndroidUtilities.defColor); + actionBar.setBackgroundColor(themePrefs.getInt("prefHeaderColor", def)); + actionBar.setTitleColor(themePrefs.getInt("prefHeaderTitleColor", 0xffffffff)); + + Drawable back = getParentActivity().getResources().getDrawable(R.drawable.ic_ab_back); + back.setColorFilter(themePrefs.getInt("prefHeaderIconsColor", 0xffffffff), PorterDuff.Mode.MULTIPLY); + actionBar.setBackButtonDrawable(back); + } + @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); @@ -523,7 +562,7 @@ public class ThemingDrawerActivity extends BaseFragment { @Override public boolean isEnabled(int i) { - return i == headerColorRow || i == headerBackgroundCheckRow || i == hideBackgroundShadowRow || i == listColorRow || i == iconColorRow || i == optionColorRow || i == optionSizeRow || i == avatarColorRow || i == avatarRadiusRow || i == nameColorRow || i == nameSizeRow || i == phoneColorRow || i == phoneSizeRow || + return i == headerColorRow || i == headerBackgroundCheckRow || i == hideBackgroundShadowRow || i == listColorRow || i == iconColorRow || i == optionColorRow || i == optionSizeRow || i == avatarColorRow || i == avatarRadiusRow || i == nameColorRow || i == avatarSizeRow || i == nameSizeRow || i == phoneColorRow || i == phoneSizeRow || i == versionColorRow || i == versionSizeRow; } @@ -575,6 +614,9 @@ public class ThemingDrawerActivity extends BaseFragment { if (i == avatarRadiusRow) { int size = themePrefs.getInt("drawerAvatarRadius", AndroidUtilities.isTablet() ? 35 : 32); textCell.setTextAndValue(LocaleController.getString("AvatarRadius", R.string.AvatarRadius), String.format("%d", size), true); + } else if (i == avatarSizeRow) { + int size = themePrefs.getInt("drawerAvatarSize", AndroidUtilities.isTablet() ? 68 : 64); + textCell.setTextAndValue(LocaleController.getString("AvatarSize", R.string.AvatarSize), String.format("%d", size), true); } else if (i == nameSizeRow) { int size = themePrefs.getInt("drawerNameSize", AndroidUtilities.isTablet() ? 17 : 15); textCell.setTextAndValue(LocaleController.getString("OwnNameSize", R.string.OwnNameSize), String.format("%d", size), true); @@ -638,7 +680,7 @@ public class ThemingDrawerActivity extends BaseFragment { else if ( i == headerSection2Row || i == rowsSection2Row ) { return 1; } - else if ( i == avatarRadiusRow || i == nameSizeRow || i == phoneSizeRow || i == optionSizeRow || i == versionSizeRow) { + else if ( i == avatarRadiusRow || i == avatarSizeRow || i == nameSizeRow || i == phoneSizeRow || i == optionSizeRow || i == versionSizeRow) { return 2; } else if ( i == headerColorRow || i == listColorRow || i == iconColorRow || i == optionColorRow || i == versionColorRow || i == avatarColorRow || i == nameColorRow || i == phoneColorRow) { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ThemingProfileActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ThemingProfileActivity.java index f81598c5..cc25b8bb 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ThemingProfileActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ThemingProfileActivity.java @@ -13,6 +13,8 @@ import android.content.Context; import android.content.DialogInterface; import android.content.SharedPreferences; import android.content.res.Configuration; +import android.graphics.PorterDuff; +import android.graphics.drawable.Drawable; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; @@ -357,9 +359,21 @@ public class ThemingProfileActivity extends BaseFragment { if (listAdapter != null) { listAdapter.notifyDataSetChanged(); } + updateTheme(); fixLayout(); } + private void updateTheme(){ + SharedPreferences themePrefs = ApplicationLoader.applicationContext.getSharedPreferences(AndroidUtilities.THEME_PREFS, AndroidUtilities.THEME_PREFS_MODE); + int def = themePrefs.getInt("themeColor", AndroidUtilities.defColor); + actionBar.setBackgroundColor(themePrefs.getInt("prefHeaderColor", def)); + actionBar.setTitleColor(themePrefs.getInt("prefHeaderTitleColor", 0xffffffff)); + + Drawable back = getParentActivity().getResources().getDrawable(R.drawable.ic_ab_back); + back.setColorFilter(themePrefs.getInt("prefHeaderIconsColor", 0xffffffff), PorterDuff.Mode.MULTIPLY); + actionBar.setBackButtonDrawable(back); + } + @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/WallpapersActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/WallpapersActivity.java index e672840a..8718183b 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/WallpapersActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/WallpapersActivity.java @@ -16,6 +16,8 @@ import android.content.Intent; import android.content.SharedPreferences; import android.graphics.Bitmap; import android.graphics.Point; +import android.graphics.PorterDuff; +import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Build; import android.os.Bundle; @@ -161,7 +163,12 @@ public class WallpapersActivity extends BaseFragment implements NotificationCent }); ActionBarMenu menu = actionBar.createMenu(); - doneButton = menu.addItemWithWidth(done_button, R.drawable.ic_done, AndroidUtilities.dp(56)); + //doneButton = menu.addItemWithWidth(done_button, R.drawable.ic_done, AndroidUtilities.dp(56)); + + SharedPreferences themePrefs = ApplicationLoader.applicationContext.getSharedPreferences(AndroidUtilities.THEME_PREFS, AndroidUtilities.THEME_PREFS_MODE); + Drawable done = getParentActivity().getResources().getDrawable(R.drawable.ic_done); + done.setColorFilter(themePrefs.getInt("prefHeaderIconsColor", 0xffffffff), PorterDuff.Mode.SRC_IN); + doneButton = menu.addItemWithWidth(done_button, done, AndroidUtilities.dp(56)); FrameLayout frameLayout = new FrameLayout(context); fragmentView = frameLayout; @@ -464,6 +471,18 @@ public class WallpapersActivity extends BaseFragment implements NotificationCent listAdapter.notifyDataSetChanged(); } processSelectedBackground(); + updateTheme(); + } + + private void updateTheme(){ + SharedPreferences themePrefs = ApplicationLoader.applicationContext.getSharedPreferences(AndroidUtilities.THEME_PREFS, AndroidUtilities.THEME_PREFS_MODE); + int def = themePrefs.getInt("themeColor", AndroidUtilities.defColor); + actionBar.setBackgroundColor(themePrefs.getInt("prefHeaderColor", def)); + actionBar.setTitleColor(themePrefs.getInt("prefHeaderTitleColor", 0xffffffff)); + + Drawable back = getParentActivity().getResources().getDrawable(R.drawable.ic_ab_back); + back.setColorFilter(themePrefs.getInt("prefHeaderIconsColor", 0xffffffff), PorterDuff.Mode.MULTIPLY); + actionBar.setBackButtonDrawable(back); } private class ListAdapter extends RecyclerView.Adapter { diff --git a/TMessagesProj/src/main/res/drawable-hdpi/Thumbs.db b/TMessagesProj/src/main/res/drawable-hdpi/Thumbs.db index 18c904c340224497c09cd0f9b20fec45fc9a9bf3..d2eb28c12b633373ba794946090e2e3bcf1871f2 100644 GIT binary patch delta 7560 zcmZXY30zF;|HtRdl98EIDy1T%#Z5IWvZmycM$KSCQBf%=*LEVg?xYmiTBbUZkfq30 zic=_2xP+43MYf-%i(Br~B1`}8X(pbz|6Z@}t7qQN=es=L^E~IAnYaxGaXSo(rg4ey ziox7LT6;eUTntL<2@Z?JihHPt<$4La;BOegVln>}X(O!^9bB=Z+DfD#c{0kgiDOfO zcoHpP_k0?-sdVNFQcu#YLwa}kZ?TCIq%YMKtOC;eXIPM1NrVI!=zC17Kvs1^)-E8u zFl`C4mhdSL3j&I8knx#}%pX)|u0a0MnQT= zsYw=ueF^fA@%aO=)CzK%M9BI8UI)}Xff9Xy?8hnT4caF_iZEJ&yd~Po1_r7c6j;Z6 zEqRp@7)qf)^cfIBg*0s-s*Fcyd8F&RG+10@K6`V}KjOS?B& zU%buebe)hG4~_;HEkU$Yqg!kLlMYivSNaGErnbMZL<&?X<6p)Bd0v@^_0!k91f7@Y zsdmyGsbCi92V>I;1n@P$1!{rrN(CbUcw(>w-IeGHiD7^SV^~4Hl?sjl_#21lEo^Ed z$g>%vCFmVQU}Xcc#7iK*N|XhnuTsH4m}$eE$ZvH9LRJHyuNbCCJ)--HQb>=GDr&6k zDN>(+I4`*(8tD^KZNV#$kHYd$qy?eu4iE+VOkmiv#*)Q#%_t;I39zel|t!!+6t`MM8-7{e4< zM8L_R0NJSFVpWr9R7}7jS_G3xYJ##KT`XfF*udI`W9y?)IdgR{s(gMf@Zt|Y7zv5< zAZS+$T+Lu1pxqdz5nzFkFoP6RF;0>7jGPNtf@8$s?q|y~9FwMcT|EhIuf zS)!(X0qUnJ@?!;vp@)Dz#n|x152q9q$+6Y{aJ`hp^K_DOjCZ|X) zTgIz-(QGi4^M%~y4&>jra#F&haX`sYp&z|LW*n)Y7x>P{{mH?co~`o@;}o)Dg7gKn0mq~@ z1aSa@FiIn!T!9Rbp;{rfAU+KA4JM|LEeEcV2@iIN9Y@B$h0W2(jw8_%61l);;GCSq zkrIL$KznhFe&tBD1i!1$kCl=#$V&oUkBKS7&~PB1a7y|D^#`KBD2;qMs<%Ok3Avt?SSX5I%rx>Npd1{d#hiMoMvt(kQ6xvI*}c)qZ~?iB zQ!jW4#7?cHtC?s#z-&xRqtzU#P;eU1N(@tEA~d)^=1-$UCRqW9^wor^5SH~!g?_FQ zu=3%S#!B>ofA(daN#uB?$(3TXrbz7kb2%kl=jKGp;ZRjDFrVw5H?aO&U!nuFRA z;}m(FX?X@<4=gc-0C(SNXz~U}q9Y`R!0a?N#Z$(y5|9aw$wsCqXGk#y!!!b{sjRvQ zy5@wHK%*v(w0HN~`(T(Nk*Wj=F{5gD6QjshW#4Gj%7MGKAEXfCK8VYOqP_r@V%aH@ z$KZj0Y%w*B0P~g4$QU)b79(dah6yI85MbpJ`f{a$t>EE~dC{mZSM?y#RKo+glKw)% z1tOW_(a4cpWrryQBO&1gPO+FHMY=Hf0U&M6k4Avu1-ygl#xzwy2nIq{5J)*{5xkiQ z*5F-*VH$aJrFsG_K!fnWWH6U`P8$KgrX~;JN^}(-9*}Ppw@%rB)lhr&2Lj&FR&#ye zVaxQ&6bnX?o0-(}AkHW(7KOU;IY7lYCbvLCw*h&GQ5tRG)+-O=aST%^1H|?~uHcl+ zWD?E>WQt)L0am>#ALq&xe_Gj4=y*@#$rBK1CdiGk(rI*pE74aj^Ae-vGOwaAGU@(; zOOY?Qs-yd&XFI%PxqnmkyM4wP1lt%yQ^l_~o0x(lIEAD%=*NQ?lb1-1~1)aA+e+G@VKJ-+>T zQ1WUHl-!T!qq?1#s3wt#GB8D&@|5?aF<4j{neuvWKo&h7FrYk&2?r|LlIO!z2VZS? zJqO-_nQY`ZP_4{pQYr!8tsHsE_YfL6{?NJhL{knR*aV(LFdA}OVvC>=(C(iDC{oIF zs6R~h#sm}stnAQqsJ|7aqOoZjO^2w;`9PS@hdCW=o*r+=%Aj(1pO#-F}O6V z!?WExazJF;zuk93jM;g;L>v&(;iYiUMcA_fa*Ct0-&cK#E)DBO=P0q2KI>}w; zDLzGsqrBY>uShZz>lb-W8aH5K@a?x3Cl9FEtX-^~GJNc;^w`q-StpCmY)H!8;JrmN z&C~PD;-Vt6mU%Je2h1nN$J%9dbiK}rc>Q$u+F0B2^RM=N4vQVrmF>7Pta9%CyLU5R z%}+0N_qQF9`C5G2yu+p<{i7FsFj9UgxP`hl?XqM3zuy{sB5Z}DV}|CY`7B}yhG+J! zoECBfO&VjKne#oXa*fWF<|rDKNv)z*jj)zExDE?QeO)Btx53}PhER=UBk#ergjGs8rIDI#pA^7DM?!&`I@8|oYB}Xsaw)sy#M#h1qbC1 zN@p)lo8f&smEgRQTX8=8&oO12%haBDQY>?qWA7- zqSn3kxWvOp(;v7!Y1%qUKf7dm|6{L56})K~;Cwl>F!Ac#!=dA6JQz~^m(Fqn)Oz#c z0r%nB^RGWIqBd{rNJ;EU3A^#ep#A)mlHHqH9t|sX6fUOTZ*Uzmy%5z!QdxW8j-}`%+x2^k@uZlK8 zrfoj`E5F~(KX09+kPbRs!cN2Y|G-Ci?=_w zFSAP*`!&s-JJ&kf*|JaXfllIi3tBp_EPJ+ca^J=1dGjE7LfG1Amu!!WeuTabjkgae z8Mwu_J@8;H!}*~_PX5PI#mC8 z)f>ZUUo=PQj9qwb!u%`J?}Z_MPI?gf*zH8brm9V+ru;8|oOs~Vc~|ucKi@hX_`*{- z;nBo1PBv){PZSqZPU~bEnO_a^mE7Fdzt8H?l+IehMY~!G5)sot;JbQVT5WB@+13AiI=8>Py!;oc)--p|o~1L_ zDmstk{yTE|tXZeaPM%zGnANJI(KfGTh;<6dliM} zv+CX$uQ`6`(6S*$F?MnHJM*^Tj4k6 z!j#WjHiyd>4!y*6w(c|A_lA9{`_2pc z*}JME2Wky{G1knz-?$COr(SgG2sbiXK{$78$ZFa&Xb5*jmW*UFkt-cfD08&=56*0z6q^IKzOz%~W{k4#1F zRFBf*5->Vq<+m*+g z_7%BiSwvjy*EDEG*Vz}b@|v=(RLFKeW6|@838f}|qVJdP+cEjZ>xPDg^s{XH*7638 zoaHOZayDl-7uxI>6___?d^GuJ8eX$rVQ3hge744{@xK4Pzy2C~{DSv@UDUO$8x}5S z{h@LE=KJulu*Z(;-))Is<#)tWUf?5-j&2?NS!>d|-X@8i16sxQLxk3s%H;Zm3zk&G zo1N%n>+`p6NN2t0#;~HhEB9 z#*It1f(F0qW%sh5*VIf(y%Cmh^{V{pj$5wI&X)pS$43NHr`k36H(iU@dE{?ynW9sh zdUR3JpK)mxB^>j8?nXwlSIr2`%g@iBx#U~rSyoo=_t2!!M8T4&+HQ9yr+T*C9J|Xi z`SY=ol9fR#UWb;QKi@bad&0J)550#B-DJJ$^)n8h9)D?}p6gZH;y_H6I*ZF}jK7 zMXkF!N`LI?j{>cMlr8NHm=w; zKUJe3EIfR5%gu!4*=eR44TG$M@;@fDPJI?V@|e*Hxn(GKP@Mfoi_K^6$ z4_U@(Owh>F@hGGU;&0rzQGDX&A=5A7Hc^NuOMmFxc^fh;Hm6@7>}0)rM@4yHsOYG5*xH zYHvZ4>yd;-ZekQt%~@e0JJnq5zUtSu%tv-jmm=r5ir=S&%Hy`N`WpMqI=Cl$W9h3Y zciZCM7hTd09%QT;U-sb6`W+A6?C@;v`Z_wvD`V#W&eVyD_h^kySu|p-lfvcIu3^Tf zZJH8N8*`Qz!yT_Se3V!atTWS|6)N=$IJ1Ef+cJcoKiT34? delta 4629 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 delta 317 zcmV-D0mA;a3C#kK8Gi%-002t~P!j+E03c&XQcVB=dL{q>fP?@5`Tzg`fam}Kbua(` z>RI+y?e7jT@qQ9J+u00Lr5M??VshmXv^00009a7bBm000XU000XU0RWnu7ytkO z#Ysd#R7l6=);$iwFboCY3@Du#dzvn6+z0gbPK=ej^&o6aJ%0{Ul!diSpoC)LI1%DU zZ;d`Rv1Ql5)QR~Dr~$!Y7Q};Kd5A>FEyP1E3vxU(XC@o!gA_sBnFtDxz5&{#uO@@~ z^ke@eG@*kD^C1d1OADwW($b5~e zA+sT0GHOF8Z#MW3JY>b|$YFR~N6Q(gT#%m!c}>ZmK~xKpS1JMh;E&c7gABv|*!HHB P00000NkvXXu0mjf#MyV% 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 100644 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-mdpi/Thumbs.db b/TMessagesProj/src/main/res/drawable-mdpi/Thumbs.db index a03d4305ebecb4f81f7d80e233b113342028d323..a4a7d8087fa7cac5bc84f357969599f3967b8d80 100644 GIT binary patch delta 390 zcmZqZ5o+iW+K|J-CQy^i!?<~J5li6Y!>opr4Omzv|6uXq`40qL3=9k)da|Io%H|T* z^8z3hn@hyb3-dCD0p%DOk>$0{D?;RbE?ni=1e6v)(!RY!iSY^#$8QuNea7?bybLu! zu_-9x=8XPdKt^r1&Gr&+rt|!h4~rRYFNtP4uglBG0n}=UqP>$TA^MK-F$ku%+V)pmrWdx~{KsK@D qAoF=KUQhslLkMn8$qnW!6FGR0luj?nVhI2T=WHa=?O(E3c%%V5X`_<> delta 375 zcmZqZ5o+iW+K|J-#;`w^TX@psB9=g2#{WQ|z{tP=q9+TQYfS#Z;={9vfq|h5h@pZi zn@d>F3qaHwq6mwf7v^P{0u*9I7y(qRbzX7$;Xr1?%_Tk;uJUjIG*`^Iv4~FWO8Y@*F@*;cnbs;>~oPfAV1#!|f%}Oy_l{ zAHKwFw7s;GDfkdaH?q1f-puD&!Ro#QGN0#~?(D&0wEb%g^Epvo#(6-6Vn|-u{-uc7 p-w$HwLFV&f5Y`RmD-$`wkj$K3lEo6h^BX8K8%cEgmn;?@X#lMFn4JIs 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 100644 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/ic_attach_music.png b/TMessagesProj/src/main/res/drawable-mdpi/ic_attach_music.png index 8c4d550605162e22ba88db57fca82dadcd2e09aa..3440214d1790323c77be51ff46462ae611d4ecc9 100644 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 delta 249 zcmX@d(Zw`DvYv&3fx)ZpYcY^gNcITwWnidMV_;}#VPNSA4k| z6a-ikUOxAmSkW?p@3UX@7C(K%Tpf*>X(~mX+b{ogV0UK@7W>S5hC@M3(2l*vvQePO z!O7)A%>DyABN+|cf641eTsZXV;DIl_tg%}8TM~Q@WFF+|mg9@gobJK&acj-_#`?|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-xhdpi/Thumbs.db b/TMessagesProj/src/main/res/drawable-xhdpi/Thumbs.db index a4590c21b4d73fe0ae64e063c4344b120ff866c1..501adba7ad9e8aae1fcc6ab37fa0219ec37b8fd9 100644 GIT binary patch delta 276 zcmZo@k#A^`-;l$?_TltP5ys7vi&z3DA7(Y2Y{0@Y`3Fk?M>+!o!+#){92lgsxrFtC zIL~sR$VU`W*(=H%Tqq)r7xwdjba62vbhno?Il4> zA&)uuko0W-V#<8}IY_eoi!96bFS4xuI@6s47!9YFc(M9VcMf7Q-2TOj^*j$RV+Pbr tm}9qp31{^`&dcxwDE<`Lz7l!1^OC%bKwH2bgQ;&Xv1Hp`V#(gq0RUyucQ60| delta 277 zcmZo@k#A^`-;l$?w&Bu8L*Yr2i&z4A8UF(TA0q<;h@L)CnNef%50(H9BL;}b8U}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!LRRWrzmzkMjSRjDdZLaZFWg5$}CGwaVyHtRRDY0DigO`9C4Zl z)tiFbElxP~>H{644~kf%h=vIPQxAv`uxa%juE{5`Lc~=UT_vy_<79qVI7;5AP|3ce~8IAH7Lloh|sQF@o7ufHi&r zOWm5Au0nH~Oe7ktKX`1K{bT8ZyFQDKFR*34Xwt2=^|h(hNxs{!@4w;FY0>eTU#{6P zDc*glBj20m8D+upG0oQnT&5qKcd(If-O3crO%FI!TJlS|rGiDyHs`LBEH61|`D20o zolPQ|1!^{J`{yuT)$H&xRle4%xBAmpmXsD=shU&G3@VFjW>qGxJ<9jrYLbe#;PWXH zxYnGsyfWXx)*O+~lR^U@I9*tL`0~1^$^AUf7l!N!)qAk;VfeHp(Kj4#mmYun zwD!b*y(Z^%tb29uHK^M&Ek04j+t2lUj-1)^eH(B7{`(;?b#L2o+ZDUl?TnxBB`yA$ z)7E90tJ~Q3=A4mkJI;K=z~p!Sxz7{hCmox*bVl;So`u0nc+T!S(wf-{RCSy&;#1*! z=^Ybh)kbWJJA62NGkNeo(8M&*62=)@H>9r2`M0Rl3^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 delta 407 zcmV;I0cigC38n*(8Gi%-008|9F$@3z03c&XQcVB=dL{q>fP?@5`Tzg`fam}Kbua(` z>RI+y?e7jT@qQ9J+u00Lr5M??VshmXv^00009a7bBm000XU000XU0RWnu7ytkP z9!W$&R9M69*iA~qKor37f0kCI*T@BgY*gqzXp1)qMsJ`}D1W_3Xq&Z^LS4A<0OBP? zX~11vjh4uC@;cKP=*%u5Gr!@@o38}d?6w3RumM8u>2WM76bOzE2do5Sxr5pN~{LLTUGBo59aH>&x~fa42@ z2aJGS-fKJd3)tm-4ZtSvYXRHly#VmP68;DH2D){HArSDFpd$bP002ovPDHLkV1oIQ BrFZ}U diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/ic_msg_panel_hide.png b/TMessagesProj/src/main/res/drawable-xhdpi/ic_msg_panel_hide.png deleted file mode 100644 index b09776f7513fbfe4bd09ff0fdd99802db6fbf757..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1439 zcmeAS@N?(olHy`uVBq!ia0vp^+CVJE!3HEFccyLzQj#UE5hcO-X(i=}MX3yqDfvmM z3ZA)%>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!LRRWrzmzkMj<>YK?XyIyNZ073dXlUqaV&P=zYGG+)Vdm`Y zXl!I@4%6$BpIn-onpXnTn}X15f>SRjDdZLaZFWg5$}CGwaVyHtRRDY0DigO`3~`zV z)tiFbEk-!?>H{644~kf%h=vIPQxAvI!SAYGAdZVh*nE&vMP2-`K7BLC^)UDaE)=|qXH}fYj*F-T-ejqmGxXzX{7M`nP zU*BZ;evf-uh2M3D>$4V|Kf`+do5hwYk#1<-j zdHEyqca!y@19B1H|0!kfe%JE0E6elO#J=#!AK%J~9n}(R<(=H4d%8J&LZ7C|*`JjQ z*B{)G6j;PGhwp%%h4`;chTZL+-y#>jZ~DkqH+inWbF2NbO~MQFCHFL6Rcw7#sC#bn z+m_H*>L(hFQx+I+(6@+Y(BHGwaoe%N?n6m$F4wQH6x{YfYe|Jj?K4s4NwuAISL?e? zj~*87a&O}Ab6$PdW`dB@rt+8mz20jc?Yw;Zmf)wfsh)Lh^Gy}?%Psbcnr;v_{@Wtj zU*@ps{E^zTM@3ivh>CuGbfQsfuD;Cue(3^{jms)>ev0s0-^}m*#h((g@!q4r&o9@v zss8rtGX43far$xM5ru6s>SZm-74x`^Mx2@LG}%6{a$`z{G8GCf`WT-G@y GGywqlxgRb7 diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/Thumbs.db b/TMessagesProj/src/main/res/drawable-xxhdpi/Thumbs.db index 48a319fe8565da22be42a51b93cfdc6a2ca31ee6..b02220d4c926f5224b86349f6e5734da6da6b3d7 100644 GIT binary patch delta 59046 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 diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/ic_attach_music.png b/TMessagesProj/src/main/res/drawable-xxhdpi/ic_attach_music.png index e5830295e20a55adc2a959f6a9781d05e6de0a0f..7317d7295c938d94e6f81b42ee8cdf71bc03d5be 100644 GIT binary patch literal 1496 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(gnVDi`X5?yO}q5J)9aF-T$-DjR|3Eakt zaqG>Tv)V3!635Of$V;#6?0r*nwWTIsM|6{#>0|x`#qQmkw(maSwT;L1X3(0cXLOF_ z{9#<9rrDk8^4Rih;H)$~w)As_^Oo27E~_qm{@nKYp66x08q-g6E-P8JqM=EnqeM?1`_-G9ZaE08X=G%6%2DduoWQK|fj#f4 zsz=zl&Q(&;mzet$SBAAOa6SEG&vJ2{7Xl(%EA;wa3W#is2ykg%VAaiPx`97waYn}C z6^0A*<>n`|7IsM59JvrHrW^Ps)@hAGThqVCTHju4i)aHK0z(p?S@$-`8ZaJuwd>HU z=dmAN6{**9rycM;_?!Ph$i{c86g1O$me^aqJ9Sj?+afJ>T^>JG*0!P+9Bg>gTe~DWM4f Dm|7&O delta 547 zcmV+;0^I%B3$X-{8Gi%-0095wd&~d;03c&XQcVB=dL{q>fP?@5`Tzg`fam}Kbua(` z>RI+y?e7jT@qQ9J+u00Lr5M??VshmXv^00009a7bBm000XU000XU0RWnu7ytkP zsYygZRA}Dq*1JvuK@@=De~}1wCImY>wIN>PrLo72HO54I0DmnEG2vN^tssd$fIb0@ zU_xXY9snx~JJDdU6_Cx&?o4KbXXs{<<;$5l7pF|TRssPD=--0UT=Gnhfu>)NCM8m% zf8zv9`$Znf83;%lm#%t*(uO#&$^*0NpmReUfHlt4K_^DvaZw$VGYZP7gHlF8b5a;p zR?^53?OquWS$??9%P0GRp$zlw6sB1SFv81ogQgPlf~;@>KYaG`W<6G*`cx z+o3>vXlH|#Vx@NUwT=$^yp8O&>|I%(!WhTu8>)?5mUYl=+_J10H_*HOFGmB-`MYso_RBP=azK_O zSzKy7h3Dw#_Bxg$6Qgd>r%}U)I><8$^3*|9qo9g9=t}<}_G{q14)cawUJP*#`3jR| zU3Mwa9DaZipK^l>_IM3b7^MygNI+3$zTtY4GCFcNsuA+yc4gJLflT(SP#|+XD|D9W l?^%(Cd>pAm0uqq^^#haIa#J(Ro0I?m002ovPDHLkV1jq6?kxZS 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 100644 index 2c9359e25d4da43a1a3bdf1a331463145310b3de..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1784 zcmaJ?c~BE~7!5)IK?M{9f$Fk&fI?0ZNJs(+0mBSIE|s>RS&|JzNOnyY2?!1bq6kvF zxKz-3j~vRNRKX(D3Nj)CS_Q>AFyb{T#|(XR5@f)Tv`Q3b69^nXEec5!VGM|a;}t3{IMi?x1QaqZxS1iQ zh|vHzK_N<0!;xvBQPQ+TDN6?W@c@pNjSDDY3<9*uB$bA(<$_bXY-_<@nN5K5+!D29?|fMW6gLzT)|v<8cSzvcU% z!kVa56edT&8YEdQ#TzGgHH1Rh0cse+5OoxSB+Z;+SOS6}ngj#|0wS4!+h&DIhNNiR zr|@DiJ6NT`Ae9sj7IHycfuvB#*aBuiAcf`a!wlr}snkF(0fjH%)9C>$9~O<`<3*d{ z3K40t5>{a|T-i4+Yfi4g3Q81@EQHmH9k47&jVOVslG%#6b79V@H_esJos0LJTr!>v z+0fX3HF{FVYkXLRyIqajx}hnt2me}bF%T8Y&)Q|4*Thy&{M$H=5t*rK8VKV8-vNp_oANT~K&m8eU;z5VA7 zuT8(jJTNBSF&*;XWo@>Rv+mF-%IB3WTkHm+d76$Q;%mZAPv^qjn*m1dp$%|5ywtH& zv)99)s6CBFn?KXFyNP&*YnHCXXs;~3&m^Mz&*v4sHy-*tww2L9{YZbMZxW++$BoL4 zUTjz*AMwk1b%)EP!)#OX}1~V>}vi>qQ26Hah#4z)mpFzJeeSHg0uox;o zKoF7;PrvdKE%@-{-RRoH_Osj`K18jtcQ(t*CB0pg@B$$>G;FF?UL6EAuNSVe&eh9W zqfF#UqmK(dd-T`c)>QqVSM8}Oh~Af-Ph8VvL^<2JQTGaXe0$*V^`Nr?@7pD7q891z z>CZRwDb<~Yy6*J8PNiZr_F`u~{gJ{qRG&qV^QjJ-UR(6U$16g3c|1$odZ@)GvAYI! z$Vt!U7^T_PI}aNTY!mT{8`ZY;%UkLOe!p(+3aq%)%+!;z#&?99wApv9-y`U5DM=5t zw}wpXjH)x8a_v{U_pRFM?{ih%A+G7XbM+FvC?8#HV^d!4-5eO$U1DCY+h(?_g0-eg zP`ikf`QyQrfLF|Et0wp1UcnN}!7Nj!3C9chS34_*7re>!(tbxg@Ns|dgAMxX`A;nm z#&{Gk+|%2$PD}jP_tjfS&|~Zcjq5N*-+U1ze-&C8L>+VTF$qd0R@D;j^Jr-BGph0L0_}C&@@? zF9lH%O8x({iVy)n2oMHLf!F`He+`HtdLh6Z;0G)bO%$*}G(kWRVU#Ml6BQE^38C{p zYyUHZPKdbSW=_^ZQ~iRDTRVovM??9)mqtNA%8a-m#0JGR3X)mLlT3*%12VP0QIP%5 z*W@S*D}bgi>jb{+F=|(sWOdg|=@imNnfibmFN%ycAHJ=Z%AJ@vfI}$!^5v`b+Lzoe zKBma#Y0OK?dgPd4GJK8EmT{k(okICobijYvydW@`pV1PWlr&yV zfPX2moto6Sg6lk$wfr;~wgGDkHRs4A;f8rtEUEyuVF7AxmC*k;VD_S{t8C|mcO(^D zDRM}*2Y;$;{Zfb~5Rq;w%FNOrvPG6H9c)UPN*tnR_v}KYwZ> zl#wvf6M-G|%AhcjM3uims)5gt!ccsXw}G|6*=Z4+H<&vW*_IFR?_yyX75rv24?&;$ z;roh`0j~Wj5&pR^rLt_KgI`QcTJS(mnI7dOX8hdhnQg;GC@zO>ub!dl&f9Fu*=OKB&m-LbYFkv1;8n* zCc}G(A-{{J4%4c+yrbV|U!A=FYJiWn@*3WSzD1N+9~&a)Q)_ACP`)a$U<3FGXU93Q zy4X}S1J|O9@A}HH^J`FZ?M2Ssg-KAJd>Gv2754nH{nt(q=_?c9IYVCkWbpevX|jId zIR0~>_i<7E4^$*GF@a*t99|O+Rap>fxOnFT{|-9qm-9kTY6Az+wD>h@`ff#F54yLF z)=z`^6ujh?OR#V7Qr{o!Y`bov<@rwD<$8%${N)^gF`NYcUx9=TV}@kru$AQE-|ldW z51j_cgXdTK3ry}1UKqVrI+}4Ab7cG#N$U4^RxC(OqRDBl9{w$484EFNy5LKEUS`~6 z3zqLJRWX3X;jP;3O>}b_wswKNUi9_I5{`!@8bU>Wb$fMS$AptRxOikUr?^AcEC}h} zLcnu$bx`>9SY5~IyK)geo?;Scs%kRbJBuDB2plKiU)_>8Hcoz0r3a)?WA^=zCGrA%nhZP*XoHTyUHK&aq;_oG(0&X5htmiMc{mSxKeW%Y1-?}*7S9Dl?-_gl9l zRNqQ(ML2cdwd9`hBI z&|Zqn|Il`a{fZFh3iS=CsTX1^N)X+^QuT-$UMCc-8Zy4)=m6&K!1`>=Sz_K8BfmY_ zz5TV?sTfIfDw4jK7%eDvx6+gujX%pYTjl|HQ@qX*LP3z)EUFZT-kjbqVS2f@u zPWsD$arlgkR&W)j02^JP4}8AX*1D;?z)AqFbjSV+Xo~P*IQ+&J|LIrzBk%sPXtc#s zaVZt4BCy@!$JI9qet%LpT&gY0T+gnFl(W8i&0~sknR8WtF?4YEgUSI_F{w*o zRoLPW>qhq=ab(+FLWp?#`eJp*-Myli((|7&#LNpwo{G&Ob;+_i@9b-S+@Do!gh-Ly zXWH={Li}D}Or?)^t#WDu8G8i)>B9F67|rz3JKx$2l69uFK6qqTM~-N742e{FC3R!7 zjx#jzA&P|z+8;fFTE>1oGU-B&rCT6{9oAt)#F`+zAJL1YO#831EtvR2Oc4nn;{5OE zCg;<}w{P+#LDU*KKcC2uJ)>&pWe&^dMXZIMVjtweqFgKFPCXY^%B|DgshntjFuWTe zGxujJikCRtza1KQJMfhEUMIeY2wM7NNt)x;Eh4C0k{L?P`14vf0BebHC$R}0r|t50 zLrOOK9+`y*O1?eU5n~A#eA^am!A~>PmZwRXD|h%We@aWRgF^cGUk|Nh(H;(|DUgZT z`+NrKvjqux49ePSiV&xQqrADb2`@fEYzB}*0$LtAg7&BNO9VxrguCtfvYb{(=AQmyiZ(A zj3a1*KT_d&l;DM^TT7sWFmID@T!;z%vJ`mWBvx!rqe%Sb&#~=^Ox8vDpY41_jm3Y( zHxybgm|uRBDD7kIlxB@*9;J3!r40Bt1Xr2GYd@(jXG!WK19GU7SD2)m_h+N^*;W)< z7h)>yCZRhL3u^DOADr)x~Z?Kk0zW+o8N*+0PV?zS@wj?md9bbTF;v8$|1c(L8* zm=Oi+#r5%x2AYL{$Eis^h?N`H{{b=hIXEx+c}K^btGahji|7wIT8?uYoCzH*dxN-C8(hvYG;imwVNgthW7A zw2We%F&h?<_3BRZC%}-R^cdOu^&=y!VJNp=v?WydqX7e z{@eymh)f}l?a#7!&Z}qMhT^et zE;moio*b!P%+$CvJnunfH|&lja;SLQ4-_`q#0or(_l8+%$lj4%G&D>yJo+58mPS$~ zY<^=~_WH}RExlc2&B$xH($uG;3>~8!4vdO!^J%6%dt4ke8waE4W%v~EG)iL?GT=qA zXW(*|faU8xhR$!18)HgpX6i3%YcMyk{)GK3v33YKw6i%vX<7m?gNp~_#z|2qD@isl zzPjc>d$KRX+(;(zuJFHcBys^C-RnK~8HTL|98?ci#-`s+EprTs^`4NXD#eqA@fkZS zWH}iJv?m!f#g?{xEiH;3?X&L{kT0B9?JN@b7Hz;O#Oou2|DK|6Ru_Zgar5NW+tExZ z!^3AAG=`aHO0?gg)ctm}X@Pv1{L}#L?f8yrj66YP<+!4@t>zV`j~C{^gFUSOonq)d zO;L|SCJfs1hD*$FFP=<|Jv@mlL3uw)RjVtIB`rDRM#{U;e|us2=u5ZL4`fUY@$_!# z)*X`bPw_Q>Uzkmeok2!K;qSd?_U=Nzj+}^;=W*>kM-S42gF3(mU{fxx{2yxt1Ez~IcmDW+5H0(@ABuJsjxQw}4pN3{(h zH8PnG1?ch9{X3?d>Nw(wWG<=e0zyB9DuCPlN2j+!7=y@^@`Z%KTCLyd+LbhVc+Dpg zxdC^*Vqvga^6-)n$pCp1$!mr%I01A`(8G5}gXW=!d&#Id*P(uB)-Sd<5l+UIG1pkT zRDxLj7Jk(Pv8O0S%^gH4`Bm5~FRy?lQ;iWO?;2#u`U_8iK_9^6BuhoZH=SeSvsO#g zs2*y@`#VS`lX}~og30|RuV54YKZmu^3>inZAVqS+oPsxI3h}c`gQ|Qr#rfB1GkgTlPS!G`6DVwW~@UaLRA5LIzz~o~-ck7SZ3&`^eiqqe8F@ zR&7;02LEBremhA((e}2NiO`-NI|B0$6@H$_N)Cgv^6W>ac2=AplX(LW-X|rQLO$bDLWEW&Xv9I-?)osUGC!W7NCR*-4*m$sx@W6{PyhKcuZi6 zSq*n#y4aK@hWP z)m;03Os9TB<29}G<1@1Q5|Y{=@q07|l@gyQYA=?-1 zY>AZt$Y1hu)nRFC8**B;;5U9MW|L@CX!!@1-eVQs#cuZU*RXPlQ7h)xf4ijAR zSik7Qj+FSg1Q>4Hoh*SYe`GeAx3Qrl@%Q7+1$WHVEh;vwDH%`U^4q9)++1bK+BUa_ zkPaszGt^T1SqGk_o~OTBO9WJ?&By>go11q17pA}`vT1B+@OmOuqW;hzB+U)~+dAQH ztH&aYg;@I@Z2~Rv>S1tx;=b9^XE7pX4}(-d6Lp(3gnM_u&kD@JxwD8ed!0-C`I05m zu<=#0=(7uhDX=6z%S7aUXlJ5oLK1-^z)mWwpLkeR!!DtlhpB|3n}1(9qZ7ZgOkIlv zKIclrFmM=$6~K5FS196{1Vcv@M0*(Z^$oapMJU-r)`RGuQ<<@6XJ}7ETY4-~w1g2S zAw`x~%V2YxA4ugDNs`{9RV{;Rm#;>SUyU;4zF;BVA)AL8ks+P#lkzs%v8Vse^ml69 zqo9EP$A-+2R$&jyOMX(L@m$Rta{M800jd&`-J}5H2b3IHscJz2oNML^``Hh>{X8c& zt~ZUCWa@6HP-=^|z^#QkYovZxu54LDWQf7>(Kz$CIcUvq#JFBNSdteZKiKmVXqI{i zXt&gLe0{(JgQ{wwnsrii$Vj|uA}&@uBp^*cjOPzfK*%2FLJ&VRfJ}@=j4}eVYURU}`@@gDn9tubS33!j z&K>wp>AG{K4@^Dlyb8xkxXJr)g3rHgKYR8V?bC1IqkcukCT~0xB@la1Zilv#sJ)(~ z;fpf+bN?8SgH$V&<@YbmRgl)E;C-(A4;~Faz*ONRz z>`lkrR_J5!y2r&tU-OX)O%IK#FpWC8z$hBJxURVxpcVFWs5xlUX!ibdnZWdPv!$Zk ze*SICeaj>KdhOp~{$LTs5}h)6lmTckmC0Ehr9m z#k_svIKTV{`8HJV&U#Cmh@%Ba#KetmnRW6tS)5;D+CiV!L1ovB0(uH-62GQF-ic<> z`}Jg*p0v_S94;*{B;mQ=>LSOy0+g0W7pE7tpRJArn>i+g$pAhDfLa5OZPMIYOp3DM zqE^T4XtmC<@uq@>z|1E}Ya1NlV~++B8TI~lnvao8O=nemv7;(+A%FAJ{kTivN*CrZ z*y_9ILR;Zn@r`);Irla4njCBjb!fWDuflQUUUUOim4yZGW(0cv-fRx-ksIiE$67%o=BV<-(6a%D3oCnfAUB51~ zv-KMOP(E?u6PR$qRr=`Jb%c!^c(&jnnwA?xGEUZnTkCB5ZNjk(q~gDqt= zrK!vdl+$ul+_>fQH-bI2?#ltYB^f)h?NB$LsbgGL+OeQ zJdK@)96`PK|uRu4E zj|K*nV*|MobOYhvEAf*2jW^v#BXcC=>V*^n1Dm^3_3b_=MPOPnmZ`7(+oT@6>KeFs zd^OsNCW!jS7+l#db8l`Kc$RG!S$QT4XU?(+Qs*v4)f`k&fIcRFixkM}Xiu%1iQoA- zkll>EOGePbUfVQ`_+&ti@x?QIMDEDjK`vIg=ys?cl6Ap$@`ELWDbd((P>jCPaA}PR zTk5ozEIz)n722IiK?pVbnt%oViMwm$+z~6h3@7MEeci``mhVQU029Fa zlmE}#Jj}m`kLkNY_7b8qLcDk@@LLwl&_ALp9U^}j0a%K%mI5(UZJ>jxmH$U4pFxLcla;bOoiEkMg(pzRbMeX6VcgDep_d;n^OpnQm9f;V`YHX} z^Xtq^wQ(J4#N_5%eg$aXYgJT#J_V=*2PqPbY0HI&{(rheoNS{xCaoPi;EFOl9*t-; z{U7g%CSM5v*jg0xD!}4l#$5wBt#ULMy8}sDo#|4v(OY7J?4I*zPC9XqRH~5I?_Evm z{h!&BAwIt1V zj~!#wjw_M&-M=D35{0xdaUsWrY(1zbiWA8$XahYnZ9ehhyOkmeqIdI z8?*>0j+@g4pc$SRY*PGBiTaYWrgyCLuG&qzU<|MqA`95zDP;Z$H{A*05?6t*D41>G z4P2GV7@fR=tF0CJb+{fonSA?!o#?Aq|Av$J0h@s!TM{IPAN0UJ8{M?&awKit=7@Kp zC<2;hQK92jJ!1lM#+WFIW?PD-5$tQsfg=(9osKxq)3p}U9{R9fxbY|?+ux4RfK2X? zx#)p_#+#pNIe$N+R+}GO1yiEMf9Oniz^k6q$5d$?m+t=0S|V%v!g-_}?PO`s-*&IS zK!T|2&daxqJyP1bGC4>m`kh4AI1^@5*QL{j zix0+SB7aHZJ3c*0@O+Che-WDQZ=H9^iA0J_P^kkm* z^qi^y3I}P|VKPYhbgX!z&E0-8p4Vm`CKGNUQ)U*X(ivw?TuJe8z#P`))w9=lWOTAp zwWo2j(0>Q}Y`8LMInGCC7|W<}=7%HJ9t;w9n&mdUEshd*p8_}dR}b3GzYO%{$8{Z( z91?8BCW%B);xcw(kLupezlVBmywGfA_VlP#89%WqF8qxq!P1*6 zFPk^aXKSJXl_|6O3Ms%fdM0xgtF2G^eL|+6`PTR0Y?kHq{7TtlN`kL)7z3iXf?)Sc z%65tl9FD(>d0T=xOmJo&DO}kNaUgRxJqYUe?&+*yF>`0@G z#+jD7UV$lf+p#M@U)B9y4&e(eGjcLK!#bKO^6&9omybyvCx}-3soG%ldW zrz`G5o+fU;%cci2Ji{4pdd;6rB?cW-n&!y=mH_rC8(OX`|l2i!+dm5hBPM{+Rg zA&Twm{7rk?l9&CH?*0jmjVNk*J4MSjl9$XCOLU+-mZxC!wzahtR_=KjzBlDx!&(1_ z@A5Yi-Yt%26VfpnjjC>7$z5bq-z8egg<8ou z8Zb95IA^6cNh}0^IxJe*-F?o8Y8$CGHciT4>}#)z1ONp>T*95^|JvG5SIdsUbBh?Z zPe07#e(F2N1)>51&5`_@cUJ8Qx}#XjcY_@FsYi}|?$U7^?2OAsc}55pPTs<}hXW)a#LUM-M(L2fUV@o5p3* zstD$(`UL>9*S>c0#Vy|-U0yYJ?7)=YPB$JKvB@#1^H=@*Kp&H5>4F4Q?zsta7>_cJ z&(ID#p7`FP-hjUq31YRFBs%n>bMv*3fxARDW;rHFgQr8T*$@?+24fsqml7$ZM9DEc34#>MZ~gwd8mAZkmlm;W4fC@@9D>zS_)ms z^Gj<3Ti-@IJXhrp;fiFT#GNahp9POG3gtJNtw+O-eZgD3n-HIzd`@XC$(@SrZr1R6 z#6NfnS6AcRncVnGyYe49dlc=|0c%4Sh}twKI*Cc$@g)~gk@GrdWlzqFG-x^M8x(KMp>+a(c)ups7PojQA;s+Wq* zzAb`sCd=MHgqKa9ph$Vx*^rqikF-(y(K|~j96N6LawFdcQ?vA=hs_&^AVIql(u`{OQ zvjE?!LM`)J{?U7Sg5-~rWwSGn*FJ2%I~`Ay9p5zN_~=!EnqZgO(AW&StNN{_=?1ae zfwT@&kJ$n?|L61Tf)v%hFhcGI3frQ5R88)+rN>v=w4||1StG5|_)-t&(@XkNU4o#` zdLZfN@V=4P3Ca~%yv$!acw+QBD+x1aKNad8+GNp*?{Ed$jy`u(jx3to@S0w68{qbh zX+0q8lWDCw7G5d7IXO|rS^v|rZ2zaUKD|fw2**lCbJewoS!}qT@sAh{$M)m4yaP_I rrXJojGP~1fVrcgaJJSCf;Ilj7j>9ofS)|b!j+=&(TVAf^Gok(;0V|@| 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 7d15e8b0..00000000 --- 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 13832bbf..00000000 --- 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 4dc257c1..2f213b97 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؟ + هل ترغب في إضافة %1$s للمجموعة %2$s؟ + عدد الرسائل الحديثة المراد إعادة تحويلها: + إضافة %1$s للمجموعة؟ + هذا المستخدم عضو مسبق في هذه المجموعة + ؟%1$s هل تريد إعادة توجيه الرسائل إلى هل ترغب في إرسال رسالة إلى %1$s؟ نرجو الأخذ بالعلم أنه يمكنك استخدام تيليجرام على أجهزتك المتعددة بسهولة تامة وفي وقت واحد.\n\nوتذكر، تسجيل الخروج يحذف كافة محادثاتك السرية. هل أنت متأكد من تسجيل الخروج من جميع الأجهزة الأخرى باستثناء هذا الجهاز؟ هل أنت متأكد من أنك تريد حذف المجموعة والخروج منها؟ - هل أنت متأكد من رغبتك في حذف المجموعة؟ + هل أنت متأكد من رغبتك في حذف المحادثة؟ هل أنت متأكد من أنك تريد مشاركة معلومات جهة الاتصال الخاصة بك؟ هل أنت متأكد من رغبتك في حظر جهة الاتصال هذه؟ هل أنت متأكد من رغبتك في إزالة الحظر عن جهة الاتصال هذه؟ @@ -611,8 +625,10 @@ هل أنت متأكد من رغبتك في حذف سجل المحادثات؟ هل أنت متأكد من رغبتك في حذف %1$s؟ هل ترغب في إرسال رسالة إلى %1$s؟ - هل تريد إعادة توجيه الرسائل إلى %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 رسالة معاد توجيهها الرسالة المعاد توجيهها @@ -804,30 +826,31 @@ HH:mm h:mm a %1$s الساعة %2$s - - 546 - - تلغرام للاندرويد - Theming - Invalid color hex code! - اعاة الضبط الافتراضي + + تيليجرام نسخة الأندرويد تم تحديثه. الجديد في نسخة ٣.٠:\n\n- أقسام مخصصة خاصة ومرتبة لكل لحزم الملصقات. يمكنك إضافة حزم الملصقات كهذه https://telegram.me/addstickers/Animals\n- واجهة برمجية خاصة جديدة بالبوت، مجانًا للجميع. إذا كنت مبرمج، اصنع البوت الخاص بك مثل @quiz_bot و @hot_or_bot باستخدام حساب @botfather. للإستزادة، فضلًا اطلع على https://telegram.org/blog/bot-revolution + 576 + + + بلاس مسنجر للأندرويد + الثيمات + شفرة تعريف اللون غير صحيحه! + لون الثيم + اعادة الضبط الافتراضي التراجع عن كافة ضبط الثيمات - اعادة ضبط الثيمات الي الافتراضي + إعادة ضبط الإعدادت الإفتراضي عام شاشات الشاشة الرئيسية شاشة المحادثة - شاشة الاسماء + شاشة الأسماء الشريط العلوي الصفوف قائمة المحادثة قائمة المحادثات قائمة الاسماء لون الشريط العلوي - لون جهات الاتصال - حجم اسماء جهات الاتصال + لون الإسم + حجم اللإسم لون الرسالة حجم الرسالة لون الزمن/التاريخ @@ -843,7 +866,7 @@ لون التريخ حجم التاريخ لون فقاعة التاريخ - لون الخط + لون النص اليمين لون الخط اليسار لون الزمن اليمين لون الزمن اليسار @@ -851,30 +874,84 @@ لون نص الادخال حجم نص الادخال لون خلفية نص الادخال - لون خلفية الفيسات - لون تبويب الفيسات - لون حالة الاتصال + لون خلفية الإبتسامات + لون تبويب الإبتسامات + لون حالة الإتصال موسيقى حفظ الثيم حفظ الثيمات في مجلد Telegram/Themes - تم حفظ الثيم - %1$s saved to %2$s - Theme not created yet. Apply any MOD first, please - Preferences restored from sdcard - No preferences file found in %s + تم حفظ الثيم! + %1$s حفظ في %2$s + لم يتم إنشاء ثيم لحد الآن. الرجاء إختيار أي تعديل بالأول. + التفضيلات المسترجعه من الذاكره + لا يوجد ملف تفضيلات في %s لاتوجد بطاقة ذاكرة - ادخل الاسم + أدخل الإسم الثيمات تطبيق الثيم - Apply xml theme from local folder - Participant Color - Ticks Color - Mute Color - Send Logs - There aren\'t logs - Send Icon - Hide Mobile Number - Floating Pencil Color - Floating Background Color - G+ Community + تطبيق ثيم XML من ملف على الجهاز + لون العضو + لون علامة اللإختيار + لون الوضع الصامت + إرسال ملفات تتبع الإستخدام + لا يوجد ملفات تتبع للإستخدام + أيقونة الإرسال + إخفاء رقم الهاتف من القائمة + لون قلم الرصاص + لون الخلفية + مجتمع G+ + لون الكتابة + لون أيقونة النص المدخل + درج التصفح + قائمة الخيارات + قائمة الألوان + حجم اللإسم + لون الهاتف + حجم الهاتف + لون الصورة الشخصية + لون أيقونة الخيارات + لون الخيارات + حجم الخيارات + لون الإصدار + حجم الإصدار + لون عنوان الصفحة + لون أيقونات الصفحة + لون المقسم + قطر الصورة الشخصية + تعيين لون العضو + لون تحويل الإسم + عنوان الصفحة + تحويل بدون الرسالة المسبقه + تعطيل الصفحات المنبثقه بالضغط + بيانات المجموعه / المتصل + إخفاء الخلفيه المُعينه + لون الرابط اليمين + لون الرابط اليسار + تم تعيين الثيم! + إضغط موافق لإعادة تشغيل البرنامج + إظهار إبتسامات الجهاز + تشكيلة فقاعيه + لا تغير الإسم الأصلي + بدلاً من ملفات مُرقمة سوف يستخدم طريقة اللإسم_اليوم + حجم الصورة الشخصية + محاذات الصورة الشخصيه للأعلى + هامش الصورة الشخصيه اليسار + لون إسم المجموعة + حجم إسم المجموعة + لون اللإسم (للرقم الغير معروف) + إخفاء ظل الخلفية المعينه + تعيين لون الخلفية + لون الخلفية + حجم الابتسامة المنبثقة + تحويل فقاعة لون الإسم اليمين + تحويل فقاعة لون الإسم اليسار + لون الأيقونات + الإعدادات / ثيم الشاشة + لون الخلفية + لون الظل + لون الخيار + لون العنوان + لون الملخص / الترجمة + لون نص الصورة / الملصق + هل تريد إستكشاف ثيمات أنشئها مستخدمين آخرين لبلس مسنجر؟ \ No newline at end of file diff --git a/TMessagesProj/src/main/res/values-ca/strings.xml b/TMessagesProj/src/main/res/values-ca/strings.xml index 8772e2b6..226329b2 100644 --- a/TMessagesProj/src/main/res/values-ca/strings.xml +++ b/TMessagesProj/src/main/res/values-ca/strings.xml @@ -706,4 +706,16 @@ Amaga l\'ombra de fons personalitzada Estableix un color de fons Color de fons + Mida de la finestra d\'Emojis + Color del nom als reenviaments drets + Color del nom als reenviaments esquerres + Color de les icones + Pantalla de Configuració/Aparença + Color de fons + Color de l\'ombra + Color de la secció + Color del títol + Color del resum/subtítol + Color del text «Foto/Adhesiu» + Voleu veure alguns temes creats per altes usuaris de Plus Messenger? diff --git a/TMessagesProj/src/main/res/values-de/strings.xml b/TMessagesProj/src/main/res/values-de/strings.xml index 5e2c45e9..88c1198c 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 Plus Messenger 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,56 +827,57 @@ h:mm a %1$s um %2$s - Plus Messenger für Android wurde aktualisiert. Neu in Version 2.9:\n\n- Prüfe, lade herunter und wende das Thema für den Plus Messenger an:\n https://play.google.com/store/apps/details?id=es.rafalense.themes - 546 - - \n\nNeu in 2.9.1.4:\n\n- Option zum Ändern der Standard-Größe für das Emoji-Fenster (Option unter \"Einstellungen/Nachrichten\")\n- Option zum Ändern der Komprimierung beim Senden von Videos\n- Option zum Bearbeiten der Farbe für \"Einstellungen/Thema\"\n- Farben der Namen im Chat für Sprechblasen auf linke und rechte Seite separat ändern\n- Option zum Ändern der Icon-Farben unter \"Kontakte\"\n- Option zum Ändern der Farbe für \"Foto/Sticker\" im Hauptfenster\n- Fehlerbehebungen + Plus Messenger 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\n- Überprüfe, lade herunter und installiere die Themes for Plus Messenger App. Neue Themen jeden Tag:\n https://play.google.com/store/apps/details?id=es.rafalense.themes + 576 + Plus Messenger für Android Themen bearbeiten Ungültiger Hex-Code! Themenfarbe - Thema-Einstellungen zurücksetzen - Alle Thema-Einstellungen rückgängig machen - Thema-Einstellungen auf Standardwerte zurücksetzen! + Thema Einstellungen zurücksetzen + Alle Thema Einstellungen rückgängig machen + Thema Einstellungen auf Standardwerte zurücksetzen! Allgemein Ansichten Chatübersicht Chat Kontaktübersicht Kopfzeile - Zeilen + Hintergrund Chatliste Chatverlauf Kontaktliste - Farbe der Kopfzeile - Farbe der Namen - Größe der Namen - Farbe der Nachrichten - Größe der Nachrichten - Farbe für Uhrzeit/Datum - Größe für Uhrzeit/Datum - Farbe für Benachrichtigungzähler - Größe für Benachrichtigungszähler - Zeilenfarbe - Hintergrundfarbe für Benachrichtigungszähler - Statusfarbe - Statusgröße - Farbe der rechten Sprechblasen - Farbe der linken Sprechblasen - Datumsfarbe - Datumsgröße - Datumsfarbe für Sprechblasen - Textfarbe für rechte Sprechblasen - Textfarbe für linke Sprechblasen - Farbe der Uhrzeit für rechte Sprechblasen - Farbe der Uhrzeit für linke Sprechblasen - Größe der Uhrzeit - Textfarbe für Texteingabefeld - Textgröße für Texteingabefeld - Hintergrundfarbe Texteingabefeld - Hintergrundfarbe für Emojis - Tabfarbe für Emojis - Statusfarbe Online + Kopfzeile + Namen + Namen + Nachrichten + Nachrichten + Uhrzeit/Datum + Uhrzeit/Datum + Benachrichtigungzähler + Benachrichtigungszähler + Hintergrund + Hintergrund Benachrichtigungszähler + Onlinestatus + Onlinestatus + rechte Sprechblasen + linke Sprechblasen + Datum + Datum + Datum Sprechblasen + Text rechte Sprechblasen + Text linke Sprechblasen + Uhrzeit rechte Sprechblasen + Uhrzeit linke Sprechblasen + Uhrzeit + Text im Texteingabefeld + Text im Texteingabefeld + Hintergrund Texteingabefeld + Hintergrund Emojis + Tab Emojis + Onlinestatus Musik Thema speichern Thema im Ordner Telegram/Themen speichern @@ -868,68 +891,71 @@ Themen auswählen Thema verwenden Thema-XML aus einem lokalen Ordner verwenden - Farbe der Gruppenmitglieder - Farbe der Häkchen - Symbolfarbe Stumm + Gruppenmitglieder + Häkchen + Symbol Stumm Sende Protokolle Keine Protokolle gespeichert - Symbolfarbe für Senden + Symbol für Senden Telefonnummer ausblenden - schwebender Stift Farbe - Hintergrundfarbe schwebender Stift + Schwebender Stift + Hintergrund schwebender Stift G+ Community - Textfarbe Eingabefeld - Symbolfarbe Texteingabefeld + Text Eingabefeld + Symbol Texteingabefeld Hauptmenü - Hauptmenü - Hintergrundfarbe Hauptmenü - Benutzernamen Größe - Telefonnummer Farbe - Telefonnummer Größe - Profilbild Farbe - Hauptmenü Symbolfarbe - Hauptmenü Textfarbe - Hauptmenü Textgröße - Versionsanzeige Textfarbe - Versionsanzeige Textgröße - Titelfarbe Kopfzeile - Symbolfarbe Kopfzeile - Trennstrich Farbe + Optionsliste + Optionsliste Hintergrund + Benutzernamen + Telefonnummer + Telefonnummer + Profilbild + Optionsliste Symbol + Optionsliste Text + Optionsliste Text + Versionsanzeige Text + Versionsanzeige Text + Titel Kopfzeile + Symbol Kopfzeile + Trennstrich Fotoecken - Gruppenmitglieder Farbe - Hinweisfarbe weitergeleitete Nachricht + Gruppenmitglieder + Hinweis weitergeleitete Nachricht Kopfzeilen Titel Weiterleiten ohne Zitieren mit Klick Pop-up deaktivieren Gruppe/Kontakt Profil Benutzerdefinerten Hintergrund ausblenden - Linkfarbe rechte Sprechblase - Linkfarbe linke Sprechblase + Link rechte Sprechblase + Link linke Sprechblase Thema angewendet! - OK klicken, um die App neu zu starten + OK klicken um die App neu zu starten Google Emojis verwenden Sprechblasen Form original Dateinamen speichern Statt Zahlen wird Dateiname_Datum gespeichert - Profilbildgröße Gruppenchat + Profilbild Gruppenchat Profilbild Gruppenchat nach oben Profilbild Randabstand Gruppenchat - Gruppenname Farbe - Gruppenname Größe - Name Farbe (unbekannte Nummer) + Gruppenname + Gruppenname + Name (unbekannte Nummer) Hintergrund Schatten ausblenden - Hintergrundfarbe festlegen - Hintergrundfarbe - Emoji Popup Größe + Hintergrund festlegen + Hintergrund + Emoji Fenstergröße Sprechblase rechts Name weiterleiten Sprechblase links Name weiterleiten - Symbolfarbe + Symbol Einstellungen Thema bearbeiten - Hintergrundfarbe - Trennbalken Farbe - Überschrift Farbe - Titelfarbe - Hinweis/Untertitel Farbe - \'Foto/Sticker\' Textfarbe + Hintergrund + Trennbalken + Überschrift + Titel + Hinweis/Untertitel + \'Foto/Sticker\' Text Möchtest Du Themen von anderen Plus Messenger Mitgliedern sehen? + Systemschrift verwenden + Der Plus Messenger wird neu gestartet + Gruppensymbole \ 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 811c653b..1e45fea9 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. Plus Messenger 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,10 +827,10 @@ h:mm a %1$s a las %2$s - Plus Messenger para Android fue actualizada. Novedades en la versión 2.9:\n\n- Ojea, descarga y aplica temas para Plus Messenger:\n https://play.google.com/store/apps/details?id=es.rafalense.themes - 546 + Plus Messenger 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\n - Ojea, descarga y aplica temas para Plus Messenger. Nuevos temas cada día:\n https://play.google.com/store/apps/details?id=es.rafalense.themes + 576 - \n\nNovedades en 2.9.1.4:\n\n- Opción para cambiar tamaño de la ventana de emoticonos en pantalla chat (opción en Ajustes/Mensajes)\n- Opción para cambiar nivel de compresión al compartir vídeos\n- Añadidos MOD para ajustar colores en pantalla Ajustes/Tematización\n- Añadido MODs distintos para nombre de reenvío en globo derecho e izquierdo en pantalla chat\n- Añadido MOD para ajustar colores de iconos en pantalla Contactos\n- Añadido MOD para cambiar color de texto \'Foto/Sticker\' en pantalla principal\n- Solución de errores + \n\nNovedades en 3.0.1.5:\n\n- Arregladas opciones para compartir música y sticker\n- Añadida opción para compartir tlf de un contacto\n - Añadida opción para añadir miembro directamente desde las opciones de grupo\n- Añadida opción para silenciar o activar notificaciones desde pantalla principal\n- Solución de errores Plus Messenger para Android Tematización ¡Color hexadecimal inválido! @@ -932,4 +954,7 @@ Color de subtítulo/sumario Color de texto \'Foto/Sticker\' ¿Te gustaría ver algunos temas creados por otros usuarios de Plus Messenger? + Usa fuente del teléfono + Plus Messenger se reiniciará + Color de icono de grupo \ No newline at end of file diff --git a/TMessagesProj/src/main/res/values-fr/strings.xml b/TMessagesProj/src/main/res/values-fr/strings.xml index 47573d93..310043e7 100644 --- a/TMessagesProj/src/main/res/values-fr/strings.xml +++ b/TMessagesProj/src/main/res/values-fr/strings.xml @@ -243,7 +243,6 @@ Une erreur est survenue. Autocollants - Grands esprits Les artistes peuvent ajouter leur propre paquet d\'autocollants en utilisant notre robot @stickers.\n\nLes utilisateurs peuvent ajouter des autocollants en les touchant et en choisissant \"Ajouter aux autocollants\". Ajouter des autocollants Ajouter aux autocollants @@ -804,7 +803,7 @@ %1$s à %2$s - 546 + 547 Plus Messenger pour Android Thème diff --git a/TMessagesProj/src/main/res/values-hi/strings.xml b/TMessagesProj/src/main/res/values-hi/strings.xml index efe424d8..5ff3738a 100644 --- a/TMessagesProj/src/main/res/values-hi/strings.xml +++ b/TMessagesProj/src/main/res/values-hi/strings.xml @@ -1,28 +1,644 @@ - एप्लिकेशन के लिए Google Play सेवाओं को सक्षम किए जाने की आवश्यकता है. - एप्लिकेशन के लिए Google Play सेवाओं के इंस्टॉलेशन की आवश्यकता है. - एप्लिकेशन के लिए Google Play सेवाओं में अपडेट की आवश्यकता है. - Google Play सेवाएं त्रुटि - %1$s द्वारा अनुरोधित - एप्लि. ने Google Play सेवाओं के खराब संस्करण के उपयोग का प्रयास किया. - Google Play सेवाएं सक्षम करें - जब तक आप Google Play सेवाएं सक्षम नहीं करते, तब तक यह एप्लिकेशन कार्य नहीं करेगा. - Google Play सेवाएं सक्षम करें - Google Play सेवाएं पाएं - यह एप्लिकेशन Google Play सेवाओं के बिना नहीं चलेगा, जो आपके फ़ोन में नहीं हैं. - यह एप्लिकेशन Google Play सेवाओं के बिना नहीं चलेगा, जो आपके टेबलेट में नहीं हैं. - Google Play सेवाएं पाएं - निर्दिष्ट खाता इस उपकरण पर मौजूद नहीं है. कृपया कोई भिन्न खाता चुनें. - अमान्य खाता - Google Play सेवाओं से कनेक्ट करने के लिए डेटा कनेक्शन की आवश्यकता है. - नेटवर्क त्रुटि - Google Play सेवाओं के साथ अज्ञात समस्या. - Google Play सेवाएं, जिन पर आपके कुछ एप्लिकेशन निर्भर करते हैं, आपके उपकरण द्वारा समर्थित नहीं हैं. कृपया सहायता के लिए निर्माता से संपर्क करें. - Google Play सेवाएं - अपडेट करें - जब तक आप Google Play सेवाओं को अपडेट नहीं करते, तब तक यह एप्लिकेशन नहीं चलेगा. - Google Play सेवाएं अपडेट करें - प्रवेश करें - Google से प्रवेश करें + अंग्रेजी + Hindi + hi + + आपका फोन + कृपया अपने देश कोड की पुष्टि करें और अपना फोन नंबर दर्ज करें। + देश चुनें + गलत देश कोड + + आपका कोड + हमने एक एसएमएस के साथ एक सक्रियण कोड आपके फोन के लिए भेज दिया है + हम आपको %1$d:%2$02d में कॉल करेंगे + कॉल कर रहे... + कोड + गलत नंबर? + कोड नहीं मिला? + + आपका शुभ नाम? + अपना पहला और आखिरी नाम नियत करें + + पहला नाम (जरूरी) + आखिरी नाम (वैकल्पिक) + पंजीकरण रद्द करें + + विन्यास + सम्पर्क + नया समूह + बिता कल + कोई परिणाम नहीं + अभीतक वार्तालाप नहीं + संदेश भेजना शुरू करने के लिए नीचे\n दायीं कोने में लिखें बटन दबाएँ\n या अधिक विकल्पों के लिए मेनू बटन दबाएँ। + नेटवर्क का इंतज़ार... + जुड़ रहा है... + अद्यतन कर रहा है... + नया गुप्त वार्तालाप + %s के ऑनलाइन आने में प्रतीक्षारत... + गुप्त वार्तालाप रद्द + गुढीकरण कुंजियों का आदान प्रदान... + %s आपके गुप्त वार्तालाप से जुड़े। + आप गुप्त वार्तालाप से जुड़े। + इतिहास साफ करें + मिटाएँ और निकलें + वार्तालाप मिटाएँ + खाता मिटाएँ? + वार्तालाप चुनें + टैप करें और देखने के लिए पकड़ें + %1$s टेलीग्राम के एक पुराने संस्करण का उपयोग कर रहा है, जिसके कारण गुप्त तस्वीरें संगतता मोड में दिखाया जाएंगी।\n\nएकबार %2$s टेलीग्राम को अद्यतन करे, तब तस्वीरें 1 मिनट या उससे कम समयक के साथ \'देखने के लिए टैप करें और पकड़ें\' मोड में‌ काम करना शुरु कर देंगी, और आपको सूचित किया जाएगा जब भी दुसरा पक्ष स्क्रीनशॉट लेता है। + संदेश + + नई प्रसारण सूचि + सूचि का नाम दर्ज करें + आपने एक प्रसारण सूचि बनाया + प्राप्तकर्ता जोड़ें + प्रसारण सूचि से हटाएँ + + फाइल चुनें + %2$s में से %1$s खाली + अनजान त्रुटि + पहुँच त्रुटि + अभीतक कोई फाइल नहीं... + फाइल का आकार %1$s से बड़ा नहीं होना चाहिए + संग्रहण माउंट नहीं + यूएसबी स्थानांतरण सक्रिय + आंतरिक संग्रहण + बाह्य संग्रहण + तंत्र मूल + एसडी कार्ड + फोल्डर + + अदृश्य + लिख रहे... + लिख रहे हैं... + लिख रहे हैं... + टेलीग्राम के बारे\nमें कोई प्रश्न? + फोटो लें + गैलरी + स्थान + विडियो + अभीतक यहाँ कोई संदेश नहीं... + अग्रेषित संदेश + से + हाल का नहीं + संदेश + संदेश + सम्पर्क साझा करें + सम्पर्क में‌ जोड़ें + %s ने आपको गुप्त वार्तालाप के लिए आमंत्रित किया है। + आपने %s को गुप्त वार्तालाप के लिए आमंत्रित किया है। + गुप्त वार्तालाप: + आद्योपांत गुढ़ीकरण करें + सर्वर पर कोई निशान मत छोड़ें + स्वत:-नष्ट घड़ी है + अग्रेषण की अनुमति नहीं + इस समूह से आप हटा दिए गए + आपने इस समूह को छोड़ दिया + इस समूह को मिटाएँ + इस वार्तालाप को मिटाएँ + स्लाइड कर रद्द करें + डाउनलोड में सहेजें + स्थानीयकरण फाइल लागू करें + असमर्थित दस्तावेज + स्वत:-नष्ट घड़ी नियत करें + + %1$s ने स्वत:-नष्ट घड़ी को %2$s पर नियत किया + आपने स्वत:-नष्ट घड़ी को %1$s पर नियत किया + %1$s ने स्वत:-नष्ट घड़ी को निष्क्रिय किया + आपने आत्म-विनाशी घड़ी को निष्क्रिय किया + आपके लिए एक नया सन्देश है + %1$s: %2$s + %1$s ने आपको एक सन्देश भेजा है + %1$s ने आपको एक फोटो भेजा है + %1$s ने आपको एक विडियो भेजा है + %1$s ने आपसे एक कांटेक्ट शेयर किया है + %1$s ने आपको एक स्थान भेजा है + %1$s ने आपको एक ऑडियो भेजा है + %1$s @ %2$s: %3$s + %1$s ने %2$s समूह को एक सन्देश भेजा है + %1$s ने %2$s समूह को एक फोटो भेजा है + %1$s ने %2$s समूह को एक विडियो भेजा है + %1$s ने %2$s समूह में एक कांटेक्ट शेयर किया है + %1$s ने %2$s समूह को एक स्थान भेजा है + %1$s ने %2$s समूह को एक ऑडियो भेजा है + %1$s ने आपको %2$s समूह में आमंत्रित किया + %1$s ने %2$s समूह का नाम संपादित किया + %1$s ने %2$s समूह का फोटो संपादित किया + %1$s ने %3$s को %2$s समूह में आमंत्रित किया + %1$s ने %3$s को %2$s समूह से हटाया + %1$s ने आपको %2$s समूह से हटाया + %1$s ने %2$s समूह छोड़ दिया + %1$s टेलीग्राम से जुड़े! + %1$s ने प्रोफ़ाइल अपडेट किया + उत्तर दें + %1$s को उत्तर दें + %1$s को उत्तर दें + %1$s %2$s + + कांटेक्ट चुनें + अभी तक कोई कॉन्टेक्ट्स नहीं + बिता कल + ऑनलाइन + लास्ट सीन + लास्ट सीन + दोस्तों को आमंत्रण + वैश्विक खोज + हाल हीं में आखिरी बार देखा + एक सप्ताह के अन्दर आखिरी बार देखा + एक महीने के अन्दर आखिरी बार देखा + बहुत पहले आखिरी बार देखा + नया संदेश + + इन्हें संदेश भेजें... + समूह का नाम दर्ज करें + समूह का नाम + %1$d/%2$d सदस्य + + साझा मिडिया + विन्यास + सदस्य जोड़ें + मिटाएँ और समूह को छोड़ें + नोटिफिकेशन्स + समूह से हटायें + + शेयर + जोड़ें + सम्पर्क जोड़ें + ब्लॉक + संपादित करें + मिटाएँ + घर + मोबाइल + कार्य + अन्य + मुख्य + गुप्त वार्तालाप चालू करें + एक त्रुटि हुई + एन्क्रिप्शन कुंजी + आत्म-विनाशी घड़ी + ऑफ + यह छवि इस गुप्त वार्तालाप के लिए गुढ़ीकरण कुंजी का एक दृश्य है ]]>%1$s]]>के साथ।
]]>अगर यह छवि एक ही लग रहा है, ]]>%2$s\'s]]> फोन पर, तो आपका वार्तालाप 200%% सुरक्षित है।
]]>और अधिक जानें telegram.org
+ अनजा + जानकारी + फोन + + यूज़रनेम + आपका यूज़रनेम + माफ़ कीजियेगा, यह यूज़रनेम पहले ही लिया जा चुका है + माफ़ कीजियेगा, यह यूज़रनेम अमान्य है + यूज़रनेम में न्यूनतम 5 अक्षर होने चाहिए + यूज़रनेम 32 अक्षरों से अधिक नहीं होना चाहिए + माफ़ कीजियेगा, यूज़रनेम नंबर से शुरू नहीं हो सकता + आप ]]>टेलीग्राम]]> पर एक यूज़रनेम चुन सकते हैं| अगर आप ऐसा करते हैं तो दूसरे लोग आपको इस यूज़रनेम से ढूंड सकते हैं और आपसे संपर्क कर सकते हैं बिना आपका फ़ोन नंबर जाने|
]]>आप ]]>a–z]]>, ]]>0–9]]> और अंडरस्कोर का इस्तेमाल कर सकते हैं| यूज़रनेम न्यूनतम ]]>5]]> अक्षरों का होना चाहिए|
+ यूज़रनेम जाँच रहे हैं... + %1$s उपलब्ध है| + कोई नहीं + एक त्रुटि हुई। + + + `सूचनाओं के विन्यास को पुनः तयशुदा पर नियत करें + संदेश का पाठ आकार + प्रश्न पूछें + एनिमेशन लागू करें + अनब्लॉक + उस उपयोक्ता को अनावरोधित करने के लिए टैप कर पकड़ें + अभीतक कोई अवरुद्ध उपयोक्ता नहीं + संदेश सूचनाएँ + चेतावनी + संदेश पूर्वावलोकन + समूह सूचनाएँ + ध्वनि + अनुप्रयोग के अंतर्गत अधिसूचनाएँ + अनुप्रयोग के अंतर्गत ध्वनियाँ + अनुप्रयोग के अंतर्गत कंपन + कंपन + अनुप्रयोग के अंतर्गत पूर्वावलोकन + पुनः नियत करें + सारे सूचनाओं को पुनः नियत करें + सभी कस्टम नोटिफिकेशन सेटिंग्स को सभी कॉन्टेक्ट्स और समूहों के लिए पूर्ववत् करें + सारे सूचनाओं को पुनः नियत करें + ब्लॉक्ड यूज़र्स + लॉग आउट + ध्वनि नहीं + तयशुदा + सहायता + वार्तालाप पृष्ठभूमि + संदेश + इंटर के द्वारा भेजें + अन्य सभी सत्रों को समाप्त करें + घटनाक्रम + कांटेक्ट टेलीग्राम में शामिल हुआ + PEBBLE + भाषा + स्वयंसेवक से पुछें + टेलीग्राम FAQ + https://telegram.org/faq + स्थानीयकरण मिटाएँ? + गलत स्थानीयकरण फाइल + सक्रिय + निष्क्रिय + सूचना सेवा + अधिसूचनाएँ प्राप्त करने के लिए अगर गूगल प्ले की सेवाओं आपके लिए पर्याप्त हैं, तो आप अधिसूचना सेवा को निष्क्रिय कर सकते हैं। लेकिन हम अनुप्रयोग को पृष्ठभूमि में सक्षम छोड़ने के लिए और तत्काल सूचनाएँ प्राप्त करने के लिए चलाए रखने के लिए सलाह देते हैं। + द्वारा क्रमबद्ध + इम्पोर्ट कॉन्टेक्ट्स + पहला नाम + आखिरी नाम + LED का रंग + पॉपअप अधिसूचनाएँ + पॉपअप नहीं + तभी जब स्क्रीन \"ऑन\" हो + तभी जब स्क्रीन \"ऑफ\" हो + पॉपअप हमेशा दिखाएँ + Badge Counter + छोटा + बड़ा + तंत्र तयशुदा + विन्यास तयशुदा + स्वचालित मिडिया डाउनलोड + मोबाइल डेटा का इस्तेमाल करते समय + वाई-फाई से जुड़े होने पर + रोमिंग पर + मिडिया नहीं + गैलरी में सेव करें + नाम संपादित करें + प्राथमिकता + तयशुदा + निम्न + उच्च + अधिकत्तम + कभी नहीं + सूचनाएँ दोहराएँ + यहाँ आप अपना टेलीग्राम नंबर बदल सकते हैं। आपका खाता और आपके सभी डेटा — संदेश, मीडिया, सम्पर्क, इत्यादि को नये नंबर में खिसका दिया जाएगा।\n\nमहत्वपूर्ण:]]> आपके सभी टेलीग्राम सम्पर्कों के पता-पुस्तिका मेंआपका नया नंबर]]> जुड़ जाएगी, अगर आपने उन्हें अवरुद्ध नहीं किया हो और उनके पास आपका पुराना नंबर हो। + आपके सभी टेलीग्राम सम्पर्कों के पता-पुस्तिका में आपका नया नंबर जुड़ जाएगी, अगर आपने उन्हें अवरुद्ध नहीं किया हो और उनके पास आपका पुराना नंबर हो। + नंबर बदलें + नया नंबर + हम आपके नये नंबर पर एसएमएस के द्वारा एक सक्रियण कोड भेजेंगे। + यह नंबर %1$s पहले से ही एक टेलीग्राम खाते से जुड़ा है। कृपया उस खाते को हटाकर नये नंबर का इस्तेमाल करें। + अन्य + + + + + नक्सा + उपग्रह + मिश्रित + मी. दूर + कि.मी. दूर + + सभी मिडिया दिखायें + गैलरी में सेव करें + %1$d of %2$d + गैलरी + सभी फोटोज + अभीतक कोई तस्वीर नहीं + कृपया पहले मिडिया डाउनलोड करें + + + गोपनीयता और सुरक्षा + गोपनीयता + अंतिम बार देखा + प्रत्येक + मेरे सम्पर्क + कोई नहीं + प्रत्येक (-%1$d) + मेरे सम्पर्क (+%1$d) + मेरे सम्पर्क (-%1$d) + मेरे सम्पर्क (-%1$d, +%2$d) + कोई नहीं (+%1$d) + सुरक्षा + खाता स्वत:-नष्ट + अगर आप दूर हैं + अगर आप इस अवधि के भीतर कम से कम एक बार भी प्रवेश नहीं करते हैं, तो आपके खाते को सभी समूहों, संदेशों और संपर्कों के साथ हटा दिया जाएगा। + आपका खाता मिटाएँ? + जो आपको पिछला बार देख सकते हैं को बदलें। + कौन आपको पिछला बार देख सकता है? + अपवाद जोड़ें + महत्वपूर्ण: आप उन लोगों के अंतिम दिखा समय नहीं‌ देख पाएँगे जिनके साथ आपने अपना अंतिम देखा समय साझा नहीं किया हो। उसके बजाय लगभग पिछली बार दिखा (एक महीने के भीतर, एक सप्ताह के भीतर, हाल ही में) दिखाया जाएगा। + के साथ हमेशा साझा करें + के साथ कभी साझा नहीं करेंं + ये विन्यास उपर के मानों को हटा देगा। + हमेशा साझा करें + इन उपयोक्तायों से हमेशा साझा करें... + कभी नहीं साझा करेंं + इन उपयोक्तायों से साझा कभी नहीं करें... + उपयोक्ता जोड़ें + क्षमा करें, बहुत सारे अनुरोध है। अभी गोपनीयता विन्यास बदलने में असमर्थ, कृपया प्रतीक्षा करें। + इसे छोड़ अन्य उपकरणों से लॉग-आउट करें। + उस उपयोक्ता को हटाने के लिए टैप कर पकड़ें। + + विडियो संपादित करें + मूल विडियो + संपादित विडियो + विडियो भेज रहा है... + विडियो संपीड़ित करें + + + अगला + पीछे + पूर्ण + खोलें + रद्द करें + जोड़ें + संपादन + भेजें + कॉल + प्रतिलिपि + मिटाएँ + अग्रेषित करें + पुन: प्रयास करें + कमरे से + गैलरी से + तस्वीर मिटाएँ + नियत करें + ठीक + + un1 ने un2 को हटाया + un1 ने समूह छोड़ा + un1 ने un2 को जोड़ा + un1 ने समूह की तस्वीर हटाई + un1 ने समूह की तस्वीर बदली + un1 ने समूह का नाम un2 पर बदला + un1 ने यह समूह बनाया + आपने un2 को हटाया + आपने समूह छोड़ा + आपने un2 को जोड़ा + आपने समूह की तस्वीर हटा दिया + आपने समूह की तस्वीर बदल दिया + आपने समूह का नाम un2 पर बदला + आपने यह समूह बनाया + un1 ने आपको हटाया + un1 ने आपको जोड़ा + फोटो + वीडियो + लोकेशन + कांटेक्ट + ऑडियो + आप + आपने एक स्क्रीनशॉट लिया! + un1 ने एक स्क्रीनशॉट लिया! + + अवैध फोन नंबर + कोड की अवधि समाप्त हो गई, कृपया पुनः लॉगिन करें + बहुत सारे प्रयास, कृपया बाद में पुन: प्रयास करें + अवैध कोड + अवैध पहला नाम + अवैध आखिरी नाम + लोड हो रहा है... + आपके पास विडियो प्लेयर नहीं‌ है, कॄपया जारी रखने के लिए एक संस्थापित करें + आपके पास \'%1$s\' फाइल प्रकार को खोलने के लिए अनुप्रयोग नहीं है, कृपया जारी रखने के लिए एक संस्थापित करें + इस उपयोक्ता के पास टेलीग्राम नहीं‌ है, आमंत्रित करें? + क्या आप सुनिश्चित हैं? + संदेश %1$s को अग्रेषित करें? + %1$s को सन्देश भेजें? + सुनिश्चित करें यदि आप लॉग आउट करना चाहते हैं?\n\nध्यान दें कि आप एक ही बार में अपने सभी उपकरणों पर टेलीग्राम का उपयोग कर सकते हैं।\n\nयाद रखें, लॉग आउट करने पर आपके सभी गुप्त चैट खत्म हो जाते हैं। + सुनिश्चित करें यदि आप अन्य सभी सत्र समाप्त करना चाहते हैं? + सुनिश्चित करें यदि आप समूह मिटाकर इसे छोड़ना चाहते हैं? + सुनिश्चित करें यदि आप इस वार्तालाप को मिटाना चाहते हैं? + सुनिश्चित करें यदि आप अपने सम्पर्क जानकारी को साझा करना चाहते हैं? + सुनिश्चित करें यदि आप इस सम्पर्क को अवरोधित करना चाहते हैं? + सुनिश्चित करें यदि आप इस सम्पर्क को अनावरोधित करना चाहते हैं? + सुनिश्चित करें यदि आप इस सम्पर्क को मिटाना चाहते हैं? + सुनिश्चित करें यदि आप एक गुप्त वार्तालाप शुरु करना चाहते हैं? + सुनिश्चित करें यदि आप पंजीकरण रद्द करना चाहते हैं? + सुनिश्चित करें यदि आप इतिहास को साफ करना चाहते हैं? + सुनिश्चित करें यदि आप %1$s को मिटाना चाहते हैं? + %1$s को सन्देश भेजें? + %1$s को संदेश अग्रेषित करें? + माफ़ कीजियेगा, ये सुविधा आपके देश में उपलब्ध नहीं है + + टेलीग्राम + तेज़ + मुफ्त + सुरक्षित + शक्तिशाली + क्लाउड-बेस्ड + निजी + दुनिया का सबसे तेज़]]> मैसेजिंग एप्प |]]>ये मुफ्त]]> और सुरक्षित]]> है | + टेलीग्राम]]> संदेश तेजी से पहुँचाता है]]>किसी अन्य अनुप्रयोग के मुकाबले। + टेलीग्राम]]> सदा के लिए निःशुल्क है। ना प्रचार।]]>ना सदस्यता शुल्क। + टेलीग्राम]]> आपके संदेशों को हैकर के हमलों से]]>सुरक्षित रखता है। + टेलीग्राम]]> में आपके मीडिया और चैट]]>पर कोई आकार का सीमा नहीं है। + टेलीग्राम]]> आपको कई उपकरणों से अपने संदेशों]]> तक पहुँचने देता है। + टेलीग्राम]]> के संदेश अत्यंत गुढ़िकृत होते हैं]]>और स्वतः-नष्ट भी हो जा सकते हैं। + संदेश भेजना शुरु करें + + %1$d ऑनलाइन + %1$d ऑनलाइन + %1$d ऑनलाइन + %1$d ऑनलाइन + %1$d ऑनलाइन + %1$d ऑनलाइन + कोई सदस्य नहीं + %1$d सदस्य + %1$d सदस्य + %1$d सदस्य + %1$d सदस्य + %1$d सदस्य + और %1$d लोग टाइप कर रहे हैं + और %1$d लोग टाइप कर रहे हैं + और %1$d लोग टाइप कर रहे हैं + और %1$d लोग टाइप कर रहे हैं + और %1$d लोग टाइप कर रहे हैं + और %1$d लोग टाइप कर रहे हैं + कोई नये सन्देश नहीं + %1$d नया संदेश + %1$d नये संदेश + %1$d नये संदेश + %1$d नये संदेश + %1$d नये संदेश + कोई सन्देश नहीं + %1$d संदेश + %1$d संदेश + %1$d संदेश + %1$d संदेश + %1$d संदेश + %1$d सेकंड + %1$d सेकंड + %1$d सेकंड + %1$d सेकंड + %1$d सेकंड + %1$d सेकंड + %1$d मिनट + %1$d मिनट + %1$d मिनट + %1$d मिनट + %1$d मिनट + %1$d मिनट + %1$d घंटे + %1$d घंटा + %1$d घंटे + %1$d घंटे + %1$d घंटे + %1$d घंटे + %1$d दिन + %1$d दिन + %1$d दिन + %1$d दिन + %1$d दिन + %1$d दिन + %1$d सप्ताह + %1$d सप्ताह + %1$d सप्ताह + %1$d सप्ताह + %1$d सप्ताह + %1$d सप्ताह + %1$d महिनों + %1$d महिना + %1$d महिनों + %1$d महिनों + %1$d महिनों + %1$d महिनों + %1$d सालों + %1$d साल + %1$d सालों + %1$d सालों + %1$d सालों + %1$d सालों + %1$d उपयोक्तायों + %1$d उपयोक्ता + %1$d उपयोक्तायों + %1$d उपयोक्तायों + %1$d उपयोक्तायों + %1$d उपयोक्तायों + + + MMMM yyyy + MMM dd + dd.MM.yy + dd.MM.yyyy + MMMM d + MMMM d, yyyy + EEE + HH:mm + h:mm a + %1$s पर %2$s + + Plus Messenger for Android has been updated. New in Version 3.0:\n\n\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\n https://play.google.com/store/apps/details?id=es.rafalense.themes + 576 + + + Android के लिए प्लस मैसेंजर + थीमिंग + रंग का हेक्स कोड गलत है! + थीम का रंग + थीम सेटिंग्स को यथावत करे + सभी थीम सेटिंग्स पूर्ववत करे + थीम सेटिंग्स को यथावत करे! + सामान्य + स्क्रीन्स + मुख्य स्क्रीन + वार्तालाप स्क्रीन + संपर्क स्क्रीन + हेडर + पंक्तियाँ + वार्तालाप की सूची + वार्तालापों की सूची + संपर्क लिस्ट + हैडर रंग + नाम का रंग + नाम का माप + संदेश का रंग + संदेश का माप + समय /दिनांक का रंग + समय /दिनांक का माप + गिनती का रंग + गिनती का माप + पंक्तियों का रंग + गिनती की पृष्ठभूमि का रंग + स्टेटस का रंग + स्टेटस का माप + दायें बबल कलर + बांये बबल कलर + दिनांक का रंग + दिनांक का माप + समय के बबल का रंग + दायें टेक्स्ट का रंग + बांये टेक्स्ट का रंग + दायें समय का रंग + बांये समय का रंग + समय का माप + सन्देश लिखने का रंग + सन्देश लिखने का माप + सन्देश लिखने की पृष्ठभूमि का रंग + ईमोजी की पृष्ठभूमि का रंग + ईमोजी के पन्ने का रंग + Online का रंग + संगीत + थीम सेव करे + थीम को Telegram/Themes फोल्डर में सेव करे + थीम सेव हो गयी! + %1$s saved to %2$s + थीम अभी तक नहीं बनी। कृपया कोई भी एक MOD लगाये। + पसंद sdcard से पुनःस्थापित हो गयी + %s में कोई पसंद की फाइल नहीं मिली + SD Card नहीं पाया गया + नाम डालें + थीम्स + थीम लगाये + XML थीम स्थानिक फोल्डर से लगाये + प्रतिभागी का रंग + टिक का रंग + मुक् का रंग + Log भेजे + कोई Log नहीं है + भेजने का चिन्ह + मेनू में से मोबाइल नंबर छुपाये + तैरती पेंसिल का रंग + तैरती पृष्ठभूमि का रंग + G+ Community + Typing का रंग + सन्देश लिखने के चिह्नों का रंग + संचालन खाना + विकल्पों की सूची + सूची का रंग + नाम का माप + फ़ोन का रंग + फ़ोन का माप + अवतार का रंग + विकल्प के चिह्न का रंग + विकल्प का रंग + विकल्प का माप + संस्करण का रंग + संस्करण का माप + हैडर शीर्षक का रंग + हैडर के चिह्नों का रंग + विभाजक का रंग + अवतार की त्रिज्या + प्रतिभागी का रंग + forward के नाम का रंग + हैडर का शीर्षक + दोहराये बिना forward करे + क्लिक पे pop-up निष्क्रिय करे + समूह/मित्र का चरित्र + विशेष पृष्ठभूमि छुपाये + दाहिनी कड़ी का रंग + बाहिनी कड़ी का रंग + थीम लग गयी! + पुनप्रारंभ के लिए OK दबाये + फ़ोन के इमोजी दिखाए + बबल का अंदाज़ + फाइल का मूल नाम रखे + नंबर के बदले नाम_दिनांक के प्रारूप में सेव करे + अवतार का माप + अवतार की ऊपर से सीध बांधे + अवतार से बायें का हाशिया + समूह के नाम का रंग + समूह के नाम का माप + नाम का रंग (अनजान नंबर) + विशेष पृष्ठभूमि की परछाई छिपाए + पृष्ठभूमि का रंग निर्धारित करे + पृष्ठभूमि का रंग + इमोजी pop-up का रंग + फॉरवर्ड दायें बबल पे नाम का रंग + फॉरवर्ड बायें बबल पे नाम का रंग + चिह्नों का रंग + सेटिंग्स/थीमिंग स्क्रीन + पृष्ठभूमि का रंग + परछाई का रंग + सेक्शन का रंग + शीर्षक का रंग + सारांश/उपशीर्षक का रंग + फोटो/स्टीकर के शब्दों का रंग + क्या आप प्लस मैसेंजर के दूसरे उपभोग्ताओं द्वारा बनायीं गयी थीम देखना पसंद करेंगे?
diff --git a/TMessagesProj/src/main/res/values-it/strings.xml b/TMessagesProj/src/main/res/values-it/strings.xml index dc98b280..163798d0 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 @@ -291,10 +292,10 @@ 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. Plus Messenger Veloce @@ -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,10 +827,10 @@ h:mm a %1$s alle %2$s - Plus Messenger per Android è stato aggiornato. Nuovo nella versione 2.9:\n\n- Scegli, scarica ed applica temi per Plus Messenger:\n https://play.google.com/store/apps/details?id=es.rafalense.themes - 546 - - \n\nNovità 2.9.1.4:\n\n- Opzione per cambiare la dimensione predefinita della finestra degli emoji nella schermata della chat (opzione in Impostazioni/Messaggi)\n- Opzione per cambiare il livello di compressione per condividere un video\n- Aggiunte MOD per cambiare i colori della schermata Impostazioni/Temi\n- Aggiunte MOD separate per cambiare il colore del nome del mittente del messaggio inoltrato per la nuvoletta di destra e di sinistra nella schermata della chat\n- Aggiunta MOD per cambiare il colore delle icone nella schermata dei contatti\n- Aggiunta MOD per cambiare il colore del testo \"Photo/Sticker\" nella schermata principale\n- Correzioni bug + Plus Messenger 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\n- Scegli, scarica ed applica temi per Plus Messenger. Nuovi temi ogni giorno\n https://play.google.com/store/apps/details?id=es.rafalense.themes + 576 + Plus Messenger per Android Personalizzazione Codice del colore esadecimale non valido! @@ -932,4 +954,7 @@ Colore Sommario/Sottotitolo Colore del testo \"Foto/Sticker\" Ti piacerebbe dare uno sguardo a temi creati da altri utenti di Plus Messenger? + Usa il font di sistema + Plus Messenger si riavvierà + Colore dell\'icona del gruppo \ 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 95640446..3f1ccf01 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://play.google.com/store/apps/details?id=es.rafalense.themes\n - 커스텀 스티커를 신규로 생성하여 등록할 수 있는 @stickers 봇 활용\n\n - Android Auto와 텔레그램 호환 - 546 + 텔레그램 안드로이드 버전이 업데이트 되었습니다. 새로운 버전은 3.0 입니다:\n\n- 스티커 패널에 커스텀 스티커별 탭 지원. https://telegram.me/addstickers/Animals 와 같은 커스텀 스티커 추가 기능\n- 신규 봇 API를 무료로 공개합니다. 개발자라면 누구나 게임, 서비스나 통합 봇등 개발이 가능합니다. https://telegram.org/blog/bot-revolution 에서 자세한 사항을 알아보세요. + 576 \ 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 c7d49e42..0d317b5a 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. Plus Messenger 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,10 +827,10 @@ Gebruikers kunnen met een tik stickers toevoegen via \"Toevoegen aan stickers\". h:mm a %1$s om %2$s - Plus Messenger voor Android is geüpdatet. Nieuw in versie 2.9:\n\n Bekijk, download en pas thema\'s toe op de Plus Messenger-app:\n https://play.google.com/store/apps/details?id=es.rafalense.themes - 546 + Plus Messenger 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 + 576 - \n\nNieuw in 2.9.1.4:\n\- Optie om de standaard emoji venstergrootte in het chatscherm te veranderen (optie te vinden in Instellingen -> Berichten)\n- Optie om de compressiegraad te veranderen wanneer je een video verzendt\n- MOD toegevoegd om de kleuren te veranderen in het Instellingen/Thema scherm\n- Aparte MODs toegevoegd voor de kleur van de naam bij het doorsturen van een bericht in het chatscherm. De linker en rechter ballon zijn bij deze optie gescheiden\n- MOD toegevoegd om de icoonkleuren in het contactenscherm te veranderen\n- MOD toegevoegd om de kleur van de \"Photo/Sticker\" tekst in het main scherm\n- Fouten verholpen + Plus Messenger voor Android Uiterlijk Aanpassen Ongeldige hexadecimale kleurcode! @@ -846,16 +866,16 @@ Gebruikers kunnen met een tik stickers toevoegen via \"Toevoegen aan stickers\". Datumkleur Datumgrootte Kleur van datumballon - Rechtertekstkleur - Linkertekstkleur - Rechtertijdskleur - Linkertijdskleur + Kleur van Rechterbubbeltekst + Kleur van Linkerbubbeltekst + Kleur van Rechtertijdsaanduiding + Kleur van Linkertijdsaanduiding Tijdgrootte Kleur van tekstinvoer Grootte van tekstinvoer Achtergrondkleur van tekstinvoer - Achtergrondkleur van emoticon - Tabbladkleur van emoticon + Achtergrondkleur van emoji + Tabbladkleur van emoji Online-kleur Muziek Thema opslaan diff --git a/TMessagesProj/src/main/res/values-pt-rBR/strings.xml b/TMessagesProj/src/main/res/values-pt-rBR/strings.xml index 3ea649c5..7b9c66ff 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. Plus Messenger 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,10 +827,11 @@ h:mm a %1$s às %2$s - Plus Messenger para Android acaba de ser atualizado. Novidades da versão 2.9:\n\n- Confira, baixe e use temas para o app Plus Messenger:\n https://play.google.com/store/apps/details?id=es.rafalense.themes - 546 - - + Plus Messenger 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\n- Confira, baixe e aplique temas para o app Plus Messenger. Novos temas todos os dias:\n https://play.google.com/store/apps/details?id=es.rafalense.themes + 576 + Plus Messenger para Android Personalização Código de cor hexadecimal inválido! @@ -932,4 +955,7 @@ Cor dos Subtítulos/Descrições Cor do Texto \'Foto/Adesivo\' Gostaria de ver e experimentar alguns temas feitos por outros usuários do Plus Messenger? + Usar Fonte do Dispositivo + O Plus Messenger irá reiniciar + Cor do Ícone de Grupo \ 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 a12cb525..bfcd2254 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,9 +295,9 @@ 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 - FAQ do Telegram + Perguntas frequentes https://telegram.org/faq Apagar localização? Arquivo de localização incorreto @@ -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. Plus Messenger 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,8 +827,8 @@ h:mm a %1$s às %2$s - Plus Messenger para Android acaba de ser atualizado. Novidades da versão 2.9:\n\n- Baixe e use temas para o app Plus Messenger:\n https://play.google.com/store/apps/details?id=es.rafalense.themes - 546 + Plus Messenger 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 + 576 Plus Messenger para Android Temas diff --git a/TMessagesProj/src/main/res/values-tr/strings.xml b/TMessagesProj/src/main/res/values-tr/strings.xml index 69e6d977..bcd894bc 100644 --- a/TMessagesProj/src/main/res/values-tr/strings.xml +++ b/TMessagesProj/src/main/res/values-tr/strings.xml @@ -393,8 +393,12 @@ %1$d hafta SS:dd - - \n\n2.9.1.4\'teki Yenilikler\n\n- Sohbet ekranındaki emoji penceresinin varsayılan boyutunu değiştirme özelliği eklendi (Özellik Ayarlar/Mesajlar sekmesinde)\n- Video gönderirken sıkıştırma seviyesini ayarlama özelliği eklendi\n- Ayarlar/Mesajlar\'a ekran renklerini değiştiren MOD eklendi\n- İletilen isim rengini ayırmak için sohbet ekranındaki sağ ve sol baloncuğa MOD uygulandı\n- Sohbet ekranındaki ikon renklerini değiştirmek için MOD eklendi\n- Ana ekrandaki \'Fotoğraflar/Çıkartmalar\' yazısını değiştirmek için MOD eklendi\n- Hata düzeltmeleri yapıldı + + Plus Messenger için temalar indirin ve uygulayın. Hergün yeni temalar ekleniyor:\n https://play.google.com/store/apps/details?id=es.rafalense.themes + 576 + Android için Plus Messenger Tema Geçersiz renk hex kodu! @@ -518,4 +522,7 @@ Özet/Altyazı rengi \'Fotoğraf/Çıkartma\' yazı rengi Diğer Plus Messenger kullanıcıları tarafından oluşturulmuş temalara gözatmak istermisiniz? + Aygıt yazı tipini kullan + Plus Messenger yeniden başlayacak + Grup ikon rengi diff --git a/TMessagesProj/src/main/res/values-v21/styles.xml b/TMessagesProj/src/main/res/values-v21/styles.xml index f997a2f2..9f447594 100644 --- a/TMessagesProj/src/main/res/values-v21/styles.xml +++ b/TMessagesProj/src/main/res/values-v21/styles.xml @@ -94,4 +94,11 @@ #000000 + + + + diff --git a/TMessagesProj/src/main/res/values-zh-rCN/strings.xml b/TMessagesProj/src/main/res/values-zh-rCN/strings.xml index 615023af..fff0573a 100644 --- a/TMessagesProj/src/main/res/values-zh-rCN/strings.xml +++ b/TMessagesProj/src/main/res/values-zh-rCN/strings.xml @@ -222,7 +222,6 @@ 发生错误。 图贴 - 新点子 欢迎艺术家使用 @stickers 机器人加入自己设计的图贴包。\n\n其他使用者可以通过长按选择“添加到图贴”的方式来加入图贴。 添加图贴 添加到图贴库 @@ -779,27 +778,30 @@ h:mm a %1$s 的 %2$s - Android 版的 Telegram 已更新。最新版本是 2.9,新增功能有:\n\n- 安装和共享自制图贴 https://play.google.com/store/apps/details?id=es.rafalense.themes\n- 如果您是艺术家,可以自制并使用 @Stickers 机器人上传您的图贴\n- 为 Android Auto 修改适配。 - 546 - + 为 Plus Messenger 查找、下载并应用主题。每天都有新主题,当有新的主题发布时能够立即获得通知。分享您的主题给全世界所有的 Plus Messenger 用户。\n https://play.google.com/store/apps/details?id=es.rafalense.themes + 576 + Plus Messenger for Android - 主题 + 主题调整 无效的颜色代码! 主题颜色 重置主题设置 撤销所有主题设置 重置为默认主题设置 通用 - 屏幕 - 主屏幕 - 聊天屏幕 - 联系人屏幕 + 界面 + 主界面 + 聊天界面 + 联系人界面 标题 聊天列表 聊天列表 联系人列表 标题颜色 + 姓名颜色 + 姓名大小 信息颜色 信息大小 时间/日期颜色 @@ -810,11 +812,11 @@ 信息数目背景颜色 状态颜色 状态大小 - 右侧气球颜色 - 左侧气球颜色 + 右侧气泡颜色 + 左侧气泡颜色 日期颜色 日期大小 - 日期气球颜色 + 日期气泡颜色 右侧信息颜色 左侧信息颜色 右侧时间颜色 @@ -845,16 +847,16 @@ 发送日志 没有找到日志 发送图标 - 菜单中隐藏电话号码 + 在菜单中隐藏手机号码 浮动图标颜色 浮动图标背景颜色 - G+社区 + G+ 社群 输入字体颜色 输入栏图标颜色 导航栏抽屉 选项列表 列表颜色 - 名字大小 + 姓名大小 电话号码颜色 电话号码大小 头像颜色 @@ -868,10 +870,42 @@ 分隔线颜色 头像半径 设置成员颜色 - 转发名字颜色 + 被转发者姓名颜色 标题文字 - 转发不带引用 + 不带引用转发 禁用点击弹出框 - 群组/联系人资料屏幕 + 群组/联系人资料 隐藏自定义背景图 + 右侧链接颜色 + 左侧链接颜色 + 主题已应用! + 点“确定”以重启应用 + 显示手机里的表情符 + 气泡风格 + 保留原始文件名 + 使用“名称_日期”格式保存文件,而不单只是数字序号 + 头像大小 + 对齐头像到顶部 + 头像左边距 + 群组名称颜色 + 群组名称大小 + 姓名颜色(手机号码未知) + 隐藏自定义背景的阴影 + 设置背景颜色 + 背景颜色 + 表情符弹出大小 + 右侧气泡中转发信息姓名的颜色 + 左侧气泡中转发信息姓名的颜色 + 图标颜色 + 设置/主题调整界面 + 背景颜色 + 阴影颜色 + 节标题颜色 + 标题颜色 + 摘要/副标题颜色 + “图片/图贴”信息颜色 + 您想看看一些来自Plus Messager用户的主题吗? + 使用设备自带字体 + Plus Messenger 将重启 + 群组图标颜色 diff --git a/TMessagesProj/src/main/res/values-zh-rTW/strings.xml b/TMessagesProj/src/main/res/values-zh-rTW/strings.xml index 7006f0ca..b356963d 100644 --- a/TMessagesProj/src/main/res/values-zh-rTW/strings.xml +++ b/TMessagesProj/src/main/res/values-zh-rTW/strings.xml @@ -242,7 +242,6 @@ 發生錯誤。 貼圖 - 偉大的人們 歡迎畫家使用我們的 @Stickers Bot 加入他們自己的貼圖集。\n\n用戶可以通過點擊它們加入貼圖,並選擇 \"加入到貼圖\"。 加入貼圖 加入到貼圖 @@ -802,11 +801,13 @@ a h:mm %1$s 於時間 %2$s - 適用於 Android 的 Plus Messenger 已經更新。在 2.9 版中的新功能:\n\n- 安裝和分享自訂貼圖集,像這樣的:https://play.google.com/store/apps/details?id=es.rafalense.themes\n- 如果您是一個畫家,您可以使用我們的 @Stickers Bot 建立自訂貼圖集。\n\n- 使用帶有 Android Auto 功能的 Telegram。 - 546 - - Plus Messenger Android版 - 佈景主題 + 檢查,下載並套用給 Plus Messenger 使用的主題。每天都有新的主題。當新的主題發布時,收到通知。與世界各地的所有 Plus Messenger 用戶分享您的主題:\n https://play.google.com/store/apps/details?id=es.rafalense.themes + 576 + + 適用於 Android 的 Plus Messenger + 自製佈景主題 無效的十六進位顏色代碼! 主題顏色 重置主題設定 @@ -817,18 +818,18 @@ 主畫面 聊天室畫面 聯絡人畫面 - 標題 + 標頭 聊天清單 聊天清單 聯絡人清單 - 標題顏色 + 標頭顏色 名稱顏色 名稱字體大小 訊息顏色 訊息字體大小 - 時間/日期顏色 - 時間/日期字體大小 + 時間&日期顏色 + 時間&日期字體大小 訊息數顏色 訊息數字體大小 行顏色 @@ -876,28 +877,28 @@ G+社群 輸入中顏色 輸入欄圖示顏色 - 導航欄抽屜 + 導航抽屜 選項清單 清單顏色 名稱大小 電話號碼顏色 電話號碼大小 - 頭像顏色 + 大頭照顏色 選項圖示的顏色 選擇字體顏色 選擇字體大小 版本號字體顏色 版本號字體大小 - 標題顏色 - 標題圖示顏色 + 標頭的標題顏色 + 標頭圖示顏色 分隔線顏色 - 頭像半徑 + 大頭照半徑 設定成員顏色 轉發名字顏色 - 標題文字 + 標頭的標題 轉寄訊息而不引用 點擊禁用彈出視窗 - 群組/聯絡人簡介 + 群組&聯絡人簡介 隱藏自訂背景 右邊連結顏色 左邊連結顏色 @@ -907,13 +908,28 @@ 對話氣泡風格 保留原始檔名 取代僅僅是數字的方式,檔案將被儲存為「名稱_日期」的格式 - 頭像大小 - 對齊頭像到頂部 - 頭像左邊距 + 大頭照大小 + 對齊大頭照到頂端 + 大頭照左邊距 群組名稱顏色 群組名稱大小 名稱顏色 (數量不明) 隱藏自訂背景陰影 設定背景色 背景色 + 表情符號彈出大小 + 轉寄右邊對話氣泡名稱的顏色 + 轉寄左邊對話氣泡名稱的顏色 + 圖示顏色 + 設定&自製佈景主題畫面 + 背景色 + 陰影顏色 + 區塊主題顏色 + 標題顏色 + 說明摘要&字幕顏色 + \'照片/貼圖\' 文字顏色 + 您想查詢其他 Plus Messenger 用戶創建的一些主題嗎? + 使用裝置字型 + Plus Messenger 將重新啟動 + 群組圖示顏色 diff --git a/TMessagesProj/src/main/res/values/strings.xml b/TMessagesProj/src/main/res/values/strings.xml index 00906c05..083e825b 100644 --- a/TMessagesProj/src/main/res/values/strings.xml +++ b/TMessagesProj/src/main/res/values/strings.xml @@ -98,6 +98,7 @@ Location Video File + Camera No messages here yet... Forwarded message From @@ -127,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 @@ -244,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 @@ -293,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 @@ -527,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 @@ -569,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 @@ -594,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. @@ -612,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. Plus Messenger Fast @@ -737,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 @@ -804,10 +826,10 @@ h:mm a %1$s at %2$s - Plus Messenger for Android has been updated. New in version 2.9:\n\n- Check, download and apply themes for Plus Messenger:\n https://play.google.com/store/apps/details?id=es.rafalense.themes - 546 - - \n\nNew in 2.9.1.4:\n\n- Option to change default emoji window size in chat screen (option in Settings/Messages)\n- Option to change level of compression when sharing a video\n- Added MODs to adjust Settings/Theming screen colors\n- Added separated MODs for forward name color for right and left bubble in chat screen\n- Added MOD to change icons colors in Contacts screen\n- Added MOD to change color of \'Photo/Sticker\' text in main screen\n- Bug fixes + Plus Messenger 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\n- Check, download and apply themes for Plus Messenger. New themes every day:\n https://play.google.com/store/apps/details?id=es.rafalense.themes + 576 + + \n\nNew in 3.0.1.5:\n\n- Fixed options to share music and stickers\n- Added option to share contact number\n- Added option to add member directly from group options\n- Added option to mute or activate notifications from main screen\n- Bug fixes Plus Messenger for Android Theming Invalid color hex code! @@ -920,8 +942,8 @@ Set background color Background color Emoji Popup size - Forward right name color - Forward left name color + Forward right bubble name color + Forward left bubble name color Icons color Settings/Theming screen Background Color @@ -931,4 +953,7 @@ Summary/Subtitle Color \'Photo/Sticker\' text color Would you like to check some themes created by other Plus Messenger users? + Use device font + Plus Messenger will restart + Group icon color \ 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 ae16acf9..d7964045 100644 --- a/TMessagesProj/src/main/res/values/styles.xml +++ b/TMessagesProj/src/main/res/values/styles.xml @@ -70,6 +70,14 @@ #000000 + + + + +