mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-15 21:57:10 +02:00
Nice starref join confirmation box.
This commit is contained in:
parent
63c36f5907
commit
0e866a0266
7 changed files with 342 additions and 208 deletions
|
@ -1647,6 +1647,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
"lng_star_ref_update" = "Update Affiliate Program";
|
||||
"lng_star_ref_update_info" = "By updating an affiliate program, you agree to the {terms} of Affiliate Programs.";
|
||||
"lng_star_ref_button_link" = "terms and conditions";
|
||||
"lng_star_ref_tos_url" = "https://telegram.org/tos/mini-apps";
|
||||
"lng_star_ref_warning_title" = "Warning";
|
||||
"lng_star_ref_warning_text" = "Once you start the affiliate program, you won't be able to decrease its commission or duration. You can only increase these parameters or end the program, which will disable all previously distributed referral links.";
|
||||
"lng_star_ref_warning_change" = "This change is irreversible. You won't be able to reduce commission or duration. You can only increase these parameters or end the program, which will disable all previously shared referral links.";
|
||||
|
|
|
@ -202,10 +202,11 @@ void Controller::prepare() {
|
|||
const auto session = &_to->session();
|
||||
auto above = object_ptr<Ui::VerticalLayout>((QWidget*)nullptr);
|
||||
above->add(
|
||||
CreateBoostReplaceUserpics(
|
||||
CreateUserpicsTransfer(
|
||||
above.data(),
|
||||
_selectedPeers.value(),
|
||||
_to),
|
||||
_to,
|
||||
UserpicsTransferType::BoostReplace),
|
||||
st::boxRowPadding + st::boostReplaceUserpicsPadding);
|
||||
above->add(
|
||||
object_ptr<Ui::FlatLabel>(
|
||||
|
@ -366,10 +367,11 @@ object_ptr<Ui::BoxContent> ReassignBoostSingleBox(
|
|||
});
|
||||
box->verticalLayout()->insert(
|
||||
0,
|
||||
CreateBoostReplaceUserpics(
|
||||
CreateUserpicsTransfer(
|
||||
box,
|
||||
rpl::single(std::vector{ peer }),
|
||||
to),
|
||||
to,
|
||||
UserpicsTransferType::BoostReplace),
|
||||
st::boxRowPadding + st::boostReplaceUserpicsPadding);
|
||||
});
|
||||
|
||||
|
@ -536,10 +538,11 @@ object_ptr<Ui::BoxContent> ReassignBoostsBox(
|
|||
return Box<PeerListBox>(std::move(controller), std::move(initBox));
|
||||
}
|
||||
|
||||
object_ptr<Ui::RpWidget> CreateBoostReplaceUserpics(
|
||||
object_ptr<Ui::RpWidget> CreateUserpicsTransfer(
|
||||
not_null<Ui::RpWidget*> parent,
|
||||
rpl::producer<std::vector<not_null<PeerData*>>> from,
|
||||
not_null<PeerData*> to) {
|
||||
not_null<PeerData*> to,
|
||||
UserpicsTransferType type) {
|
||||
struct State {
|
||||
std::vector<not_null<PeerData*>> from;
|
||||
std::vector<std::unique_ptr<Ui::UserpicButton>> buttons;
|
||||
|
@ -640,13 +643,18 @@ object_ptr<Ui::RpWidget> CreateBoostReplaceUserpics(
|
|||
button->render(&q, position, QRegion(), QWidget::DrawChildren);
|
||||
}
|
||||
state->painting = false;
|
||||
const auto boosting = (type == UserpicsTransferType::BoostReplace);
|
||||
const auto last = state->buttons.back().get();
|
||||
const auto back = boosting ? last : right;
|
||||
const auto add = st::boostReplaceIconAdd;
|
||||
const auto skip = st::boostReplaceIconSkip;
|
||||
const auto w = st::boostReplaceIcon.width() + 2 * skip;
|
||||
const auto h = st::boostReplaceIcon.height() + 2 * skip;
|
||||
const auto x = last->x() + last->width() - w + add.x();
|
||||
const auto y = last->y() + last->height() - h + add.y();
|
||||
const auto &icon = boosting
|
||||
? st::boostReplaceIcon
|
||||
: st::starrefJoinIcon;
|
||||
const auto skip = boosting ? st::boostReplaceIconSkip : 0;
|
||||
const auto w = icon.width() + 2 * skip;
|
||||
const auto h = icon.height() + 2 * skip;
|
||||
const auto x = back->x() + back->width() - w + add.x();
|
||||
const auto y = back->y() + back->height() - h + add.y();
|
||||
|
||||
auto brush = QLinearGradient(QPointF(x + w, y + h), QPointF(x, y));
|
||||
brush.setStops(Ui::Premium::ButtonGradientStops());
|
||||
|
@ -654,7 +662,7 @@ object_ptr<Ui::RpWidget> CreateBoostReplaceUserpics(
|
|||
pen.setWidthF(stroke);
|
||||
q.setPen(pen);
|
||||
q.drawEllipse(x - half, y - half, w + stroke, h + stroke);
|
||||
st::boostReplaceIcon.paint(q, x + skip, y + skip, outerw);
|
||||
icon.paint(q, x + skip, y + skip, outerw);
|
||||
|
||||
const auto size = st::boostReplaceArrow.size();
|
||||
st::boostReplaceArrow.paint(
|
||||
|
|
|
@ -53,10 +53,15 @@ object_ptr<Ui::BoxContent> ReassignBoostsBox(
|
|||
Fn<void(std::vector<int> slots, int groups, int channels)> reassign,
|
||||
Fn<void()> cancel);
|
||||
|
||||
[[nodiscard]] object_ptr<Ui::RpWidget> CreateBoostReplaceUserpics(
|
||||
enum class UserpicsTransferType {
|
||||
BoostReplace,
|
||||
StarRefJoin,
|
||||
};
|
||||
[[nodiscard]] object_ptr<Ui::RpWidget> CreateUserpicsTransfer(
|
||||
not_null<Ui::RpWidget*> parent,
|
||||
rpl::producer<std::vector<not_null<PeerData*>>> from,
|
||||
not_null<PeerData*> to);
|
||||
not_null<PeerData*> to,
|
||||
UserpicsTransferType type);
|
||||
|
||||
[[nodiscard]] object_ptr<Ui::RpWidget> CreateUserpicsWithMoreBadge(
|
||||
not_null<Ui::RpWidget*> parent,
|
||||
|
|
|
@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "apiwrap.h"
|
||||
#include "base/timer_rpl.h"
|
||||
#include "base/unixtime.h"
|
||||
#include "boxes/peers/replace_boost_box.h" // CreateUserpicsTransfer.
|
||||
#include "boxes/peer_list_box.h"
|
||||
#include "core/click_handler_types.h"
|
||||
#include "data/data_session.h"
|
||||
|
@ -31,6 +32,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/widgets/labels.h"
|
||||
#include "ui/widgets/popup_menu.h"
|
||||
#include "ui/wrap/fade_wrap.h"
|
||||
#include "ui/wrap/padding_wrap.h"
|
||||
#include "ui/wrap/slide_wrap.h"
|
||||
#include "ui/wrap/vertical_layout.h"
|
||||
#include "ui/ui_utility.h"
|
||||
|
@ -53,6 +55,19 @@ enum class JoinType {
|
|||
Suggested,
|
||||
};
|
||||
|
||||
struct ConnectedBotState {
|
||||
StarRefProgram program;
|
||||
QString link;
|
||||
TimeId date = 0;
|
||||
int users = 0;
|
||||
bool revoked = false;
|
||||
};
|
||||
struct ConnectedBot {
|
||||
not_null<UserData*> bot;
|
||||
ConnectedBotState state;
|
||||
};
|
||||
using ConnectedBots = std::vector<ConnectedBot>;
|
||||
|
||||
class ListController final : public PeerListController {
|
||||
public:
|
||||
ListController(
|
||||
|
@ -71,36 +86,17 @@ public:
|
|||
|
||||
[[nodiscard]] rpl::producer<int> rowCountValue() const;
|
||||
|
||||
//std::unique_ptr<PeerListRow> createRestoredRow(
|
||||
// not_null<PeerData*> peer) override {
|
||||
// return createRow(peer);
|
||||
//}
|
||||
|
||||
//std::unique_ptr<PeerListState> saveState() const override;
|
||||
//void restoreState(std::unique_ptr<PeerListState> state) override;
|
||||
|
||||
void setContentWidget(not_null<Ui::RpWidget*> widget);
|
||||
[[nodiscard]] rpl::producer<int> unlockHeightValue() const;
|
||||
|
||||
private:
|
||||
struct RowState {
|
||||
StarRefProgram program;
|
||||
QString link;
|
||||
int users = 0;
|
||||
};
|
||||
[[nodiscard]] std::unique_ptr<PeerListRow> createRow(ConnectedBot bot);
|
||||
|
||||
[[nodiscard]] std::unique_ptr<PeerListRow> createRow(
|
||||
not_null<PeerData*> peer,
|
||||
RowState state);
|
||||
void showLink(not_null<PeerData*> peer, RowState state);
|
||||
|
||||
struct SavedState : SavedStateBase {
|
||||
};
|
||||
const not_null<Controller*> _controller;
|
||||
const not_null<PeerData*> _peer;
|
||||
const JoinType _type = {};
|
||||
|
||||
base::flat_map<not_null<PeerData*>, RowState> _states;
|
||||
base::flat_map<not_null<PeerData*>, ConnectedBotState> _states;
|
||||
|
||||
mtpRequestId _requestId = 0;
|
||||
TimeId _offsetDate = 0;
|
||||
|
@ -111,6 +107,246 @@ private:
|
|||
|
||||
};
|
||||
|
||||
[[nodiscard]] ConnectedBots Parse(
|
||||
not_null<Main::Session*> session,
|
||||
const MTPpayments_ConnectedStarRefBots &bots) {
|
||||
const auto &data = bots.data();
|
||||
session->data().processUsers(data.vusers());
|
||||
const auto &list = data.vconnected_bots().v;
|
||||
auto result = ConnectedBots();
|
||||
for (const auto &bot : list) {
|
||||
const auto &data = bot.data();
|
||||
const auto botId = UserId(data.vbot_id());
|
||||
const auto link = qs(data.vurl());
|
||||
const auto date = data.vdate().v;
|
||||
const auto commission = data.vcommission_permille().v;
|
||||
const auto durationMonths
|
||||
= data.vduration_months().value_or_empty();
|
||||
const auto users = int(data.vparticipants().v);
|
||||
const auto revoked = data.is_revoked();
|
||||
result.push_back({
|
||||
.bot = session->data().user(botId),
|
||||
.state = {
|
||||
.program = {
|
||||
.commission = ushort(commission),
|
||||
.durationMonths = uchar(durationMonths),
|
||||
},
|
||||
.link = link,
|
||||
.date = date,
|
||||
.users = users,
|
||||
.revoked = revoked,
|
||||
},
|
||||
});
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
[[nodiscard]] rpl::producer<TextWithEntities> FormatProgramDuration(
|
||||
StarRefProgram program) {
|
||||
return !program.durationMonths
|
||||
? tr::lng_star_ref_one_about_for_forever(Ui::Text::RichLangValue)
|
||||
: (program.durationMonths < 12)
|
||||
? tr::lng_star_ref_one_about_for_months(
|
||||
lt_count,
|
||||
rpl::single(program.durationMonths * 1.),
|
||||
Ui::Text::RichLangValue)
|
||||
: tr::lng_star_ref_one_about_for_years(
|
||||
lt_count,
|
||||
rpl::single((program.durationMonths / 12) * 1.),
|
||||
Ui::Text::RichLangValue);
|
||||
}
|
||||
|
||||
[[nodiscard]] not_null<Ui::RoundButton*> AddFullWidthButton(
|
||||
not_null<Ui::BoxContent*> box,
|
||||
rpl::producer<QString> text,
|
||||
Fn<void()> callback = nullptr) {
|
||||
const auto &boxSt = box->getDelegate()->style();
|
||||
const auto result = box->addButton(std::move(text), std::move(callback));
|
||||
rpl::combine(
|
||||
box->widthValue(),
|
||||
result->widthValue()
|
||||
) | rpl::start_with_next([=](int width, int buttonWidth) {
|
||||
const auto correct = width
|
||||
- boxSt.buttonPadding.left()
|
||||
- boxSt.buttonPadding.right();
|
||||
if (correct > 0 && buttonWidth != correct) {
|
||||
result->resizeToWidth(correct);
|
||||
result->moveToLeft(
|
||||
boxSt.buttonPadding.left(),
|
||||
boxSt.buttonPadding.top(),
|
||||
width);
|
||||
}
|
||||
}, result->lifetime());
|
||||
return result;
|
||||
}
|
||||
|
||||
[[nodiscard]] object_ptr<Ui::BoxContent> StarRefLinkBox(
|
||||
ConnectedBot row,
|
||||
not_null<PeerData*> peer) {
|
||||
return Box([=](not_null<Ui::GenericBox*> box) {
|
||||
box->setTitle(tr::lng_star_ref_link_title());
|
||||
|
||||
const auto bot = row.bot;
|
||||
const auto program = row.state.program;
|
||||
auto duration = !program.durationMonths
|
||||
? tr::lng_star_ref_one_about_for_forever(Ui::Text::RichLangValue)
|
||||
: (program.durationMonths < 12)
|
||||
? tr::lng_star_ref_one_about_for_months(
|
||||
lt_count,
|
||||
rpl::single(program.durationMonths * 1.),
|
||||
Ui::Text::RichLangValue)
|
||||
: tr::lng_star_ref_one_about_for_years(
|
||||
lt_count,
|
||||
rpl::single((program.durationMonths / 12) * 1.),
|
||||
Ui::Text::RichLangValue);
|
||||
auto text = tr::lng_star_ref_link_about_channel(
|
||||
lt_amount,
|
||||
rpl::single(Ui::Text::Bold(FormatStarRefCommission(program.commission))),
|
||||
lt_app,
|
||||
rpl::single(Ui::Text::Bold(bot->name())),
|
||||
lt_duration,
|
||||
std::move(duration),
|
||||
Ui::Text::WithEntities);
|
||||
box->addRow(
|
||||
object_ptr<Ui::FlatLabel>(box, std::move(text), st::boxLabel));
|
||||
Ui::AddSkip(box->verticalLayout());
|
||||
box->addRow(
|
||||
object_ptr<Ui::FlatLabel>(
|
||||
box,
|
||||
rpl::single(row.state.link) | Ui::Text::ToLink(),
|
||||
st::boxLabel));
|
||||
Ui::AddSkip(box->verticalLayout());
|
||||
if (row.state.users > 0) {
|
||||
box->addRow(
|
||||
object_ptr<Ui::FlatLabel>(
|
||||
box,
|
||||
tr::lng_star_ref_link_copy_users(
|
||||
lt_count,
|
||||
rpl::single(row.state.users * 1.),
|
||||
lt_app,
|
||||
rpl::single(bot->name())),
|
||||
st::boxLabel));
|
||||
} else {
|
||||
box->addRow(
|
||||
object_ptr<Ui::FlatLabel>(
|
||||
box,
|
||||
tr::lng_star_ref_link_copy_none(
|
||||
lt_app,
|
||||
rpl::single(bot->name())),
|
||||
st::boxLabel));
|
||||
}
|
||||
|
||||
box->addButton(tr::lng_star_ref_link_copy(), [=] {
|
||||
QApplication::clipboard()->setText(row.state.link);
|
||||
box->uiShow()->showToast(tr::lng_username_copied(tr::now));
|
||||
});
|
||||
box->addButton(tr::lng_cancel(), [=] {
|
||||
box->closeBox();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
[[nodiscard]] object_ptr<Ui::BoxContent> JoinStarRefBox(
|
||||
ConnectedBot row,
|
||||
not_null<PeerData*> peer) {
|
||||
Expects(row.bot->isUser());
|
||||
|
||||
return Box([=](not_null<Ui::GenericBox*> box) {
|
||||
const auto show = box->uiShow();
|
||||
|
||||
const auto bot = row.bot;
|
||||
const auto program = row.state.program;
|
||||
|
||||
box->setStyle(st::starrefFooterBox);
|
||||
box->setNoContentMargin(true);
|
||||
box->addTopButton(st::boxTitleClose, [=] {
|
||||
box->closeBox();
|
||||
});
|
||||
|
||||
box->addRow(
|
||||
CreateUserpicsTransfer(
|
||||
box,
|
||||
rpl::single(std::vector{ not_null<PeerData*>(bot) }),
|
||||
peer,
|
||||
UserpicsTransferType::StarRefJoin),
|
||||
st::boxRowPadding + st::starrefJoinUserpicsPadding);
|
||||
box->addRow(
|
||||
object_ptr<Ui::CenterWrap<Ui::FlatLabel>>(
|
||||
box,
|
||||
object_ptr<Ui::FlatLabel>(
|
||||
box,
|
||||
tr::lng_star_ref_title(),
|
||||
st::boxTitle)),
|
||||
st::boxRowPadding + st::starrefJoinTitlePadding);
|
||||
box->addRow(
|
||||
object_ptr<Ui::FlatLabel>(
|
||||
box,
|
||||
tr::lng_star_ref_one_about(
|
||||
lt_app,
|
||||
rpl::single(Ui::Text::Bold(bot->name())),
|
||||
lt_amount,
|
||||
rpl::single(Ui::Text::Bold(
|
||||
FormatStarRefCommission(program.commission))),
|
||||
lt_duration,
|
||||
FormatProgramDuration(program),
|
||||
Ui::Text::WithEntities),
|
||||
st::boxLabel),
|
||||
st::boxRowPadding);
|
||||
struct State {
|
||||
QPointer<Ui::GenericBox> weak;
|
||||
bool sent = false;
|
||||
};
|
||||
const auto state = std::make_shared<State>();
|
||||
state->weak = box;
|
||||
|
||||
const auto send = [=] {
|
||||
if (state->sent) {
|
||||
return;
|
||||
}
|
||||
state->sent = true;
|
||||
bot->session().api().request(MTPpayments_ConnectStarRefBot(
|
||||
peer->input,
|
||||
bot->asUser()->inputUser
|
||||
)).done([=](const MTPpayments_ConnectedStarRefBots &result) {
|
||||
const auto parsed = Parse(&bot->session(), result);
|
||||
if (parsed.empty()) {
|
||||
state->sent = false;
|
||||
show->showToast(u"Failed."_q);
|
||||
} else {
|
||||
show->show(StarRefLinkBox(parsed.front(), peer));
|
||||
if (const auto strong = state->weak.data()) {
|
||||
strong->closeBox();
|
||||
}
|
||||
}
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
state->sent = false;
|
||||
show->showToast(u"Failed: "_q + error.type());
|
||||
}).send();
|
||||
};
|
||||
const auto button = AddFullWidthButton(
|
||||
box,
|
||||
tr::lng_star_ref_one_join(),
|
||||
send);
|
||||
const auto footer = Ui::CreateChild<Ui::FlatLabel>(
|
||||
button->parentWidget(),
|
||||
tr::lng_star_ref_one_join_text(
|
||||
lt_terms,
|
||||
tr::lng_star_ref_button_link(
|
||||
) | Ui::Text::ToLink(tr::lng_star_ref_tos_url(tr::now)),
|
||||
Ui::Text::WithEntities),
|
||||
st::starrefJoinFooter);
|
||||
button->geometryValue() | rpl::start_with_next([=](QRect geometry) {
|
||||
footer->resizeToWidth(geometry.width());
|
||||
const auto &st = box->getDelegate()->style();
|
||||
const auto top = geometry.y() + geometry.height();
|
||||
const auto available = st.buttonPadding.bottom();
|
||||
footer->moveToLeft(
|
||||
geometry.left(),
|
||||
top + (available - footer->height()) / 2);
|
||||
}, footer->lifetime());
|
||||
});
|
||||
}
|
||||
|
||||
ListController::ListController(
|
||||
not_null<Controller*> controller,
|
||||
not_null<PeerData*> peer,
|
||||
|
@ -131,20 +367,22 @@ Main::Session &ListController::session() const {
|
|||
return _peer->session();
|
||||
}
|
||||
|
||||
std::unique_ptr<PeerListRow> ListController::createRow(
|
||||
not_null<PeerData*> peer,
|
||||
RowState state) {
|
||||
_states.emplace(peer, state);
|
||||
auto result = std::make_unique<PeerListRow>(peer);
|
||||
const auto program = state.program;
|
||||
std::unique_ptr<PeerListRow> ListController::createRow(ConnectedBot bot) {
|
||||
_states.emplace(bot.bot, bot.state);
|
||||
auto result = std::make_unique<PeerListRow>(bot.bot);
|
||||
const auto program = bot.state.program;
|
||||
const auto duration = !program.durationMonths
|
||||
? tr::lng_star_ref_duration_forever(tr::now)
|
||||
: (program.durationMonths < 12)
|
||||
? tr::lng_months(tr::now, lt_count, program.durationMonths)
|
||||
: tr::lng_years(tr::now, lt_count, program.durationMonths / 12);
|
||||
result->setCustomStatus(u"+%1%, %2"_q.arg(
|
||||
QString::number(program.commission / 10.),
|
||||
duration));
|
||||
if (bot.state.revoked) {
|
||||
result->setCustomStatus(u"Revoked"_q);
|
||||
} else {
|
||||
result->setCustomStatus(u"+%1%, %2"_q.arg(
|
||||
QString::number(program.commission / 10.),
|
||||
duration));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -170,32 +408,12 @@ void ListController::loadMoreRows() {
|
|||
MTP_string(_offsetThing),
|
||||
MTP_int(kPerPage)
|
||||
)).done([=](const MTPpayments_ConnectedStarRefBots &result) {
|
||||
const auto &data = result.data();
|
||||
session().data().processUsers(data.vusers());
|
||||
const auto &list = data.vconnected_bots().v;
|
||||
if (list.empty()) {
|
||||
const auto parsed = Parse(&session(), result);
|
||||
if (parsed.empty()) {
|
||||
_allLoaded = true;
|
||||
} else {
|
||||
for (const auto &bot : list) {
|
||||
const auto &data = bot.data();
|
||||
const auto botId = UserId(data.vbot_id());
|
||||
_offsetThing = qs(data.vurl());
|
||||
_offsetDate = data.vdate().v;
|
||||
const auto commission = data.vcommission_permille().v;
|
||||
const auto durationMonths
|
||||
= data.vduration_months().value_or_empty();
|
||||
const auto user = session().data().user(botId);
|
||||
if (data.is_revoked()) {
|
||||
continue;
|
||||
}
|
||||
delegate()->peerListAppendRow(createRow(user, {
|
||||
.program = {
|
||||
.commission = ushort(commission),
|
||||
.durationMonths = uchar(durationMonths),
|
||||
},
|
||||
.link = _offsetThing,
|
||||
.users = int(data.vparticipants().v),
|
||||
}));
|
||||
for (const auto &bot : parsed) {
|
||||
delegate()->peerListAppendRow(createRow(bot));
|
||||
}
|
||||
delegate()->peerListRefreshRows();
|
||||
_rowCount = delegate()->peerListFullRowsCount();
|
||||
|
@ -226,10 +444,13 @@ void ListController::loadMoreRows() {
|
|||
const auto durationMonths
|
||||
= data.vduration_months().value_or_empty();
|
||||
const auto user = session().data().user(botId);
|
||||
delegate()->peerListAppendRow(createRow(user, {
|
||||
.program = {
|
||||
.commission = ushort(commission),
|
||||
.durationMonths = uchar(durationMonths),
|
||||
delegate()->peerListAppendRow(createRow({
|
||||
.bot = user,
|
||||
.state = {
|
||||
.program = {
|
||||
.commission = ushort(commission),
|
||||
.durationMonths = uchar(durationMonths),
|
||||
},
|
||||
},
|
||||
}));
|
||||
}
|
||||
|
@ -246,152 +467,25 @@ void ListController::loadMoreRows() {
|
|||
rpl::producer<int> ListController::rowCountValue() const {
|
||||
return _rowCount.value();
|
||||
}
|
||||
//
|
||||
//std::unique_ptr<PeerListState> ListController::saveState() const {
|
||||
// auto result = PeerListController::saveState();
|
||||
// auto my = std::make_unique<SavedState>();
|
||||
// result->controllerState = std::move(my);
|
||||
// return result;
|
||||
//}
|
||||
//
|
||||
//void ListController::restoreState(
|
||||
// std::unique_ptr<PeerListState> state) {
|
||||
// auto typeErasedState = state
|
||||
// ? state->controllerState.get()
|
||||
// : nullptr;
|
||||
// if (dynamic_cast<SavedState*>(typeErasedState)) {
|
||||
// PeerListController::restoreState(std::move(state));
|
||||
// }
|
||||
//}
|
||||
|
||||
void ListController::showLink(not_null<PeerData*> peer, RowState state) {
|
||||
const auto window = _controller->parentController();
|
||||
window->show(Box([=](not_null<Ui::GenericBox*> box) {
|
||||
box->setTitle(tr::lng_star_ref_link_title());
|
||||
|
||||
const auto program = state.program;
|
||||
auto duration = !program.durationMonths
|
||||
? tr::lng_star_ref_one_about_for_forever(Ui::Text::RichLangValue)
|
||||
: (program.durationMonths < 12)
|
||||
? tr::lng_star_ref_one_about_for_months(
|
||||
lt_count,
|
||||
rpl::single(program.durationMonths * 1.),
|
||||
Ui::Text::RichLangValue)
|
||||
: tr::lng_star_ref_one_about_for_years(
|
||||
lt_count,
|
||||
rpl::single((program.durationMonths / 12) * 1.),
|
||||
Ui::Text::RichLangValue);
|
||||
auto text = tr::lng_star_ref_link_about_channel(
|
||||
lt_amount,
|
||||
rpl::single(Ui::Text::Bold(QString::number(program.commission / 10.) + '%')),
|
||||
lt_app,
|
||||
rpl::single(Ui::Text::Bold(peer->name())),
|
||||
lt_duration,
|
||||
std::move(duration),
|
||||
Ui::Text::WithEntities);
|
||||
box->addRow(
|
||||
object_ptr<Ui::FlatLabel>(box, std::move(text), st::boxLabel));
|
||||
Ui::AddSkip(box->verticalLayout());
|
||||
box->addRow(
|
||||
object_ptr<Ui::FlatLabel>(
|
||||
box,
|
||||
rpl::single(state.link) | Ui::Text::ToLink(),
|
||||
st::boxLabel));
|
||||
Ui::AddSkip(box->verticalLayout());
|
||||
if (state.users > 0) {
|
||||
box->addRow(
|
||||
object_ptr<Ui::FlatLabel>(
|
||||
box,
|
||||
tr::lng_star_ref_link_copy_users(
|
||||
lt_count,
|
||||
rpl::single(state.users * 1.),
|
||||
lt_app,
|
||||
rpl::single(peer->name())),
|
||||
st::boxLabel));
|
||||
} else {
|
||||
box->addRow(
|
||||
object_ptr<Ui::FlatLabel>(
|
||||
box,
|
||||
tr::lng_star_ref_link_copy_none(
|
||||
lt_app,
|
||||
rpl::single(peer->name())),
|
||||
st::boxLabel));
|
||||
}
|
||||
|
||||
box->addButton(tr::lng_star_ref_link_copy(), [=] {
|
||||
QApplication::clipboard()->setText(state.link);
|
||||
window->showToast(tr::lng_username_copied(tr::now));
|
||||
});
|
||||
box->addButton(tr::lng_cancel(), [=] {
|
||||
box->closeBox();
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
void ListController::rowClicked(not_null<PeerListRow*> row) {
|
||||
const auto peer = row->peer();
|
||||
const auto i = _states.find(peer);
|
||||
const auto bot = row->peer()->asUser();
|
||||
const auto i = _states.find(bot);
|
||||
Assert(i != end(_states));
|
||||
const auto state = i->second;
|
||||
const auto program = state.program;
|
||||
const auto window = _controller->parentController();
|
||||
if (_type == JoinType::Joined || !state.link.isEmpty()) {
|
||||
showLink(row->peer(), state);
|
||||
window->show(StarRefLinkBox({ bot, state }, _peer));
|
||||
} else {
|
||||
const auto join = [=](Fn<void()> close) {
|
||||
session().api().request(MTPpayments_ConnectStarRefBot(
|
||||
_peer->input,
|
||||
peer->asUser()->inputUser
|
||||
)).done([=](const MTPpayments_ConnectedStarRefBots &result) {
|
||||
window->showToast(u"Connected!"_q);
|
||||
close();
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
window->showToast(u"Failed: "_q + error.type());
|
||||
}).send();
|
||||
};
|
||||
auto duration = !program.durationMonths
|
||||
? tr::lng_star_ref_one_about_for_forever(Ui::Text::RichLangValue)
|
||||
: (program.durationMonths < 12)
|
||||
? tr::lng_star_ref_one_about_for_months(
|
||||
lt_count,
|
||||
rpl::single(program.durationMonths * 1.),
|
||||
Ui::Text::RichLangValue)
|
||||
: tr::lng_star_ref_one_about_for_years(
|
||||
lt_count,
|
||||
rpl::single((program.durationMonths / 12) * 1.),
|
||||
Ui::Text::RichLangValue);
|
||||
auto text = tr::lng_star_ref_one_about(
|
||||
lt_app,
|
||||
rpl::single(Ui::Text::Bold(peer->name())),
|
||||
lt_amount,
|
||||
rpl::single(Ui::Text::Bold(QString::number(program.commission / 10.) + '%')),
|
||||
lt_duration,
|
||||
std::move(duration),
|
||||
Ui::Text::WithEntities);
|
||||
auto added = tr::lng_star_ref_one_join_text(
|
||||
lt_terms,
|
||||
tr::lng_star_ref_button_link() | Ui::Text::ToLink(),
|
||||
Ui::Text::WithEntities);
|
||||
auto joined = rpl::combine(
|
||||
std::move(text),
|
||||
std::move(added)
|
||||
) | rpl::map([=](TextWithEntities a, TextWithEntities b) {
|
||||
return a.append("\n\n").append(b);
|
||||
});
|
||||
window->show(Ui::MakeConfirmBox({
|
||||
.text = std::move(joined),
|
||||
.confirmed = join,
|
||||
.confirmText = tr::lng_star_ref_one_join(),
|
||||
.title = tr::lng_star_ref_title(),
|
||||
}));
|
||||
window->show(JoinStarRefBox({ bot, state }, _peer));
|
||||
}
|
||||
}
|
||||
|
||||
base::unique_qptr<Ui::PopupMenu> ListController::rowContextMenu(
|
||||
QWidget *parent,
|
||||
not_null<PeerListRow*> row) {
|
||||
const auto peer = row->peer();
|
||||
const auto i = _states.find(peer);
|
||||
const auto bot = row->peer()->asUser();
|
||||
const auto i = _states.find(bot);
|
||||
Assert(i != end(_states));
|
||||
const auto state = i->second;
|
||||
if (state.link.isEmpty()) {
|
||||
|
@ -403,7 +497,7 @@ base::unique_qptr<Ui::PopupMenu> ListController::rowContextMenu(
|
|||
const auto addAction = Ui::Menu::CreateAddActionCallback(result.get());
|
||||
|
||||
addAction(tr::lng_star_ref_list_my_open(tr::now), [=] {
|
||||
_controller->parentController()->showPeerHistory(peer);
|
||||
_controller->parentController()->showPeerHistory(bot);
|
||||
}, &st::menuIconBot);
|
||||
addAction(tr::lng_star_ref_list_my_copy(tr::now), [=] {
|
||||
QApplication::clipboard()->setText(state.link);
|
||||
|
@ -774,5 +868,9 @@ std::shared_ptr<Info::Memento> Make(not_null<PeerData*> peer) {
|
|||
std::make_shared<Memento>(peer)));
|
||||
}
|
||||
|
||||
QString FormatStarRefCommission(ushort commission) {
|
||||
return QString::number(commission / 10.) + '%';
|
||||
}
|
||||
|
||||
} // namespace Info::BotStarRef::Join
|
||||
|
||||
|
|
|
@ -76,4 +76,6 @@ private:
|
|||
|
||||
[[nodiscard]] std::shared_ptr<Info::Memento> Make(not_null<PeerData*> peer);
|
||||
|
||||
[[nodiscard]] QString FormatStarRefCommission(ushort commission);
|
||||
|
||||
} // namespace Info::BotStarRef::Join
|
||||
|
|
|
@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "base/unixtime.h"
|
||||
#include "core/click_handler_types.h"
|
||||
#include "data/data_user.h"
|
||||
#include "info/bot/starref/info_bot_starref_join_widget.h"
|
||||
#include "info/profile/info_profile_icon.h"
|
||||
#include "info/info_controller.h"
|
||||
#include "info/info_memento.h"
|
||||
|
@ -495,7 +496,7 @@ void InnerWidget::setupCommission() {
|
|||
commission,
|
||||
setCommission,
|
||||
setCommission,
|
||||
[=](int value) { return QString::number(value / 10.) + '%'; },
|
||||
[=](int value) { return Join::FormatStarRefCommission(value); },
|
||||
_state.exists),
|
||||
st::boxRowPadding);
|
||||
|
||||
|
@ -852,7 +853,8 @@ std::unique_ptr<Ui::RpWidget> Widget::setupBottom() {
|
|||
? tr::lng_star_ref_update_info
|
||||
: tr::lng_star_ref_start_info)(
|
||||
lt_terms,
|
||||
tr::lng_star_ref_button_link() | Ui::Text::ToLink(),
|
||||
tr::lng_star_ref_button_link(
|
||||
) | Ui::Text::ToLink(tr::lng_star_ref_tos_url(tr::now)),
|
||||
Ui::Text::WithEntities),
|
||||
st::boxDividerLabel),
|
||||
QMargins(margins.left(), 0, margins.right(), 0));
|
||||
|
|
|
@ -81,6 +81,24 @@ starrefCover: PremiumCover(userPremiumCover) {
|
|||
titlePadding: margins(0px, 12px, 0px, 11px);
|
||||
}
|
||||
starrefCoverHeight: 180px;
|
||||
starrefFooterBox: Box(defaultBox) {
|
||||
buttonPadding: margins(22px, 11px, 22px, 54px);
|
||||
buttonHeight: 42px;
|
||||
button: RoundButton(defaultActiveButton) {
|
||||
height: 42px;
|
||||
textTop: 12px;
|
||||
style: semiboldTextStyle;
|
||||
}
|
||||
shadowIgnoreTopSkip: true;
|
||||
}
|
||||
starrefJoinIcon: icon{{ "payments/small_star", premiumButtonFg }};
|
||||
starrefJoinUserpicsPadding: margins(0px, 32px, 0px, 10px);
|
||||
starrefJoinTitlePadding: margins(0px, 0px, 0px, 12px);
|
||||
starrefJoinFooter: FlatLabel(defaultFlatLabel) {
|
||||
textFg: windowSubTextFg;
|
||||
align: align(top);
|
||||
minWidth: 240px;
|
||||
}
|
||||
|
||||
defaultPremiumBoxLabel: FlatLabel(defaultFlatLabel) {
|
||||
minWidth: 220px;
|
||||
|
|
Loading…
Add table
Reference in a new issue