From 1301c42afaf779330c50f6fbf8f45167d4a70235 Mon Sep 17 00:00:00 2001 From: Ilya Fedin Date: Sat, 3 Aug 2024 03:04:26 +0400 Subject: [PATCH 001/104] Add ada to macOS packaged action --- .github/workflows/mac_packaged.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/mac_packaged.yml b/.github/workflows/mac_packaged.yml index 3a37311e6..bc9f5dd4a 100644 --- a/.github/workflows/mac_packaged.yml +++ b/.github/workflows/mac_packaged.yml @@ -69,7 +69,7 @@ jobs: run: | brew update brew upgrade || true - brew install autoconf automake boost cmake ffmpeg@6 openal-soft openh264 openssl opus ninja pkg-config python qt yasm xz + brew install ada-url autoconf automake boost cmake ffmpeg@6 openal-soft openh264 openssl opus ninja pkg-config python qt yasm xz sudo xcode-select -s /Applications/Xcode.app/Contents/Developer xcodebuild -version > CACHE_KEY.txt From 2d1b1fbd449facb8ed4b65a2d6722c0cfe0ed516 Mon Sep 17 00:00:00 2001 From: Ilya Fedin Date: Sat, 3 Aug 2024 03:04:45 +0400 Subject: [PATCH 002/104] Ensure tdesktop builds after ada in snap --- snap/snapcraft.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index 8378b599f..11f78a28a 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -156,6 +156,7 @@ parts: craftctl default rm -rf "$CRAFT_PART_INSTALL/usr/share/icons" after: + - ada - ffmpeg - libjxl - qt From 9eb15f7b177589f33f8733d2807361276d160f7c Mon Sep 17 00:00:00 2001 From: Ilya Fedin Date: Sat, 3 Aug 2024 03:06:01 +0400 Subject: [PATCH 003/104] Move ada snap part to maintain alphabetical order --- snap/snapcraft.yaml | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index 11f78a28a..dfba0b01e 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -210,6 +210,24 @@ parts: after: - telegram + ada: + source: https://github.com/ada-url/ada.git + source-depth: 1 + source-tag: v2.9.0 + plugin: cmake + build-environment: + - LDFLAGS: ${LDFLAGS:+$LDFLAGS} -s + cmake-generator: Ninja + cmake-parameters: + - -DCMAKE_BUILD_TYPE=Release + - -DCMAKE_INSTALL_PREFIX=/usr + - -DADA_TESTING=OFF + - -DADA_TOOLS=OFF + prime: + - -./usr/include + - -./usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/cmake + - -./usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/*.a + ffmpeg: plugin: nil build-packages: @@ -489,21 +507,3 @@ parts: after: - ffmpeg - libjxl - - ada: - source: https://github.com/ada-url/ada.git - source-depth: 1 - source-tag: v2.9.0 - plugin: cmake - build-environment: - - LDFLAGS: ${LDFLAGS:+$LDFLAGS} -s - cmake-generator: Ninja - cmake-parameters: - - -DCMAKE_BUILD_TYPE=Release - - -DCMAKE_INSTALL_PREFIX=/usr - - -DADA_TESTING=OFF - - -DADA_TOOLS=OFF - prime: - - -./usr/include - - -./usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/cmake - - -./usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/*.a From 916926bfa66faa703bfe57fd5e7350021b13fc0e Mon Sep 17 00:00:00 2001 From: Ilya Fedin Date: Tue, 13 Aug 2024 03:04:06 +0400 Subject: [PATCH 004/104] Fix default export directory in flatpak --- Telegram/SourceFiles/boxes/download_path_box.cpp | 4 ++-- Telegram/SourceFiles/core/application.cpp | 14 ++++++-------- Telegram/SourceFiles/core/application.h | 2 +- .../export/view/export_view_settings.cpp | 4 ++++ Telegram/SourceFiles/settings/settings_chat.cpp | 2 +- 5 files changed, 14 insertions(+), 12 deletions(-) diff --git a/Telegram/SourceFiles/boxes/download_path_box.cpp b/Telegram/SourceFiles/boxes/download_path_box.cpp index f61c0e6e7..a5e15f317 100644 --- a/Telegram/SourceFiles/boxes/download_path_box.cpp +++ b/Telegram/SourceFiles/boxes/download_path_box.cpp @@ -25,7 +25,7 @@ DownloadPathBox::DownloadPathBox( , _path(Core::App().settings().downloadPath()) , _pathBookmark(Core::App().settings().downloadPathBookmark()) , _group(std::make_shared>(typeFromPath(_path))) -, _default(Core::App().canReadDefaultDownloadPath(true) +, _default(Core::App().canReadDefaultDownloadPath() ? object_ptr>( this, _group, @@ -149,7 +149,7 @@ void DownloadPathBox::setPathText(const QString &text) { DownloadPathBox::Directory DownloadPathBox::typeFromPath( const QString &path) { if (path.isEmpty()) { - return Core::App().canReadDefaultDownloadPath(true) + return Core::App().canReadDefaultDownloadPath() ? Directory::Downloads : Directory::Temp; } else if (path == FileDialog::Tmp()) { diff --git a/Telegram/SourceFiles/core/application.cpp b/Telegram/SourceFiles/core/application.cpp index 39b7ac32f..bd1a17475 100644 --- a/Telegram/SourceFiles/core/application.cpp +++ b/Telegram/SourceFiles/core/application.cpp @@ -737,14 +737,12 @@ void Application::saveSettings() { Local::writeSettings(); } -bool Application::canReadDefaultDownloadPath(bool always) const { - if (KSandbox::isInside() - && (always || settings().downloadPath().isEmpty())) { - const auto path = QStandardPaths::writableLocation( - QStandardPaths::DownloadLocation); - return base::CanReadDirectory(path); - } - return true; +bool Application::canReadDefaultDownloadPath() const { + return KSandbox::isInside() + ? base::CanReadDirectory( + QStandardPaths::writableLocation( + QStandardPaths::DownloadLocation)) + : true; } bool Application::canSaveFileWithoutAskingForPath() const { diff --git a/Telegram/SourceFiles/core/application.h b/Telegram/SourceFiles/core/application.h index 373ba3546..bfb330d35 100644 --- a/Telegram/SourceFiles/core/application.h +++ b/Telegram/SourceFiles/core/application.h @@ -209,7 +209,7 @@ public: void saveSettingsDelayed(crl::time delay = kDefaultSaveDelay); void saveSettings(); - [[nodiscard]] bool canReadDefaultDownloadPath(bool always = false) const; + [[nodiscard]] bool canReadDefaultDownloadPath() const; [[nodiscard]] bool canSaveFileWithoutAskingForPath() const; // Fallback config and proxy. diff --git a/Telegram/SourceFiles/export/view/export_view_settings.cpp b/Telegram/SourceFiles/export/view/export_view_settings.cpp index 6cd12298f..73c8908a3 100644 --- a/Telegram/SourceFiles/export/view/export_view_settings.cpp +++ b/Telegram/SourceFiles/export/view/export_view_settings.cpp @@ -294,7 +294,9 @@ void SettingsWidget::addLocationLabel( }) | rpl::distinct_until_changed( ) | rpl::map([=](const QString &path) { const auto text = IsDefaultPath(_session, path) + ? Core::App().canReadDefaultDownloadPath() ? u"Downloads/"_q + File::DefaultDownloadPathFolder(_session) + : tr::lng_download_path_temp(tr::now) : path; return Ui::Text::Link( QDir::toNativeSeparators(text), @@ -341,7 +343,9 @@ void SettingsWidget::addFormatAndLocationLabel( }) | rpl::distinct_until_changed( ) | rpl::map([=](const QString &path) { const auto text = IsDefaultPath(_session, path) + ? Core::App().canReadDefaultDownloadPath() ? u"Downloads/"_q + File::DefaultDownloadPathFolder(_session) + : tr::lng_download_path_temp(tr::now) : path; return Ui::Text::Link( QDir::toNativeSeparators(text), diff --git a/Telegram/SourceFiles/settings/settings_chat.cpp b/Telegram/SourceFiles/settings/settings_chat.cpp index 9b2222b0e..9d6203c13 100644 --- a/Telegram/SourceFiles/settings/settings_chat.cpp +++ b/Telegram/SourceFiles/settings/settings_chat.cpp @@ -1106,7 +1106,7 @@ void SetupDataStorage( auto pathtext = Core::App().settings().downloadPathValue( ) | rpl::map([](const QString &text) { if (text.isEmpty()) { - return Core::App().canReadDefaultDownloadPath(true) + return Core::App().canReadDefaultDownloadPath() ? tr::lng_download_path_default(tr::now) : tr::lng_download_path_temp(tr::now); } else if (text == FileDialog::Tmp()) { From fe86f5d0500b35081ccdc3d893ca5dd70025ff9a Mon Sep 17 00:00:00 2001 From: Ilya Fedin Date: Thu, 1 Aug 2024 13:51:59 +0400 Subject: [PATCH 005/104] Check IV support early --- Telegram/SourceFiles/core/application.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Telegram/SourceFiles/core/application.cpp b/Telegram/SourceFiles/core/application.cpp index bd1a17475..d7df2a9e6 100644 --- a/Telegram/SourceFiles/core/application.cpp +++ b/Telegram/SourceFiles/core/application.cpp @@ -48,6 +48,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "countries/countries_manager.h" #include "iv/iv_delegate_impl.h" #include "iv/iv_instance.h" +#include "iv/iv_data.h" #include "lang/lang_file_parser.h" #include "lang/lang_translator.h" #include "lang/lang_cloud_manager.h" @@ -336,6 +337,9 @@ void Application::run() { // Create mime database, so it won't be slow later. QMimeDatabase().mimeTypeForName(u"text/plain"_q); + // Check now to avoid re-entrance later. + [[maybe_unused]] const auto ivSupported = Iv::ShowButton(); + _windows.emplace(nullptr, std::make_unique()); setLastActiveWindow(_windows.front().second.get()); _windowInSettings = _lastActivePrimaryWindow = _lastActiveWindow; From 6148fb947427f62463b8a856e3c3e56c3062825e Mon Sep 17 00:00:00 2001 From: Ilya Fedin Date: Tue, 13 Aug 2024 18:07:57 +0400 Subject: [PATCH 006/104] Use CMAKE_CXX_COMPILER_FRONTEND_VARIANT --- Telegram/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Telegram/CMakeLists.txt b/Telegram/CMakeLists.txt index 8923211da..d3fc32100 100644 --- a/Telegram/CMakeLists.txt +++ b/Telegram/CMakeLists.txt @@ -1820,7 +1820,7 @@ endif() set_target_properties(Telegram PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${output_folder}) -if (WIN32) +if (WIN32 AND CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC") target_link_libraries(Telegram PRIVATE delayimp @@ -1917,7 +1917,7 @@ if (NOT DESKTOP_APP_DISABLE_AUTOUPDATE AND NOT build_macstore AND NOT build_wins base/platform/win/base_windows_safe_library.h ) target_include_directories(Updater PRIVATE ${lib_base_loc}) - if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") + if (CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC") target_link_libraries(Updater PRIVATE delayimp From c985b77a481e80821c0f6de3e02adca1f05191da Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Mon, 5 Aug 2024 18:53:24 +0300 Subject: [PATCH 007/104] Removed event filter from input field in edit peer info box on close. --- .../boxes/peers/edit_peer_info_box.cpp | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp b/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp index 0ba6354f9..88464ed1c 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp +++ b/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp @@ -620,13 +620,17 @@ object_ptr Controller::createTitleEdit() { local.x() + emojiToggle->width() * 3); }; - base::install_event_filter(container, [=](not_null event) { - const auto type = event->type(); - if (type == QEvent::Move || type == QEvent::Resize) { - crl::on_main(field, [=] { updateEmojiPanelGeometry(); }); - } - return base::EventFilterResult::Continue; - }); + + field->lifetime().make_state>([&] { + return base::install_event_filter(container, [=]( + not_null event) { + const auto type = event->type(); + if (type == QEvent::Move || type == QEvent::Resize) { + crl::on_main(field, [=] { updateEmojiPanelGeometry(); }); + } + return base::EventFilterResult::Continue; + }); + }()); field->widthValue() | rpl::start_with_next([=](int width) { const auto &p = st::editPeerTitleEmojiPosition; From c4f45c4b7c8646beec52392222a22aa9e868dabd Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Mon, 5 Aug 2024 19:00:16 +0300 Subject: [PATCH 008/104] Fixed resizing of label in section of profile info. --- .../SourceFiles/info/profile/info_profile_text.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Telegram/SourceFiles/info/profile/info_profile_text.cpp b/Telegram/SourceFiles/info/profile/info_profile_text.cpp index b09e35484..bfca3d053 100644 --- a/Telegram/SourceFiles/info/profile/info_profile_text.cpp +++ b/Telegram/SourceFiles/info/profile/info_profile_text.cpp @@ -29,11 +29,9 @@ TextWithLabel CreateTextWithLabel( parent, object_ptr(parent), padding); - result->setDuration( - st::infoSlideDuration - ); + result->setDuration(st::infoSlideDuration); auto layout = result->entity(); - auto nonEmptyText = std::move( + auto nonEmptyText = rpl::duplicate( text ) | rpl::before_next([slide = result.data()]( const TextWithEntities &value) { @@ -46,10 +44,13 @@ TextWithLabel CreateTextWithLabel( const TextWithEntities &value) { slide->show(anim::type::normal); }); - auto labeled = layout->add(object_ptr( + const auto labeled = layout->add(object_ptr( layout, std::move(nonEmptyText), textSt)); + std::move(text) | rpl::start_with_next([=] { + labeled->resizeToWidth(layout->width()); + }, labeled->lifetime()); labeled->setSelectable(true); layout->add(Ui::CreateSkipWidget(layout, st::infoLabelSkip)); const auto subtext = layout->add(object_ptr( From efc8417ab1efa33393007b21d8409bdc9bad0afd Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Mon, 5 Aug 2024 20:26:47 +0300 Subject: [PATCH 009/104] Improved text size in list of credits options. --- Telegram/SourceFiles/boxes/gift_credits_box.cpp | 1 + .../settings/settings_credits_graphics.cpp | 15 +++++++-------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Telegram/SourceFiles/boxes/gift_credits_box.cpp b/Telegram/SourceFiles/boxes/gift_credits_box.cpp index a2e36038a..0b20d498e 100644 --- a/Telegram/SourceFiles/boxes/gift_credits_box.cpp +++ b/Telegram/SourceFiles/boxes/gift_credits_box.cpp @@ -39,6 +39,7 @@ void GiftCreditsBox( not_null box, not_null peer, Fn gifted) { + box->setWidth(st::boxWideWidth); box->setStyle(st::creditsGiftBox); box->setNoContentMargin(true); box->addButton(tr::lng_create_group_back(), [=] { box->closeBox(); }); diff --git a/Telegram/SourceFiles/settings/settings_credits_graphics.cpp b/Telegram/SourceFiles/settings/settings_credits_graphics.cpp index a8c63b5f8..c620f19d9 100644 --- a/Telegram/SourceFiles/settings/settings_credits_graphics.cpp +++ b/Telegram/SourceFiles/settings/settings_credits_graphics.cpp @@ -256,7 +256,7 @@ void FillCreditOptions( const auto &st = st::creditsTopupButton; const auto diffBetweenTextAndStar = st.padding.left() - st.iconLeft - - singleStarWidth; + - int(singleStarWidth * 1.5); const auto buttonHeight = st.height + rect::m::sum::v(st.padding); const auto minCredits = (!options.empty() && (minimumCredits > options.back().credits)) @@ -283,26 +283,25 @@ void FillCreditOptions( st::creditsTopupPrice); const auto inner = Ui::CreateChild(button); const auto stars = Ui::GenerateStars(st.height, (i + 1)); + const auto textLeft = diffBetweenTextAndStar + + stars.width() / style::DevicePixelRatio(); inner->paintRequest( ) | rpl::start_with_next([=](const QRect &rect) { auto p = QPainter(inner); p.drawImage(0, 0, stars); - const auto textLeft = diffBetweenTextAndStar - + stars.width() / style::DevicePixelRatio(); p.setPen(st.textFg); text->draw(p, { .position = QPoint(textLeft, 0), .availableWidth = inner->width() - textLeft, + .elisionLines = 1, }); }, inner->lifetime()); - button->sizeValue( - ) | rpl::start_with_next([=](const QSize &size) { + button->widthValue( + ) | rpl::start_with_next([=](int width) { price->moveToRight(st.padding.right(), st.padding.top()); inner->moveToLeft(st.iconLeft, st.padding.top()); inner->resize( - size.width() - - rect::m::sum::h(st.padding) - - price->width(), + width - price->width() - st.padding.left(), buttonHeight); }, button->lifetime()); button->setClickedCallback([=] { From ba99706e75c10b9cb8c4baf331de76f03179ed8a Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Mon, 5 Aug 2024 21:01:39 +0300 Subject: [PATCH 010/104] Fixed indents in qrc file. --- Telegram/Resources/qrc/telegram/animations.qrc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Telegram/Resources/qrc/telegram/animations.qrc b/Telegram/Resources/qrc/telegram/animations.qrc index 16920ae4d..af3e89fb6 100644 --- a/Telegram/Resources/qrc/telegram/animations.qrc +++ b/Telegram/Resources/qrc/telegram/animations.qrc @@ -15,12 +15,12 @@ ../../animations/voice_ttl_start.tgs ../../animations/palette.tgs ../../animations/sleep.tgs - ../../animations/greeting.tgs - ../../animations/location.tgs - ../../animations/robot.tgs - ../../animations/writing.tgs - ../../animations/hours.tgs - ../../animations/phone.tgs + ../../animations/greeting.tgs + ../../animations/location.tgs + ../../animations/robot.tgs + ../../animations/writing.tgs + ../../animations/hours.tgs + ../../animations/phone.tgs ../../animations/chat_link.tgs ../../animations/collectible_username.tgs ../../animations/collectible_phone.tgs From 89dc18aaea38045d60566161fda140722ae1c378 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Mon, 5 Aug 2024 21:01:25 +0300 Subject: [PATCH 011/104] Added mode animations to loading screen from different stats. --- .../Resources/animations/stats_boosts.tgs | Bin 0 -> 33261 bytes Telegram/Resources/animations/stats_earn.tgs | Bin 0 -> 60056 bytes Telegram/Resources/langs/lang.strings | 4 ++++ .../Resources/qrc/telegram/animations.qrc | 2 ++ .../info/bot/earn/info_bot_earn_list.cpp | 1 + .../boosts/info_boosts_inner_widget.cpp | 1 + .../earn/info_channel_earn_list.cpp | 1 + .../info_statistics_inner_widget.cpp | 21 +++++++++++++++--- .../statistics/info_statistics_inner_widget.h | 7 ++++++ 9 files changed, 34 insertions(+), 3 deletions(-) create mode 100644 Telegram/Resources/animations/stats_boosts.tgs create mode 100644 Telegram/Resources/animations/stats_earn.tgs diff --git a/Telegram/Resources/animations/stats_boosts.tgs b/Telegram/Resources/animations/stats_boosts.tgs new file mode 100644 index 0000000000000000000000000000000000000000..10ba08cf203eeb0cd71a0385f6653bafd79b550e GIT binary patch literal 33261 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�L~> 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

