mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Added ability to create invite links with subscription.
This commit is contained in:
parent
44c1109798
commit
8158c52e82
10 changed files with 306 additions and 23 deletions
|
@ -1474,6 +1474,8 @@ PRIVATE
|
||||||
support/support_preload.h
|
support/support_preload.h
|
||||||
support/support_templates.cpp
|
support/support_templates.cpp
|
||||||
support/support_templates.h
|
support/support_templates.h
|
||||||
|
ui/boxes/edit_invite_link_session.cpp
|
||||||
|
ui/boxes/edit_invite_link_session.h
|
||||||
ui/chat/attach/attach_item_single_file_preview.cpp
|
ui/chat/attach/attach_item_single_file_preview.cpp
|
||||||
ui/chat/attach/attach_item_single_file_preview.h
|
ui/chat/attach/attach_item_single_file_preview.h
|
||||||
ui/chat/attach/attach_item_single_media_preview.cpp
|
ui/chat/attach/attach_item_single_media_preview.cpp
|
||||||
|
|
|
@ -2021,6 +2021,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_group_invite_about_no_approve" = "New users will be able to join the group without being approved by the admins.";
|
"lng_group_invite_about_no_approve" = "New users will be able to join the group without being approved by the admins.";
|
||||||
"lng_group_invite_about_approve_channel" = "New users will be able to join the channel only after having been approved by the admins.";
|
"lng_group_invite_about_approve_channel" = "New users will be able to join the channel only after having been approved by the admins.";
|
||||||
"lng_group_invite_about_no_approve_channel" = "New users will be able to join the channel without being approved by the admins.";
|
"lng_group_invite_about_no_approve_channel" = "New users will be able to join the channel without being approved by the admins.";
|
||||||
|
"lng_group_invite_subscription" = "Require Monthly Fee";
|
||||||
|
"lng_group_invite_subscription_ph" = "Stars Amount per month";
|
||||||
|
"lng_group_invite_subscription_price" = "~{cost} / month";
|
||||||
|
"lng_group_invite_subscription_toast" = "Sorry, you cannot change the number of Stars for an already created invite link.";
|
||||||
|
"lng_group_invite_subscription_about" = "Charge a subscription fee from people joining your channel via this link. {link}";
|
||||||
|
"lng_group_invite_subscription_about_link" = "Learn more {emoji}";
|
||||||
|
"lng_group_invite_subscription_about_url" = "https://telegram.org/tos/stars";
|
||||||
|
|
||||||
"lng_group_request_to_join" = "Request to Join";
|
"lng_group_request_to_join" = "Request to Join";
|
||||||
"lng_group_request_about" = "This group accepts new members only after they are approved by its admins.";
|
"lng_group_request_about" = "This group accepts new members only after they are approved by its admins.";
|
||||||
|
|
|
@ -737,6 +737,12 @@ auto InviteLinks::parse(
|
||||||
return std::optional<Link>(Link{
|
return std::optional<Link>(Link{
|
||||||
.link = qs(data.vlink()),
|
.link = qs(data.vlink()),
|
||||||
.label = qs(data.vtitle().value_or_empty()),
|
.label = qs(data.vtitle().value_or_empty()),
|
||||||
|
.subscription = data.vsubscription_pricing()
|
||||||
|
? Data::PeerSubscription{
|
||||||
|
data.vsubscription_pricing()->data().vamount().v,
|
||||||
|
data.vsubscription_pricing()->data().vperiod().v,
|
||||||
|
}
|
||||||
|
: Data::PeerSubscription(),
|
||||||
.admin = peer->session().data().user(data.vadmin_id()),
|
.admin = peer->session().data().user(data.vadmin_id()),
|
||||||
.date = data.vdate().v,
|
.date = data.vdate().v,
|
||||||
.startDate = data.vstart_date().value_or_empty(),
|
.startDate = data.vstart_date().value_or_empty(),
|
||||||
|
|
|
@ -16,6 +16,7 @@ namespace Api {
|
||||||
struct InviteLink {
|
struct InviteLink {
|
||||||
QString link;
|
QString link;
|
||||||
QString label;
|
QString label;
|
||||||
|
Data::PeerSubscription subscription;
|
||||||
not_null<UserData*> admin;
|
not_null<UserData*> admin;
|
||||||
TimeId date = 0;
|
TimeId date = 0;
|
||||||
TimeId startDate = 0;
|
TimeId startDate = 0;
|
||||||
|
|
|
@ -28,6 +28,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/toast/toast.h"
|
#include "ui/toast/toast.h"
|
||||||
#include "ui/text/text_utilities.h"
|
#include "ui/text/text_utilities.h"
|
||||||
#include "ui/boxes/edit_invite_link.h"
|
#include "ui/boxes/edit_invite_link.h"
|
||||||
|
#include "ui/boxes/edit_invite_link_session.h"
|
||||||
#include "ui/painter.h"
|
#include "ui/painter.h"
|
||||||
#include "ui/vertical_list.h"
|
#include "ui/vertical_list.h"
|
||||||
#include "boxes/share_box.h"
|
#include "boxes/share_box.h"
|
||||||
|
@ -1251,6 +1252,8 @@ object_ptr<Ui::BoxContent> InviteLinkQrBox(
|
||||||
object_ptr<Ui::BoxContent> EditLinkBox(
|
object_ptr<Ui::BoxContent> EditLinkBox(
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
const Api::InviteLink &data) {
|
const Api::InviteLink &data) {
|
||||||
|
constexpr auto kPeriod = 3600 * 24 * 30;
|
||||||
|
constexpr auto kTestModePeriod = 300;
|
||||||
const auto creating = data.link.isEmpty();
|
const auto creating = data.link.isEmpty();
|
||||||
const auto box = std::make_shared<QPointer<Ui::GenericBox>>();
|
const auto box = std::make_shared<QPointer<Ui::GenericBox>>();
|
||||||
using Fields = Ui::InviteLinkFields;
|
using Fields = Ui::InviteLinkFields;
|
||||||
|
@ -1266,6 +1269,9 @@ object_ptr<Ui::BoxContent> EditLinkBox(
|
||||||
};
|
};
|
||||||
if (creating) {
|
if (creating) {
|
||||||
Assert(data.admin->isSelf());
|
Assert(data.admin->isSelf());
|
||||||
|
const auto period = peer->session().isTestMode()
|
||||||
|
? kTestModePeriod
|
||||||
|
: kPeriod;
|
||||||
peer->session().api().inviteLinks().create({
|
peer->session().api().inviteLinks().create({
|
||||||
peer,
|
peer,
|
||||||
finish,
|
finish,
|
||||||
|
@ -1273,6 +1279,7 @@ object_ptr<Ui::BoxContent> EditLinkBox(
|
||||||
result.expireDate,
|
result.expireDate,
|
||||||
result.usageLimit,
|
result.usageLimit,
|
||||||
result.requestApproval,
|
result.requestApproval,
|
||||||
|
{ uint64(result.subscriptionCredits), period },
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
peer->session().api().inviteLinks().edit(
|
peer->session().api().inviteLinks().edit(
|
||||||
|
@ -1288,26 +1295,31 @@ object_ptr<Ui::BoxContent> EditLinkBox(
|
||||||
};
|
};
|
||||||
const auto isGroup = !peer->isBroadcast();
|
const auto isGroup = !peer->isBroadcast();
|
||||||
const auto isPublic = peer->isChannel() && peer->asChannel()->isPublic();
|
const auto isPublic = peer->isChannel() && peer->asChannel()->isPublic();
|
||||||
if (creating) {
|
auto object = Box([=](not_null<Ui::GenericBox*> box) {
|
||||||
auto object = Box(Ui::CreateInviteLinkBox, isGroup, isPublic, done);
|
const auto fill = [=] {
|
||||||
*box = Ui::MakeWeak(object.data());
|
return Ui::FillCreateInviteLinkSubscriptionToggle(box, peer);
|
||||||
return object;
|
};
|
||||||
} else {
|
if (creating) {
|
||||||
auto object = Box(
|
Ui::CreateInviteLinkBox(box, fill, isGroup, isPublic, done);
|
||||||
Ui::EditInviteLinkBox,
|
} else {
|
||||||
Fields{
|
Ui::EditInviteLinkBox(
|
||||||
.link = data.link,
|
box,
|
||||||
.label = data.label,
|
fill,
|
||||||
.expireDate = data.expireDate,
|
Fields{
|
||||||
.usageLimit = data.usageLimit,
|
.link = data.link,
|
||||||
.requestApproval = data.requestApproval,
|
.label = data.label,
|
||||||
.isGroup = isGroup,
|
.expireDate = data.expireDate,
|
||||||
.isPublic = isPublic,
|
.usageLimit = data.usageLimit,
|
||||||
},
|
.subscriptionCredits = data.subscription.period,
|
||||||
done);
|
.requestApproval = data.requestApproval,
|
||||||
*box = Ui::MakeWeak(object.data());
|
.isGroup = isGroup,
|
||||||
return object;
|
.isPublic = isPublic,
|
||||||
}
|
},
|
||||||
|
done);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
*box = Ui::MakeWeak(object.data());
|
||||||
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
object_ptr<Ui::BoxContent> RevokeLinkBox(
|
object_ptr<Ui::BoxContent> RevokeLinkBox(
|
||||||
|
|
|
@ -992,6 +992,24 @@ inviteLinkQrSkip: 24px;
|
||||||
inviteLinkQrMargin: margins(0px, 0px, 0px, 13px);
|
inviteLinkQrMargin: margins(0px, 0px, 0px, 13px);
|
||||||
inviteLinkQrValuePadding: margins(22px, 0px, 22px, 12px);
|
inviteLinkQrValuePadding: margins(22px, 0px, 22px, 12px);
|
||||||
|
|
||||||
|
inviteLinkCreditsField: InputField(defaultInputField) {
|
||||||
|
textMargins: margins(23px, 10px, 0px, 0px);
|
||||||
|
textAlign: align(left);
|
||||||
|
textFg: historyComposeAreaFg;
|
||||||
|
textBg: historyComposeAreaBg;
|
||||||
|
heightMin: 36px;
|
||||||
|
heightMax: 36px;
|
||||||
|
placeholderFg: placeholderFg;
|
||||||
|
placeholderFgActive: placeholderFgActive;
|
||||||
|
placeholderFgError: placeholderFgActive;
|
||||||
|
placeholderMargins: margins(0px, 0px, 2px, 0px);
|
||||||
|
placeholderAlign: align(left);
|
||||||
|
placeholderScale: 0.;
|
||||||
|
placeholderFont: normalFont;
|
||||||
|
placeholderShift: -50px;
|
||||||
|
duration: 100;
|
||||||
|
}
|
||||||
|
|
||||||
usernamesReorderIcon: icon {{ "stickers_reorder", dialogsMenuIconFg }};
|
usernamesReorderIcon: icon {{ "stickers_reorder", dialogsMenuIconFg }};
|
||||||
|
|
||||||
infoAboutGigagroup: FlatLabel(defaultFlatLabel) {
|
infoAboutGigagroup: FlatLabel(defaultFlatLabel) {
|
||||||
|
|
|
@ -11,9 +11,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
#include "ui/boxes/choose_date_time.h"
|
#include "ui/boxes/choose_date_time.h"
|
||||||
#include "ui/layers/generic_box.h"
|
#include "ui/layers/generic_box.h"
|
||||||
|
#include "ui/vertical_list.h"
|
||||||
|
#include "ui/text/format_values.h"
|
||||||
#include "ui/widgets/checkbox.h"
|
#include "ui/widgets/checkbox.h"
|
||||||
#include "ui/widgets/fields/input_field.h"
|
#include "ui/widgets/fields/input_field.h"
|
||||||
#include "ui/widgets/fields/number_input.h"
|
#include "ui/widgets/fields/number_input.h"
|
||||||
|
#include "ui/effects/credits_graphics.h"
|
||||||
#include "ui/widgets/labels.h"
|
#include "ui/widgets/labels.h"
|
||||||
#include "ui/wrap/slide_wrap.h"
|
#include "ui/wrap/slide_wrap.h"
|
||||||
#include "styles/style_settings.h"
|
#include "styles/style_settings.h"
|
||||||
|
@ -44,6 +47,7 @@ constexpr auto kMaxLabelLength = 32;
|
||||||
|
|
||||||
void EditInviteLinkBox(
|
void EditInviteLinkBox(
|
||||||
not_null<GenericBox*> box,
|
not_null<GenericBox*> box,
|
||||||
|
Fn<InviteLinkSubscriptionToggle()> fillSubscription,
|
||||||
const InviteLinkFields &data,
|
const InviteLinkFields &data,
|
||||||
Fn<void(InviteLinkFields)> done) {
|
Fn<void(InviteLinkFields)> done) {
|
||||||
using namespace rpl::mappers;
|
using namespace rpl::mappers;
|
||||||
|
@ -95,14 +99,17 @@ void EditInviteLinkBox(
|
||||||
int expireValue = 0;
|
int expireValue = 0;
|
||||||
int usageValue = 0;
|
int usageValue = 0;
|
||||||
rpl::variable<bool> requestApproval = false;
|
rpl::variable<bool> requestApproval = false;
|
||||||
|
rpl::variable<bool> subscription = false;
|
||||||
};
|
};
|
||||||
const auto state = box->lifetime().make_state<State>(State{
|
const auto state = box->lifetime().make_state<State>(State{
|
||||||
.expireValue = expire,
|
.expireValue = expire,
|
||||||
.usageValue = usage,
|
.usageValue = usage,
|
||||||
.requestApproval = (data.requestApproval && !isPublic),
|
.requestApproval = (data.requestApproval && !isPublic),
|
||||||
|
.subscription = false,
|
||||||
});
|
});
|
||||||
|
|
||||||
const auto requestApproval = isPublic
|
const auto subscriptionLocked = data.subscriptionCredits > 0;
|
||||||
|
const auto requestApproval = (isPublic || subscriptionLocked)
|
||||||
? nullptr
|
? nullptr
|
||||||
: container->add(
|
: container->add(
|
||||||
object_ptr<SettingsButton>(
|
object_ptr<SettingsButton>(
|
||||||
|
@ -111,8 +118,11 @@ void EditInviteLinkBox(
|
||||||
st::settingsButtonNoIcon),
|
st::settingsButtonNoIcon),
|
||||||
style::margins{ 0, 0, 0, st::defaultVerticalListSkip });
|
style::margins{ 0, 0, 0, st::defaultVerticalListSkip });
|
||||||
if (requestApproval) {
|
if (requestApproval) {
|
||||||
requestApproval->toggleOn(state->requestApproval.value());
|
requestApproval->toggleOn(state->requestApproval.value(), true);
|
||||||
state->requestApproval = requestApproval->toggledValue();
|
requestApproval->setClickedCallback([=] {
|
||||||
|
state->requestApproval.force_assign(!requestApproval->toggled());
|
||||||
|
state->subscription.force_assign(false);
|
||||||
|
});
|
||||||
addDivider(container, rpl::conditional(
|
addDivider(container, rpl::conditional(
|
||||||
state->requestApproval.value(),
|
state->requestApproval.value(),
|
||||||
(isGroup
|
(isGroup
|
||||||
|
@ -122,6 +132,30 @@ void EditInviteLinkBox(
|
||||||
? tr::lng_group_invite_about_no_approve()
|
? tr::lng_group_invite_about_no_approve()
|
||||||
: tr::lng_group_invite_about_no_approve_channel())));
|
: tr::lng_group_invite_about_no_approve_channel())));
|
||||||
}
|
}
|
||||||
|
auto credits = (Ui::NumberInput*)(nullptr);
|
||||||
|
if (!isPublic && fillSubscription) {
|
||||||
|
Ui::AddSkip(container);
|
||||||
|
const auto &[subscription, input] = fillSubscription();
|
||||||
|
credits = input.get();
|
||||||
|
subscription->toggleOn(state->subscription.value(), true);
|
||||||
|
if (subscriptionLocked) {
|
||||||
|
input->setText(QString::number(data.subscriptionCredits));
|
||||||
|
input->setReadOnly(true);
|
||||||
|
state->subscription.force_assign(true);
|
||||||
|
state->requestApproval.force_assign(false);
|
||||||
|
subscription->setToggleLocked(true);
|
||||||
|
subscription->finishAnimating();
|
||||||
|
}
|
||||||
|
subscription->setClickedCallback([=, show = box->uiShow()] {
|
||||||
|
if (subscriptionLocked) {
|
||||||
|
show->showToast(
|
||||||
|
tr::lng_group_invite_subscription_toast(tr::now));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
state->subscription.force_assign(!subscription->toggled());
|
||||||
|
state->requestApproval.force_assign(false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const auto labelField = container->add(
|
const auto labelField = container->add(
|
||||||
object_ptr<Ui::InputField>(
|
object_ptr<Ui::InputField>(
|
||||||
|
@ -327,6 +361,9 @@ void EditInviteLinkBox(
|
||||||
.label = label,
|
.label = label,
|
||||||
.expireDate = expireDate,
|
.expireDate = expireDate,
|
||||||
.usageLimit = usageLimit,
|
.usageLimit = usageLimit,
|
||||||
|
.subscriptionCredits = credits
|
||||||
|
? credits->getLastText().toInt()
|
||||||
|
: 0,
|
||||||
.requestApproval = state->requestApproval.current(),
|
.requestApproval = state->requestApproval.current(),
|
||||||
.isGroup = isGroup,
|
.isGroup = isGroup,
|
||||||
.isPublic = isPublic,
|
.isPublic = isPublic,
|
||||||
|
@ -337,11 +374,13 @@ void EditInviteLinkBox(
|
||||||
|
|
||||||
void CreateInviteLinkBox(
|
void CreateInviteLinkBox(
|
||||||
not_null<GenericBox*> box,
|
not_null<GenericBox*> box,
|
||||||
|
Fn<InviteLinkSubscriptionToggle()> fillSubscription,
|
||||||
bool isGroup,
|
bool isGroup,
|
||||||
bool isPublic,
|
bool isPublic,
|
||||||
Fn<void(InviteLinkFields)> done) {
|
Fn<void(InviteLinkFields)> done) {
|
||||||
EditInviteLinkBox(
|
EditInviteLinkBox(
|
||||||
box,
|
box,
|
||||||
|
std::move(fillSubscription),
|
||||||
InviteLinkFields{ .isGroup = isGroup, .isPublic = isPublic },
|
InviteLinkFields{ .isGroup = isGroup, .isPublic = isPublic },
|
||||||
std::move(done));
|
std::move(done));
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
|
|
||||||
class GenericBox;
|
class GenericBox;
|
||||||
|
class NumberInput;
|
||||||
class SettingsButton;
|
class SettingsButton;
|
||||||
|
|
||||||
struct InviteLinkFields {
|
struct InviteLinkFields {
|
||||||
|
@ -17,18 +18,26 @@ struct InviteLinkFields {
|
||||||
QString label;
|
QString label;
|
||||||
TimeId expireDate = 0;
|
TimeId expireDate = 0;
|
||||||
int usageLimit = 0;
|
int usageLimit = 0;
|
||||||
|
int subscriptionCredits = 0;
|
||||||
bool requestApproval = false;
|
bool requestApproval = false;
|
||||||
bool isGroup = false;
|
bool isGroup = false;
|
||||||
bool isPublic = false;
|
bool isPublic = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct InviteLinkSubscriptionToggle final {
|
||||||
|
not_null<Ui::SettingsButton*> button;
|
||||||
|
not_null<Ui::NumberInput*> amount;
|
||||||
|
};
|
||||||
|
|
||||||
void EditInviteLinkBox(
|
void EditInviteLinkBox(
|
||||||
not_null<Ui::GenericBox*> box,
|
not_null<Ui::GenericBox*> box,
|
||||||
|
Fn<InviteLinkSubscriptionToggle()> fillSubscription,
|
||||||
const InviteLinkFields &data,
|
const InviteLinkFields &data,
|
||||||
Fn<void(InviteLinkFields)> done);
|
Fn<void(InviteLinkFields)> done);
|
||||||
|
|
||||||
void CreateInviteLinkBox(
|
void CreateInviteLinkBox(
|
||||||
not_null<Ui::GenericBox*> box,
|
not_null<Ui::GenericBox*> box,
|
||||||
|
Fn<InviteLinkSubscriptionToggle()> fillSubscription,
|
||||||
bool isGroup,
|
bool isGroup,
|
||||||
bool isPublic,
|
bool isPublic,
|
||||||
Fn<void(InviteLinkFields)> done);
|
Fn<void(InviteLinkFields)> done);
|
||||||
|
|
166
Telegram/SourceFiles/ui/boxes/edit_invite_link_session.cpp
Normal file
166
Telegram/SourceFiles/ui/boxes/edit_invite_link_session.cpp
Normal file
|
@ -0,0 +1,166 @@
|
||||||
|
/*
|
||||||
|
This file is part of Telegram Desktop,
|
||||||
|
the official desktop application for the Telegram messaging service.
|
||||||
|
|
||||||
|
For license and copyright information please follow this link:
|
||||||
|
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
*/
|
||||||
|
#include "ui/boxes/edit_invite_link_session.h"
|
||||||
|
|
||||||
|
#include "api/api_credits.h"
|
||||||
|
#include "data/data_peer.h"
|
||||||
|
#include "data/data_session.h"
|
||||||
|
#include "data/stickers/data_custom_emoji.h"
|
||||||
|
#include "lang/lang_keys.h"
|
||||||
|
#include "main/main_app_config.h"
|
||||||
|
#include "main/main_session.h"
|
||||||
|
#include "ui/boxes/edit_invite_link.h" // InviteLinkSubscriptionToggle
|
||||||
|
#include "ui/effects/credits_graphics.h"
|
||||||
|
#include "ui/layers/generic_box.h"
|
||||||
|
#include "ui/rect.h"
|
||||||
|
#include "ui/text/format_values.h"
|
||||||
|
#include "ui/text/text_utilities.h"
|
||||||
|
#include "ui/vertical_list.h"
|
||||||
|
#include "ui/widgets/buttons.h"
|
||||||
|
#include "ui/widgets/fields/number_input.h"
|
||||||
|
#include "ui/widgets/label_with_custom_emoji.h"
|
||||||
|
#include "ui/widgets/labels.h"
|
||||||
|
#include "ui/wrap/slide_wrap.h"
|
||||||
|
#include "ui/wrap/vertical_layout.h"
|
||||||
|
#include "styles/style_channel_earn.h"
|
||||||
|
#include "styles/style_chat.h"
|
||||||
|
#include "styles/style_settings.h"
|
||||||
|
#include "styles/style_layers.h"
|
||||||
|
#include "styles/style_info.h"
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
|
||||||
|
InviteLinkSubscriptionToggle FillCreateInviteLinkSubscriptionToggle(
|
||||||
|
not_null<Ui::GenericBox*> box,
|
||||||
|
not_null<PeerData*> peer) {
|
||||||
|
struct State final {
|
||||||
|
float64 usdRate = 0;
|
||||||
|
};
|
||||||
|
const auto state = box->lifetime().make_state<State>();
|
||||||
|
const auto currency = u"USD"_q;
|
||||||
|
|
||||||
|
const auto container = box->verticalLayout();
|
||||||
|
const auto toggle = container->add(
|
||||||
|
object_ptr<SettingsButton>(
|
||||||
|
container,
|
||||||
|
tr::lng_group_invite_subscription(),
|
||||||
|
st::settingsButtonNoIconLocked),
|
||||||
|
style::margins{ 0, 0, 0, st::defaultVerticalListSkip });
|
||||||
|
|
||||||
|
const auto maxCredits = peer->session().appConfig().get<int>(
|
||||||
|
u"stars_subscription_amount_max"_q,
|
||||||
|
2500);
|
||||||
|
|
||||||
|
const auto &st = st::inviteLinkCreditsField;
|
||||||
|
const auto skip = st.textMargins.top() / 2;
|
||||||
|
const auto wrap = container->add(
|
||||||
|
object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
|
||||||
|
container,
|
||||||
|
object_ptr<Ui::VerticalLayout>(container)));
|
||||||
|
box->setShowFinishedCallback([=] {
|
||||||
|
wrap->toggleOn(toggle->toggledValue());
|
||||||
|
wrap->finishAnimating();
|
||||||
|
});
|
||||||
|
const auto inputContainer = wrap->entity()->add(
|
||||||
|
CreateSkipWidget(container, st.heightMin - skip));
|
||||||
|
const auto input = CreateChild<NumberInput>(
|
||||||
|
inputContainer,
|
||||||
|
st,
|
||||||
|
tr::lng_group_invite_subscription_ph(),
|
||||||
|
QString(),
|
||||||
|
maxCredits);
|
||||||
|
wrap->toggledValue() | rpl::start_with_next([=](bool shown) {
|
||||||
|
if (shown) {
|
||||||
|
input->setFocus();
|
||||||
|
}
|
||||||
|
}, input->lifetime());
|
||||||
|
const auto icon = CreateSingleStarWidget(
|
||||||
|
inputContainer,
|
||||||
|
st.style.font->height);
|
||||||
|
const auto priceOverlay = Ui::CreateChild<Ui::RpWidget>(inputContainer);
|
||||||
|
priceOverlay->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||||
|
inputContainer->sizeValue(
|
||||||
|
) | rpl::start_with_next([=](const QSize &size) {
|
||||||
|
input->resize(
|
||||||
|
size.width() - rect::m::sum::h(st::boxRowPadding),
|
||||||
|
st.heightMin);
|
||||||
|
input->moveToLeft(st::boxRowPadding.left(), -skip);
|
||||||
|
icon->moveToLeft(
|
||||||
|
st::boxRowPadding.left(),
|
||||||
|
input->pos().y() + st.textMargins.top());
|
||||||
|
priceOverlay->resize(size);
|
||||||
|
}, input->lifetime());
|
||||||
|
ToggleChildrenVisibility(inputContainer, true);
|
||||||
|
QObject::connect(input, &Ui::MaskedInputField::changed, [=] {
|
||||||
|
priceOverlay->update();
|
||||||
|
});
|
||||||
|
priceOverlay->paintRequest(
|
||||||
|
) | rpl::start_with_next([=, right = st::boxRowPadding.right()] {
|
||||||
|
if (state->usdRate <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto amount = input->getLastText().toDouble();
|
||||||
|
if (amount <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto text = tr::lng_group_invite_subscription_price(
|
||||||
|
tr::now,
|
||||||
|
lt_cost,
|
||||||
|
Ui::FillAmountAndCurrency(amount * state->usdRate, currency));
|
||||||
|
auto p = QPainter(priceOverlay);
|
||||||
|
p.setFont(st.placeholderFont);
|
||||||
|
p.setPen(st.placeholderFg);
|
||||||
|
p.setBrush(Qt::NoBrush);
|
||||||
|
const auto textWidth = st.placeholderFont->width(text);
|
||||||
|
const auto m = QMargins(0, skip, right, 0);
|
||||||
|
p.drawText(priceOverlay->rect() - m, text, style::al_right);
|
||||||
|
}, priceOverlay->lifetime());
|
||||||
|
|
||||||
|
{
|
||||||
|
auto &lifetime = priceOverlay->lifetime();
|
||||||
|
const auto api = lifetime.make_state<Api::CreditsEarnStatistics>(
|
||||||
|
peer);
|
||||||
|
api->request(
|
||||||
|
) | rpl::start_with_done([=] {
|
||||||
|
state->usdRate = api->data().usdRate;
|
||||||
|
priceOverlay->update();
|
||||||
|
}, priceOverlay->lifetime());
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto arrow = Ui::Text::SingleCustomEmoji(
|
||||||
|
peer->owner().customEmojiManager().registerInternalEmoji(
|
||||||
|
st::topicButtonArrow,
|
||||||
|
st::channelEarnLearnArrowMargins,
|
||||||
|
false));
|
||||||
|
auto about = Ui::CreateLabelWithCustomEmoji(
|
||||||
|
container,
|
||||||
|
tr::lng_group_invite_subscription_about(
|
||||||
|
lt_link,
|
||||||
|
tr::lng_group_invite_subscription_about_link(
|
||||||
|
lt_emoji,
|
||||||
|
rpl::single(arrow),
|
||||||
|
Ui::Text::RichLangValue
|
||||||
|
) | rpl::map([](TextWithEntities text) {
|
||||||
|
return Ui::Text::Link(
|
||||||
|
std::move(text),
|
||||||
|
tr::lng_group_invite_subscription_about_url(tr::now));
|
||||||
|
}),
|
||||||
|
Ui::Text::RichLangValue),
|
||||||
|
{ .session = &peer->session() },
|
||||||
|
st::boxDividerLabel);
|
||||||
|
Ui::AddSkip(wrap->entity());
|
||||||
|
Ui::AddSkip(wrap->entity());
|
||||||
|
container->add(object_ptr<Ui::DividerLabel>(
|
||||||
|
container,
|
||||||
|
std::move(about),
|
||||||
|
st::defaultBoxDividerLabelPadding,
|
||||||
|
RectPart::Top | RectPart::Bottom));
|
||||||
|
return { toggle, input };
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Ui
|
23
Telegram/SourceFiles/ui/boxes/edit_invite_link_session.h
Normal file
23
Telegram/SourceFiles/ui/boxes/edit_invite_link_session.h
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
/*
|
||||||
|
This file is part of Telegram Desktop,
|
||||||
|
the official desktop application for the Telegram messaging service.
|
||||||
|
|
||||||
|
For license and copyright information please follow this link:
|
||||||
|
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
class PeerData;
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
|
||||||
|
class GenericBox;
|
||||||
|
class SettingsButton;
|
||||||
|
|
||||||
|
struct InviteLinkSubscriptionToggle;
|
||||||
|
|
||||||
|
InviteLinkSubscriptionToggle FillCreateInviteLinkSubscriptionToggle(
|
||||||
|
not_null<Ui::GenericBox*> box,
|
||||||
|
not_null<PeerData*> peer);
|
||||||
|
|
||||||
|
} // namespace Ui
|
Loading…
Add table
Reference in a new issue