mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
"Add {bot}" button in existing starrefs list.
This commit is contained in:
parent
1e14667006
commit
82cec83d87
7 changed files with 128 additions and 30 deletions
|
@ -1641,6 +1641,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_star_ref_duration_about" = "Set the duration for which affiliates will earn commissions from referred users.";
|
"lng_star_ref_duration_about" = "Set the duration for which affiliates will earn commissions from referred users.";
|
||||||
"lng_star_ref_existing_title" = "View existing programs";
|
"lng_star_ref_existing_title" = "View existing programs";
|
||||||
"lng_star_ref_existing_about" = "Explore what other mini apps offer.";
|
"lng_star_ref_existing_about" = "Explore what other mini apps offer.";
|
||||||
|
"lng_star_ref_add_bot" = "Add {bot}";
|
||||||
"lng_star_ref_end" = "End Affiliate Program";
|
"lng_star_ref_end" = "End Affiliate Program";
|
||||||
"lng_star_ref_start" = "Start Affiliate Program";
|
"lng_star_ref_start" = "Start Affiliate Program";
|
||||||
"lng_star_ref_start_disabled" = "Available in {time}";
|
"lng_star_ref_start_disabled" = "Available in {time}";
|
||||||
|
@ -1690,6 +1691,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_star_ref_one_about_for_months#other" = "for **{count} months**";
|
"lng_star_ref_one_about_for_months#other" = "for **{count} months**";
|
||||||
"lng_star_ref_one_about_for_years#one" = "for **{count} year**";
|
"lng_star_ref_one_about_for_years#one" = "for **{count} year**";
|
||||||
"lng_star_ref_one_about_for_years#other" = "for **{count} years**";
|
"lng_star_ref_one_about_for_years#other" = "for **{count} years**";
|
||||||
|
"lng_star_ref_one_daily_revenue" = "Daily revenue per user: {amount}";
|
||||||
"lng_star_ref_one_join" = "Join Program";
|
"lng_star_ref_one_join" = "Join Program";
|
||||||
"lng_star_ref_one_join_text" = "By joining this program, you agree to the {terms} of Affiliate Programs.";
|
"lng_star_ref_one_join_text" = "By joining this program, you agree to the {terms} of Affiliate Programs.";
|
||||||
"lng_star_ref_joined_title" = "Program joined";
|
"lng_star_ref_joined_title" = "Program joined";
|
||||||
|
|
|
@ -739,6 +739,9 @@ StarRefProgram ParseStarRefProgram(const MTPStarRefProgram *program) {
|
||||||
const auto &data = program->data();
|
const auto &data = program->data();
|
||||||
result.commission = data.vcommission_permille().v;
|
result.commission = data.vcommission_permille().v;
|
||||||
result.durationMonths = data.vduration_months().value_or_empty();
|
result.durationMonths = data.vduration_months().value_or_empty();
|
||||||
|
result.revenuePerUser = data.vdaily_revenue_per_user()
|
||||||
|
? Data::FromTL(*data.vdaily_revenue_per_user())
|
||||||
|
: StarsAmount();
|
||||||
result.endDate = data.vend_date().value_or_empty();
|
result.endDate = data.vend_date().value_or_empty();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "core/stars_amount.h"
|
||||||
#include "data/data_birthday.h"
|
#include "data/data_birthday.h"
|
||||||
#include "data/data_peer.h"
|
#include "data/data_peer.h"
|
||||||
#include "data/data_chat_participant_status.h"
|
#include "data/data_chat_participant_status.h"
|
||||||
|
@ -20,6 +21,7 @@ struct BusinessDetails;
|
||||||
} // namespace Data
|
} // namespace Data
|
||||||
|
|
||||||
struct StarRefProgram {
|
struct StarRefProgram {
|
||||||
|
StarsAmount revenuePerUser;
|
||||||
TimeId endDate = 0;
|
TimeId endDate = 0;
|
||||||
ushort commission = 0;
|
ushort commission = 0;
|
||||||
uint8 durationMonths = 0;
|
uint8 durationMonths = 0;
|
||||||
|
|
|
@ -9,7 +9,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
|
||||||
#include "apiwrap.h"
|
#include "apiwrap.h"
|
||||||
#include "boxes/peers/replace_boost_box.h" // CreateUserpicsTransfer.
|
#include "boxes/peers/replace_boost_box.h" // CreateUserpicsTransfer.
|
||||||
|
#include "boxes/send_credits_box.h" // Ui::CreditsEmoji.
|
||||||
#include "chat_helpers/stickers_lottie.h"
|
#include "chat_helpers/stickers_lottie.h"
|
||||||
|
#include "core/ui_integration.h"
|
||||||
#include "data/data_document.h"
|
#include "data/data_document.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
#include "history/view/media/history_view_sticker.h"
|
#include "history/view/media/history_view_sticker.h"
|
||||||
|
@ -499,8 +501,32 @@ object_ptr<Ui::BoxContent> StarRefLinkBox(
|
||||||
st::starrefCenteredText),
|
st::starrefCenteredText),
|
||||||
st::boxRowPadding);
|
st::boxRowPadding);
|
||||||
|
|
||||||
Ui::AddSkip(box->verticalLayout(), st::defaultVerticalListSkip * 4);
|
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 makeContext = [session](Fn<void()> update) {
|
||||||
|
return Core::MarkedTextContext{
|
||||||
|
.session = session,
|
||||||
|
.customEmojiRepaint = std::move(update),
|
||||||
|
};
|
||||||
|
};
|
||||||
|
auto text = Ui::Text::Colorized(Ui::CreditsEmoji(session));
|
||||||
|
text.append(Lang::FormatStarsAmountDecimal(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)),
|
||||||
|
Ui::Text::WithEntities),
|
||||||
|
st::starrefRevenueText,
|
||||||
|
st::defaultPopupMenu,
|
||||||
|
makeContext),
|
||||||
|
st::boxRowPadding);
|
||||||
|
Ui::AddSkip(layout, st::defaultVerticalListSkip);
|
||||||
|
}
|
||||||
|
#if 0
|
||||||
box->addRow(
|
box->addRow(
|
||||||
object_ptr<Ui::FlatLabel>(
|
object_ptr<Ui::FlatLabel>(
|
||||||
box,
|
box,
|
||||||
|
@ -510,6 +536,7 @@ object_ptr<Ui::BoxContent> StarRefLinkBox(
|
||||||
box->addRow(object_ptr<Ui::AbstractButton>::fromRaw(
|
box->addRow(object_ptr<Ui::AbstractButton>::fromRaw(
|
||||||
MakePeerBubbleButton(box, peer).release()
|
MakePeerBubbleButton(box, peer).release()
|
||||||
))->setAttribute(Qt::WA_TransparentForMouseEvents);
|
))->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||||
|
#endif
|
||||||
|
|
||||||
struct State {
|
struct State {
|
||||||
QPointer<Ui::GenericBox> weak;
|
QPointer<Ui::GenericBox> weak;
|
||||||
|
|
|
@ -57,6 +57,7 @@ constexpr auto kPerPage = 50;
|
||||||
enum class JoinType {
|
enum class JoinType {
|
||||||
Joined,
|
Joined,
|
||||||
Suggested,
|
Suggested,
|
||||||
|
Existing,
|
||||||
};
|
};
|
||||||
|
|
||||||
class ListController final
|
class ListController final
|
||||||
|
@ -79,12 +80,14 @@ public:
|
||||||
|
|
||||||
[[nodiscard]] rpl::producer<int> rowCountValue() const;
|
[[nodiscard]] rpl::producer<int> rowCountValue() const;
|
||||||
[[nodiscard]] rpl::producer<ConnectedBot> connected() const;
|
[[nodiscard]] rpl::producer<ConnectedBot> connected() const;
|
||||||
|
[[nodiscard]] rpl::producer<> addForBotRequests() const;
|
||||||
|
|
||||||
void process(ConnectedBot row);
|
void process(ConnectedBot row);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
[[nodiscard]] std::unique_ptr<PeerListRow> createRow(ConnectedBot bot);
|
[[nodiscard]] std::unique_ptr<PeerListRow> createRow(ConnectedBot bot);
|
||||||
void open(not_null<UserData*> bot, ConnectedBotState state);
|
void open(not_null<UserData*> bot, ConnectedBotState state);
|
||||||
|
void setupAddForBot();
|
||||||
|
|
||||||
const not_null<Window::SessionController*> _controller;
|
const not_null<Window::SessionController*> _controller;
|
||||||
const not_null<PeerData*> _peer;
|
const not_null<PeerData*> _peer;
|
||||||
|
@ -95,6 +98,7 @@ private:
|
||||||
UserData *_openOnResolve = nullptr;
|
UserData *_openOnResolve = nullptr;
|
||||||
|
|
||||||
rpl::event_stream<ConnectedBot> _connected;
|
rpl::event_stream<ConnectedBot> _connected;
|
||||||
|
rpl::event_stream<> _addForBot;
|
||||||
|
|
||||||
mtpRequestId _requestId = 0;
|
mtpRequestId _requestId = 0;
|
||||||
TimeId _offsetDate = 0;
|
TimeId _offsetDate = 0;
|
||||||
|
@ -171,15 +175,16 @@ void ListController::loadMoreRows() {
|
||||||
return;
|
return;
|
||||||
} else if (_type == JoinType::Joined) {
|
} else if (_type == JoinType::Joined) {
|
||||||
using Flag = MTPpayments_GetConnectedStarRefBots::Flag;
|
using Flag = MTPpayments_GetConnectedStarRefBots::Flag;
|
||||||
_requestId = session().api().request(MTPpayments_GetConnectedStarRefBots(
|
_requestId = session().api().request(
|
||||||
MTP_flags(Flag()
|
MTPpayments_GetConnectedStarRefBots(
|
||||||
| (_offsetDate ? Flag::f_offset_date : Flag())
|
MTP_flags(Flag()
|
||||||
| (_offsetThing.isEmpty() ? Flag() : Flag::f_offset_link)),
|
| (_offsetDate ? Flag::f_offset_date : Flag())
|
||||||
_peer->input,
|
| (_offsetThing.isEmpty() ? Flag() : Flag::f_offset_link)),
|
||||||
MTP_int(_offsetDate),
|
_peer->input,
|
||||||
MTP_string(_offsetThing),
|
MTP_int(_offsetDate),
|
||||||
MTP_int(kPerPage)
|
MTP_string(_offsetThing),
|
||||||
)).done([=](const MTPpayments_ConnectedStarRefBots &result) {
|
MTP_int(kPerPage))
|
||||||
|
).done([=](const MTPpayments_ConnectedStarRefBots &result) {
|
||||||
const auto parsed = Parse(&session(), result);
|
const auto parsed = Parse(&session(), result);
|
||||||
if (parsed.empty()) {
|
if (parsed.empty()) {
|
||||||
_allLoaded = true;
|
_allLoaded = true;
|
||||||
|
@ -195,6 +200,9 @@ void ListController::loadMoreRows() {
|
||||||
_requestId = 0;
|
_requestId = 0;
|
||||||
}).send();
|
}).send();
|
||||||
} else {
|
} else {
|
||||||
|
if (_type == JoinType::Existing) {
|
||||||
|
setDescriptionText(tr::lng_contacts_loading(tr::now));
|
||||||
|
}
|
||||||
using Flag = MTPpayments_GetSuggestedStarRefBots::Flag;
|
using Flag = MTPpayments_GetSuggestedStarRefBots::Flag;
|
||||||
_requestId = session().api().request(
|
_requestId = session().api().request(
|
||||||
MTPpayments_GetSuggestedStarRefBots(
|
MTPpayments_GetSuggestedStarRefBots(
|
||||||
|
@ -203,6 +211,9 @@ void ListController::loadMoreRows() {
|
||||||
MTP_string(_offsetThing),
|
MTP_string(_offsetThing),
|
||||||
MTP_int(kPerPage))
|
MTP_int(kPerPage))
|
||||||
).done([=](const MTPpayments_SuggestedStarRefBots &result) {
|
).done([=](const MTPpayments_SuggestedStarRefBots &result) {
|
||||||
|
setDescriptionText(QString());
|
||||||
|
setupAddForBot();
|
||||||
|
|
||||||
const auto &data = result.data();
|
const auto &data = result.data();
|
||||||
if (data.vnext_offset()) {
|
if (data.vnext_offset()) {
|
||||||
_offsetThing = qs(*data.vnext_offset());
|
_offsetThing = qs(*data.vnext_offset());
|
||||||
|
@ -210,20 +221,13 @@ void ListController::loadMoreRows() {
|
||||||
_allLoaded = true;
|
_allLoaded = true;
|
||||||
}
|
}
|
||||||
session().data().processUsers(data.vusers());
|
session().data().processUsers(data.vusers());
|
||||||
for (const auto &bot : data.vsuggested_bots().v) {
|
for (const auto &program : data.vsuggested_bots().v) {
|
||||||
const auto &data = bot.data();
|
const auto botId = UserId(program.data().vbot_id());
|
||||||
const auto botId = UserId(data.vbot_id());
|
|
||||||
const auto commission = data.vcommission_permille().v;
|
|
||||||
const auto durationMonths
|
|
||||||
= data.vduration_months().value_or_empty();
|
|
||||||
const auto user = session().data().user(botId);
|
const auto user = session().data().user(botId);
|
||||||
delegate()->peerListAppendRow(createRow({
|
delegate()->peerListAppendRow(createRow({
|
||||||
.bot = user,
|
.bot = user,
|
||||||
.state = {
|
.state = {
|
||||||
.program = {
|
.program = Data::ParseStarRefProgram(&program),
|
||||||
.commission = ushort(commission),
|
|
||||||
.durationMonths = uchar(durationMonths),
|
|
||||||
},
|
|
||||||
.unresolved = true,
|
.unresolved = true,
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
@ -238,6 +242,46 @@ void ListController::loadMoreRows() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ListController::setupAddForBot() {
|
||||||
|
const auto user = _peer->asUser();
|
||||||
|
if (_type != JoinType::Existing
|
||||||
|
|| !user
|
||||||
|
|| !user->isBot()
|
||||||
|
|| user->botInfo->starRefProgram.commission > 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto button = object_ptr<Ui::PaddingWrap<Ui::SettingsButton>>(
|
||||||
|
nullptr,
|
||||||
|
object_ptr<Ui::SettingsButton>(
|
||||||
|
nullptr,
|
||||||
|
tr::lng_star_ref_add_bot(lt_bot, rpl::single(user->name())),
|
||||||
|
st::inviteViaLinkButton),
|
||||||
|
style::margins(0, st::membersMarginTop, 0, 0));
|
||||||
|
|
||||||
|
const auto icon = Ui::CreateChild<Info::Profile::FloatingIcon>(
|
||||||
|
button->entity(),
|
||||||
|
st::starrefAddForBotIcon,
|
||||||
|
QPoint());
|
||||||
|
button->entity()->heightValue(
|
||||||
|
) | rpl::start_with_next([=](int height) {
|
||||||
|
icon->moveToLeft(
|
||||||
|
st::starrefAddForBotIconPosition.x(),
|
||||||
|
(height - st::starrefAddForBotIcon.height()) / 2);
|
||||||
|
}, icon->lifetime());
|
||||||
|
|
||||||
|
button->entity()->setClickedCallback([=] {
|
||||||
|
_addForBot.fire({});
|
||||||
|
});
|
||||||
|
button->entity()->events(
|
||||||
|
) | rpl::filter([=](not_null<QEvent*> e) {
|
||||||
|
return (e->type() == QEvent::Enter);
|
||||||
|
}) | rpl::start_with_next([=] {
|
||||||
|
delegate()->peerListMouseLeftGeometry();
|
||||||
|
}, button->lifetime());
|
||||||
|
delegate()->peerListSetAboveWidget(std::move(button));
|
||||||
|
delegate()->peerListRefreshRows();
|
||||||
|
}
|
||||||
|
|
||||||
rpl::producer<int> ListController::rowCountValue() const {
|
rpl::producer<int> ListController::rowCountValue() const {
|
||||||
return _rowCount.value();
|
return _rowCount.value();
|
||||||
}
|
}
|
||||||
|
@ -246,6 +290,10 @@ rpl::producer<ConnectedBot> ListController::connected() const {
|
||||||
return _connected.events();
|
return _connected.events();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rpl::producer<> ListController::addForBotRequests() const {
|
||||||
|
return _addForBot.events();
|
||||||
|
}
|
||||||
|
|
||||||
void ListController::process(ConnectedBot row) {
|
void ListController::process(ConnectedBot row) {
|
||||||
if (!delegate()->peerListFindRow(PeerListRowId(row.bot->id.value))) {
|
if (!delegate()->peerListFindRow(PeerListRowId(row.bot->id.value))) {
|
||||||
delegate()->peerListPrependRow(createRow(row));
|
delegate()->peerListPrependRow(createRow(row));
|
||||||
|
@ -720,19 +768,27 @@ std::shared_ptr<Info::Memento> Make(not_null<PeerData*> peer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
object_ptr<Ui::BoxContent> ProgramsListBox(
|
object_ptr<Ui::BoxContent> ProgramsListBox(
|
||||||
not_null<Window::SessionController*> controller,
|
not_null<Window::SessionController*> window,
|
||||||
not_null<PeerData*> peer) {
|
not_null<PeerData*> peer) {
|
||||||
|
const auto weak = std::make_shared<QPointer<PeerListBox>>();
|
||||||
const auto initBox = [=](not_null<PeerListBox*> box) {
|
const auto initBox = [=](not_null<PeerListBox*> box) {
|
||||||
|
*weak = box;
|
||||||
box->addButton(tr::lng_close(), [=] {
|
box->addButton(tr::lng_close(), [=] {
|
||||||
box->closeBox();
|
box->closeBox();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
return Box<PeerListBox>(
|
|
||||||
std::make_unique<ListController>(
|
auto controller = std::make_unique<ListController>(
|
||||||
controller,
|
window,
|
||||||
peer,
|
peer,
|
||||||
JoinType::Suggested),
|
JoinType::Existing);
|
||||||
initBox);
|
controller->addForBotRequests() | rpl::start_with_next([=] {
|
||||||
|
if (const auto strong = weak->data()) {
|
||||||
|
strong->closeBox();
|
||||||
|
}
|
||||||
|
}, controller->lifetime());
|
||||||
|
|
||||||
|
return Box<PeerListBox>(std::move(controller), initBox);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Info::BotStarRef::Join
|
} // namespace Info::BotStarRef::Join
|
||||||
|
|
|
@ -83,7 +83,7 @@ private:
|
||||||
[[nodiscard]] std::shared_ptr<Info::Memento> Make(not_null<PeerData*> peer);
|
[[nodiscard]] std::shared_ptr<Info::Memento> Make(not_null<PeerData*> peer);
|
||||||
|
|
||||||
[[nodiscard]] object_ptr<Ui::BoxContent> ProgramsListBox(
|
[[nodiscard]] object_ptr<Ui::BoxContent> ProgramsListBox(
|
||||||
not_null<Window::SessionController*> controller,
|
not_null<Window::SessionController*> window,
|
||||||
not_null<PeerData*> peer);
|
not_null<PeerData*> peer);
|
||||||
|
|
||||||
} // namespace Info::BotStarRef::Join
|
} // namespace Info::BotStarRef::Join
|
||||||
|
|
|
@ -441,6 +441,11 @@ starrefCenteredText: FlatLabel(defaultFlatLabel) {
|
||||||
starrefJoinFooter: FlatLabel(starrefCenteredText) {
|
starrefJoinFooter: FlatLabel(starrefCenteredText) {
|
||||||
textFg: windowSubTextFg;
|
textFg: windowSubTextFg;
|
||||||
}
|
}
|
||||||
|
starrefRevenueText: FlatLabel(starrefCenteredText) {
|
||||||
|
palette: TextPalette(defaultTextPalette) {
|
||||||
|
linkFg: creditsBg1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
starrefInfoIconPosition: point(16px, 8px);
|
starrefInfoIconPosition: point(16px, 8px);
|
||||||
starrefBottomButton: RoundButton(defaultActiveButton) {
|
starrefBottomButton: RoundButton(defaultActiveButton) {
|
||||||
|
@ -469,4 +474,7 @@ starrefLinkCountAdd: 6px;
|
||||||
starrefLinkCountIcon: icon{{ "chat/mini_subscribers", historyPeerUserpicFg }};
|
starrefLinkCountIcon: icon{{ "chat/mini_subscribers", historyPeerUserpicFg }};
|
||||||
starrefLinkCountIconPosition: point(0px, 1px);
|
starrefLinkCountIconPosition: point(0px, 1px);
|
||||||
starrefLinkCountFont: font(10px bold);
|
starrefLinkCountFont: font(10px bold);
|
||||||
starrefLinkCountPadding: margins(2px, 0px, 3px, 1px);
|
starrefLinkCountPadding: margins(2px, 0px, 3px, 1px);
|
||||||
|
|
||||||
|
starrefAddForBotIcon: icon {{ "menu/bot_add", lightButtonFg }};
|
||||||
|
starrefAddForBotIconPosition: point(23px, 2px);
|
||||||
|
|
Loading…
Add table
Reference in a new issue