From 10d472728c52640bfae0badd4bd8577eb5a96666 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Sun, 6 Apr 2025 00:47:57 +0300 Subject: [PATCH] Added userpic suggestion to top bar in dialogs. --- Telegram/Resources/langs/lang.strings | 2 + Telegram/SourceFiles/boxes/boxes.style | 7 ++ .../dialogs/dialogs_top_bar_suggestion.cpp | 96 ++++++++++++++++--- .../ui/dialogs_top_bar_suggestion_content.cpp | 8 +- .../ui/dialogs_top_bar_suggestion_content.h | 3 + 5 files changed, 104 insertions(+), 12 deletions(-) diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 403cc2fd0b..0871186847 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -3871,6 +3871,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_dialogs_suggestions_premium_upgrade_about" = "Upgrade to the annual payment plan for Telegram Premium now to get the discount."; "lng_dialogs_suggestions_premium_restore_title" = "Get Premium back with up to {text} off"; "lng_dialogs_suggestions_premium_restore_about" = "Your Telegram Premium has recently expired. Tap here to extend it."; +"lng_dialogs_suggestions_userpics_title" = "Add your photo! 📸"; +"lng_dialogs_suggestions_userpics_about" = "Help your friends spot you easily."; "lng_about_random" = "Send a {emoji} emoji to any chat to try your luck."; "lng_about_random_send" = "Send"; diff --git a/Telegram/SourceFiles/boxes/boxes.style b/Telegram/SourceFiles/boxes/boxes.style index 52fb1b43b9..f77b417432 100644 --- a/Telegram/SourceFiles/boxes/boxes.style +++ b/Telegram/SourceFiles/boxes/boxes.style @@ -1129,3 +1129,10 @@ foldersMenu: PopupMenu(popupMenuWithIcons) { itemPadding: margins(54px, 8px, 44px, 8px); } } + +fakeUserpicButton: UserpicButton(defaultUserpicButton) { + size: size(1px, 1px); + photoSize: 1px; + changeIcon: icon {{ "settings/photo", transparent }}; + uploadBg: transparent; +} diff --git a/Telegram/SourceFiles/dialogs/dialogs_top_bar_suggestion.cpp b/Telegram/SourceFiles/dialogs/dialogs_top_bar_suggestion.cpp index 7a8f521425..4f899240c8 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_top_bar_suggestion.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_top_bar_suggestion.cpp @@ -7,12 +7,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "dialogs/dialogs_top_bar_suggestion.h" +#include "api/api_peer_photo.h" #include "api/api_premium.h" #include "apiwrap.h" #include "base/call_delayed.h" #include "core/application.h" #include "core/click_handler_types.h" #include "data/data_birthday.h" +#include "data/data_changes.h" #include "data/data_user.h" #include "dialogs/ui/dialogs_top_bar_suggestion_content.h" #include "info/profile/info_profile_values.h" @@ -20,10 +22,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "main/main_app_config.h" #include "main/main_session.h" #include "settings/settings_premium.h" +#include "ui/controls/userpic_button.h" #include "ui/text/text_utilities.h" +#include "ui/ui_utility.h" #include "ui/wrap/slide_wrap.h" #include "window/window_controller.h" #include "window/window_session_controller.h" +#include "styles/style_boxes.h" +#include "styles/style_dialogs.h" namespace Dialogs { namespace { @@ -38,6 +44,7 @@ constexpr auto kSugSetBirthday = "BIRTHDAY_SETUP"_cs; constexpr auto kSugPremiumAnnual = "PREMIUM_ANNUAL"_cs; constexpr auto kSugPremiumUpgrade = "PREMIUM_UPGRADE"_cs; constexpr auto kSugPremiumRestore = "PREMIUM_RESTORE"_cs; +constexpr auto kSugSetUserpic = "USERPIC_SETUP"_cs; } // namespace @@ -52,6 +59,7 @@ rpl::producer*> TopBarSuggestionValue( Ui::SlideWrap *wrap = nullptr; rpl::lifetime birthdayLifetime; rpl::lifetime premiumLifetime; + rpl::lifetime userpicLifetime; }; const auto state = lifetime.make_state(); const auto ensureWrap = [=] { @@ -79,7 +87,6 @@ rpl::producer*> TopBarSuggestionValue( const auto wrap = state->wrap; using RightIcon = TopBarSuggestionContent::RightIcon; const auto config = &session->appConfig(); - auto hide = false; if (config->suggestionCurrent(kSugSetBirthday.utf8()) && !Data::IsBirthdayToday(session->user()->birthday())) { content->setRightIcon(RightIcon::Close); @@ -116,6 +123,7 @@ rpl::producer*> TopBarSuggestionValue( tr::now, TextWithEntities::Simple)); wrap->toggle(true, anim::type::normal); + return; } else if (session->premiumPossible() && !session->premium()) { const auto isPremiumAnnual = config->suggestionCurrent( kSugPremiumAnnual.utf8()); @@ -171,20 +179,86 @@ rpl::producer*> TopBarSuggestionValue( } }, state->premiumLifetime); api->reload(); - } else { - hide = true; + return; } - } else { - hide = true; } - if (hide) { - wrap->toggle(false, anim::type::normal); - base::call_delayed(st::slideWrapDuration * 2, wrap, [=] { - state->content = nullptr; - state->wrap = nullptr; - consumer.put_next(nullptr); + if (config->suggestionCurrent(kSugSetUserpic.utf8()) + && !session->user()->userpicPhotoId()) { + const auto controller = FindSessionController(parent); + if (!controller) { + return; + } + content->setRightIcon(RightIcon::Close); + const auto upload = Ui::CreateChild( + content, + &controller->window(), + Ui::UserpicButton::Role::ChoosePhoto, + st::uploadUserpicButton); + const auto leftPadding = st::defaultDialogRow.padding.left(); + content->sizeValue() | rpl::filter_size( + ) | rpl::start_with_next([=](const QSize &s) { + upload->raise(); + upload->show(); + upload->moveToLeft( + leftPadding, + (s.height() - upload->height()) / 2); + }, content->lifetime()); + content->setLeftPadding(upload->width() + leftPadding); + upload->chosenImages() | rpl::start_with_next([=]( + Ui::UserpicButton::ChosenImage &&chosen) { + if (chosen.type == Ui::UserpicButton::ChosenType::Set) { + session->api().peerPhoto().upload( + session->user(), + { + std::move(chosen.image), + chosen.markup.documentId, + chosen.markup.colors, + }); + } + }, upload->lifetime()); + + state->userpicLifetime = session->changes().peerUpdates( + session->user(), + Data::PeerUpdate::Flag::Photo + ) | rpl::start_with_next([=] { + if (session->user()->userpicPhotoId()) { + repeat(repeat); + } }); + + content->setHideCallback([=] { + config->dismissSuggestion(kSugSetUserpic.utf8()); + repeat(repeat); + }); + + content->setClickedCallback([=] { + const auto syntetic = [=](QEvent::Type type) { + Ui::SendSynteticMouseEvent( + upload, + type, + Qt::LeftButton, + upload->mapToGlobal(QPoint(0, 0))); + }; + syntetic(QEvent::MouseMove); + syntetic(QEvent::MouseButtonPress); + syntetic(QEvent::MouseButtonRelease); + }); + content->setContent( + tr::lng_dialogs_suggestions_userpics_title( + tr::now, + Ui::Text::Bold), + tr::lng_dialogs_suggestions_userpics_about( + tr::now, + TextWithEntities::Simple)); + wrap->toggle(true, anim::type::normal); + return; } + wrap->toggle(false, anim::type::normal); + base::call_delayed(st::slideWrapDuration * 2, wrap, [=] { + state->content = nullptr; + state->wrap = nullptr; + consumer.put_next(nullptr); + }); }; session->appConfig().value() | rpl::start_with_next([=] { diff --git a/Telegram/SourceFiles/dialogs/ui/dialogs_top_bar_suggestion_content.cpp b/Telegram/SourceFiles/dialogs/ui/dialogs_top_bar_suggestion_content.cpp index c085d9c8e8..badde385e0 100644 --- a/Telegram/SourceFiles/dialogs/ui/dialogs_top_bar_suggestion_content.cpp +++ b/Telegram/SourceFiles/dialogs/ui/dialogs_top_bar_suggestion_content.cpp @@ -67,7 +67,8 @@ void TopBarSuggestionContent::draw(QPainter &p) { const auto r = Ui::RpWidget::rect(); p.fillRect(r, st::historyPinnedBg); Ui::RippleButton::paintRipple(p, 0, 0); - const auto leftPadding = st::defaultDialogRow.padding.left(); + const auto leftPadding = st::defaultDialogRow.padding.left() + + _leftPadding; const auto rightPadding = st::msgReplyBarSkip; const auto topPadding = st::msgReplyPadding.top(); const auto availableWidthNoPhoto = r.width() @@ -174,4 +175,9 @@ void TopBarSuggestionContent::setHideCallback(Fn hideCallback) { _rightHide->setClickedCallback(std::move(hideCallback)); } +void TopBarSuggestionContent::setLeftPadding(int value) { + _leftPadding = value; + update(); +} + } // namespace Dialogs diff --git a/Telegram/SourceFiles/dialogs/ui/dialogs_top_bar_suggestion_content.h b/Telegram/SourceFiles/dialogs/ui/dialogs_top_bar_suggestion_content.h index fc9868cf7c..82b2f3b9f6 100644 --- a/Telegram/SourceFiles/dialogs/ui/dialogs_top_bar_suggestion_content.h +++ b/Telegram/SourceFiles/dialogs/ui/dialogs_top_bar_suggestion_content.h @@ -34,6 +34,7 @@ public: void setHideCallback(Fn); void setRightIcon(RightIcon); + void setLeftPadding(int); protected: void paintEvent(QPaintEvent *) override; @@ -54,6 +55,8 @@ private: base::unique_qptr _rightArrow; Fn _hideCallback; + int _leftPadding = 0; + RightIcon _rightIcon = RightIcon::None; std::shared_ptr _rightPhoto;