jGJdwtLtTt##nIW0^ncf64CP%r~ar2QZs zKNQr)dj-hi>qX)p6vvUu(6y1O@Aw}lm%U0~MygCv5#CGt9lcgj*Bo)P{Q3TiDAHO! zl+CwvzMy3=0xqBj@>;9gzL5bL8*6+f2I|!^Ld^g4bS1%!-Syo1!Ck`pJ9Edy!e#%x zENZ_q177=AX`8HNxMSVsqX)Cvl&=2Mhw~eG&g~VSnfo~n&@*Z$(SI8kB@k-mveNcO zpksjT+%57Z$g+5>zDaI07E307<6+Mt>sp>xxwAI)e_skM9mbUpGnGZlmzb z>uuE5?r$THw>knnE^Y2Y@KHY8Mg?}F$6|eQbi!+0?*fpu`0i}=7?a&(tHEM2AUKbA zfgtx528!N~1C2j+;Q<&YEg7Mwz(e&$^hTWlTL-j4qjvt0xPqh|`^iZhK$%faD5)H7 z1j3lN_dzri%1MlaIjC|t_yCU;5*_}cMmtjl=%8TJNtrUN*slCn*olWa9dD)AYqv7C zd}X1j-A)qA@1becR3C~cav>esp#SfGs18P9Y90X+DLMLA{csC!mlKRNOJSYK||FREgB6AwL1nC5TqBLe!x3)z-o zNPq9^S01+s?5PvQj5f8_^+mO8kZGbQH4{jy^YrEV`;tN8Cm{z1pKAiATeYZ$s5Lg%OMn-1{h zB%K(+BH`S%(K*(;ab}1&@20D?3UTjtKpugIfXcne&tRA)w%rYX-(a}Tck0v0yC+AQ z0pCKP@@+5~^81mNlV5J9vLr?gp|HH1PX9d!0Oe*_T96{Za;ZXORoaLX<=4Jq8zp8k z^Twp!4$%m?$lc%ASj@}CRG9ah!!jfqVJ^$aOHwtb1b#N$9Lg1ko1+pVhO*0FB3!>t zr(#;{&rYZ4^8IvjL=GON6Z|9&^C<#A{N{Z6$gau>mD|(@XK7~SsqyiI>ghmRL026( z@{kT|9rhd$Buwk85IuSACOUx+I%im!T*?!-SI(#?s3E3&k$qu(IHSbJ-0z1P1ppl` zw*#&ahg@n#59_==Ang3|0iakVJ+sMvtL^2u)rN;#ZTMQ#nFN4)%Bm|-zigr_XZW%I zZ%#h~Ga-M-HrD^eQl8a7LMaW3iemu}55G-#yCU4PBg%XY-?1Kj4Y%pJi zPr?hAvz#n8Kyk5L=$($VPId+J-@V|cPD;~n91f7wO3-gz>U(_YvhvM)Vovf+?EBw^ zM!^y_L&}SdL*u!iZ`zj+>=&(CRe2uKfe;YZ;dS@P_>CNMI9)JHA{-_2{uQLVCGLM0 zz=NYbEc9=o_O=1cli5$$2mD0?8o94WoL6BriJQO2_su@{#29OgV)~!DWW?$kfPoh7 z_`$0~fgQ<-e|ZpB`!!Y|$_7H(&c8m2!A$MXjN)jLc3ZLpa9T9e=(k33V%IZRkJM3k zGPL_)46s9c$1v_b-wk7Li0~1`5bj>GlFo>_e640#L6-*_k9e;10FpE4nIB*U;Fv{I zC@&v?V=;#;ZC4(A;yk5ZMVle(Bem(jgo4Hei$__;@U+U<#&EQOv5n#V1C8N4qqRAP zoq0)E&UEwl_)I~cb5Cf~dKc!XUW z32bbwJe(BE5bp4=g(pwk*Up&Pzy(_W?GX&JQ{bj+-)0wW*=Lb37c!{&n@7v$&x43_ z55$3`8R2;4<7p?$LKGy|CPmck1N%W~rbTFf11;c}tmXD^ zz(Q%Lsyu-uSHt|ro&+kwj~lT)4x521MR-p*W6h-74>2d zmv%Ze&=5&1a*=MkNJtrqpIMI_p)NKo3RV5CdSaL6pZ0yo5~uyoUZ>EuWvX`{kP^VZ z!Do@7c8Es(1egH9O|risAy62S+jDYbm?XbRufUWouOILi0JBN(K!1bxW3)%rr0+gx zxa+TQjYIg=unu=;D?{jovBcwHifVZauZ?4Z@USZ<(^qZ$#dSiD9*t$Z9Q2lRsILuW zE@z60{eGwj=bv;DqxS8w+}OyTV;M#C3gnvkYt3)LnU!=$SKmD57yxMXqKvuNnRQRI zp$Kr2w>3Feft5_LprpfqMj^}8lsSSM8Y+!ZtWoOiCv!~CzxOe06^gqLwm}UHDE3C2 zM5rGdo}xrG1~LgGNM|mOVhOsN00o# zah#znJ0@Fqbfo+e$3KW#>@jluffnp5F*26!{&bL>h$DL~NY2Q<@^e8l-q3B3ED`@_ zgXBOFVKOl8d5wxaC*B$+j~}d2GKkw-P^^~J?cZ+( z$sa10!BGrNW#N1AXb~gV$1w)s&e+picqK+wU6-ZXPV8HLVTnUDml{Ki65AUgMr4d! zOIeE*o}}7Po(M5uHz70iEk+hfdQSu4`i2POi4}Pag{CZTEmv18n~4aiq~wP9F`}&0 zjpy1qwJo4$jtX6ACLA(`PynEP`=CNp1*6lOy2|{3^59krE8H6HKS8z4Y7;mvihOx$ zepLB_Gg!8`0pbUE!m4Qkg(_0C^Z_btz4P)nzmG)!|(+gu5i6GhkrM*&d6XYxc*5K)%9$pA7pj;yT{^s6Vh5-ddFcJ3^7j~MN z7`xh@7{m%PgJofilS^%fb(+O?#K~_@3It=)Fe+`2D@tM7gLAdKHDQScH1#e14anR? znfqWnewKnzcX9vQzTb#V-~R>}vgW1YeD}c!PfWHEex%@zq8RVn{uQb-g#GVQW*m&* zfq}Bun=GsquOILSjhMdWfKFxat@V8KH<*#NJyjL|RSEw3N^rfY1lM<0g6mBsxc)4a z;ClD>qe}3x9TFdcF#quH|2uzjgEh^qg_y@mKxc_C{yU7UGy+df$JI1uWE<+q+8;s!iyuUZC^t&JS__gR#7|((Nm54Pz_eST@`-3a+B9K? zB4IBPPR8((B!VPsu%;kxsaQEISTN0mE|@>uQW|v?{nVI5Vol;$6$lMTI0sy|oPsCS)Pzm+3!j9LkmB1{Am=vT8?y22 zO)e8UFFtyrHkevKwT;AD(Gx?ZjGhO8kNF5FFerAR@h<(zM2rD;eUTMGiHyYhWz_(j zM88s(!R|OHxK@Rsg&d|(MrLydCM`#@O!^{*Ea?Z^5L!8k$G5yp++$QGKL)|83Q8=uL>FwV|QUzO= zj1O=lF65<v?RC1EJ}N z*75Q5(rU!qIaTQOJm%xrCZ~9HdKmUBY;MjcvCqw{0+P+mK2!8woC*aZ&tYph^!4@-ShEQkp_M*X{rYUfbklQr1G^83+1s)T!5(YKXufPpdTc#@U z7ck+ISqPF)RO7S=5b1BjgvxoiZ}qztru%-&@4`E`33*Z>`tk;;Ov zp2d6=_9V6kFR;W8g~}&!Zm{m908wnihywJNF&6#IB$TR>Bk~ zYJIHfiA8J}qFQ8vHU%CO9OE>jTcmz9=D)Gx5T_s+Kt;A&x?K^^V7n4qBBSIsh7xw< zETLvxW4(|d%AFBK)Dh-X9E9_;G*;!YY7-X*&5MG@bd*HSm>y#wF~KSl{_WsSbMt}b zwW({cD8?;2oXyO@>tdp11BC&c=Miim3Jy_Um^cQf!Oln|d1~DM1~hR>ibf%(13xJpf0#n0P~A2_8h`q#1xm9SDD9 zS&)BqX%vuof_dMg@r$W^2SUO=Kd}%tM4={esb{f03i@9(?&E%H#&%*@HAJp@7~8YJ zY%9=tkQ9L)#e5R>AhzcKgn$eygXSkyvbDNUJ&hr5vn#Wil}wm5Py&TM6I`93uh^7| zmhWkOgD{0Eu!tFQxBmhn{}WiQM+n9MT=?2ZYNoWt=&X< zmmo*5XnK}leHONNyor*J2^>ePRr;nIUD3S=m+no=m@^?jAcVc|B982sy_lMcDxggQ zLV^!ghsGiR2@N0!vP z=A*DDu{{Wqp{X6My^v`$v370d*HtBmcKW5W1#U4P5UXv`rEX13LbyDIhn`3cP z$iUXg1;CE+j@dc37AovFi!-@#f?^F|S~JReWkN{R-Duk@j2VCy$)*}I{>@VWy(H6T zx`Oi!i4sWUdrN~Os~(Fpx+w9|!S-swv^e>&~d z^H|eP7?Uq)Cu%@T)=62NJ?mtDcFQ{PC}!4)2eCbeRL!SiCY?~b4acO@=R?vN^D*f} z*nLPkUGvARlQr&Bvd-3-2p+Re)Wh;I>qPL-4q0d9NtdiMVjV4O)|tQ?X?xb$DxF#O ztP^1eg+*X7$ls_ zj_F7utwzGV+Edsbf<#*AnLa%bplpH#L-j;Hi0wH5RyD4?f-a+QJ6`5fu!pccgOPVT z&Z!^Xtm8}R+A-&p%rc|#CS@MGW}MKrWCsSbR0y+x+{l*-#Q;#Qt5fCm69k%NX8%)a zr9`iMb0t$1#(o@n_R2iPWO)2I!<|54FOdbYTfrT4ze10MWbC1wq`Hn=UAt`{Kq1b` z_t-vA)TKeVtsVfuj7YLWLdKBj4(1_{wNiSXILT?2q-FymS0Json3paIkq9`&s|bR{ z|BCW43RsBo(DQ_{p=eDOlABgd73&k8JE88X{dXn?Xb$_cVFj$3%lXe)4<&UitP%$B z(n_OmGn}Klwo^f@ypin3^Gu3w8CZ3bHNqI9OSdIGkQ(etHLGGAh^vrAHQOg}jw0$! zsV3Cqv5=c$J&{=iC(=h7gmfp)TF{gbi(bd!q<3cMW?+I?;&W`oTz zgI9YJ+k+tUoAo9$2xLQ+{gh(=9;nA-&w?{8V1twfB%j566!s*x2Z8EPmN8B=m^hGt z2sfii6r{qmVr%B`Nh9AZR{W{law~NxR4;Opbc>T8%Q8kXlq6axrK^Qv_65isW=z|c zm=?04Re_tgX93DM*I;ah7Uqsu(N*a*h?$D8g+Xo0Hanxpm#E_D11cc_zaGuI64CM4 z?fbS|cPKapc2Tq;LOm405fV;KEpSVn5>BZj6-S=|B%G@2&}ye5;mm0kdQe@24Z2+B zux?y%w;K4Nax?-|D@C|EYg^DNOlD8y9i#oR20w$A_|>xf>$fb^ua@QCV$1RwX|n(P zpN}9QX{5idj)1)f%7^vjeJ#1u7{>lBCLlszM1cI);j=bA`S<^e1l)iBSN^{h8}fht z&p-dizy0&O&><#{jXbi(?~M)#-vu4w=r{g3RJryUtUzu0wo_8 zlvxR+ftV8SdvFsGtz|AL))JEbDU@@Cm$Fk{w{uPh#i;N(qkyIL0WF!P6iOP-nAgzw zf%=Agz#`oOve}!VUIf2CL{N+VO_RQb9VB5PCYhZ|$Iu%!avlk|;&G}7-|%3GVIwgps^ti)?ITBVtE zHoekQOM|}V2FrZZ|I4rS{}M~g-dX1$v#>d#r^@ zxs&{okw1zC3=$Gh9K@a~E)I;*pjr~@SE$<2E0!CXQ zWRE;3r98rYp0VXy@HdYwrzOzs)F26L5fc*i;s-X5k$I zOK^eJ8iP6my`2m%;-Tlw>Rr~l2tGCzVKhctwp!l>72o`7>;@FutlmzU zr*#*jFmzjXF+lI*x{U={^6uLh=zx*7xF+3<|3DqYy|Isdq$CZJkAU@kg6^V!UmY3h zgeW1XR2Nv>WJ;(aPNrmJW{R`DF5-h2naCZ0XMM74i>e^Sp%Knl)u}M4tVTR$ago(e zR3Y~lmZ8_Dp+B)sP=%IBah+{XFY9e64mA_MCe;uW7v*(Pu6EVTO1%7)c-%hC1ze<- zS7NW~+BKiJ6d1jdm;#=qz&9Ziv<~~+eIiqwLz!HuW zRkY3uJnUtWL&9yWHf7<3a1U%_6TqhT4J1L2&+&bJrB%OOTJ_uLt=A+Wb+`;Uy2?W) zHV7?A9rZ?w+)gVGey2!T9seuO2o!|e_B(p!>Z|cYyHafbz%NAsfOfl5M}_^4{^^Zz zUySh+*{PRDF~ZoG?~DRju-?uWG3elKUOtgyDG7lF|8j>qwhq19X(H4jiTg8ILez%q zu`SfqH4ul_(f2a~3JZhU&xW{8z|?@q0L$`zQbNmliv76)NQeC{hffD-*3=JZspXn+JWD{{=wJuMj z$hW%GTU$|2Y|Y1~6xL-n)eq;xp>^clrIHp-4<_(?<`c1ASdM$Bt0!iKgZy#+Hm-F~ zdhot5onSfVnUJ7RyWJgyciqu_cSPWq_{#G19xu~E$+Z-g2a3aAtApJCVTCedN6PfO4+ zHr2z97!hUM71?9KPGA1=*!iQoca-ymt4dzM-M231$6sX6U!BumWY1q@&%YD0r>AqI zmxB2(vL`T2QN@(zf3ZD(u|0pWJ%6!1f3ZD(u|0pWJ%6!1f3ZFP%4|=vvw}4zeiOE5 z`<84^7pf*_`9=5qMfdzU>7K|m(wcbwJ<~nqBYsFbf6+aE(LH}#x~C_N5PN2fzv!Nb zc@yK8s3ZJhd;Vg3{$hLnVtf8#d;Vg3{$hLn>REn2w&$mTk$0fTHbx*qJdABPonZP@ zeha1%`U|kuMkr+3eu2Ws$xuinliZ(JrQT6x6w7Zr{Dx4HkHa4eeQO=o#_cQ+ub<$a z{e%yr6a2?pS^ex-J-nmkTz7X;wqq3@>%k+#e;w=Y?>@^1(2bAY47Y)F0I0&12%kKA zSFcq>B2S8lA=Gz0yr+`7M@L_7U>gnFO@4SVY!T~|?`hq24?j5(A&KgBXgAk_y_zty z9!{ETBkrL?W_aNpu4nx8WP5l|9~dw%bhjQJK456vqe>fYtG$9MeR}4hgsN`UVd~)o zZN-)%9Ma~U)8|3OU>J_Qpcpy9W{1vUr`WNO+ogPBHX<2~X#~;faK^)v+)=cNS8;#J zk4(yEN6k7bkH2{lbjf#i2ZcnM(UN}wbXmh6{x(Gv(sw~!2Khpv1E}_~(6uARQG{8Q zhoj}N5Vd9W!+)CfD9cpTI-bEVqG~f9EgL{##F4ZvRh0z>v}Ur{&PA=!xbnix9e!4md1q!!3GOmEe);CkU>;Za($pSdK`)agy~9NS5|I|8N+B$HT`~|9GC}KP z$fI59PlihbavSp$9?0xF^UhS-XKaq5OuxUg)HEEkYNv&seW5OQ2D*1K|Gi*ITo`!_ ziv(SXBirnuqj~cstnZ)W{yyBYyPb8B9kZuq9g1J!owH8H@9&>=A8C1v@CMMFG%JJ& z-J50FRbCvXUC4I}N@{(Zc0tC503huqxT1-od}j4W3J;){Ajli~t^kN(8v3(Yw?O)E zAu#pTH2Fa`E>Zj_7?-h?yIbpVAD3f%lOM9c&vw7SV0tKpmiB0Z%@TDbMcu?e-m1EN z<2~!Qp>w)WSdk!UljKZ@B;fi`qsXjhL{=|Qlz>6)81VS_kVxIczvviw`&G#EtA`qf zo%0G)PHz;tyk=fAih_VaL=Og?bsJ=lgSr;-zdRq+xytH(aOi*e?;X|U?-JEQp;>od$zlxIXUwjr0TaHQw#*Xa$N7y zZ2+V=vx^{%1O^KFFf6PV)siEo^H>g4D8x#^Lj9jM zuBE8==vbAV4+a*|HL-UnQGxkjCVWpoutX4{_CUA`qDH-t&z%8;iz#8u2Qvn`D+YF< zjU$kBLi54Nlzr6zzu|DQ>JxfEV6p}j`KLR1j~q3HkT7uIUB@I(3we_whj4CA~dJ2Vr8dkm>mO0vnL!gOYDiUJfNwD)eaO8 z04S@!s!8#Ypp-}jXM5BHO^&%jNKDPvg!B+@!QRmLaDpQc8%X+XMnSBnBCVIByeF&# zHMY3nVT)|+`vlH-jhwu=iwn~Pw|Nd6sGFg2L%5FIn9+uzbF4KJp;Sed2a0!J5Y;|@ zK#lDYbV6~Jo#lVD`iPKw?g2$~&jDSI20-xW*hM~qXP*yImPyZtT4bg{6M;7g?|MET zj*73UjvUt=VB7bFXT(<7zqRr-B4zfK2bUE0l?R$-@y(SdvJAN`JV2i3W!XT7$L#(*Ph6wFp;ND{S0c~HF36V-PxfyksM*RowZp7Mmu|_Y@CGN&Kawg zcB|mq&BDVl2X*iyIyp9{GG=6*Fn5B2kau;YF?=`(DcRQQ6d61>E+?LfUccU;1W4|^ zJcT7m>CBTLNkhxuTS#3ws}`UgFq1;K z<_TDgp0mmT{~r2|X~U-@#Uzu#B_Lj&3GDxd!p`XRaDpXHu&QL4;tK!_ZnH~# zk~ZR;_Gof}ZKI`p16Z>}VoReY7ln1kjqX?&dvzN4h%vL_Lxu~W(1l0V+N8)*GEDZ;Ng2p zQ0ZS^@lea7lpqRtI@Sn7J)yqM*r%0!)Ob@_NhsF@$$o(X1Nu@V#|Zj__+1Da#?O(f z2o^(h<@Bsz+$VM`Yy}TE+GzU=XhwdUjL0ELi`E6!~;(35{-$%zEL?Mu!v8Ned@#EO%} z2;WwmF<5=t7aaV&e`vw^ST5j%u?BAZK_(C!$)0dK+76k=R?CW#l_*hAz4LUy>u(=!3gKyBU0 z*V*PH13*f&L3u9n-Y9f8NS&BJYjuWl2cVD_O9VPVK0ePCjIBR}byNJ2jR8mE&XOjP z`;ogTRbqz(TYu!wt{9S5=~gu5R}OV#P92Z!xn$sPF;@9oZ4ivTH(668_(u%_Y)P3r zQm3HdtBF9&@5lte2Z7#h7Y*ZEX9DfpWCEF;W)YHXZb51mD(IM7n5AQ@#W2`+;{=*$ zAidm{-%K?SW7%NI3{`3}y)A8N(B?7KA~3;H?|>-pm@&~AG(#%Yj_Mlc2KR|HE=Yf< z*g>+^C77BrB5oHUIF5~YTRAdW;iUTux8KMVn6)FyVThdAS1w{A^^YzMqW)1FJI$yf zKslU@;&O7Nj;cE40R2vQ=3QpSO(@GoG~IL9Z&FtY5BLYdI|Q1v%L-|Q=P~MHlcr3Wl*Gxsxf0nM7?m22k^Xco7r3) zi-?pc2G2;?<*6sVR)A0@_KGegf6++Z!%C;ZlGgn|e*6~%(D(NWatgTT`5pI47E);O zUAKxL&-cri?^!MH=Wg}m@$mg5MY{6dNm{6=^X^Hi66^aX>W3oS{3D7lG{b(tSH|l~ z3Neu>gP^^>RDe4%O(mO@$vMAHoh0%zn_jB-3-2U?Dcq_4ZVZ|+bb>@7)I32#lo{LC z^TXBI5Sl6@olTcuTgBKy8piHO;MY_bZ3dJSxBx-Z$8(}?B;V47>a8^&b{FU6Cc@v5 zu{q|cpL9@MgNQV(Jr{cZESuxsFx-S|UuY~6J+3Q{D7>H!RbG!K$NB&8kIzSwuAq7| zUha78-yLt#zfClm$k@lyRPW~tfDA&ijW~UqFAxI&>2oR*-Od**{@N1yl6j)+p#D%X zP#nsxV@(&uuu&fjbLI66{3C&6{J|QV_1SLX$S#S;3=fX|7P;JEq3FFo2qQ^XypVak z_Ghd7HS(0HL!Ao>Ud)G8C}SbCgL8Xs9GOUhzHT(+n>ftjVA~BKF_0XOWDF=}KbXGv`4JFDSsf4ow$%I{nfXC<`M3Q)Ofx4hQ?WA%j zYT)*#P{nO18OaaCkag`4FDG(KVH0Cg5@R1Dztfud!HAyFtp9>Y@@Kr+kH?aC^K=a* zpPZ-1Nb=cvD({;2&eIQtk)YidPE=JjkAWoT6xD_NV*Z7SrpGiDtp7HU1awo=)E%6= z#xTJ19MjS)xR6|sVQxBr6n@Dd%$BpG$fRq`Q_t=gMWTEOO_Vf=2y@8;Cmpt;0v}z7H;8lj3q5!<6*VoNb1(G8ONT>kXzKm?W%R-g;%& zf+$=B70YdwKz)HGOlBs52^k}L7BF_Q_5uq79kMn4Y}7GRMu3i_fVJIVHHTGC7+DOE zb$RgyrM&3rG;h45^-}BD;XQ{$ZONtSOKYEM=MvgU~*5> zCJ}NIu+f6n_wD_aPO&O)PP^!zIBDMI#jgvkO!7XmY2B|{aFRxX4R&!}jG5a8^i-vJ8zOa| z0dr^q=UF)nok?tIU(vh2z0tKQWnAqVQ^`-FBB zjr$5saxbimcmUEV)YHBsRzxi(uhTNo>}{Es5R>aK%}dbG%04g0Q(~d%W?ptl5AGAw zoUG@(WGoP#nV28zsY4q`ir5TGYcky<1Q)y{vzk-wl6=4?7cB!0nVQV=18rj%+Ob#WUPWegi*4ROaEPBODK2?ogtKmC<0)8dQLdl zxR1Zb^4RO`UItIy2s>uegGK8TEeI&al_dik`v+S_kTRFF6HZ!eS05xF~EFeY1g>GrbKg|Jf^3nH|cLz$BMEI)YY2{2Foeb81D36+|%bq2Nfvm z78AGgs2}ilikWB^h9Rdj%Md_t@h{ShZx9q~vi&U5VIE%q((jgbUD^)^BV#88If#l^ z#U5kvI>;k?itIzy&x*-VhTo(r5i!%s!2fvl-F-Bcyt_k;7D#GKL>&5ssZxY+fqmKw zgi59)ZcTy{P667PoeQtrBvlcMCZO=IlH0!aFt^dOLrF-5CXNNvm?n!5loC%QKc}Z zVxvfaV?c(Hj6^+B1^DI`9ns1V^_Y^Zof^x)3f6-@a-(U>cwBtp2|AV>t|CW5{T+Ep zf2IBm!gqRoLsH@Y{X=-Z!;L`#fC0)#@tZTJ zeE2pc%8IDIbHccb{e?|x{n$R8)9cZ{U0yiSrj{c4;btyk{4e|J{`qzPhjYu6$4hI0 z44j*rv`-)2SNdO8}*n4=Z^PkTxTXtA3Y_CE}*)j=B^W(bdXY+p7 zUu-|P9)5AHHNQQv=`^r(7Y z*h1}R*F%v(*0>E>ZyNqhC`vOD@5Q@`r z6854aVk%~tkm%3BK6G%Wx6|Q%Gx7{)is#UxM>UvmoAuui00zwR()VC-`GS7C{d7I9 zetO-1yFCmB?UB~F^I>$(^J$6Tf>uE1^L!Sy1M%F$Q)>J_#TNbBwA|tF2=);*%^8|b zee?R@bN}$WIELSTlV1vB&FTVcU3*jw)tJYk=cLN|P#pFy3Ux0?!shrd|Mq-49#*E~ z?9mHC@x5c+_+4UMW6BZ#JPR*mHdEPxIe28nC2b71RmKrIE>$*T7RroRhgyzM7g;m? zOiKme1~uzI;EhD6vk{!&&uK>D@#KztXOZtZC8kK?4uT`fORXb~2Lspm(d!*za#Z5i zZLWJI`Y_e&Hj5)E#q63X} zD&Lm`JnVW$++lVU&4|DR=dbpNP%RqwqjR)IfEEfstY79r0&kqZI@4GeN>av;@z$!P zNh>^#MQ%k$xnCe(ba#K57*!M!t&mn}KP~OsL&XhG8828cJ97Jpp_6kZA~ku{JNFgk z(?@q{o=d&Hd6z{7EPb>1dh#v{jXB_$y~$ynfU_Wrr} zA-6mjq05)cq|D5&ubbN{9m5i-?RgRWvh^miVgt~cQIy~}g`UNaqZ1-5l28O}vpSn) zPQ<7?Md=BGSrX3;3Snji(*5# zmZ3|-?^0Ntwq5&g?xM!e1t=sHNRb9a#c2S+EFQ)7c8*mCv>>qCQ6li6EzWYrPg`|7 zzNyoVao&HLcW+uxzn-f;eDnZ6W{>mc8~dC;&cnkWZsOFDv8}GpzO!{%JO1V`k8-j= zrFB8_((A2-e~SJc=~jk1;8+YB$pPOx-TF2j9Dr*v@))sBoZGwATIJjao_bod;)4ME&XDO(1ciVZ^!l6~sb^ohl}=$lKfX~@zq=>+ z;MqO7s*GdVM!~)H65v$W7HHuIwr?`mUV508O5fg7Gb(iB9b@rq;dDWIr1unv>5Mdq ze`vWODlgqw(=WXBCJs3cTjEq*~P?#yl- zcH(KmQt$03Oi4A0q_et+KtMm3inBWBV>FIo4*U9OqcI`qhoHijs1kqwJNt0HbU(X1 zRZriXU4XE@XLcd;d;jG6P>KYh|G?R03esblvR+H4upegE180ru;=H9)#fi)5koPqp zmJ3yk=iBMf8K}-g#T?KWrNL45?7Rr7Ro5`zy_Ubq19dKc;roxJW-ej zy_9{DC2KUIHroy98oGz@Xr)r>h#v?i93RBfa(^9?_|=;cM(f)&+95XI3B|VPNCk& zQ9vPrd*V!Ak)&qq1pRE4Eo#F?L!XK`2%TGJqlq2{owmTi=jD|mXlM|?X{Lkd)b93% zrGzXdzz#6M+UsIJLZvge;X*;h8Zkx&gT`bx3qYqy(8e#Qu#W>%{K^~5xEdxSnW*gJ zyCu-N;I%rjr~pT;-0DlIFWoIbBVoEafWYI%qxP2q399^_yZw0ND5HdRzIxZ*p0A1g z&Sk!WIvw7auiyaI!+cFFt-gQ0ekh^@OEL4!#;H!-GbgNglmyy0@0Z&w6dVXsQW^_# zH$ouWEs1~)Ox7LTPz8Cw$eng8;8%rWBF-bf3s|-)7wWSE%*2ulCTp!4zOb;sWSzuf z8m(aQiieFRkN6){TT|B>(JzU8P@Ce70vN!i{=Cn?k-{#JDMoa%B{Lu!7KUbwtr5(* z^b};{r`aa|+5qOqF=}C?dH;E1sXnK;2d`PtX!cv&TH^t~oGcv0F_&Y!j9#YL$#`>+ z9qtbzQn&(pF68m`cr^Y?_+QVn;3@{{7`XweNZ&jh{WiuANbjVl=D0U^@M6H{-i(z- z)&ObbMHT02%IOf&Q|}qfD0bhld@D0_S%Ow^Pfx*Jk&RdgQ^USF4-=i(%{qqKfEBXd z<=k)-+ZNB=g2ZV$49mtM-)4|WxI#^Bxlb5p`3pJBlVD$oR!guC;9&x>AyDSqcehGr zF0$;n*`X>%|X!kOVHI>?#T&&VhOec224 z*vVFDjb=tMAL5nTI$E}|%;(V%X~4+GnF&(#)ITbHxl?X=43FIO1{<*&aK4h(6`%#W z1u=hxZvrk0kv&}9gh{3(899-rg$xu|SEdvf|cVmW2+9-zbWa z^ud@QDC$O3B9r*78Bd|3c-&78N8veGI9H{K(J7HI=1`gMsV6y)#luFEk;M~ZV3#b3 z3RJ00&n#2U0VUhr=np_uO3iKli6aIEE;-8{50!t=d>(=D+!cQ?`D|2HDC&iK1yauDxHt z$n4f0%ar(#l;af|(?JVTKe>XsKa3HN><@!ZgL!`%J=Xnc)B}lOK8umfd(9P~!91Q(Gx=FhZoM}J$?AxJ70+(GV5>UEMQND9l0661j)#A#^Y$IpwIFhG2BM?vA((b7z5AW*Tv}X@G>A z;g)75LU1)gAGj#qqsP#pj5l^e?*zJ3p#)Nsm>teGD!Bgy2`bamV;UP16&cN^_=^U#0&#c93NO zfp3|qeM#ajCyVH6HO4)ZozT{1ya&YqpUh0pe+ic_C{fxMlBt)kg#@#8Uq~wZEw>8^ zWVDur1bf@Ikg%}7E+iQt_i-TsP!8@N+e#A1;o4Rb1fh9ZNgyQ+9Q2z@$%m+Zf#Dim zkX6$}DtB$BCDZu6isgfN>3lwZ;k-e6zmA8bP7SQKBJ>^1R~rQYE+yQB!n8(oi?HmJ zt0k(g1x#{CNc&}gQI z`uOrR5JFA;U~Z@sEt#GjsdLh#Zu^YX3&MiJ_kk+740Wq{I|sVno7r?Bn#(7{YIwHJ zneRR4ApB%t5r2lj;kW^A6DW z9UArlfZ0~LzycQ*m>%8*Uw$SQdvx$9#{1YyBBR#lcF<-YGuuz-u)iEx~q;K6U@X^5|>Ge?72m*0CD*^XK1#gC`1??=vsZ2-(pZ{Zlg!A^Gjet~&lzC)m!}$HYMX;6FX{ zSow;CTv7yMJ1tIe)j2j^L~NZp?*22A(98&u^0l3ZfrDS&&3!g9ENZc-D`DgYOa5dA4WLa&!4SOS?W|ISmz_nMMl1iz+{WO6fKQv$H6gf+ZWkLO zRZ|RosGQH%4%IEPTz$O7#thPvq}oVOyuC+QbNTfio62=wotF`Euk2g9M+El7dD%@y z1J8}Hn;zVO-tK2Bh{CHFiH4udQr9l5oXFb{Oyf$H>UNKj0WnFa^5O6*!YHu@!wUNA zG*{m;y~vIuOG#aH+mZ{~E`fbK{6`hN(|@43^rnued98;!&GIOw4&t_Ma=htEmGk8$ z<5*Wc5+HN_cEsOLBCBk%8(eHwNLRqOis7M1I;OmAZGAe=%e1-Xuc-Z~+e>U=nH7Xc z8A3Eq%&QWGow(w<=mP?!17Bw$KxlWHmUP%_6boPM1}ddA(JZ8&c16+c!cL_b$Afr} zZle1lNzs_w&Ge+;_?({fa=)LRweGVsn!x=&JJ|ufnVo13r?gB@On`lMVoZ1c#Ps}_ zs3@Za->0hsaJB(qQIk48m3Yd;xz3>*#xzI2kE0IBcIFEWqV_||y>N!6ee6bwYJyE~ z0evZg)($^`_F{6nM{f_|d!ypO*{Y&^ei*dX#;l8cks;U`)UXDvBE~2-W%1fIJA?T3 z#RxyL1_EbgX>iLit?UkJ9S*73S-crkp_mTH#B(M_@7M(WUuzfqjas2TZmf1$8Og*5 zN~!p~(VB>j%+7*J-s$la5*1dwK~;*F3J0MFIv;tX(wD6tTJU3@aXUlSG5vOosz36X z?D``6KPQCb7F`qGiXpH?*9d9_6N06{C$c^W-I9hz>zA1%;n+I#p7v#4SPtbAApwMV zJ=-P8?@1;fCk{MM<~i#9)5*#UdozlhS^CwX&C}`FSHI>eP^(VNUwrxOHW@m7DIFVP zdo?7p>+XD6&xry|$S0(MSbi1xq{BJQ|7>}%tbIGm1$|=cfb+O`Aj`1P!FBAtBqL6m zzq`$ME#qjZ6yf&U{#12z9o$Zcn2A|#evl4^IlD4scb_ZIJTq;9w#Ia+ZJDzW{=rJS z%-OMqHhE6<@QFDK!FcX5X{&`4Z~hH)fuij#lHB$NP%Wa{ZrExTYh028N*U$kA(K%;9Kzq%wG(l7C$p@Y4rf} zPw(SWp2ER(>}}dsvJQMMck_0cU4MB4$NsPX{CrWS!3YgD-vO!bH!sS3AEW91Lke%? z9I;IpsKst>2sNV5Z!kP8g7~v7NLgk&H0Lqq2vTM+Oq@9=uq<#<6+_Cjfm?W3*m)T( zUK46Ew9H7<;zk)mS+oo9Cv|5+m_1>(G53?VLFgVGh-=5RSCLBjKN}0rEvbN3K~fEJyF6XP5BBxVyPIW zYje!ZkTF_S&;rx72+$r={1Vec7>r1<&bSbnl_e|D-D!@x!(3P7n*dx&|sb|3r%F`voAD3jN$0!>KpDBnye-ehMiS8 z8l08K!xBmZp=n+g8ai4(vCe$VT~V1maC9s!V%0!7(u#z5IuVuEvOScJXS5V2F;-O7 zOSVLeaYhjRk8DqYwkud@4pYi6)k;VURS`9ujFtdP@+#CeBWqH82o?ijdPemuYwz06 z7CvG7PpcT=L40fFa&;3tmE_VLC$R;U5EL^@JZwvjlgSpRKs^6A1gSsHxJ#y{@2Dt% zrDmagDB))TtLrz=GJ#=KolyOprNUt>3_A0GIS`&wPWc;*NPe4wnv4E%K`pY-#u`Rq z>B|eA68QbnW|b^7!jvegQm9X$;u)R7wdUT{)OgbEBr$Kt<)QlaA%A|VZe^!2SCsbh zmZc}p{e>dSN=32?Yp=m^o+_+?^`o3}LE`A(2OtiFcqB+rKM{6aA?P!HP!6Z#v32Mz z(NbkCKAFJ25X}Gp0Fw~Zo%W)~R$7Zo?m8wUU+`ERKdo+Aun}o@YJ0H~$G_?X`$^Ga zloG_}t80OYx?dlyPB675X0fX)ONV;wXS6O6nw|z*2OHq`(rr`I!P+ z#9|IGF115u)ddIFvG)oh)^kUE`+bFNon$8#*s_{tk?Pl*s;T3e!$os0M7GX@F7w5E{SjQ?u7+`54L; zZy#UU41#NGn?c=_^7+{tt+wR_J>Gf^YHr{R`&ki7LFyxZdirALr4}2*lI^Sv)^vvL z>4Lk6-b)Rin!cSu6R6#>u1~iT%1fh}ZT2SVBeq^XH+#p*%cmGZ+-ENiu4C`BSH>jC z_O^BQ9wylvmA3!-W9ZLw^r#jxmg83W=1(oP-7PG?bG9b`HxBU+%kv}FI@-Uue>ki# zI?soXGRJuS)KNxyaX1V<%3-;{e>kb07~J;(dDSM|16$K@AtR&3^j$#`>JW%Y$#N=i zA`nC`&2CThVT&dw$3%uso7T8A~+t zGcuZpH`a8wT7=tD1pzJz*(pqYd)c1}%4N|6ijwde%nreCXFZN}fzv@`IS30>crCyH zDG9SYZ|rCgyYWBtmUiil+T8d&(KrEWY!`VZq?>MH)P-aP&z9L z^WX(sO~M1RM7U)>Buu;j3MNd^<;vkP?&;Ws4r${S9(n$ z;KMf24SOVbci`;7r1uYB$-9~iU zrM2F)6|)_KwWcjlLNZBnG1Z!DrKU!pcC)98u0p2E4y8-nEZTIJ(cYkZ4$#27F zbgciWq8O;vsJddJ$SN>~5|fczcTeeoMzfBQw_mYn#;-nF-7uc`d$`OF60#W8HgUOOh+H}~84KH?+RAqN1XNp9T~&)V#pG=W|AB0X5q z6g&{>6%kb`m)W4{)M${N?)I;!;np?sxDDUG2LQz0o#pE^!IhK_yeLToC zoZH{elq7~ODACaselrAUu@wYaGi~wR?O`UONHDQuoJk3ygkTy?;thCOIxL(HLpyu1 z9Wpy}3Bt&Fk`*C(qW9RzoqF)-IZ7)-vBEwnMycJP^W2sCLO&{OBz8EbDGKUn0BD22 zd!az@vbjTafszz#Ka0Epvs9Bkp*fvF^W9ej$5;6b0+`6h3wLzxaWTJmj|fNrU)e4Z z#>`{Gr|R3In+#C`3*LHiBR%TlG|^cE^XyH2ym5Xr8_^;x@12b)xA)CPM|{8sX5)vt z;E6JIn2vP)q~Hu@V`{V2tI3#`JFL!whuTfnh$87^?J(Renu~`{Zcx#{ITJL@UcIDX zqMZ@&4J5|?>}EFlt6d5|rc$A)XrWhj8mEg%dSQ^!&C%zoG%pxw305Q=r8@_wvqp)s zyTV0aYCPdnu5J;3m)uNzO3Uv1?{mLRqdA7hqIB6w%z_PQ!nQ*cvEngx0}@bAQa5Z8XV>3SH6j8^Pp1{#W?#=K-lG7mYC!l8717yl?t?%%9Lw?7A9%YN0n?#sjrLji2C_<1Bs&&pE8GYOTwsE!O9WHv z50|crHJ|mBNJk60^)AwDxKFf!kbaY~2#18OvQ-kd4_jP=Aq}ftC&Na&3Txn!73X9e-q^=0@glbwAk+wi3D#;8?QA|75Dudv$@Zwfn$=V#7g=S3*CCn^v z>Dd_2%5#HFIyH$pyOG_bXo-=kG#c7&vXK!@;U?NfP-7JWE-H^vCySV`WzdEow_d0) zHCZfE&Iz?4Q2}#jc@LhzF?8&XT4-(UJgC~ zG-B6xi6~dtxj2dHfA7#Ue4o%Wu)T5J$oQ;7QSQ=8^Krb-NLc)`;v=~LE5Grkw(oqU699 zfpY8ziUHTmIGrEp&;_Vyk{(9oUSaYe+d2}lyg+n`O&>V>7D^ZhE}dY1RVd4udOJJl zq*NqVF-g*70Rdpa*=80F4+OIkn~P;(pjy=9FY>!UokB+GfvqD%m?J`z#T(CxKL27zQw6fw6D8M^n z=0nMr_;?I0Z?OsFY1Dp4ud`M8dzAh)5hpCH>1d}~7J86WBsBoU!yB#aCnD#MHm-fZ zjdqt`ywOg28r}71OhQ=lC2q08)3^HZh_g$$V40qNPS5nx^mMG;@6!`C^zz2^Orizt z)6-M&`Tf)LqZFU!H8BE7U6MP1K-<(sj#Mc;aC(9o2icZc6q(2D^rm*zSRd_ub@eqP zw`NZd?+u=h7J35L)2KJ>sjz!?sA*!hxLLEMltfZdoLd=^AR*Xm@!;YyjWlFWOBs{1 zYRo!k+80Op-);?uqFQ_#*EQ1LBuU;FxE~SJ6ykHC=6Bx(e}$R1apbr%%0P!C&&@}% zrVnyi4^c8guZEldoywo`^QF!ta%pg|OG@87-i+TR-h@G~bjr)LJF6nxX>Vm3DO}Z! zOE{vb4k1_bcrE17IvV2c1r&(wU#_$%3KRM@W+~hylL>Scz!+QNtUEQ*%n~7khM%8C z3O-ZYyQs5>N}Poi;r8}2%OnZxGV2GCaTLNL3eFuo=Se^Bl(9>wKA0!Hc!v)A$jJd_ zrIZ#+JALZN0oTG#Yt;Jz4s}C*t@lRxKkVVAm`=@;SjwS%z#u*Nu{|cUse)u148w~N zg$W@FR2n=tu&hGn(p0$`@~SdeuyN$Gkb3}d`P;i2yIR1mX6#&`xMb{pv|-Jd^W;IM{^;O~JKFS@38;Ps|f_jWQVF&K61v z8}E>Xoej&RM4|Zg#-jFeVUV;9-;Z;Kq0INUSBT(HDVZS_@2?#~V}ctZ5~4EQr!hQ% zaIS4(|3s!edFw8-*2jX&@My}Ep!*@&w9Jm;bH4rw04quU|E`M5#V!pTY|Q)RlAR| z1oF8iRTShUbt)B|8X`i#qOce2Hxfo1YltIWsf^+8^F;Iers?N#hx=LUws7`;$tod9}piJZ2i@dB_4*4rh!5QgtmykS%T zvFYWWBH02eWw6;66B~r%9=uGD#bxs@=i+xuvneVeMMtUdE-)I$FwY>z*l0{i?gT02uh72!_ILK-=ZBx^vdZ{g%7f1IS=gf}A>S{8VUR7CK`xGwh-oj+CYSW5NvBx3`2D|9~vR z^Xw}F{RNuRa>Z0Wp5PWN|M|E{9Q-6FqsvA?D;^_f{B=>I~)#dLJ z)wLgqwjVW_ab0pm3v_GaNd4Sx;*Olr$ULzoL3|@w_pjV0RHz0+iME;+Sc8c>l}$v= z80j-xcxv|OQ2UWg{|qfY&O_O&W9jc~PBnC zIih#EpO7USZ9kYjK~Ftvn%zzvItNJ-YE>Frx`L<=RxBSfswP#cgWPyP>#i3Nu)9Au zRP_|eLdP%0*%Kc-HyEyB#AcRQAmO+x4;Ao5cw?#kN|#NUxMlOSp~j`Q>s~5{a~R#ngmG6+{4B z)8p&YFFB#jSIT6biz=4atra2xne)%4aI|Ycrsd{EqvxGLR4;NOmJD2C{~2+@hzH9U zhxH5M?_Uq_vtfRv{OP(52Czk5UI%G5w6BAnt;HADLCT1{xDJX`zpR5g+U+{1FRbgJ z&a3n9=E^{MUj{R2UhEQd+lq0p?O3*vz%km>9$m4)_%CUeV6f%sL5>GlP#3Ux zpQ2TWnmG{3NyM)2{n>1;#⋘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 V0}q)_BmU~L>EGzfmPs&31pxFlTQ&dy literal 0 HcmV?d00001 diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 3924a85f6..1b6ab0ea1 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -5179,6 +5179,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_stats_loading" = "Loading stats..."; "lng_stats_loading_subtext" = "Please wait a few moments while we generate your stats."; +"lng_stats_boosts_loading" = "Loading boosts list..."; +"lng_stats_boosts_loading_subtext" = "Please wait a few moments while we generate your stats."; +"lng_stats_earn_loading" = "Loading rewards info..."; +"lng_stats_earn_loading_subtext" = "Please wait a few moments while we generate your stats."; "lng_chart_title_member_count" = "Growth"; "lng_chart_title_join" = "Followers"; diff --git a/Telegram/Resources/qrc/telegram/animations.qrc b/Telegram/Resources/qrc/telegram/animations.qrc index af3e89fb6..0d6663d8f 100644 --- a/Telegram/Resources/qrc/telegram/animations.qrc +++ b/Telegram/Resources/qrc/telegram/animations.qrc @@ -11,6 +11,8 @@ ../../animations/ttl.tgs ../../animations/discussion.tgs ../../animations/stats.tgs + ../../animations/stats_boosts.tgs + ../../animations/stats_earn.tgs ../../animations/voice_ttl_idle.tgs ../../animations/voice_ttl_start.tgs ../../animations/palette.tgs diff --git a/Telegram/SourceFiles/info/bot/earn/info_bot_earn_list.cpp b/Telegram/SourceFiles/info/bot/earn/info_bot_earn_list.cpp index cbe32faf5..aac6f38ee 100644 --- a/Telegram/SourceFiles/info/bot/earn/info_bot_earn_list.cpp +++ b/Telegram/SourceFiles/info/bot/earn/info_bot_earn_list.cpp @@ -87,6 +87,7 @@ void InnerWidget::load() { Info::Statistics::FillLoading( this, + Info::Statistics::LoadingType::Earn, _loaded.events_starting_with(false) | rpl::map(!rpl::mappers::_1), _showFinished.events()); diff --git a/Telegram/SourceFiles/info/channel_statistics/boosts/info_boosts_inner_widget.cpp b/Telegram/SourceFiles/info/channel_statistics/boosts/info_boosts_inner_widget.cpp index 6234ab010..cddb8d9a3 100644 --- a/Telegram/SourceFiles/info/channel_statistics/boosts/info_boosts_inner_widget.cpp +++ b/Telegram/SourceFiles/info/channel_statistics/boosts/info_boosts_inner_widget.cpp @@ -273,6 +273,7 @@ void InnerWidget::load() { Info::Statistics::FillLoading( this, + Info::Statistics::LoadingType::Boosts, _loaded.events_starting_with(false) | rpl::map(!rpl::mappers::_1), _showFinished.events()); diff --git a/Telegram/SourceFiles/info/channel_statistics/earn/info_channel_earn_list.cpp b/Telegram/SourceFiles/info/channel_statistics/earn/info_channel_earn_list.cpp index c96dac4ea..707a045cd 100644 --- a/Telegram/SourceFiles/info/channel_statistics/earn/info_channel_earn_list.cpp +++ b/Telegram/SourceFiles/info/channel_statistics/earn/info_channel_earn_list.cpp @@ -287,6 +287,7 @@ void InnerWidget::load() { Info::Statistics::FillLoading( this, + Info::Statistics::LoadingType::Earn, _loaded.events_starting_with(false) | rpl::map(!rpl::mappers::_1), _showFinished.events()); diff --git a/Telegram/SourceFiles/info/statistics/info_statistics_inner_widget.cpp b/Telegram/SourceFiles/info/statistics/info_statistics_inner_widget.cpp index 6e5803114..193622135 100644 --- a/Telegram/SourceFiles/info/statistics/info_statistics_inner_widget.cpp +++ b/Telegram/SourceFiles/info/statistics/info_statistics_inner_widget.cpp @@ -560,6 +560,7 @@ void FillOverview( void FillLoading( not_null container, + LoadingType type, rpl::producer toggleOn, rpl::producer<> showFinished) { const auto emptyWrap = container->add( @@ -569,9 +570,14 @@ void FillLoading( emptyWrap->toggleOn(std::move(toggleOn), anim::type::instant); const auto content = emptyWrap->entity(); + const auto iconName = (type == LoadingType::Boosts) + ? u"stats_boosts"_q + : (type == LoadingType::Earn) + ? u"stats_earn"_q + : u"stats"_q; auto icon = ::Settings::CreateLottieIcon( content, - { .name = u"stats"_q, .sizeOverride = Size(st::changePhoneIconSize) }, + { .name = iconName, .sizeOverride = Size(st::changePhoneIconSize) }, st::settingsBlockedListIconPadding); ( @@ -586,7 +592,11 @@ void FillLoading( content, object_ptr( content, - tr::lng_stats_loading(), + (type == LoadingType::Boosts) + ? tr::lng_stats_boosts_loading() + : (type == LoadingType::Earn) + ? tr::lng_stats_earn_loading() + : tr::lng_stats_loading(), st::changePhoneTitle)), st::changePhoneTitlePadding + st::boxRowPadding); @@ -595,7 +605,11 @@ void FillLoading( content, object_ptr( content, - tr::lng_stats_loading_subtext(), + (type == LoadingType::Boosts) + ? tr::lng_stats_boosts_loading_subtext() + : (type == LoadingType::Earn) + ? tr::lng_stats_earn_loading_subtext() + : tr::lng_stats_loading_subtext(), st::statisticsLoadingSubtext)), st::changePhoneDescriptionPadding + st::boxRowPadding); @@ -626,6 +640,7 @@ void InnerWidget::load() { FillLoading( inner, + Info::Statistics::LoadingType::Statistic, _loaded.events_starting_with(false) | rpl::map(!rpl::mappers::_1), _showFinished.events()); diff --git a/Telegram/SourceFiles/info/statistics/info_statistics_inner_widget.h b/Telegram/SourceFiles/info/statistics/info_statistics_inner_widget.h index c0a31231e..8da4fd007 100644 --- a/Telegram/SourceFiles/info/statistics/info_statistics_inner_widget.h +++ b/Telegram/SourceFiles/info/statistics/info_statistics_inner_widget.h @@ -21,8 +21,15 @@ namespace Info::Statistics { class Memento; class MessagePreview; +enum class LoadingType { + Statistic, + Boosts, + Earn, +}; + void FillLoading( not_null container, + LoadingType type, rpl::producer toggleOn, rpl::producer<> showFinished); From cedf161e44c04c5ab650b43a06fe3d848750fee0 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Mon, 5 Aug 2024 22:11:56 +0300 Subject: [PATCH 012/104] Removed inappropriate phrase from photo editor for profile bot photo. --- Telegram/SourceFiles/ui/controls/userpic_button.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Telegram/SourceFiles/ui/controls/userpic_button.cpp b/Telegram/SourceFiles/ui/controls/userpic_button.cpp index 0b26e1810..9c3de25e4 100644 --- a/Telegram/SourceFiles/ui/controls/userpic_button.cpp +++ b/Telegram/SourceFiles/ui/controls/userpic_button.cpp @@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/controls/userpic_button.h" #include "base/call_delayed.h" +#include "boxes/peers/edit_peer_info_box.h" // EditPeerInfoBox::Available. #include "ui/effects/ripple_animation.h" #include "ui/empty_userpic.h" #include "data/data_photo.h" @@ -285,6 +286,8 @@ void UserpicButton::choosePhotoLocally() { : QString(); const auto phrase = (type == ChosenType::Suggest) ? &tr::lng_profile_suggest_sure + : (user && EditPeerInfoBox::Available(user)) + ? nullptr : (user && !user->isSelf()) ? &tr::lng_profile_set_personal_sure : nullptr; From fb8f3ad26cda243fe9fba7f90f80f04c76eddb14 Mon Sep 17 00:00:00 2001 From: John Preston Date: Thu, 25 Jul 2024 10:24:21 +0200 Subject: [PATCH 013/104] Update API scheme to layer 186. --- Telegram/SourceFiles/api/api_credits.cpp | 18 +++++--- Telegram/SourceFiles/api/api_invite_links.cpp | 3 +- .../boxes/peers/edit_peer_info_box.cpp | 26 ++++++++++-- .../boxes/peers/edit_peer_reactions.cpp | 3 +- Telegram/SourceFiles/data/data_channel.h | 4 ++ .../data/data_message_reaction_id.cpp | 14 ++++--- .../data/data_message_reaction_id.h | 17 +++++++- Telegram/SourceFiles/data/data_session.cpp | 2 + .../SourceFiles/mtproto/mtproto_config.cpp | 2 + Telegram/SourceFiles/mtproto/scheme/api.tl | 41 ++++++++++++------- 10 files changed, 99 insertions(+), 31 deletions(-) diff --git a/Telegram/SourceFiles/api/api_credits.cpp b/Telegram/SourceFiles/api/api_credits.cpp index 727cee565..4a5aece89 100644 --- a/Telegram/SourceFiles/api/api_credits.cpp +++ b/Telegram/SourceFiles/api/api_credits.cpp @@ -109,14 +109,19 @@ constexpr auto kTransactionsLimit = 100; [[nodiscard]] Data::CreditsStatusSlice StatusFromTL( const MTPpayments_StarsStatus &status, not_null peer) { - peer->owner().processUsers(status.data().vusers()); - peer->owner().processChats(status.data().vchats()); - return Data::CreditsStatusSlice{ - .list = ranges::views::all( - status.data().vhistory().v + const auto &data = status.data(); + peer->owner().processUsers(data.vusers()); + peer->owner().processChats(data.vchats()); + auto list = std::vector(); + if (const auto history = data.vhistory()) { + list = ranges::views::all( + history->v ) | ranges::views::transform([&](const MTPStarsTransaction &tl) { return HistoryFromTL(tl, peer); - }) | ranges::to_vector, + }) | ranges::to_vector; + } + return Data::CreditsStatusSlice{ + .list = std::move(list), .balance = status.data().vbalance().v, .allLoaded = !status.data().vnext_offset().has_value(), .token = qs(status.data().vnext_offset().value_or_empty()), @@ -220,6 +225,7 @@ void CreditsHistory::request( } _requestId = _api.request(MTPpayments_GetStarsTransactions( MTP_flags(_flags), + MTPstring(), // subscription_id _peer->isSelf() ? MTP_inputPeerSelf() : _peer->input, MTP_string(token), MTP_int(kTransactionsLimit) diff --git a/Telegram/SourceFiles/api/api_invite_links.cpp b/Telegram/SourceFiles/api/api_invite_links.cpp index 1f02b78c1..79fab14d5 100644 --- a/Telegram/SourceFiles/api/api_invite_links.cpp +++ b/Telegram/SourceFiles/api/api_invite_links.cpp @@ -120,7 +120,8 @@ void InviteLinks::performCreate( peer->input, MTP_int(expireDate), MTP_int(usageLimit), - MTP_string(label) + MTP_string(label), + MTPStarsSubscriptionPricing() )).done([=](const MTPExportedChatInvite &result) { const auto callbacks = _createCallbacks.take(peer); const auto link = prepend(peer, peer->session().user(), result); diff --git a/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp b/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp index 88464ed1c..86dd68802 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp +++ b/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp @@ -318,6 +318,7 @@ private: std::optional hiddenPreHistory; std::optional forum; std::optional signatures; + std::optional signatureProfiles; std::optional noForwards; std::optional joinToWrite; std::optional requestToJoin; @@ -408,6 +409,7 @@ private: std::optional _typeDataSavedValue; std::optional _forumSavedValue; std::optional _signaturesSavedValue; + std::optional _signatureProfilesSavedValue; const not_null _navigation; const not_null _box; @@ -1066,6 +1068,8 @@ void Controller::fillSignaturesButton() { ) | rpl::start_with_next([=](bool toggled) { _signaturesSavedValue = toggled; }, _controls.buttonsLayout->lifetime()); + + _signatureProfilesSavedValue = channel->signatureProfiles(); } void Controller::fillHistoryVisibilityButton() { @@ -1783,10 +1787,14 @@ bool Controller::validateForum(Saving &to) const { } bool Controller::validateSignatures(Saving &to) const { + Expects(_signaturesSavedValue.has_value() + == _signatureProfilesSavedValue.has_value()); + if (!_signaturesSavedValue.has_value()) { return true; } to.signatures = _signaturesSavedValue; + to.signatureProfiles = _signatureProfilesSavedValue; return true; } @@ -2219,15 +2227,27 @@ void Controller::saveForum() { } void Controller::saveSignatures() { + Expects(_savingData.signatures.has_value() + == _savingData.signatureProfiles.has_value()); + const auto channel = _peer->asChannel(); if (!_savingData.signatures || !channel - || *_savingData.signatures == channel->addsSignature()) { + || ((*_savingData.signatures == channel->addsSignature()) + && (*_savingData.signatureProfiles + == channel->signatureProfiles()))) { return continueSave(); } + using Flag = MTPchannels_ToggleSignatures::Flag; _api.request(MTPchannels_ToggleSignatures( - channel->inputChannel, - MTP_bool(*_savingData.signatures) + MTP_flags(Flag() + | (*_savingData.signatures + ? Flag::f_signatures_enabled + : Flag()) + | (*_savingData.signatureProfiles + ? Flag::f_profiles_enabled + : Flag())), + channel->inputChannel )).done([=](const MTPUpdates &result) { channel->session().api().applyUpdates(result); continueSave(); diff --git a/Telegram/SourceFiles/boxes/peers/edit_peer_reactions.cpp b/Telegram/SourceFiles/boxes/peers/edit_peer_reactions.cpp index 8905c33c1..226e30af2 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_peer_reactions.cpp +++ b/Telegram/SourceFiles/boxes/peers/edit_peer_reactions.cpp @@ -911,7 +911,8 @@ void SaveAllowedReactions( allowed.maxCount ? MTP_flags(Flag::f_reactions_limit) : MTP_flags(0), peer->input, updated, - MTP_int(allowed.maxCount) + MTP_int(allowed.maxCount), + MTPbool() // paid_enabled )).done([=](const MTPUpdates &result) { peer->session().api().applyUpdates(result); auto parsed = Data::Parse(updated); diff --git a/Telegram/SourceFiles/data/data_channel.h b/Telegram/SourceFiles/data/data_channel.h index 81ad7778d..457e759a0 100644 --- a/Telegram/SourceFiles/data/data_channel.h +++ b/Telegram/SourceFiles/data/data_channel.h @@ -68,6 +68,7 @@ enum class ChannelDataFlag : uint64 { CanViewRevenue = (1ULL << 32), PaidMediaAllowed = (1ULL << 33), CanViewCreditsRevenue = (1ULL << 34), + SignatureProfiles = (1ULL << 35), }; inline constexpr bool is_flag_type(ChannelDataFlag) { return true; }; using ChannelDataFlags = base::flags; @@ -231,6 +232,9 @@ public: [[nodiscard]] bool addsSignature() const { return flags() & Flag::Signatures; } + [[nodiscard]] bool signatureProfiles() const { + return flags() & Flag::SignatureProfiles; + } [[nodiscard]] bool isForbidden() const { return flags() & Flag::Forbidden; } diff --git a/Telegram/SourceFiles/data/data_message_reaction_id.cpp b/Telegram/SourceFiles/data/data_message_reaction_id.cpp index 1e93abfcd..1deac2bbb 100644 --- a/Telegram/SourceFiles/data/data_message_reaction_id.cpp +++ b/Telegram/SourceFiles/data/data_message_reaction_id.cpp @@ -56,17 +56,21 @@ ReactionId ReactionFromMTP(const MTPReaction &reaction) { return ReactionId{ qs(data.vemoticon()) }; }, [](const MTPDreactionCustomEmoji &data) { return ReactionId{ DocumentId(data.vdocument_id().v) }; + }, [](const MTPDreactionPaid &) { + return ReactionId::Paid(); }); } MTPReaction ReactionToMTP(ReactionId id) { - if (const auto custom = id.custom()) { + if (!id) { + return MTP_reactionEmpty(); + } else if (id.paid()) { + return MTP_reactionPaid(); + } else if (const auto custom = id.custom()) { return MTP_reactionCustomEmoji(MTP_long(custom)); + } else { + return MTP_reactionEmoji(MTP_string(id.emoji())); } - const auto emoji = id.emoji(); - return emoji.isEmpty() - ? MTP_reactionEmpty() - : MTP_reactionEmoji(MTP_string(emoji)); } } // namespace Data diff --git a/Telegram/SourceFiles/data/data_message_reaction_id.h b/Telegram/SourceFiles/data/data_message_reaction_id.h index 69f765871..c624ef865 100644 --- a/Telegram/SourceFiles/data/data_message_reaction_id.h +++ b/Telegram/SourceFiles/data/data_message_reaction_id.h @@ -14,13 +14,28 @@ namespace Data { struct ReactionId { std::variant data; + [[nodiscard]] static QChar PaidTag() { + return '*'; + } + [[nodiscard]] static ReactionId Paid() { + return { QString(PaidTag()) }; + } + [[nodiscard]] bool empty() const { const auto emoji = std::get_if(&data); return emoji && emoji->isEmpty(); } + [[nodiscard]] bool paid() const { + const auto emoji = std::get_if(&data); + return emoji + && emoji->size() == 1 + && emoji->at(0) == PaidTag(); + } [[nodiscard]] QString emoji() const { const auto emoji = std::get_if(&data); - return emoji ? *emoji : QString(); + return (emoji && (emoji->size() != 1 || emoji->at(0) != PaidTag())) + ? *emoji + : QString(); } [[nodiscard]] DocumentId custom() const { const auto custom = std::get_if(&data); diff --git a/Telegram/SourceFiles/data/data_session.cpp b/Telegram/SourceFiles/data/data_session.cpp index f88fb6abb..a673ebca5 100644 --- a/Telegram/SourceFiles/data/data_session.cpp +++ b/Telegram/SourceFiles/data/data_session.cpp @@ -944,6 +944,7 @@ not_null Session::processChat(const MTPChat &data) { | Flag::Gigagroup | Flag::Username | Flag::Signatures + | Flag::SignatureProfiles | Flag::HasLink | Flag::SlowmodeEnabled | Flag::CallActive @@ -972,6 +973,7 @@ not_null Session::processChat(const MTPChat &data) { | (data.is_gigagroup() ? Flag::Gigagroup : Flag()) | (hasUsername ? Flag::Username : Flag()) | (data.is_signatures() ? Flag::Signatures : Flag()) + | (data.is_signature_profiles() ? Flag::SignatureProfiles : Flag()) | (data.is_has_link() ? Flag::HasLink : Flag()) | (data.is_slowmode_enabled() ? Flag::SlowmodeEnabled : Flag()) | (data.is_call_active() ? Flag::CallActive : Flag()) diff --git a/Telegram/SourceFiles/mtproto/mtproto_config.cpp b/Telegram/SourceFiles/mtproto/mtproto_config.cpp index 1da5325ef..e8fc605ca 100644 --- a/Telegram/SourceFiles/mtproto/mtproto_config.cpp +++ b/Telegram/SourceFiles/mtproto/mtproto_config.cpp @@ -271,6 +271,8 @@ void Config::apply(const MTPDconfig &data) { _fields.reactionDefaultEmoji = qs(data.vemoticon()); }, [&](const MTPDreactionCustomEmoji &data) { _fields.reactionDefaultCustom = data.vdocument_id().v; + }, [&](const MTPDreactionPaid &data) { + _fields.reactionDefaultEmoji = QString(QChar('*')); }); } _fields.autologinToken = qs(data.vautologin_token().value_or_empty()); diff --git a/Telegram/SourceFiles/mtproto/scheme/api.tl b/Telegram/SourceFiles/mtproto/scheme/api.tl index 2d35a0c52..e8e8f837d 100644 --- a/Telegram/SourceFiles/mtproto/scheme/api.tl +++ b/Telegram/SourceFiles/mtproto/scheme/api.tl @@ -26,6 +26,7 @@ inputPhoneContact#f392b7f4 client_id:long phone:string first_name:string last_na inputFile#f52ff27f id:long parts:int name:string md5_checksum:string = InputFile; inputFileBig#fa4f0bb5 id:long parts:int name:string = InputFile; +inputFileStoryDocument#62dc8b48 id:InputDocument = InputFile; inputMediaEmpty#9664f57f = InputMedia; inputMediaUploadedPhoto#1e287d04 flags:# spoiler:flags.2?true file:InputFile stickers:flags.0?Vector ttl_seconds:flags.1?int = InputMedia; @@ -98,11 +99,11 @@ userStatusLastMonth#65899777 flags:# by_me:flags.0?true = UserStatus; chatEmpty#29562865 id:long = Chat; chat#41cbf256 flags:# creator:flags.0?true left:flags.2?true deactivated:flags.5?true call_active:flags.23?true call_not_empty:flags.24?true noforwards:flags.25?true id:long title:string photo:ChatPhoto participants_count:int date:int version:int migrated_to:flags.6?InputChannel admin_rights:flags.14?ChatAdminRights default_banned_rights:flags.18?ChatBannedRights = Chat; chatForbidden#6592a1a7 id:long title:string = Chat; -channel#aadfc8f flags:# creator:flags.0?true left:flags.2?true broadcast:flags.5?true verified:flags.7?true megagroup:flags.8?true restricted:flags.9?true signatures:flags.11?true min:flags.12?true scam:flags.19?true has_link:flags.20?true has_geo:flags.21?true slowmode_enabled:flags.22?true call_active:flags.23?true call_not_empty:flags.24?true fake:flags.25?true gigagroup:flags.26?true noforwards:flags.27?true join_to_send:flags.28?true join_request:flags.29?true forum:flags.30?true flags2:# stories_hidden:flags2.1?true stories_hidden_min:flags2.2?true stories_unavailable:flags2.3?true id:long access_hash:flags.13?long title:string username:flags.6?string photo:ChatPhoto date:int restriction_reason:flags.9?Vector admin_rights:flags.14?ChatAdminRights banned_rights:flags.15?ChatBannedRights default_banned_rights:flags.18?ChatBannedRights participants_count:flags.17?int usernames:flags2.0?Vector stories_max_id:flags2.4?int color:flags2.7?PeerColor profile_color:flags2.8?PeerColor emoji_status:flags2.9?EmojiStatus level:flags2.10?int = Chat; +channel#fe4478bd flags:# creator:flags.0?true left:flags.2?true broadcast:flags.5?true verified:flags.7?true megagroup:flags.8?true restricted:flags.9?true signatures:flags.11?true min:flags.12?true scam:flags.19?true has_link:flags.20?true has_geo:flags.21?true slowmode_enabled:flags.22?true call_active:flags.23?true call_not_empty:flags.24?true fake:flags.25?true gigagroup:flags.26?true noforwards:flags.27?true join_to_send:flags.28?true join_request:flags.29?true forum:flags.30?true flags2:# stories_hidden:flags2.1?true stories_hidden_min:flags2.2?true stories_unavailable:flags2.3?true signature_profiles:flags2.12?true id:long access_hash:flags.13?long title:string username:flags.6?string photo:ChatPhoto date:int restriction_reason:flags.9?Vector admin_rights:flags.14?ChatAdminRights banned_rights:flags.15?ChatBannedRights default_banned_rights:flags.18?ChatBannedRights participants_count:flags.17?int usernames:flags2.0?Vector stories_max_id:flags2.4?int color:flags2.7?PeerColor profile_color:flags2.8?PeerColor emoji_status:flags2.9?EmojiStatus level:flags2.10?int subscription_until_date:flags2.11?int = Chat; channelForbidden#17d493d5 flags:# broadcast:flags.5?true megagroup:flags.8?true id:long access_hash:long title:string until_date:flags.16?int = Chat; chatFull#2633421b flags:# can_set_username:flags.7?true has_scheduled:flags.8?true translations_disabled:flags.19?true id:long about:string participants:ChatParticipants chat_photo:flags.2?Photo notify_settings:PeerNotifySettings exported_invite:flags.13?ExportedChatInvite bot_info:flags.3?Vector pinned_msg_id:flags.6?int folder_id:flags.11?int call:flags.12?InputGroupCall ttl_period:flags.14?int groupcall_default_join_as:flags.15?Peer theme_emoticon:flags.16?string requests_pending:flags.17?int recent_requesters:flags.17?Vector available_reactions:flags.18?ChatReactions reactions_limit:flags.20?int = ChatFull; -channelFull#bbab348d flags:# can_view_participants:flags.3?true can_set_username:flags.6?true can_set_stickers:flags.7?true hidden_prehistory:flags.10?true can_set_location:flags.16?true has_scheduled:flags.19?true can_view_stats:flags.20?true blocked:flags.22?true flags2:# can_delete_channel:flags2.0?true antispam:flags2.1?true participants_hidden:flags2.2?true translations_disabled:flags2.3?true stories_pinned_available:flags2.5?true view_forum_as_messages:flags2.6?true restricted_sponsored:flags2.11?true can_view_revenue:flags2.12?true paid_media_allowed:flags2.14?true can_view_stars_revenue:flags2.15?true id:long about:string participants_count:flags.0?int admins_count:flags.1?int kicked_count:flags.2?int banned_count:flags.2?int online_count:flags.13?int read_inbox_max_id:int read_outbox_max_id:int unread_count:int chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:flags.23?ExportedChatInvite bot_info:Vector migrated_from_chat_id:flags.4?long migrated_from_max_id:flags.4?int pinned_msg_id:flags.5?int stickerset:flags.8?StickerSet available_min_id:flags.9?int folder_id:flags.11?int linked_chat_id:flags.14?long location:flags.15?ChannelLocation slowmode_seconds:flags.17?int slowmode_next_send_date:flags.18?int stats_dc:flags.12?int pts:int call:flags.21?InputGroupCall ttl_period:flags.24?int pending_suggestions:flags.25?Vector groupcall_default_join_as:flags.26?Peer theme_emoticon:flags.27?string requests_pending:flags.28?int recent_requesters:flags.28?Vector default_send_as:flags.29?Peer available_reactions:flags.30?ChatReactions reactions_limit:flags2.13?int stories:flags2.4?PeerStories wallpaper:flags2.7?WallPaper boosts_applied:flags2.8?int boosts_unrestrict:flags2.9?int emojiset:flags2.10?StickerSet = ChatFull; +channelFull#bbab348d flags:# can_view_participants:flags.3?true can_set_username:flags.6?true can_set_stickers:flags.7?true hidden_prehistory:flags.10?true can_set_location:flags.16?true has_scheduled:flags.19?true can_view_stats:flags.20?true blocked:flags.22?true flags2:# can_delete_channel:flags2.0?true antispam:flags2.1?true participants_hidden:flags2.2?true translations_disabled:flags2.3?true stories_pinned_available:flags2.5?true view_forum_as_messages:flags2.6?true restricted_sponsored:flags2.11?true can_view_revenue:flags2.12?true paid_media_allowed:flags2.14?true can_view_stars_revenue:flags2.15?true paid_reactions_available:flags2.16?true id:long about:string participants_count:flags.0?int admins_count:flags.1?int kicked_count:flags.2?int banned_count:flags.2?int online_count:flags.13?int read_inbox_max_id:int read_outbox_max_id:int unread_count:int chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:flags.23?ExportedChatInvite bot_info:Vector migrated_from_chat_id:flags.4?long migrated_from_max_id:flags.4?int pinned_msg_id:flags.5?int stickerset:flags.8?StickerSet available_min_id:flags.9?int folder_id:flags.11?int linked_chat_id:flags.14?long location:flags.15?ChannelLocation slowmode_seconds:flags.17?int slowmode_next_send_date:flags.18?int stats_dc:flags.12?int pts:int call:flags.21?InputGroupCall ttl_period:flags.24?int pending_suggestions:flags.25?Vector groupcall_default_join_as:flags.26?Peer theme_emoticon:flags.27?string requests_pending:flags.28?int recent_requesters:flags.28?Vector default_send_as:flags.29?Peer available_reactions:flags.30?ChatReactions reactions_limit:flags2.13?int stories:flags2.4?PeerStories wallpaper:flags2.7?WallPaper boosts_applied:flags2.8?int boosts_unrestrict:flags2.9?int emojiset:flags2.10?StickerSet = ChatFull; chatParticipant#c02d4007 user_id:long inviter_id:long date:int = ChatParticipant; chatParticipantCreator#e46bcee4 user_id:long = ChatParticipant; @@ -604,11 +605,11 @@ auth.passwordRecovery#137948a5 email_pattern:string = auth.PasswordRecovery; receivedNotifyMessage#a384b779 id:int flags:int = ReceivedNotifyMessage; -chatInviteExported#ab4a819 flags:# revoked:flags.0?true permanent:flags.5?true request_needed:flags.6?true link:string admin_id:long date:int start_date:flags.4?int expire_date:flags.1?int usage_limit:flags.2?int usage:flags.3?int requested:flags.7?int title:flags.8?string = ExportedChatInvite; +chatInviteExported#93f2df18 flags:# revoked:flags.0?true permanent:flags.5?true request_needed:flags.6?true link:string admin_id:long date:int start_date:flags.4?int expire_date:flags.1?int usage_limit:flags.2?int usage:flags.3?int requested:flags.7?int title:flags.8?string subscription_pricing:flags.9?StarsSubscriptionPricing = ExportedChatInvite; chatInvitePublicJoinRequests#ed107ab7 = ExportedChatInvite; chatInviteAlready#5a686d7c chat:Chat = ChatInvite; -chatInvite#cde0ec40 flags:# channel:flags.0?true broadcast:flags.1?true public:flags.2?true megagroup:flags.3?true request_needed:flags.6?true verified:flags.7?true scam:flags.8?true fake:flags.9?true title:string about:flags.5?string photo:Photo participants_count:int participants:flags.4?Vector color:int = ChatInvite; +chatInvite#fe65389d flags:# channel:flags.0?true broadcast:flags.1?true public:flags.2?true megagroup:flags.3?true request_needed:flags.6?true verified:flags.7?true scam:flags.8?true fake:flags.9?true can_refulfill_subscription:flags.11?true title:string about:flags.5?string photo:Photo participants_count:int participants:flags.4?Vector color:int subscription_pricing:flags.10?StarsSubscriptionPricing subscription_form_id:flags.12?long = ChatInvite; chatInvitePeek#61695cb0 chat:Chat expires:int = ChatInvite; inputStickerSetEmpty#ffb62b95 = InputStickerSet; @@ -694,8 +695,8 @@ updates.channelDifference#2064674e flags:# final:flags.0?true pts:int timeout:fl channelMessagesFilterEmpty#94d42ee7 = ChannelMessagesFilter; channelMessagesFilter#cd77d957 flags:# exclude_new_messages:flags.1?true ranges:Vector = ChannelMessagesFilter; -channelParticipant#c00c07c0 user_id:long date:int = ChannelParticipant; -channelParticipantSelf#35a8bfa7 flags:# via_request:flags.0?true user_id:long inviter_id:long date:int = ChannelParticipant; +channelParticipant#cb397619 flags:# user_id:long date:int subscription_until_date:flags.0?int = ChannelParticipant; +channelParticipantSelf#4f607bef flags:# via_request:flags.0?true user_id:long inviter_id:long date:int subscription_until_date:flags.1?int = ChannelParticipant; channelParticipantCreator#2fe601d3 flags:# user_id:long admin_rights:ChatAdminRights rank:flags.0?string = ChannelParticipant; channelParticipantAdmin#34c3bb53 flags:# can_edit:flags.0?true self:flags.1?true user_id:long inviter_id:flags.1?long promoted_by:long date:int admin_rights:ChatAdminRights rank:flags.2?string = ChannelParticipant; channelParticipantBanned#6df8014e flags:# left:flags.0?true peer:Peer kicked_by:long date:int banned_rights:ChatBannedRights = ChannelParticipant; @@ -1399,7 +1400,7 @@ auth.loggedOut#c3a2835f flags:# future_auth_token:flags.0?bytes = auth.LoggedOut reactionCount#a3d1cb80 flags:# chosen_order:flags.0?int reaction:Reaction count:int = ReactionCount; -messageReactions#4f2b9479 flags:# min:flags.0?true can_see_list:flags.2?true reactions_as_tags:flags.3?true results:Vector recent_reactions:flags.1?Vector = MessageReactions; +messageReactions#a339f0b flags:# min:flags.0?true can_see_list:flags.2?true reactions_as_tags:flags.3?true results:Vector recent_reactions:flags.1?Vector top_reactors:flags.4?Vector = MessageReactions; messages.messageReactionsList#31bd492d flags:# count:int reactions:Vector chats:Vector users:Vector next_offset:flags.0?string = messages.MessageReactionsList; @@ -1456,6 +1457,7 @@ inputInvoiceMessage#c5b56859 peer:InputPeer msg_id:int = InputInvoice; inputInvoiceSlug#c326caef slug:string = InputInvoice; inputInvoicePremiumGiftCode#98986c0d purpose:InputStorePaymentPurpose option:PremiumGiftCodeOption = InputInvoice; inputInvoiceStars#65f00ce3 purpose:InputStorePaymentPurpose = InputInvoice; +inputInvoiceChatInviteSubscription#34e793f1 hash:string = InputInvoice; payments.exportedInvoice#aed0cbd9 url:string = payments.ExportedInvoice; @@ -1484,6 +1486,7 @@ account.emojiStatuses#90c467d1 hash:long statuses:Vector = account. reactionEmpty#79f5d419 = Reaction; reactionEmoji#1b2286b8 emoticon:string = Reaction; reactionCustomEmoji#8935fc73 document_id:long = Reaction; +reactionPaid#523da4eb = Reaction; chatReactionsNone#eafc32bc = ChatReactions; chatReactionsAll#52928bca flags:# allow_custom:flags.0?true = ChatReactions; @@ -1810,9 +1813,9 @@ starsTransactionPeerAds#60682812 = StarsTransactionPeer; starsTopupOption#bd915c0 flags:# extended:flags.1?true stars:long store_product:flags.0?string currency:string amount:long = StarsTopupOption; -starsTransaction#2db5418f flags:# refund:flags.3?true pending:flags.4?true failed:flags.6?true gift:flags.10?true id:string stars:long date:int peer:StarsTransactionPeer title:flags.0?string description:flags.1?string photo:flags.2?WebDocument transaction_date:flags.5?int transaction_url:flags.5?string bot_payload:flags.7?bytes msg_id:flags.8?int extended_media:flags.9?Vector = StarsTransaction; +starsTransaction#433aeb2b flags:# refund:flags.3?true pending:flags.4?true failed:flags.6?true gift:flags.10?true reaction:flags.11?true id:string stars:long date:int peer:StarsTransactionPeer title:flags.0?string description:flags.1?string photo:flags.2?WebDocument transaction_date:flags.5?int transaction_url:flags.5?string bot_payload:flags.7?bytes msg_id:flags.8?int extended_media:flags.9?Vector subscription_period:flags.12?int = StarsTransaction; -payments.starsStatus#8cf4ee60 flags:# balance:long history:Vector next_offset:flags.0?string chats:Vector users:Vector = payments.StarsStatus; +payments.starsStatus#bbfa316c flags:# balance:long subscriptions:flags.1?Vector subscriptions_next_offset:flags.2?string subscriptions_missing_balance:flags.4?long history:flags.3?Vector next_offset:flags.0?string chats:Vector users:Vector = payments.StarsStatus; foundStory#e87acbc0 peer:Peer story:StoryItem = FoundStory; @@ -1838,6 +1841,12 @@ botPreviewMedia#23e91ba3 date:int media:MessageMedia = BotPreviewMedia; bots.previewInfo#ca71d64 media:Vector lang_codes:Vector = bots.PreviewInfo; +starsSubscriptionPricing#5416d58 period:int amount:long = StarsSubscriptionPricing; + +starsSubscription#d073f1e6 flags:# canceled:flags.0?true can_refulfill:flags.1?true missing_balance:flags.2?true id:string peer:Peer until_date:int pricing:StarsSubscriptionPricing = StarsSubscription; + +messageReactor#ef00d448 flags:# top:flags.0?true my:flags.1?true peer_id:Peer count:int = MessageReactor; + ---functions--- invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X; @@ -2057,7 +2066,7 @@ messages.readMessageContents#36a73f77 id:Vector = messages.AffectedMessages messages.getStickers#d5a5d3a1 emoticon:string hash:long = messages.Stickers; messages.getAllStickers#b8a0a1a8 hash:long = messages.AllStickers; messages.getWebPagePreview#8b68b0cc flags:# message:string entities:flags.3?Vector = MessageMedia; -messages.exportChatInvite#a02ce5d5 flags:# legacy_revoke_permanent:flags.2?true request_needed:flags.3?true peer:InputPeer expire_date:flags.0?int usage_limit:flags.1?int title:flags.4?string = ExportedChatInvite; +messages.exportChatInvite#a455de90 flags:# legacy_revoke_permanent:flags.2?true request_needed:flags.3?true peer:InputPeer expire_date:flags.0?int usage_limit:flags.1?int title:flags.4?string subscription_pricing:flags.5?StarsSubscriptionPricing = ExportedChatInvite; messages.checkChatInvite#3eadb1bb hash:string = ChatInvite; messages.importChatInvite#6c50051c hash:string = Updates; messages.getStickerSet#c8a0ec74 stickerset:InputStickerSet hash:int = messages.StickerSet; @@ -2171,7 +2180,7 @@ messages.saveDefaultSendAs#ccfddf96 peer:InputPeer send_as:InputPeer = Bool; messages.sendReaction#d30d78d4 flags:# big:flags.1?true add_to_recent:flags.2?true peer:InputPeer msg_id:int reaction:flags.0?Vector = Updates; messages.getMessagesReactions#8bba90e6 peer:InputPeer id:Vector = Updates; messages.getMessageReactionsList#461b3f48 flags:# peer:InputPeer id:int reaction:flags.0?Reaction offset:flags.1?string limit:int = messages.MessageReactionsList; -messages.setChatAvailableReactions#5a150bd4 flags:# peer:InputPeer available_reactions:ChatReactions reactions_limit:flags.0?int = Updates; +messages.setChatAvailableReactions#864b2581 flags:# peer:InputPeer available_reactions:ChatReactions reactions_limit:flags.0?int paid_enabled:flags.1?Bool = Updates; messages.getAvailableReactions#18dea0ac hash:int = messages.AvailableReactions; messages.setDefaultReaction#4f47a016 reaction:Reaction = Bool; messages.translateText#63183030 flags:# peer:flags.0?InputPeer id:flags.0?Vector text:flags.1?Vector to_lang:string = messages.TranslatedText; @@ -2234,6 +2243,7 @@ messages.editFactCheck#589ee75 peer:InputPeer msg_id:int text:TextWithEntities = messages.deleteFactCheck#d1da940c peer:InputPeer msg_id:int = Updates; messages.getFactCheck#b9cdc5ee peer:InputPeer msg_id:Vector = Vector; messages.requestMainWebView#c9e01e7b flags:# compact:flags.7?true peer:InputPeer bot:InputUser start_param:flags.1?string theme_params:flags.0?DataJSON platform:string = WebViewResult; +messages.sendPaidReaction#1e55d333 peer:InputPeer msg_id:int count:int random_id:long = Updates; updates.getState#edd4882a = updates.State; updates.getDifference#19c2f763 flags:# pts:int pts_limit:flags.1?int pts_total_limit:flags.0?int date:int qts:int qts_limit:flags.2?int = updates.Difference; @@ -2299,7 +2309,7 @@ channels.leaveChannel#f836aa95 channel:InputChannel = Updates; channels.inviteToChannel#c9e33d54 channel:InputChannel users:Vector = messages.InvitedUsers; channels.deleteChannel#c0111fe3 channel:InputChannel = Updates; channels.exportMessageLink#e63fadeb flags:# grouped:flags.0?true thread:flags.1?true channel:InputChannel id:int = ExportedMessageLink; -channels.toggleSignatures#1f69b606 channel:InputChannel enabled:Bool = Updates; +channels.toggleSignatures#418d549c flags:# signatures_enabled:flags.0?true profiles_enabled:flags.1?true channel:InputChannel = Updates; channels.getAdminedPublicChannels#f8b036af flags:# by_location:flags.0?true check_limit:flags.1?true for_personal:flags.2?true = messages.Chats; channels.editBanned#96e6cd81 channel:InputChannel participant:InputPeer banned_rights:ChatBannedRights = Updates; channels.getAdminLog#33ddf480 flags:# channel:InputChannel q:string events_filter:flags.0?ChannelAdminLogEventsFilter admins:flags.1?Vector max_id:long min_id:long limit:int = channels.AdminLogResults; @@ -2388,7 +2398,7 @@ payments.getGiveawayInfo#f4239425 peer:InputPeer msg_id:int = payments.GiveawayI payments.launchPrepaidGiveaway#5ff58f20 peer:InputPeer giveaway_id:long purpose:InputStorePaymentPurpose = Updates; payments.getStarsTopupOptions#c00ec7d3 = Vector; payments.getStarsStatus#104fcfa7 peer:InputPeer = payments.StarsStatus; -payments.getStarsTransactions#97938d5a flags:# inbound:flags.0?true outbound:flags.1?true ascending:flags.2?true peer:InputPeer offset:string limit:int = payments.StarsStatus; +payments.getStarsTransactions#69da4557 flags:# inbound:flags.0?true outbound:flags.1?true ascending:flags.2?true subscription_id:flags.3?string peer:InputPeer offset:string limit:int = payments.StarsStatus; payments.sendStarsForm#2bb731d flags:# form_id:long invoice:InputInvoice = payments.PaymentResult; payments.refundStarsCharge#25ae8f4a user_id:InputUser charge_id:string = Updates; payments.getStarsRevenueStats#d91ffad6 flags:# dark:flags.0?true peer:InputPeer = payments.StarsRevenueStats; @@ -2396,6 +2406,9 @@ payments.getStarsRevenueWithdrawalUrl#13bbe8b3 peer:InputPeer stars:long passwor payments.getStarsRevenueAdsAccountUrl#d1d7efc5 peer:InputPeer = payments.StarsRevenueAdsAccountUrl; payments.getStarsTransactionsByID#27842d2e peer:InputPeer id:Vector = payments.StarsStatus; payments.getStarsGiftOptions#d3c96bc8 flags:# user_id:flags.0?InputUser = Vector; +payments.getStarsSubscriptions#32512c5 flags:# missing_balance:flags.0?true peer:InputPeer offset:string = payments.StarsStatus; +payments.changeStarsSubscription#c7770878 flags:# peer:InputPeer subscription_id:string canceled:flags.0?Bool = Bool; +payments.fulfillStarsSubscription#cc5bebb3 peer:InputPeer subscription_id:string = Bool; stickers.createStickerSet#9021ab67 flags:# masks:flags.0?true emojis:flags.5?true text_color:flags.6?true user_id:InputUser title:string short_name:string thumb:flags.2?InputDocument stickers:Vector software:flags.3?string = messages.StickerSet; stickers.removeStickerFromSet#f7760f51 sticker:InputDocument = messages.StickerSet; @@ -2515,4 +2528,4 @@ smsjobs.finishJob#4f1ebf24 flags:# job_id:string error:flags.0?string = Bool; fragment.getCollectibleInfo#be1e85ba collectible:InputCollectible = fragment.CollectibleInfo; -// LAYER 185 +// LAYER 186 From 126fd89bb7d5d16a2124459cc866e3ecc694b8ad Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 2 Aug 2024 15:21:39 +0200 Subject: [PATCH 014/104] Remove accidentally added files from git. --- .../_history_view_reactions_button.cpp | 1422 ----------------- .../_history_view_reactions_button.h | 373 ----- 2 files changed, 1795 deletions(-) delete mode 100644 Telegram/SourceFiles/history/view/reactions/_history_view_reactions_button.cpp delete mode 100644 Telegram/SourceFiles/history/view/reactions/_history_view_reactions_button.h diff --git a/Telegram/SourceFiles/history/view/reactions/_history_view_reactions_button.cpp b/Telegram/SourceFiles/history/view/reactions/_history_view_reactions_button.cpp deleted file mode 100644 index e4578c7b5..000000000 --- a/Telegram/SourceFiles/history/view/reactions/_history_view_reactions_button.cpp +++ /dev/null @@ -1,1422 +0,0 @@ -/* -This file is part of Telegram Desktop, -the official desktop application for the Telegram messaging service. - -For license and copyright information please follow this link: -https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL -*/ -#include "history/view/history_view_react_button.h" - -#include "history/view/history_view_cursor_state.h" -#include "history/history_item.h" -#include "ui/chat/chat_style.h" -#include "ui/chat/message_bubble.h" -#include "ui/widgets/popup_menu.h" -#include "data/data_message_reactions.h" -#include "data/data_session.h" -#include "data/data_document.h" -#include "data/data_document_media.h" -#include "data/data_peer_values.h" -#include "lang/lang_keys.h" -#include "core/click_handler_types.h" -#include "lottie/lottie_icon.h" -#include "main/main_session.h" -#include "base/event_filter.h" -#include "styles/style_chat.h" -#include "styles/style_menu_icons.h" - -namespace HistoryView::Reactions { -namespace { - -constexpr auto kDivider = 4; -constexpr auto kToggleDuration = crl::time(120); -constexpr auto kActivateDuration = crl::time(150); -constexpr auto kExpandDuration = crl::time(300); -constexpr auto kCollapseDuration = crl::time(250); -constexpr auto kEmojiCacheIndex = 0; -constexpr auto kButtonShowDelay = crl::time(300); -constexpr auto kButtonExpandDelay = crl::time(25); -constexpr auto kButtonHideDelay = crl::time(300); -constexpr auto kButtonExpandedHideDelay = crl::time(0); -constexpr auto kSizeForDownscale = 96; -constexpr auto kHoverScaleDuration = crl::time(200); -constexpr auto kHoverScale = 1.24; -constexpr auto kMaxReactionsScrollAtOnce = 2; - -[[nodiscard]] QPoint LocalPosition(not_null e) { -#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) - return e->position().toPoint(); -#else // Qt >= 6.0 - return e->pos(); -#endif // Qt >= 6.0 -} - -[[nodiscard]] QSize CountMaxSizeWithMargins(style::margins margins) { - return QRect( - QPoint(), - st::reactionCornerSize - ).marginsAdded(margins).size(); -} - -[[nodiscard]] QSize CountOuterSize() { - return CountMaxSizeWithMargins(st::reactionCornerShadow); -} - -[[nodiscard]] int CornerImageSize(float64 scale) { - return int(base::SafeRound(st::reactionCornerImage * scale)); -} - -[[nodiscard]] int MainReactionSize() { - return style::ConvertScale(kSizeForDownscale); -} - -[[nodiscard]] std::shared_ptr CreateIcon( - not_null media, - int size, - int frame) { - Expects(media->loaded()); - - return std::make_shared(Lottie::IconDescriptor{ - .path = media->owner()->filepath(true), - .json = media->bytes(), - .sizeOverride = QSize(size, size), - .frame = frame, - }); -} - -} // namespace - -Button::Button( - Fn update, - ButtonParameters parameters, - Fn toggleExpanded, - Fn hide) -: _update(std::move(update)) -, _toggleExpanded(std::move(toggleExpanded)) -, _finalScale(ScaleForState(_state)) -, _collapsed(QPoint(), CountOuterSize()) -, _finalHeight(_collapsed.height()) -, _expandTimer([=] { _toggleExpanded(true); }) -, _hideTimer(hide) { - applyParameters(parameters, nullptr); -} - -Button::~Button() = default; - -void Button::expandWithoutCustom() { - applyState(State::Inside, _update); -} - -bool Button::isHidden() const { - return (_state == State::Hidden) && !_opacityAnimation.animating(); -} - -QRect Button::geometry() const { - return _geometry; -} - -int Button::expandedHeight() const { - return _expandedHeight; -} - -int Button::scroll() const { - return _scroll; -} - -int Button::scrollMax() const { - return _expandedInnerHeight - _expandedHeight; -} - -float64 Button::expandAnimationOpacity(float64 expandRatio) const { - return (_collapseType == CollapseType::Fade) - ? expandRatio - : 1.; -} - -int Button::expandAnimationScroll(float64 expandRatio) const { - return (_collapseType == CollapseType::Scroll && expandRatio < 1.) - ? std::clamp(int(base::SafeRound(expandRatio * _scroll)), 0, _scroll) - : _scroll; -} - -bool Button::expandUp() const { - return (_expandDirection == ExpandDirection::Up); -} - -bool Button::consumeWheelEvent(not_null e) { - const auto scrollMax = (_expandedInnerHeight - _expandedHeight); - if (_state != State::Inside - || scrollMax <= 0 - || !_geometry.contains(LocalPosition(e))) { - return false; - } - const auto delta = e->angleDelta(); - const auto horizontal = std::abs(delta.x()) > std::abs(delta.y()); - if (horizontal) { - return false; - } - const auto between = st::reactionCornerSkip; - const auto oneHeight = (st::reactionCornerSize.height() + between); - const auto max = oneHeight * kMaxReactionsScrollAtOnce; - const auto shift = std::clamp( - delta.y() * (expandUp() ? 1 : -1), - -max, - max); - _scroll = std::clamp(_scroll + shift, 0, scrollMax); - _update(_geometry); - e->accept(); - return true; -} - -void Button::applyParameters(ButtonParameters parameters) { - applyParameters(std::move(parameters), _update); -} - -void Button::applyParameters( - ButtonParameters parameters, - Fn update) { - const auto shift = parameters.center - _collapsed.center(); - _collapsed = _collapsed.translated(shift); - updateGeometry(update); - const auto inner = _geometry.marginsRemoved(st::reactionCornerShadow); - const auto active = inner.marginsAdded( - st::reactionCornerActiveAreaPadding - ).contains(parameters.pointer); - const auto inside = inner.contains(parameters.pointer) - || (active && (_state == State::Inside)); - if (_state != State::Inside && !_heightAnimation.animating()) { - updateExpandDirection(parameters); - } - const auto delayInside = inside && (_state != State::Inside); - if (!delayInside) { - _expandTimer.cancel(); - _lastGlobalPosition = std::nullopt; - } else { - const auto globalPositionChanged = _lastGlobalPosition - && (*_lastGlobalPosition != parameters.globalPointer); - if (globalPositionChanged || _state == State::Hidden) { - _expandTimer.callOnce(kButtonExpandDelay); - } - _lastGlobalPosition = parameters.globalPointer; - } - const auto wasInside = (_state == State::Inside); - const auto state = (inside && !delayInside) - ? State::Inside - : active - ? State::Active - : State::Shown; - applyState(state, update); - if (parameters.outside && _state == State::Shown) { - _hideTimer.callOnce(wasInside - ? kButtonExpandedHideDelay - : kButtonHideDelay); - } else { - _hideTimer.cancel(); - } -} - -void Button::updateExpandDirection(const ButtonParameters ¶meters) { - const auto maxAddedHeight = (parameters.reactionsCount - 1) - * (st::reactionCornerSize.height() + st::reactionCornerSkip) - + (parameters.reactionsCount > 1 ? 2 * st::reactionExpandedSkip : 0); - _expandedInnerHeight = _collapsed.height() + maxAddedHeight; - const auto addedHeight = std::min( - maxAddedHeight, - st::reactionCornerAddedHeightMax); - _expandedHeight = _collapsed.height() + addedHeight; - _scroll = std::clamp(_scroll, 0, scrollMax()); - if (parameters.reactionsCount < 2) { - return; - } - const auto up = (_collapsed.y() - addedHeight >= parameters.visibleTop) - || (_collapsed.y() + _collapsed.height() + addedHeight - > parameters.visibleBottom); - _expandDirection = up ? ExpandDirection::Up : ExpandDirection::Down; -} - -void Button::updateGeometry(Fn update) { - const auto added = int(base::SafeRound( - _heightAnimation.value(_finalHeight) - )) - _collapsed.height(); - if (!added && _state != State::Inside) { - _scroll = 0; - } - const auto geometry = _collapsed.marginsAdded({ - 0, - (_expandDirection == ExpandDirection::Up) ? added : 0, - 0, - (_expandDirection == ExpandDirection::Down) ? added : 0, - }); - if (_geometry != geometry) { - if (update) { - update(_geometry); - } - _geometry = geometry; - if (update) { - update(_geometry); - } - } -} - -void Button::applyState(State state) { - applyState(state, _update); -} - -void Button::applyState(State state, Fn update) { - if (state == State::Hidden) { - _expandTimer.cancel(); - _hideTimer.cancel(); - } - const auto finalHeight = (state == State::Hidden) - ? _heightAnimation.value(_finalHeight) - : (state == State::Inside) - ? _expandedHeight - : _collapsed.height(); - if (_finalHeight != finalHeight) { - if (state == State::Hidden) { - _heightAnimation.stop(); - } else { - if (!_heightAnimation.animating()) { - _collapseType = (_scroll < st::reactionCollapseFadeThreshold) - ? CollapseType::Scroll - : CollapseType::Fade; - } - _heightAnimation.start( - [=] { updateGeometry(_update); }, - _finalHeight, - finalHeight, - (state == State::Inside - ? kExpandDuration - : kCollapseDuration), - anim::easeOutCirc); - } - _finalHeight = finalHeight; - } - updateGeometry(update); - if (_state == state) { - return; - } - const auto duration = (state == State::Hidden || _state == State::Hidden) - ? kToggleDuration - : kActivateDuration; - const auto finalScale = ScaleForState(state); - _opacityAnimation.start( - [=] { _update(_geometry); }, - OpacityForScale(ScaleForState(_state)), - OpacityForScale(ScaleForState(state)), - duration, - anim::sineInOut); - if (state != State::Hidden && _finalScale != finalScale) { - _scaleAnimation.start( - [=] { _update(_geometry); }, - _finalScale, - finalScale, - duration, - anim::sineInOut); - _finalScale = finalScale; - } - _state = state; - _toggleExpanded(false); -} - -float64 Button::ScaleForState(State state) { - switch (state) { - case State::Hidden: return 1. / 3; - case State::Shown: return 2. / 3; - case State::Active: - case State::Inside: return 1.; - } - Unexpected("State in ReactionButton::ScaleForState."); -} - -float64 Button::OpacityForScale(float64 scale) { - return std::min( - ((scale - ScaleForState(State::Hidden)) - / (ScaleForState(State::Shown) - ScaleForState(State::Hidden))), - 1.); -} - -float64 Button::currentScale() const { - return _scaleAnimation.value(_finalScale); -} - -float64 Button::currentOpacity() const { - return _opacityAnimation.value(OpacityForScale(ScaleForState(_state))); -} - -Manager::Manager( - QWidget *wheelEventsTarget, - rpl::producer uniqueLimitValue, - Fn buttonUpdate, - IconFactory iconFactory) -: _iconFactory(std::move(iconFactory)) -, _outer(CountOuterSize()) -, _inner(QRect({}, st::reactionCornerSize)) -, _cachedRound( - st::reactionCornerSize, - st::reactionCornerShadow, - _inner.width()) -, _uniqueLimit(std::move(uniqueLimitValue)) -, _buttonShowTimer([=] { showButtonDelayed(); }) -, _buttonUpdate(std::move(buttonUpdate)) { - _inner.translate(QRect({}, _outer).center() - _inner.center()); - - _emojiParts = _cachedRound.PrepareFramesCache(_outer); - _expandedBuffer = _cachedRound.PrepareImage(QSize( - _outer.width(), - _outer.height() + st::reactionCornerAddedHeightMax)); - if (wheelEventsTarget) { - stealWheelEvents(wheelEventsTarget); - } - - _uniqueLimit.changes( - ) | rpl::start_with_next([=] { - applyListFilters(); - }, _lifetime); - - _createChooseCallback = [=](ReactionId id) { - return [=] { - if (auto chosen = lookupChosen(id)) { - _chosen.fire(std::move(chosen)); - } - }; - }; -} - -ChosenReaction Manager::lookupChosen(const ReactionId &id) const { - auto result = ChosenReaction{ - .context = _buttonContext, - .id = id, - }; - const auto button = _button.get(); - const auto i = ranges::find(_icons, id, &ReactionIcons::id); - if (i == end(_icons) || !button) { - return result; - } - const auto &icon = *i; - if (const auto &appear = icon->appear; appear && appear->animating()) { - result.icon = CreateIcon( - icon->appearAnimation->activeMediaView().get(), - appear->width(), - appear->frameIndex()); - } else if (const auto &select = icon->select) { - result.icon = CreateIcon( - icon->selectAnimation->activeMediaView().get(), - select->width(), - select->frameIndex()); - } - const auto index = (i - begin(_icons)); - const auto between = st::reactionCornerSkip; - const auto oneHeight = (st::reactionCornerSize.height() + between); - const auto expanded = (_icons.size() > 1); - const auto skip = (expanded ? st::reactionExpandedSkip : 0); - const auto scroll = button->scroll(); - const auto local = skip + index * oneHeight - scroll; - const auto geometry = button->geometry(); - const auto top = button->expandUp() - ? (geometry.height() - local - _outer.height()) - : local; - const auto rect = QRect(geometry.topLeft() + QPoint(0, top), _outer); - const auto imageSize = int(base::SafeRound( - st::reactionCornerImage * kHoverScale)); - result.geometry = QRect( - rect.x() + (rect.width() - imageSize) / 2, - rect.y() + (rect.height() - imageSize) / 2, - imageSize, - imageSize); - return result; -} - -bool Manager::applyUniqueLimit() const { - const auto limit = _uniqueLimit.current(); - return _buttonContext - && (limit > 0) - && (_buttonAlreadyNotMineCount >= limit); -} - -void Manager::applyListFilters() { - const auto limited = applyUniqueLimit(); - auto icons = std::vector>(); - icons.reserve(_list.size()); - auto showPremiumLock = (ReactionIcons*)nullptr; - auto favoriteIndex = -1; - for (auto &icon : _list) { - const auto &id = icon.id; - const auto add = limited - ? _buttonAlreadyList.contains(id) - : id.emoji().isEmpty() - ? _filter.customAllowed - : (!_filter.allowed || _filter.allowed->contains(id.emoji())); - if (add) { - if (icon.premium - && !_allowSendingPremium - && !_buttonAlreadyList.contains(id)) { - if (_premiumPossible) { - showPremiumLock = &icon; - } else { - clearStateForHidden(icon); - } - } else { - icon.premiumLock = false; - if (id == _favorite) { - favoriteIndex = int(icons.size()); - } - icons.push_back(&icon); - } - } else { - clearStateForHidden(icon); - } - } - if (showPremiumLock) { - showPremiumLock->premiumLock = true; - icons.push_back(showPremiumLock); - } - if (favoriteIndex > 0) { - const auto first = begin(icons); - std::rotate(first, first + favoriteIndex, first + favoriteIndex + 1); - } - if (!limited && _filter.customAllowed && icons.size() > 1) { - icons.erase(begin(icons) + 1, end(icons)); - } - if (_icons == icons) { - return; - } - const auto selected = _selectedIcon; - setSelectedIcon(-1); - _icons = std::move(icons); - setSelectedIcon((selected < _icons.size()) ? selected : -1); - resolveMainReactionIcon(); -} - -void Manager::stealWheelEvents(not_null target) { - base::install_event_filter(target, [=](not_null e) { - if (e->type() != QEvent::Wheel - || !consumeWheelEvent(static_cast(e.get()))) { - return base::EventFilterResult::Continue; - } - Ui::SendSynteticMouseEvent(target, QEvent::MouseMove, Qt::NoButton); - return base::EventFilterResult::Cancel; - }); -} - -Manager::~Manager() = default; - -void Manager::updateButton(ButtonParameters parameters) { - if (parameters.cursorLeft) { - if (_menu) { - return; - } else if (_externalSelectorShown) { - setSelectedIcon(-1); - return; - } - } - const auto contextChanged = (_buttonContext != parameters.context); - if (contextChanged) { - setSelectedIcon(-1); - if (_button) { - _button->applyState(ButtonState::Hidden); - _buttonHiding.push_back(std::move(_button)); - } - _buttonShowTimer.cancel(); - _scheduledParameters = std::nullopt; - } - _buttonContext = parameters.context; - parameters.reactionsCount = _icons.size(); - if (!_buttonContext || !parameters.reactionsCount) { - return; - } else if (_button) { - _button->applyParameters(parameters); - if (_button->geometry().height() == _outer.height()) { - clearAppearAnimations(); - } - return; - } else if (parameters.outside) { - _buttonShowTimer.cancel(); - _scheduledParameters = std::nullopt; - return; - } - const auto globalPositionChanged = _scheduledParameters - && (_scheduledParameters->globalPointer != parameters.globalPointer); - const auto positionChanged = _scheduledParameters - && (_scheduledParameters->pointer != parameters.pointer); - _scheduledParameters = parameters; - if ((_buttonShowTimer.isActive() && positionChanged) - || globalPositionChanged) { - _buttonShowTimer.callOnce(kButtonShowDelay); - } -} - -void Manager::toggleExpanded(bool expanded) { - if (!_button || !_buttonContext) { - } else if (!expanded || (_filter.customAllowed && !applyUniqueLimit())) { - _expandSelectorRequests.fire({ - .context = _buttonContext, - .button = _button->geometry().marginsRemoved( - st::reactionCornerShadow), - .expanded = expanded, - }); - } else { - _button->expandWithoutCustom(); - } -} - -void Manager::setExternalSelectorShown(rpl::producer shown) { - std::move(shown) | rpl::start_with_next([=](bool shown) { - _externalSelectorShown = shown; - }, _lifetime); -} - -void Manager::showButtonDelayed() { - clearAppearAnimations(); - _button = std::make_unique