mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-15 13:47:05 +02:00
Allow changing the recipients.
This commit is contained in:
parent
82cec83d87
commit
b8bf3f6520
14 changed files with 386 additions and 56 deletions
|
@ -1404,10 +1404,6 @@ void Session::forgetPassportCredentials() {
|
|||
_passportCredentials = nullptr;
|
||||
}
|
||||
|
||||
QString Session::nameSortKey(const QString &name) const {
|
||||
return TextUtilities::RemoveAccents(name).toLower();
|
||||
}
|
||||
|
||||
void Session::setupMigrationViewer() {
|
||||
session().changes().peerUpdates(
|
||||
PeerUpdate::Flag::Migration
|
||||
|
|
|
@ -115,8 +115,6 @@ public:
|
|||
return *_session;
|
||||
}
|
||||
|
||||
[[nodiscard]] QString nameSortKey(const QString &name) const;
|
||||
|
||||
[[nodiscard]] Groups &groups() {
|
||||
return _groups;
|
||||
}
|
||||
|
|
|
@ -98,7 +98,7 @@ History::History(not_null<Data::Session*> owner, PeerId peerId)
|
|||
: Thread(owner, Type::History)
|
||||
, peer(owner->peer(peerId))
|
||||
, _delegateMixin(HistoryInner::DelegateMixin())
|
||||
, _chatListNameSortKey(owner->nameSortKey(peer->name()))
|
||||
, _chatListNameSortKey(TextUtilities::NameSortKey(peer->name()))
|
||||
, _sendActionPainter(this) {
|
||||
Thread::setMuted(owner->notifySettings().isMuted(peer));
|
||||
|
||||
|
@ -2314,7 +2314,7 @@ const QString &History::chatListNameSortKey() const {
|
|||
}
|
||||
|
||||
void History::refreshChatListNameSortKey() {
|
||||
_chatListNameSortKey = owner().nameSortKey(peer->name());
|
||||
_chatListNameSortKey = TextUtilities::NameSortKey(peer->name());
|
||||
}
|
||||
|
||||
const base::flat_set<QString> &History::chatListNameWords() const {
|
||||
|
|
|
@ -12,6 +12,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "boxes/send_credits_box.h" // Ui::CreditsEmoji.
|
||||
#include "chat_helpers/stickers_lottie.h"
|
||||
#include "core/ui_integration.h"
|
||||
#include "data/stickers/data_custom_emoji.h"
|
||||
#include "data/data_channel.h"
|
||||
#include "data/data_document.h"
|
||||
#include "data/data_session.h"
|
||||
#include "history/view/media/history_view_sticker.h"
|
||||
|
@ -21,9 +23,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "settings/settings_common.h"
|
||||
#include "ui/boxes/confirm_box.h"
|
||||
#include "ui/controls/userpic_button.h"
|
||||
#include "ui/controls/who_reacted_context_action.h"
|
||||
#include "ui/dynamic_image.h"
|
||||
#include "ui/dynamic_thumbnails.h"
|
||||
#include "ui/layers/generic_box.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/labels.h"
|
||||
#include "ui/widgets/popup_menu.h"
|
||||
#include "ui/wrap/padding_wrap.h"
|
||||
#include "ui/wrap/table_layout.h"
|
||||
#include "ui/wrap/vertical_layout.h"
|
||||
|
@ -31,6 +37,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/painter.h"
|
||||
#include "ui/vertical_list.h"
|
||||
#include "styles/style_chat.h"
|
||||
#include "styles/style_chat_helpers.h"
|
||||
#include "styles/style_dialogs.h"
|
||||
#include "styles/style_giveaway.h"
|
||||
#include "styles/style_layers.h"
|
||||
|
@ -156,6 +163,58 @@ void ConnectStarRef(
|
|||
return result;
|
||||
}
|
||||
|
||||
void ChooseRecipient(
|
||||
not_null<Ui::RpWidget*> button,
|
||||
const std::vector<not_null<PeerData*>> &list,
|
||||
not_null<PeerData*> now,
|
||||
Fn<void(not_null<PeerData*>)> done) {
|
||||
const auto menu = Ui::CreateChild<Ui::PopupMenu>(
|
||||
button,
|
||||
st::starrefPopupMenu);
|
||||
|
||||
struct Entry {
|
||||
not_null<Ui::WhoReactedEntryAction*> action;
|
||||
std::shared_ptr<Ui::DynamicImage> userpic;
|
||||
};
|
||||
auto actions = std::make_shared<std::vector<Entry>>();
|
||||
actions->reserve(list.size());
|
||||
for (const auto &peer : list) {
|
||||
auto view = peer->createUserpicView();
|
||||
auto action = base::make_unique_q<Ui::WhoReactedEntryAction>(
|
||||
menu->menu(),
|
||||
Data::ReactedMenuFactory(&list.front()->session()),
|
||||
menu->menu()->st(),
|
||||
Ui::WhoReactedEntryData());
|
||||
const auto index = int(actions->size());
|
||||
actions->push_back({ action.get(), Ui::MakeUserpicThumbnail(peer) });
|
||||
|
||||
const auto updateUserpic = [=] {
|
||||
const auto size = st::defaultWhoRead.photoSize;
|
||||
actions->at(index).action->setData({
|
||||
.text = peer->name(),
|
||||
.date = (peer->isSelf()
|
||||
? tr::lng_group_call_join_as_personal(tr::now)
|
||||
: peer->isUser()
|
||||
? tr::lng_status_bot(tr::now)
|
||||
: peer->isBroadcast()
|
||||
? tr::lng_channel_status(tr::now)
|
||||
: tr::lng_group_status(tr::now)),
|
||||
.type = (peer == now
|
||||
? Ui::WhoReactedType::RefRecipientNow
|
||||
: Ui::WhoReactedType::RefRecipient),
|
||||
.userpic = actions->at(index).userpic->image(size),
|
||||
.callback = [=] { done(peer); },
|
||||
});
|
||||
};
|
||||
actions->back().userpic->subscribeToUpdates(updateUserpic);
|
||||
|
||||
menu->addAction(std::move(action));
|
||||
updateUserpic();
|
||||
}
|
||||
|
||||
menu->popup(button->mapToGlobal(QPoint(button->width() / 2, 0)));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
QString FormatCommission(ushort commission) {
|
||||
|
@ -453,9 +512,10 @@ object_ptr<Ui::BoxContent> StarRefLinkBox(
|
|||
});
|
||||
}
|
||||
|
||||
[[nodiscard]] object_ptr<Ui::BoxContent> JoinStarRefBox(
|
||||
object_ptr<Ui::BoxContent> JoinStarRefBox(
|
||||
ConnectedBot row,
|
||||
not_null<PeerData*> peer,
|
||||
not_null<PeerData*> initialRecipient,
|
||||
std::vector<not_null<PeerData*>> recipients,
|
||||
Fn<void(ConnectedBotState)> done) {
|
||||
Expects(row.bot->isUser());
|
||||
|
||||
|
@ -464,6 +524,13 @@ object_ptr<Ui::BoxContent> StarRefLinkBox(
|
|||
|
||||
const auto bot = row.bot;
|
||||
const auto program = row.state.program;
|
||||
auto list = recipients;
|
||||
if (!list.empty()) {
|
||||
list.erase(ranges::remove(list, bot), end(list));
|
||||
if (!ranges::contains(list, initialRecipient)) {
|
||||
list.insert(begin(list), initialRecipient);
|
||||
}
|
||||
}
|
||||
|
||||
box->setStyle(st::starrefFooterBox);
|
||||
box->setNoContentMargin(true);
|
||||
|
@ -471,13 +538,34 @@ object_ptr<Ui::BoxContent> StarRefLinkBox(
|
|||
box->closeBox();
|
||||
});
|
||||
|
||||
box->addRow(
|
||||
CreateUserpicsTransfer(
|
||||
box,
|
||||
rpl::single(std::vector{ not_null<PeerData*>(bot) }),
|
||||
peer,
|
||||
UserpicsTransferType::StarRefJoin),
|
||||
st::boxRowPadding + st::starrefJoinUserpicsPadding);
|
||||
struct State {
|
||||
rpl::variable<not_null<PeerData*>> recipient;
|
||||
QPointer<Ui::GenericBox> weak;
|
||||
bool sent = false;
|
||||
};
|
||||
const auto state = std::make_shared<State>(State{
|
||||
.recipient = initialRecipient,
|
||||
.weak = box.get(),
|
||||
});
|
||||
const auto userpicsWrap = box->addRow(
|
||||
object_ptr<Ui::VerticalLayout>(box),
|
||||
QMargins());
|
||||
|
||||
state->recipient.value(
|
||||
) | rpl::start_with_next([=](not_null<PeerData*> recipient) {
|
||||
while (userpicsWrap->count()) {
|
||||
delete userpicsWrap->widgetAt(0);
|
||||
}
|
||||
userpicsWrap->add(
|
||||
CreateUserpicsTransfer(
|
||||
box,
|
||||
rpl::single(std::vector{ not_null<PeerData*>(bot) }),
|
||||
recipient,
|
||||
UserpicsTransferType::StarRefJoin),
|
||||
st::boxRowPadding + st::starrefJoinUserpicsPadding);
|
||||
userpicsWrap->resizeToWidth(box->width());
|
||||
}, box->lifetime());
|
||||
|
||||
box->addRow(
|
||||
object_ptr<Ui::CenterWrap<Ui::FlatLabel>>(
|
||||
box,
|
||||
|
@ -504,7 +592,7 @@ object_ptr<Ui::BoxContent> StarRefLinkBox(
|
|||
Ui::AddSkip(box->verticalLayout(), st::defaultVerticalListSkip * 3);
|
||||
if (const auto average = program.revenuePerUser) {
|
||||
const auto layout = box->verticalLayout();
|
||||
const auto session = &peer->session();
|
||||
const auto session = &initialRecipient->session();
|
||||
const auto makeContext = [session](Fn<void()> update) {
|
||||
return Core::MarkedTextContext{
|
||||
.session = session,
|
||||
|
@ -512,13 +600,14 @@ object_ptr<Ui::BoxContent> StarRefLinkBox(
|
|||
};
|
||||
};
|
||||
auto text = Ui::Text::Colorized(Ui::CreditsEmoji(session));
|
||||
text.append(Lang::FormatStarsAmountDecimal(average));
|
||||
text.append(Lang::FormatStarsAmountRounded(average));
|
||||
layout->add(
|
||||
object_ptr<Ui::FlatLabel>(
|
||||
box,
|
||||
tr::lng_star_ref_one_daily_revenue(
|
||||
lt_amount,
|
||||
rpl::single(Ui::Text::Wrapped(text, EntityType::Bold)),
|
||||
rpl::single(
|
||||
Ui::Text::Wrapped(text, EntityType::Bold)),
|
||||
Ui::Text::WithEntities),
|
||||
st::starrefRevenueText,
|
||||
st::defaultPopupMenu,
|
||||
|
@ -526,35 +615,89 @@ object_ptr<Ui::BoxContent> StarRefLinkBox(
|
|||
st::boxRowPadding);
|
||||
Ui::AddSkip(layout, st::defaultVerticalListSkip);
|
||||
}
|
||||
#if 0
|
||||
box->addRow(
|
||||
object_ptr<Ui::FlatLabel>(
|
||||
box,
|
||||
tr::lng_star_ref_link_recipient(),
|
||||
st::starrefCenteredText));
|
||||
Ui::AddSkip(box->verticalLayout());
|
||||
box->addRow(object_ptr<Ui::AbstractButton>::fromRaw(
|
||||
MakePeerBubbleButton(box, peer).release()
|
||||
))->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||
#endif
|
||||
|
||||
struct State {
|
||||
QPointer<Ui::GenericBox> weak;
|
||||
bool sent = false;
|
||||
};
|
||||
const auto state = std::make_shared<State>();
|
||||
state->weak = box;
|
||||
if (!list.empty()) {
|
||||
struct Name {
|
||||
not_null<PeerData*> peer;
|
||||
QString name;
|
||||
};
|
||||
auto names = ranges::views::transform(list, [](auto peer) {
|
||||
const auto name = TextUtilities::NameSortKey(peer->name());
|
||||
return Name{ peer, name };
|
||||
}) | ranges::to_vector;
|
||||
ranges::sort(names, ranges::less(), &Name::name);
|
||||
|
||||
list = ranges::views::transform(names, &Name::peer)
|
||||
| ranges::to_vector;
|
||||
|
||||
box->addRow(
|
||||
object_ptr<Ui::FlatLabel>(
|
||||
box,
|
||||
tr::lng_star_ref_link_recipient(),
|
||||
st::starrefCenteredText));
|
||||
Ui::AddSkip(box->verticalLayout());
|
||||
const auto recipientWrap = box->addRow(
|
||||
object_ptr<Ui::VerticalLayout>(box),
|
||||
QMargins());
|
||||
state->recipient.value(
|
||||
) | rpl::start_with_next([=](not_null<PeerData*> recipient) {
|
||||
while (recipientWrap->count()) {
|
||||
delete recipientWrap->widgetAt(0);
|
||||
}
|
||||
|
||||
const auto selectable = (list.size() > 1);
|
||||
const auto bgOverride = selectable
|
||||
? &st::lightButtonBgOver
|
||||
: nullptr;
|
||||
const auto right = selectable
|
||||
? Ui::CreateChild<Ui::RpWidget>(recipientWrap)
|
||||
: nullptr;
|
||||
if (right) {
|
||||
const auto skip = st::chatGiveawayPeerPadding.right();
|
||||
const auto icon = &st::starrefRecipientArrow;
|
||||
right->resize(skip + icon->width(), icon->height());
|
||||
right->paintRequest() | rpl::start_with_next([=] {
|
||||
auto p = QPainter(right);
|
||||
icon->paint(p, skip, 0, right->width());
|
||||
}, right->lifetime());
|
||||
}
|
||||
const auto button = recipientWrap->add(
|
||||
object_ptr<Ui::AbstractButton>::fromRaw(
|
||||
MakePeerBubbleButton(
|
||||
box,
|
||||
recipient,
|
||||
right,
|
||||
bgOverride).release()),
|
||||
st::boxRowPadding);
|
||||
recipientWrap->resizeToWidth(box->width());
|
||||
if (!selectable) {
|
||||
button->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||
return;
|
||||
}
|
||||
button->setClickedCallback([=] {
|
||||
const auto callback = [=](not_null<PeerData*> peer) {
|
||||
state->recipient = peer;
|
||||
};
|
||||
ChooseRecipient(
|
||||
button,
|
||||
list,
|
||||
state->recipient.current(),
|
||||
crl::guard(button, callback));
|
||||
});
|
||||
}, box->lifetime());
|
||||
}
|
||||
|
||||
const auto send = [=] {
|
||||
if (state->sent) {
|
||||
return;
|
||||
}
|
||||
state->sent = true;
|
||||
ConnectStarRef(bot->asUser(), peer, [=](ConnectedBot info) {
|
||||
const auto recipient = state->recipient.current();
|
||||
ConnectStarRef(bot->asUser(), recipient, [=](ConnectedBot info) {
|
||||
if (const auto onstack = done) {
|
||||
onstack(info.state);
|
||||
}
|
||||
show->show(StarRefLinkBox(info, peer));
|
||||
show->show(StarRefLinkBox(info, recipient));
|
||||
if (const auto strong = state->weak.data()) {
|
||||
strong->closeBox();
|
||||
}
|
||||
|
@ -624,18 +767,103 @@ object_ptr<Ui::BoxContent> ConfirmEndBox(Fn<void()> finish) {
|
|||
});
|
||||
}
|
||||
|
||||
void ResolveRecipients(
|
||||
not_null<Main::Session*> session,
|
||||
Fn<void(std::vector<not_null<PeerData*>>)> done) {
|
||||
struct State {
|
||||
not_null<Main::Session*> session;
|
||||
std::vector<not_null<PeerData*>> list;
|
||||
Fn<void(std::vector<not_null<PeerData*>>)> done;
|
||||
};
|
||||
const auto state = std::make_shared<State>(State{
|
||||
.session = session,
|
||||
.done = std::move(done),
|
||||
});
|
||||
const auto finish1 = [state](const MTPmessages_Chats &result) {
|
||||
const auto already = int(state->list.size());
|
||||
const auto session = state->session;
|
||||
result.match([&](const auto &data) {
|
||||
const auto &list = data.vchats().v;
|
||||
state->list.reserve(list.size() + (already ? already : 1));
|
||||
if (!already) {
|
||||
state->list.push_back(session->user());
|
||||
}
|
||||
for (const auto &chat : list) {
|
||||
const auto peer = session->data().processChat(chat);
|
||||
if (const auto channel = peer->asBroadcast()) {
|
||||
if (channel->canPostMessages()) {
|
||||
state->list.push_back(channel);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (already) {
|
||||
base::take(state->done)(base::take(state->list));
|
||||
}
|
||||
});
|
||||
};
|
||||
const auto finish2 = [state](const MTPVector<MTPUser> &result) {
|
||||
const auto already = int(state->list.size());
|
||||
const auto session = state->session;
|
||||
const auto &list = result.v;
|
||||
state->list.reserve(list.size() + (already ? already : 1));
|
||||
if (!already) {
|
||||
state->list.push_back(session->user());
|
||||
}
|
||||
for (const auto &user : list) {
|
||||
state->list.push_back(session->data().processUser(user));
|
||||
}
|
||||
if (already) {
|
||||
base::take(state->done)(base::take(state->list));
|
||||
}
|
||||
};
|
||||
|
||||
session->api().request(MTPchannels_GetAdminedPublicChannels(
|
||||
MTP_flags(0)
|
||||
)).done(finish1).fail([=] {
|
||||
finish1(MTP_messages_chats(MTP_vector<MTPChat>(0)));
|
||||
}).send();
|
||||
|
||||
state->session->api().request(MTPbots_GetAdminedBots(
|
||||
)).done(finish2).fail([=] {
|
||||
finish2(MTP_vector<MTPUser>(0));
|
||||
}).send();
|
||||
}
|
||||
|
||||
std::unique_ptr<Ui::AbstractButton> MakePeerBubbleButton(
|
||||
not_null<QWidget*> parent,
|
||||
not_null<PeerData*> peer,
|
||||
Ui::RpWidget *right) {
|
||||
auto result = std::make_unique<Ui::AbstractButton>(parent);
|
||||
Ui::RpWidget *right,
|
||||
const style::color *bgOverride) {
|
||||
class Button final : public Ui::AbstractButton {
|
||||
public:
|
||||
Button(QWidget *parent, not_null<int*> innerWidth)
|
||||
: AbstractButton(parent)
|
||||
, _innerWidth(innerWidth) {
|
||||
}
|
||||
|
||||
void mouseMoveEvent(QMouseEvent *e) override {
|
||||
const auto inner = *_innerWidth;
|
||||
const auto skip = (width() - inner) / 2;
|
||||
const auto p = e->pos();
|
||||
const auto over = QRect(skip, 0, inner, height()).contains(p);
|
||||
setOver(over, StateChangeSource::ByHover);
|
||||
}
|
||||
|
||||
private:
|
||||
const not_null<int*> _innerWidth;
|
||||
|
||||
};
|
||||
|
||||
auto ownedWidth = std::make_unique<int>();
|
||||
const auto width = ownedWidth.get();
|
||||
auto result = std::make_unique<Button>(parent, width);
|
||||
result->lifetime().add([moved = std::move(ownedWidth)] {});
|
||||
|
||||
const auto size = st::chatGiveawayPeerSize;
|
||||
const auto padding = st::chatGiveawayPeerPadding;
|
||||
|
||||
const auto raw = result.get();
|
||||
|
||||
const auto width = raw->lifetime().make_state<int>();
|
||||
const auto name = raw->lifetime().make_state<Ui::FlatLabel>(
|
||||
raw,
|
||||
rpl::single(peer->name()),
|
||||
|
@ -691,7 +919,7 @@ std::unique_ptr<Ui::AbstractButton> MakePeerBubbleButton(
|
|||
p.setClipRect(left + skip, 0, *width - skip, size);
|
||||
auto hq = PainterHighQualityEnabler(p);
|
||||
p.setPen(Qt::NoPen);
|
||||
p.setBrush(st::windowBgOver);
|
||||
p.setBrush(bgOverride ? *bgOverride : st::windowBgOver);
|
||||
p.drawRoundedRect(left, 0, *width, size, skip, skip);
|
||||
}, raw->lifetime());
|
||||
|
||||
|
|
|
@ -23,6 +23,10 @@ namespace style {
|
|||
struct RoundButton;
|
||||
} // namespace style
|
||||
|
||||
namespace Main {
|
||||
class Session;
|
||||
} // namespace Main
|
||||
|
||||
namespace Info::BotStarRef {
|
||||
|
||||
struct ConnectedBotState {
|
||||
|
@ -65,14 +69,20 @@ void AddFullWidthButtonFooter(
|
|||
not_null<PeerData*> peer);
|
||||
[[nodiscard]] object_ptr<Ui::BoxContent> JoinStarRefBox(
|
||||
ConnectedBot row,
|
||||
not_null<PeerData*> peer,
|
||||
not_null<PeerData*> initialRecipient,
|
||||
std::vector<not_null<PeerData*>> recipients,
|
||||
Fn<void(ConnectedBotState)> done = nullptr);
|
||||
[[nodiscard]] object_ptr<Ui::BoxContent> ConfirmEndBox(Fn<void()> finish);
|
||||
|
||||
void ResolveRecipients(
|
||||
not_null<Main::Session*> session,
|
||||
Fn<void(std::vector<not_null<PeerData*>>)> done);
|
||||
|
||||
std::unique_ptr<Ui::AbstractButton> MakePeerBubbleButton(
|
||||
not_null<QWidget*> parent,
|
||||
not_null<PeerData*> peer,
|
||||
Ui::RpWidget *right = nullptr);
|
||||
Ui::RpWidget *right = nullptr,
|
||||
const style::color *bgOverride = nullptr);
|
||||
|
||||
void ConfirmUpdate(
|
||||
std::shared_ptr<Ui::Show> show,
|
||||
|
|
|
@ -87,6 +87,7 @@ public:
|
|||
private:
|
||||
[[nodiscard]] std::unique_ptr<PeerListRow> createRow(ConnectedBot bot);
|
||||
void open(not_null<UserData*> bot, ConnectedBotState state);
|
||||
void requestRecipients();
|
||||
void setupAddForBot();
|
||||
|
||||
const not_null<Window::SessionController*> _controller;
|
||||
|
@ -97,6 +98,8 @@ private:
|
|||
base::flat_set<not_null<PeerData*>> _resolving;
|
||||
UserData *_openOnResolve = nullptr;
|
||||
|
||||
Fn<void()> _recipientsReady;
|
||||
std::vector<not_null<PeerData*>> _recipients;
|
||||
rpl::event_stream<ConnectedBot> _connected;
|
||||
rpl::event_stream<> _addForBot;
|
||||
|
||||
|
@ -104,6 +107,7 @@ private:
|
|||
TimeId _offsetDate = 0;
|
||||
QString _offsetThing;
|
||||
bool _allLoaded = false;
|
||||
bool _recipientsRequested = false;
|
||||
|
||||
rpl::variable<int> _rowCount = 0;
|
||||
|
||||
|
@ -328,17 +332,50 @@ void ListController::rowClicked(not_null<PeerListRow*> row) {
|
|||
}
|
||||
|
||||
void ListController::open(not_null<UserData*> bot, ConnectedBotState state) {
|
||||
const auto show = _controller->uiShow();
|
||||
if (_type == JoinType::Joined || !state.link.isEmpty()) {
|
||||
_controller->show(StarRefLinkBox({ bot, state }, _peer));
|
||||
_recipientsReady = nullptr;
|
||||
show->show(StarRefLinkBox({ bot, state }, _peer));
|
||||
} else {
|
||||
const auto requireOthers = (_type == JoinType::Existing)
|
||||
|| _peer->isSelf();
|
||||
const auto requestOthers = requireOthers && _recipients.empty();
|
||||
if (requestOthers) {
|
||||
_recipientsReady = [=] {
|
||||
Expects(!_recipients.empty());
|
||||
|
||||
open(bot, state);
|
||||
};
|
||||
requestRecipients();
|
||||
return;
|
||||
}
|
||||
const auto connected = crl::guard(this, [=](ConnectedBotState now) {
|
||||
_states[bot] = now;
|
||||
_connected.fire({ bot, now });
|
||||
});
|
||||
_controller->show(JoinStarRefBox({ bot, state }, _peer, connected));
|
||||
show->show(JoinStarRefBox(
|
||||
{ bot, state },
|
||||
_peer,
|
||||
requireOthers ? _recipients : std::vector<not_null<PeerData*>>(),
|
||||
connected));
|
||||
}
|
||||
}
|
||||
|
||||
void ListController::requestRecipients() {
|
||||
if (_recipientsRequested) {
|
||||
return;
|
||||
}
|
||||
_recipientsRequested = true;
|
||||
const auto session = &this->session();
|
||||
ResolveRecipients(session, crl::guard(this, [=](
|
||||
std::vector<not_null<PeerData*>> list) {
|
||||
_recipients = std::move(list);
|
||||
if (const auto callback = base::take(_recipientsReady)) {
|
||||
callback();
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
void RevokeLink(
|
||||
not_null<Window::SessionController*> controller,
|
||||
not_null<PeerData*> peer,
|
||||
|
|
|
@ -2142,6 +2142,29 @@ void ActionsFiller::addAffiliateProgram(not_null<UserData*> user) {
|
|||
});
|
||||
const auto show = _controller->uiShow();
|
||||
|
||||
struct StarRefRecipients {
|
||||
std::vector<not_null<PeerData*>> list;
|
||||
bool requested = false;
|
||||
Fn<void()> open;
|
||||
};
|
||||
const auto recipients = std::make_shared<StarRefRecipients>();
|
||||
recipients->open = [=] {
|
||||
if (!recipients->list.empty()) {
|
||||
const auto program = user->botInfo->starRefProgram;
|
||||
show->show(Info::BotStarRef::JoinStarRefBox(
|
||||
{ user, { program } },
|
||||
user->session().user(),
|
||||
recipients->list));
|
||||
} else if (!recipients->requested) {
|
||||
recipients->requested = true;
|
||||
const auto done = [=](std::vector<not_null<PeerData*>> list) {
|
||||
recipients->list = std::move(list);
|
||||
recipients->open();
|
||||
};
|
||||
Info::BotStarRef::ResolveRecipients(&user->session(), done);
|
||||
}
|
||||
};
|
||||
|
||||
Ui::AddSkip(inner);
|
||||
::Settings::AddButtonWithLabel(
|
||||
inner,
|
||||
|
@ -2149,12 +2172,7 @@ void ActionsFiller::addAffiliateProgram(not_null<UserData*> user) {
|
|||
rpl::duplicate(commission),
|
||||
st::infoSharedMediaButton,
|
||||
{ &st::menuIconSharing }
|
||||
)->setClickedCallback([=] {
|
||||
const auto program = user->botInfo->starRefProgram;
|
||||
show->show(Info::BotStarRef::JoinStarRefBox(
|
||||
{ user, { program } },
|
||||
user->session().user()));
|
||||
});
|
||||
)->setClickedCallback(recipients->open);
|
||||
Ui::AddSkip(inner);
|
||||
Ui::AddDividerText(
|
||||
inner,
|
||||
|
|
|
@ -963,6 +963,11 @@ QString FormatStarsAmountDecimal(StarsAmount amount) {
|
|||
return FormatExactCountDecimal(amount.value());
|
||||
}
|
||||
|
||||
QString FormatStarsAmountRounded(StarsAmount amount) {
|
||||
const auto value = amount.value();
|
||||
return FormatExactCountDecimal(base::SafeRound(value * 100.) / 100.);
|
||||
}
|
||||
|
||||
PluralResult Plural(
|
||||
ushort keyBase,
|
||||
float64 value,
|
||||
|
|
|
@ -31,6 +31,7 @@ struct ShortenedCount {
|
|||
[[nodiscard]] QString FormatExactCountDecimal(float64 number);
|
||||
[[nodiscard]] ShortenedCount FormatStarsAmountToShort(StarsAmount amount);
|
||||
[[nodiscard]] QString FormatStarsAmountDecimal(StarsAmount amount);
|
||||
[[nodiscard]] QString FormatStarsAmountRounded(StarsAmount amount);
|
||||
|
||||
struct PluralResult {
|
||||
int keyShift = 0;
|
||||
|
|
|
@ -1177,6 +1177,8 @@ botEmojiStatusUserpic: UserpicButton(defaultUserpicButton) {
|
|||
photoSize: chatGiveawayPeerSize;
|
||||
}
|
||||
botEmojiStatusName: FlatLabel(defaultFlatLabel) {
|
||||
minWidth: 32px;
|
||||
maxHeight: 20px;
|
||||
}
|
||||
botEmojiStatusEmoji: FlatLabel(botEmojiStatusName) {
|
||||
textFg: profileVerifiedCheckBg;
|
||||
|
|
|
@ -796,7 +796,8 @@ void WhoReactedEntryAction::paint(Painter &&p) {
|
|||
if (selected && _st.itemBgOver->c.alpha() < 255) {
|
||||
p.fillRect(0, 0, width(), _height, _st.itemBg);
|
||||
}
|
||||
p.fillRect(0, 0, width(), _height, selected ? _st.itemBgOver : _st.itemBg);
|
||||
const auto bg = selected ? _st.itemBgOver : _st.itemBg;
|
||||
p.fillRect(0, 0, width(), _height, bg);
|
||||
if (enabled) {
|
||||
paintRipple(p, 0, 0);
|
||||
}
|
||||
|
@ -817,6 +818,18 @@ void WhoReactedEntryAction::paint(Painter &&p) {
|
|||
p.drawEllipse(photoLeft, photoTop, photoSize, photoSize);
|
||||
} else if (!_userpic.isNull()) {
|
||||
p.drawImage(photoLeft, photoTop, _userpic);
|
||||
if (_type == WhoReactedType::RefRecipientNow) {
|
||||
auto hq = PainterHighQualityEnabler(p);
|
||||
p.setBrush(Qt::NoBrush);
|
||||
auto bgPen = bg->p;
|
||||
bgPen.setWidthF(st::lineWidth * 6.);
|
||||
p.setPen(bgPen);
|
||||
p.drawEllipse(photoLeft, photoTop, photoSize, photoSize);
|
||||
auto fgPen = st::windowBgActive->p;
|
||||
fgPen.setWidthF(st::lineWidth * 2.);
|
||||
p.setPen(fgPen);
|
||||
p.drawEllipse(photoLeft, photoTop, photoSize, photoSize);
|
||||
}
|
||||
} else if (!_custom) {
|
||||
st::menuIconReactions.paintInCenter(
|
||||
p,
|
||||
|
@ -852,7 +865,16 @@ void WhoReactedEntryAction::paint(Painter &&p) {
|
|||
_textWidth,
|
||||
width());
|
||||
}
|
||||
if (withDate) {
|
||||
if (_type == WhoReactedType::RefRecipient
|
||||
|| _type == WhoReactedType::RefRecipientNow) {
|
||||
p.setPen(selected ? _st.itemFgShortcutOver : _st.itemFgShortcut);
|
||||
_date.drawLeftElided(
|
||||
p,
|
||||
st::defaultWhoRead.nameLeft,
|
||||
st::whoReadDateTop,
|
||||
_textWidth,
|
||||
width());
|
||||
} else if (withDate) {
|
||||
const auto iconPosition = QPoint(
|
||||
st::defaultWhoRead.nameLeft,
|
||||
st::whoReadDateTop) + st::whoReadDateChecksPosition;
|
||||
|
|
|
@ -74,6 +74,8 @@ enum class WhoReactedType : uchar {
|
|||
Reposted,
|
||||
Forwarded,
|
||||
Preloader,
|
||||
RefRecipient,
|
||||
RefRecipientNow,
|
||||
};
|
||||
|
||||
struct WhoReactedEntryData {
|
||||
|
|
|
@ -475,6 +475,17 @@ starrefLinkCountIcon: icon{{ "chat/mini_subscribers", historyPeerUserpicFg }};
|
|||
starrefLinkCountIconPosition: point(0px, 1px);
|
||||
starrefLinkCountFont: font(10px bold);
|
||||
starrefLinkCountPadding: margins(2px, 0px, 3px, 1px);
|
||||
starrefRecipientBg: lightButtonBgOver;
|
||||
starrefRecipientBgDisabled: windowBgOver;
|
||||
starrefRecipientArrow: icon{{ "calendar_down", lightButtonFg }};
|
||||
|
||||
starrefAddForBotIcon: icon {{ "menu/bot_add", lightButtonFg }};
|
||||
starrefAddForBotIconPosition: point(23px, 2px);
|
||||
|
||||
starrefPopupMenu: PopupMenu(defaultPopupMenu) {
|
||||
maxHeight: 320px;
|
||||
menu: Menu(defaultMenu) {
|
||||
widthMin: 156px;
|
||||
widthMax: 200px;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 3254aebf55133066e0a8775cabdfcef568b79625
|
||||
Subproject commit 93c1299a39258199d0336b33dc49cab029371785
|
Loading…
Add table
Reference in a new issue