From a9824fde91a2eeee155e82bd936ec08ab95e6f2b Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Mon, 25 Nov 2024 12:25:36 +0300 Subject: [PATCH] Added right button for bots in list from recent dialogs. --- Telegram/SourceFiles/dialogs/dialogs.style | 1 + .../SourceFiles/dialogs/dialogs_widget.cpp | 4 +- .../dialogs/ui/dialogs_suggestions.cpp | 108 +++++++++++++++++- .../dialogs/ui/dialogs_suggestions.h | 5 + .../settings/business/settings_chatbots.cpp | 10 +- 5 files changed, 114 insertions(+), 14 deletions(-) diff --git a/Telegram/SourceFiles/dialogs/dialogs.style b/Telegram/SourceFiles/dialogs/dialogs.style index 2cc193d59..4b6c382da 100644 --- a/Telegram/SourceFiles/dialogs/dialogs.style +++ b/Telegram/SourceFiles/dialogs/dialogs.style @@ -112,6 +112,7 @@ dialogRowOpenBotTextStyle: semiboldTextStyle; dialogRowOpenBotHeight: 20px; dialogRowOpenBotRight: 10px; dialogRowOpenBotTop: 32px; +dialogRowOpenBotRecentTop: 28px; forumDialogJumpArrow: icon{{ "dialogs/dialogs_topic_arrow", dialogsTextFg }}; forumDialogJumpArrowOver: icon{{ "dialogs/dialogs_topic_arrow", dialogsTextFgOver }}; diff --git a/Telegram/SourceFiles/dialogs/dialogs_widget.cpp b/Telegram/SourceFiles/dialogs/dialogs_widget.cpp index bc5841380..9c9b16234 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_widget.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_widget.cpp @@ -1443,7 +1443,9 @@ void Widget::updateSuggestions(anim::type animated) { } }, _suggestions->lifetime()); - _suggestions->recentAppChosen( + rpl::merge( + _suggestions->openBotMainAppRequests(), + _suggestions->recentAppChosen() ) | rpl::start_with_next([=](not_null peer) { if (const auto user = peer->asUser()) { if (const auto info = user->botInfo.get()) { diff --git a/Telegram/SourceFiles/dialogs/ui/dialogs_suggestions.cpp b/Telegram/SourceFiles/dialogs/ui/dialogs_suggestions.cpp index 43b5c5882..0951bf756 100644 --- a/Telegram/SourceFiles/dialogs/ui/dialogs_suggestions.cpp +++ b/Telegram/SourceFiles/dialogs/ui/dialogs_suggestions.cpp @@ -28,6 +28,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "main/main_session.h" #include "settings/settings_common.h" #include "ui/boxes/confirm_box.h" +#include "ui/effects/ripple_animation.h" #include "ui/text/text_utilities.h" #include "ui/widgets/menu/menu_add_action_callback_factory.h" #include "ui/widgets/buttons.h" @@ -76,12 +77,18 @@ public: bool selected, bool actionSelected) override; bool rightActionDisabled() const override; + void rightActionAddRipple( + QPoint point, + Fn updateCallback) override; + void rightActionStopLastRipple() override; const style::PeerListItem &computeSt( const style::PeerListItem &st) const override; private: const not_null _history; + std::unique_ptr _mainAppText; + std::unique_ptr _actionRipple; QString _badgeString; QSize _badgeSize; uint32 _counter : 30 = 0; @@ -181,7 +188,17 @@ void FillEntryMenu( RecentRow::RecentRow(not_null peer) : PeerListRow(peer) -, _history(peer->owner().history(peer)) { +, _history(peer->owner().history(peer)) +, _mainAppText([&]() -> std::unique_ptr { + if (const auto user = peer->asUser()) { + if (user->botInfo && user->botInfo->hasMainApp) { + return std::make_unique( + st::dialogRowOpenBotTextStyle, + tr::lng_profile_open_app_short(tr::now).toUpper()); + } + } + return nullptr; +}()) { if (peer->isSelf() || peer->isRepliesChat() || peer->isVerifyCodes()) { setCustomStatus(u" "_q); } else if (const auto chat = peer->asChat()) { @@ -244,10 +261,23 @@ bool RecentRow::refreshBadge() { } QSize RecentRow::rightActionSize() const { + if (_mainAppText) { + const auto &font = st::dialogRowOpenBotTextStyle.font; + return QSize( + _mainAppText->maxWidth() + _mainAppText->minHeight(), + st::dialogRowOpenBotHeight); + } return _badgeSize; } QMargins RecentRow::rightActionMargins() const { + if (_mainAppText) { + return QMargins( + 0, + st::dialogRowOpenBotRecentTop, + st::dialogRowOpenBotRight, + 0); + } if (_badgeSize.isEmpty()) { return {}; } @@ -263,6 +293,32 @@ void RecentRow::rightActionPaint( int outerWidth, bool selected, bool actionSelected) { + if (_mainAppText) { + const auto size = RecentRow::rightActionSize(); + p.setPen(Qt::NoPen); + p.setBrush(actionSelected + ? st::activeButtonBgOver + : st::activeButtonBg); + const auto radius = size.height() / 2; + p.drawRoundedRect(QRect(QPoint(x, y), size), radius, radius); + if (_actionRipple) { + _actionRipple->paint(p, x, y, outerWidth); + if (_actionRipple->empty()) { + _actionRipple.reset(); + } + } + p.setPen(actionSelected + ? st::activeButtonFgOver + : st::activeButtonFg); + const auto top = 0 + + (st::dialogRowOpenBotHeight - _mainAppText->minHeight()) / 2; + _mainAppText->draw(p, { + .position = QPoint(x + size.height() / 2, y + top), + .availableWidth = outerWidth, + .outerWidth = outerWidth, + .elisionLines = 1, + }); + } if (!_counter && !_unread) { return; } else if (_badgeString.isEmpty()) { @@ -280,7 +336,31 @@ void RecentRow::rightActionPaint( } bool RecentRow::rightActionDisabled() const { - return true; + return !_mainAppText; +} + +void RecentRow::rightActionAddRipple( + QPoint point, + Fn updateCallback) { + if (!_mainAppText) { + return; + } + if (!_actionRipple) { + const auto size = rightActionSize(); + const auto radius = size.height() / 2; + auto mask = Ui::RippleAnimation::RoundRectMask(size, radius); + _actionRipple = std::make_unique( + st::defaultActiveButton.ripple, + std::move(mask), + std::move(updateCallback)); + } + _actionRipple->add(point); +} + +void RecentRow::rightActionStopLastRipple() { + if (_actionRipple) { + _actionRipple->lastStop(); + } } const style::PeerListItem &RecentRow::computeSt( @@ -357,14 +437,18 @@ private: class RecentsController final : public Suggestions::ObjectListController { public: + using RightActionCallback = Fn)>; + RecentsController( not_null window, - RecentPeersList list); + RecentPeersList list, + RightActionCallback rightActionCallback); void prepare() override; base::unique_qptr rowContextMenu( QWidget *parent, not_null row) override; + void rowRightActionClicked(not_null row) override; QString savedMessagesChatStatus() const override; @@ -374,6 +458,7 @@ private: [[nodiscard]] Fn removeAllCallback(); RecentPeersList _recent; + RightActionCallback _rightActionCallback; rpl::lifetime _lifetime; }; @@ -671,9 +756,11 @@ void Suggestions::ObjectListController::setupExpandDivider( RecentsController::RecentsController( not_null window, - RecentPeersList list) + RecentPeersList list, + RightActionCallback rightActionCallback) : ObjectListController(window) -, _recent(std::move(list)) { +, _recent(std::move(list)) +, _rightActionCallback(std::move(rightActionCallback)) { } void RecentsController::prepare() { @@ -735,6 +822,14 @@ base::unique_qptr RecentsController::rowContextMenu( return result; } +void RecentsController::rowRightActionClicked(not_null row) { + if (_rightActionCallback) { + if (const auto peer = row->peer()) { + _rightActionCallback(peer); + } + } +} + QString RecentsController::savedMessagesChatStatus() const { return tr::lng_saved_forward_here(tr::now); } @@ -1785,7 +1880,8 @@ auto Suggestions::setupRecentPeers(RecentPeersList recentPeers) -> std::unique_ptr { const auto controller = lifetime().make_state( _controller, - std::move(recentPeers)); + std::move(recentPeers), + [=](not_null p) { _openBotMainAppRequests.fire_copy(p); }); const auto addToScroll = [=] { return _topPeersWrap->toggled() ? _topPeers->height() : 0; diff --git a/Telegram/SourceFiles/dialogs/ui/dialogs_suggestions.h b/Telegram/SourceFiles/dialogs/ui/dialogs_suggestions.h index 32998519f..973f65c7d 100644 --- a/Telegram/SourceFiles/dialogs/ui/dialogs_suggestions.h +++ b/Telegram/SourceFiles/dialogs/ui/dialogs_suggestions.h @@ -88,6 +88,10 @@ public: -> rpl::producer> { return _popularApps->chosen.events(); } + [[nodiscard]] auto openBotMainAppRequests() const + -> rpl::producer> { + return _openBotMainAppRequests.events(); + } class ObjectListController; @@ -174,6 +178,7 @@ private: const not_null*> _topPeersWrap; const not_null _topPeers; rpl::event_stream> _topPeerChosen; + rpl::event_stream> _openBotMainAppRequests; const std::unique_ptr _recent; diff --git a/Telegram/SourceFiles/settings/business/settings_chatbots.cpp b/Telegram/SourceFiles/settings/business/settings_chatbots.cpp index cd439e139..c5006bf78 100644 --- a/Telegram/SourceFiles/settings/business/settings_chatbots.cpp +++ b/Telegram/SourceFiles/settings/business/settings_chatbots.cpp @@ -134,11 +134,7 @@ void PreviewRow::rightActionPaint( bool selected, bool actionSelected) { if (_actionRipple) { - _actionRipple->paint( - p, - x, - y, - outerWidth); + _actionRipple->paint(p, x, y, outerWidth); if (_actionRipple->empty()) { _actionRipple.reset(); } @@ -150,8 +146,8 @@ void PreviewRow::rightActionPaint( } void PreviewRow::rightActionAddRipple( - QPoint point, - Fn updateCallback) { + QPoint point, + Fn updateCallback) { if (!_actionRipple) { auto mask = Ui::RippleAnimation::EllipseMask(rightActionSize()); _actionRipple = std::make_unique(