Added right button for bots in list from recent dialogs.

This commit is contained in:
23rd 2024-11-25 12:25:36 +03:00
parent 6c62bbe6fb
commit a9824fde91
5 changed files with 114 additions and 14 deletions

View file

@ -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 }};

View file

@ -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<PeerData*> peer) {
if (const auto user = peer->asUser()) {
if (const auto info = user->botInfo.get()) {

View file

@ -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<void()> updateCallback) override;
void rightActionStopLastRipple() override;
const style::PeerListItem &computeSt(
const style::PeerListItem &st) const override;
private:
const not_null<History*> _history;
std::unique_ptr<Ui::Text::String> _mainAppText;
std::unique_ptr<Ui::RippleAnimation> _actionRipple;
QString _badgeString;
QSize _badgeSize;
uint32 _counter : 30 = 0;
@ -181,7 +188,17 @@ void FillEntryMenu(
RecentRow::RecentRow(not_null<PeerData*> peer)
: PeerListRow(peer)
, _history(peer->owner().history(peer)) {
, _history(peer->owner().history(peer))
, _mainAppText([&]() -> std::unique_ptr<Ui::Text::String> {
if (const auto user = peer->asUser()) {
if (user->botInfo && user->botInfo->hasMainApp) {
return std::make_unique<Ui::Text::String>(
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<void()> 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<Ui::RippleAnimation>(
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<void(not_null<PeerData*>)>;
RecentsController(
not_null<Window::SessionController*> window,
RecentPeersList list);
RecentPeersList list,
RightActionCallback rightActionCallback);
void prepare() override;
base::unique_qptr<Ui::PopupMenu> rowContextMenu(
QWidget *parent,
not_null<PeerListRow*> row) override;
void rowRightActionClicked(not_null<PeerListRow*> row) override;
QString savedMessagesChatStatus() const override;
@ -374,6 +458,7 @@ private:
[[nodiscard]] Fn<void()> removeAllCallback();
RecentPeersList _recent;
RightActionCallback _rightActionCallback;
rpl::lifetime _lifetime;
};
@ -671,9 +756,11 @@ void Suggestions::ObjectListController::setupExpandDivider(
RecentsController::RecentsController(
not_null<Window::SessionController*> 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<Ui::PopupMenu> RecentsController::rowContextMenu(
return result;
}
void RecentsController::rowRightActionClicked(not_null<PeerListRow*> 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<ObjectList> {
const auto controller = lifetime().make_state<RecentsController>(
_controller,
std::move(recentPeers));
std::move(recentPeers),
[=](not_null<PeerData*> p) { _openBotMainAppRequests.fire_copy(p); });
const auto addToScroll = [=] {
return _topPeersWrap->toggled() ? _topPeers->height() : 0;

View file

@ -88,6 +88,10 @@ public:
-> rpl::producer<not_null<PeerData*>> {
return _popularApps->chosen.events();
}
[[nodiscard]] auto openBotMainAppRequests() const
-> rpl::producer<not_null<PeerData*>> {
return _openBotMainAppRequests.events();
}
class ObjectListController;
@ -174,6 +178,7 @@ private:
const not_null<Ui::SlideWrap<TopPeersStrip>*> _topPeersWrap;
const not_null<TopPeersStrip*> _topPeers;
rpl::event_stream<not_null<PeerData*>> _topPeerChosen;
rpl::event_stream<not_null<PeerData*>> _openBotMainAppRequests;
const std::unique_ptr<ObjectList> _recent;

View file

@ -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<void()> updateCallback) {
QPoint point,
Fn<void()> updateCallback) {
if (!_actionRipple) {
auto mask = Ui::RippleAnimation::EllipseMask(rightActionSize());
_actionRipple = std::make_unique<Ui::RippleAnimation>(