Star-count button in multi-Forward/CreatePoll.

This commit is contained in:
John Preston 2025-02-28 12:57:39 +04:00
parent b3f9a77ba7
commit 97b021efaf
7 changed files with 111 additions and 41 deletions

View file

@ -30,6 +30,11 @@ ShortInfoBox {
labeledOneLine: FlatLabel;
}
boxStarIconEmoji: IconEmoji {
icon: icon{{ "payments/small_star", windowFg }};
padding: margins(0px, -2px, 0px, 0px);
}
countryRowHeight: 36px;
countryRowNameFont: semiboldFont;
countryRowNameFg: boxTextFg;

View file

@ -817,13 +817,15 @@ CreatePollBox::CreatePollBox(
not_null<Window::SessionController*> controller,
PollData::Flags chosen,
PollData::Flags disabled,
rpl::producer<int> starsRequired,
Api::SendType sendType,
SendMenu::Details sendMenuDetails)
: _controller(controller)
, _chosen(chosen)
, _disabled(disabled)
, _sendType(sendType)
, _sendMenuDetails([result = sendMenuDetails] { return result; }) {
, _sendMenuDetails([result = sendMenuDetails] { return result; })
, _starsRequired(std::move(starsRequired)) {
}
rpl::producer<CreatePollBox::Result> CreatePollBox::submitRequests() const {
@ -1226,10 +1228,18 @@ object_ptr<Ui::RpWidget> CreatePollBox::setupContent() {
_sendMenuDetails());
};
const auto submit = addButton(
(isNormal
? tr::lng_polls_create_button()
: tr::lng_schedule_button()),
tr::lng_polls_create_button(),
[=] { isNormal ? send({}) : schedule(); });
submit->setText(_starsRequired.value() | rpl::map([=](int stars) {
using namespace Ui;
if (!stars) {
return (isNormal
? tr::lng_polls_create_button
: tr::lng_schedule_button)(tr::now, Text::WithEntities);
}
return Text::IconEmoji(&st::boxStarIconEmoji).append(
Lang::FormatCountToShort(stars).string);
}));
const auto sendMenuDetails = [=] {
collectError();
return (*error) ? SendMenu::Details() : _sendMenuDetails();

View file

@ -42,6 +42,7 @@ public:
not_null<Window::SessionController*> controller,
PollData::Flags chosen,
PollData::Flags disabled,
rpl::producer<int> starsRequired,
Api::SendType sendType,
SendMenu::Details sendMenuDetails);
@ -76,6 +77,7 @@ private:
const PollData::Flags _disabled = PollData::Flags();
const Api::SendType _sendType = Api::SendType();
const Fn<SendMenu::Details()> _sendMenuDetails;
rpl::variable<int> _starsRequired;
base::unique_qptr<ChatHelpers::TabbedPanel> _emojiPanel;
Fn<void()> _setInnerFocus;
Fn<rpl::producer<bool>()> _dataIsValidValue;

View file

@ -39,7 +39,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/widgets/peer_bubble.h"
#include "styles/style_boxes.h"
#include "styles/style_chat.h"
#include "styles/style_chat_helpers.h"
#include "styles/style_credits.h"
#include "styles/style_giveaway.h"
#include "styles/style_info.h" // inviteLinkSubscribeBoxTerms

View file

@ -54,7 +54,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "core/application.h"
#include "core/core_settings.h"
#include "styles/style_calls.h"
#include "styles/style_chat_helpers.h"
#include "styles/style_layers.h"
#include "styles/style_boxes.h"
#include "styles/style_menu_icons.h"

View file

@ -1364,11 +1364,6 @@ defaultComposeControls: ComposeControls {
restrictionLabel: defaultRestrictionLabel;
}
boxStarIconEmoji: IconEmoji {
icon: icon{{ "payments/small_star", windowFg }};
padding: margins(0px, -2px, 0px, 0px);
}
moreChatsBarHeight: 48px;
moreChatsBarTextPosition: point(12px, 4px);
moreChatsBarStatusPosition: point(12px, 24px);

View file

@ -1762,10 +1762,18 @@ void PeerMenuCreatePoll(
chosen &= ~PollData::Flag::PublicVotes;
disabled |= PollData::Flag::PublicVotes;
}
auto starsRequired = peer->session().changes().peerFlagsValue(
peer,
Data::PeerUpdate::Flag::FullInfo
| Data::PeerUpdate::Flag::StarsPerMessage
) | rpl::map([=] {
return peer->starsPerMessageChecked();
});
auto box = Box<CreatePollBox>(
controller,
chosen,
disabled,
std::move(starsRequired),
sendType,
sendMenuDetails);
struct State {
@ -1996,8 +2004,7 @@ object_ptr<Ui::BoxContent> PrepareChooseRecipientBox(
ChooseRecipientBoxController::rowClicked(row);
} else {
delegate()->peerListSetRowChecked(row, !row->checked());
_hasSelectedChanges.fire(
delegate()->peerListSelectedRowsCount() > 0);
_selectionChanges.fire({});
}
}
@ -2015,16 +2022,18 @@ object_ptr<Ui::BoxContent> PrepareChooseRecipientBox(
st::popupMenuWithIcons);
menu->addAction(tr::lng_bot_choose_chat(tr::now), [=] {
delegate()->peerListSetRowChecked(row, true);
_hasSelectedChanges.fire(
delegate()->peerListSelectedRowsCount() > 0);
_selectionChanges.fire({});
}, &st::menuIconSelect);
return menu;
}
return nullptr;
}
[[nodiscard]] rpl::producer<bool> hasSelectedChanges() const {
return _hasSelectedChanges.events_starting_with(false);
[[nodiscard]] rpl::producer<> selectionChanges() const {
return _selectionChanges.events_starting_with({});
}
[[nodiscard]] bool hasSelected() const {
return delegate()->peerListSelectedRowsCount() > 0;
}
[[nodiscard]] rpl::producer<Chosen> singleChosen() const {
@ -2033,7 +2042,7 @@ object_ptr<Ui::BoxContent> PrepareChooseRecipientBox(
private:
rpl::event_stream<Chosen> _singleChosen;
rpl::event_stream<bool> _hasSelectedChanges;
rpl::event_stream<> _selectionChanges;
bool _selectable = false;
};
@ -2078,13 +2087,24 @@ object_ptr<Ui::BoxContent> PrepareChooseRecipientBox(
struct State {
Fn<void(Api::SendOptions)> submit;
rpl::variable<int> starsToSend;
Fn<void()> refreshStarsToSend;
rpl::lifetime submitLifetime;
};
const auto state = std::make_shared<State>();
auto initBox = [=](not_null<PeerListBox*> box) {
raw->hasSelectedChanges(
) | rpl::start_with_next([=](bool shown) {
state->refreshStarsToSend = [=] {
auto perMessage = 0;
for (const auto &peer : box->collectSelectedRows()) {
perMessage += peer->starsPerMessageChecked();
}
state->starsToSend = perMessage;
};
raw->selectionChanges(
) | rpl::start_with_next([=] {
box->clearButtons();
state->refreshStarsToSend();
const auto shown = raw->hasSelected();
if (shown) {
const auto weak = Ui::MakeWeak(box);
state->submit = [=](Api::SendOptions options) {
@ -2147,11 +2167,21 @@ object_ptr<Ui::BoxContent> PrepareChooseRecipientBox(
return peer->owner().history(peer);
}) | ranges::to_vector, options);
};
box->addButton(tr::lng_send_button(), [=] {
if (const auto onstack = state->submit) {
onstack({});
}
});
const auto send = box->addButton(
tr::lng_send_button(),
[=] {
if (const auto onstack = state->submit) {
onstack({});
}
});
send->setText(state->starsToSend.value(
) | rpl::map([=](int stars) {
using namespace Ui;
return stars
? Text::IconEmoji(&st::boxStarIconEmoji).append(
Lang::FormatCountToShort(stars).string)
: tr::lng_send_button(tr::now, Text::WithEntities);
}));
}
box->addButton(tr::lng_cancel(), [=] {
box->closeBox();
@ -2282,8 +2312,7 @@ QPointer<Ui::BoxContent> ShowForwardMessagesBox(
ChooseRecipientBoxController::rowClicked(row);
} else if (count) {
delegate()->peerListSetRowChecked(row, !row->checked());
_hasSelectedChanges.fire(
delegate()->peerListSelectedRowsCount() > 0);
_selectionChanges.fire({});
}
}
@ -2296,16 +2325,18 @@ QPointer<Ui::BoxContent> ShowForwardMessagesBox(
st::popupMenuWithIcons);
menu->addAction(tr::lng_bot_choose_chat(tr::now), [=] {
delegate()->peerListSetRowChecked(row, true);
_hasSelectedChanges.fire(
delegate()->peerListSelectedRowsCount() > 0);
_selectionChanges.fire({});
}, &st::menuIconSelect);
return menu;
}
return nullptr;
}
[[nodiscard]] rpl::producer<bool> hasSelectedChanges() const {
return _hasSelectedChanges.events_starting_with(false);
[[nodiscard]] rpl::producer<> selectionChanges() const {
return _selectionChanges.events_starting_with({});
}
[[nodiscard]] bool hasSelected() const {
return delegate()->peerListSelectedRowsCount() > 0;
}
[[nodiscard]] rpl::producer<Chosen> singleChosen() const{
@ -2314,7 +2345,7 @@ QPointer<Ui::BoxContent> ShowForwardMessagesBox(
private:
rpl::event_stream<Chosen> _singleChosen;
rpl::event_stream<bool> _hasSelectedChanges;
rpl::event_stream<> _selectionChanges;
};
@ -2323,6 +2354,8 @@ QPointer<Ui::BoxContent> ShowForwardMessagesBox(
not_null<Controller*> controller;
base::unique_qptr<Ui::PopupMenu> menu;
Fn<void(Api::SendOptions options)> submit;
rpl::variable<int> starsToSend;
Fn<void()> refreshStarsToSend;
rpl::lifetime submitLifetime;
};
@ -2622,8 +2655,20 @@ QPointer<Ui::BoxContent> ShowForwardMessagesBox(
}
};
state->refreshStarsToSend = [=] {
auto perMessage = 0;
for (const auto &peer : state->box->collectSelectedRows()) {
perMessage += peer->starsPerMessageChecked();
}
state->starsToSend = perMessage
* countMessages(field->getTextWithTags());
};
comment->hide(anim::type::instant);
comment->toggleOn(state->controller->hasSelectedChanges());
comment->toggleOn(state->controller->selectionChanges(
) | rpl::map([=] {
return state->controller->hasSelected();
}));
rpl::combine(
state->box->sizeValue(),
@ -2650,6 +2695,9 @@ QPointer<Ui::BoxContent> ShowForwardMessagesBox(
},
});
field->setSubmitSettings(Core::App().settings().sendSubmitWay());
field->changes() | rpl::start_with_next([=] {
state->refreshStarsToSend();
}, field->lifetime());
Ui::SendPendingMoveResizeEvents(comment);
@ -2660,16 +2708,20 @@ QPointer<Ui::BoxContent> ShowForwardMessagesBox(
}
}, comment->lifetime());
state->controller->hasSelectedChanges(
) | rpl::start_with_next([=](bool shown) {
state->controller->selectionChanges(
) | rpl::start_with_next([=] {
const auto shown = state->controller->hasSelected();
state->box->clearButtons();
state->refreshStarsToSend();
if (shown) {
auto text = tr::lng_send_button();
const auto send = state->box->addButton(std::move(text), [=] {
if (const auto onstack = state->submit) {
onstack({});
}
});
const auto send = state->box->addButton(
tr::lng_send_button(),
[=] {
if (const auto onstack = state->submit) {
onstack({});
}
});
send->setAcceptBoth();
send->clicks(
) | rpl::start_with_next([=](Qt::MouseButton button) {
@ -2677,6 +2729,14 @@ QPointer<Ui::BoxContent> ShowForwardMessagesBox(
showMenu(send);
}
}, send->lifetime());
send->setText(state->starsToSend.value(
) | rpl::map([=](int stars) {
using namespace Ui;
return stars
? Text::IconEmoji(&st::boxStarIconEmoji).append(
Lang::FormatCountToShort(stars).string)
: tr::lng_send_button(tr::now, Text::WithEntities);
}));
}
state->box->addButton(tr::lng_cancel(), [=] {
state->box->closeBox();