mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Added initial ability to gift premium to contacts from settings.
This commit is contained in:
parent
82d73e2396
commit
b9b6226692
7 changed files with 254 additions and 7 deletions
|
@ -813,6 +813,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_settings_manage_enabled_dictionary" = "Dictionary is enabled";
|
"lng_settings_manage_enabled_dictionary" = "Dictionary is enabled";
|
||||||
"lng_settings_manage_remove_dictionary" = "Remove Dictionary";
|
"lng_settings_manage_remove_dictionary" = "Remove Dictionary";
|
||||||
|
|
||||||
|
"lng_settings_gift_premium" = "Premium Gifting";
|
||||||
|
"lng_settings_gift_premium_users_confirm" = "Proceed";
|
||||||
|
"lng_settings_gift_premium_users_error#one" = "You can select maximum {count} user.";
|
||||||
|
"lng_settings_gift_premium_users_error#other" = "You can select maximum {count} users.";
|
||||||
|
|
||||||
"lng_backgrounds_header" = "Choose Wallpaper";
|
"lng_backgrounds_header" = "Choose Wallpaper";
|
||||||
"lng_theme_sure_keep" = "Keep this theme?";
|
"lng_theme_sure_keep" = "Keep this theme?";
|
||||||
"lng_theme_reverting#one" = "Reverting to the old theme in {count} second.";
|
"lng_theme_reverting#one" = "Reverting to the old theme in {count} second.";
|
||||||
|
|
|
@ -342,15 +342,12 @@ PremiumGiftCodeOptions::PremiumGiftCodeOptions(not_null<PeerData*> peer)
|
||||||
rpl::producer<rpl::no_value, QString> PremiumGiftCodeOptions::request() {
|
rpl::producer<rpl::no_value, QString> PremiumGiftCodeOptions::request() {
|
||||||
return [=](auto consumer) {
|
return [=](auto consumer) {
|
||||||
auto lifetime = rpl::lifetime();
|
auto lifetime = rpl::lifetime();
|
||||||
const auto channel = _peer->asChannel();
|
|
||||||
if (!channel) {
|
|
||||||
return lifetime;
|
|
||||||
}
|
|
||||||
|
|
||||||
using TLOption = MTPPremiumGiftCodeOption;
|
using TLOption = MTPPremiumGiftCodeOption;
|
||||||
_api.request(MTPpayments_GetPremiumGiftCodeOptions(
|
_api.request(MTPpayments_GetPremiumGiftCodeOptions(
|
||||||
MTP_flags(
|
MTP_flags(_peer->isChannel()
|
||||||
MTPpayments_GetPremiumGiftCodeOptions::Flag::f_boost_peer),
|
? MTPpayments_GetPremiumGiftCodeOptions::Flag::f_boost_peer
|
||||||
|
: MTPpayments_GetPremiumGiftCodeOptions::Flag(0)),
|
||||||
_peer->input
|
_peer->input
|
||||||
)).done([=](const MTPVector<TLOption> &result) {
|
)).done([=](const MTPVector<TLOption> &result) {
|
||||||
auto tlMapOptions = base::flat_map<Amount, QVector<TLOption>>();
|
auto tlMapOptions = base::flat_map<Amount, QVector<TLOption>>();
|
||||||
|
|
|
@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "apiwrap.h"
|
#include "apiwrap.h"
|
||||||
#include "base/unixtime.h"
|
#include "base/unixtime.h"
|
||||||
#include "base/weak_ptr.h"
|
#include "base/weak_ptr.h"
|
||||||
|
#include "boxes/peer_list_controllers.h" // ContactsBoxController.
|
||||||
#include "boxes/peers/prepare_short_info_box.h"
|
#include "boxes/peers/prepare_short_info_box.h"
|
||||||
#include "data/data_boosts.h"
|
#include "data/data_boosts.h"
|
||||||
#include "data/data_changes.h"
|
#include "data/data_changes.h"
|
||||||
|
@ -24,6 +25,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
#include "mainwidget.h"
|
#include "mainwidget.h"
|
||||||
|
#include "payments/payments_checkout_process.h"
|
||||||
|
#include "payments/payments_form.h"
|
||||||
#include "settings/settings_premium.h"
|
#include "settings/settings_premium.h"
|
||||||
#include "ui/basic_click_handlers.h" // UrlClickHandler::Open.
|
#include "ui/basic_click_handlers.h" // UrlClickHandler::Open.
|
||||||
#include "ui/boxes/boost_box.h" // StartFireworks.
|
#include "ui/boxes/boost_box.h" // StartFireworks.
|
||||||
|
@ -211,7 +214,7 @@ void GiftBox(
|
||||||
auto raw = Settings::CreateSubscribeButton({
|
auto raw = Settings::CreateSubscribeButton({
|
||||||
controller,
|
controller,
|
||||||
box,
|
box,
|
||||||
[] { return QString("gift"); },
|
[] { return u"gift"_q; },
|
||||||
state->buttonText.events(),
|
state->buttonText.events(),
|
||||||
Ui::Premium::GiftGradientStops(),
|
Ui::Premium::GiftGradientStops(),
|
||||||
[=] {
|
[=] {
|
||||||
|
@ -239,6 +242,117 @@ void GiftBox(
|
||||||
}, box->lifetime());
|
}, box->lifetime());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GiftsBox(
|
||||||
|
not_null<Ui::GenericBox*> box,
|
||||||
|
not_null<Window::SessionController*> controller,
|
||||||
|
std::vector<not_null<UserData*>> users,
|
||||||
|
not_null<Api::PremiumGiftCodeOptions*> api) {
|
||||||
|
Expects(!users.empty());
|
||||||
|
|
||||||
|
const auto boxWidth = st::boxWideWidth;
|
||||||
|
box->setWidth(boxWidth);
|
||||||
|
box->setNoContentMargin(true);
|
||||||
|
const auto buttonsParent = box->verticalLayout().get();
|
||||||
|
const auto session = &users.front()->session();
|
||||||
|
|
||||||
|
struct State {
|
||||||
|
rpl::event_stream<QString> buttonText;
|
||||||
|
};
|
||||||
|
const auto state = box->lifetime().make_state<State>();
|
||||||
|
|
||||||
|
const auto userpicPadding = st::premiumGiftUserpicPadding;
|
||||||
|
const auto top = box->addRow(object_ptr<Ui::FixedHeightWidget>(
|
||||||
|
buttonsParent,
|
||||||
|
userpicPadding.top()
|
||||||
|
+ userpicPadding.bottom()
|
||||||
|
+ st::defaultUserpicButton.size.height()));
|
||||||
|
|
||||||
|
// Header.
|
||||||
|
const auto &padding = st::premiumGiftAboutPadding;
|
||||||
|
const auto available = boxWidth - padding.left() - padding.right();
|
||||||
|
|
||||||
|
const auto close = Ui::CreateChild<Ui::IconButton>(
|
||||||
|
buttonsParent,
|
||||||
|
st::infoTopBarClose);
|
||||||
|
close->setClickedCallback([=] { box->closeBox(); });
|
||||||
|
|
||||||
|
buttonsParent->widthValue(
|
||||||
|
) | rpl::start_with_next([=](int width) {
|
||||||
|
close->moveToRight(0, 0, width);
|
||||||
|
}, close->lifetime());
|
||||||
|
|
||||||
|
// List.
|
||||||
|
const auto options = api->options(users.size());
|
||||||
|
const auto group = std::make_shared<Ui::RadiobuttonGroup>();
|
||||||
|
const auto groupValueChangedCallback = [=](int value) {
|
||||||
|
Expects(value < options.size() && value >= 0);
|
||||||
|
auto text = tr::lng_premium_gift_button(
|
||||||
|
tr::now,
|
||||||
|
lt_cost,
|
||||||
|
options[value].costTotal);
|
||||||
|
state->buttonText.fire(std::move(text));
|
||||||
|
};
|
||||||
|
group->setChangedCallback(groupValueChangedCallback);
|
||||||
|
Ui::Premium::AddGiftOptions(
|
||||||
|
buttonsParent,
|
||||||
|
group,
|
||||||
|
options,
|
||||||
|
st::premiumGiftOption);
|
||||||
|
|
||||||
|
// Footer.
|
||||||
|
auto terms = object_ptr<Ui::FlatLabel>(
|
||||||
|
box,
|
||||||
|
tr::lng_premium_gift_terms(
|
||||||
|
lt_link,
|
||||||
|
tr::lng_premium_gift_terms_link(
|
||||||
|
) | rpl::map([=](const QString &t) {
|
||||||
|
return Ui::Text::Link(t, 1);
|
||||||
|
}),
|
||||||
|
Ui::Text::WithEntities),
|
||||||
|
st::premiumGiftTerms);
|
||||||
|
terms->setLink(1, std::make_shared<LambdaClickHandler>([=] {
|
||||||
|
box->closeBox();
|
||||||
|
Settings::ShowPremium(session, QString());
|
||||||
|
}));
|
||||||
|
terms->resizeToWidth(available);
|
||||||
|
box->addRow(
|
||||||
|
object_ptr<Ui::CenterWrap<Ui::FlatLabel>>(box, std::move(terms)),
|
||||||
|
st::premiumGiftTermsPadding);
|
||||||
|
|
||||||
|
// Button.
|
||||||
|
const auto &stButton = st::premiumGiftBox;
|
||||||
|
box->setStyle(stButton);
|
||||||
|
auto raw = Settings::CreateSubscribeButton({
|
||||||
|
controller,
|
||||||
|
box,
|
||||||
|
[] { return u"gift"_q; },
|
||||||
|
state->buttonText.events(),
|
||||||
|
Ui::Premium::GiftGradientStops(),
|
||||||
|
});
|
||||||
|
raw->setClickedCallback([=] {
|
||||||
|
auto invoice = api->invoice(
|
||||||
|
users.size(),
|
||||||
|
api->monthsFromPreset(group->value()));
|
||||||
|
invoice.purpose = Payments::InvoicePremiumGiftCodeUsers{ users };
|
||||||
|
|
||||||
|
const auto done = [=](Payments::CheckoutResult result) {
|
||||||
|
box->uiShow()->showToast(tr::lng_share_done(tr::now));
|
||||||
|
};
|
||||||
|
|
||||||
|
Payments::CheckoutProcess::Start(std::move(invoice), done);
|
||||||
|
});
|
||||||
|
auto button = object_ptr<Ui::GradientButton>::fromRaw(raw);
|
||||||
|
button->resizeToWidth(boxWidth
|
||||||
|
- stButton.buttonPadding.left()
|
||||||
|
- stButton.buttonPadding.right());
|
||||||
|
box->setShowFinishedCallback([raw = button.data()]{
|
||||||
|
raw->startGlareAnimation();
|
||||||
|
});
|
||||||
|
box->addButton(std::move(button));
|
||||||
|
|
||||||
|
groupValueChangedCallback(0);
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]] Data::GiftCodeLink MakeGiftCodeLink(
|
[[nodiscard]] Data::GiftCodeLink MakeGiftCodeLink(
|
||||||
not_null<Main::Session*> session,
|
not_null<Main::Session*> session,
|
||||||
const QString &slug) {
|
const QString &slug) {
|
||||||
|
@ -441,6 +555,112 @@ void GiftPremiumValidator::cancel() {
|
||||||
_requestId = 0;
|
_requestId = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GiftPremiumValidator::showChoosePeerBox() {
|
||||||
|
if (_manyGiftsLifetime) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
using namespace Api;
|
||||||
|
const auto api = _manyGiftsLifetime.make_state<PremiumGiftCodeOptions>(
|
||||||
|
_controller->session().user());
|
||||||
|
const auto show = _controller->uiShow();
|
||||||
|
api->request(
|
||||||
|
) | rpl::start_with_error_done([=](const QString &error) {
|
||||||
|
show->showToast(error);
|
||||||
|
}, [=] {
|
||||||
|
const auto maxAmount = *ranges::max_element(api->availablePresets());
|
||||||
|
|
||||||
|
class Controller final : public ContactsBoxController {
|
||||||
|
public:
|
||||||
|
Controller(
|
||||||
|
not_null<Main::Session*> session,
|
||||||
|
Fn<bool(int)> checkErrorCallback)
|
||||||
|
: ContactsBoxController(session)
|
||||||
|
, _checkErrorCallback(std::move(checkErrorCallback)) {
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::unique_ptr<PeerListRow> createRow(
|
||||||
|
not_null<UserData*> user) override {
|
||||||
|
return !user->isSelf()
|
||||||
|
? ContactsBoxController::createRow(user)
|
||||||
|
: nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void rowClicked(not_null<PeerListRow*> row) override {
|
||||||
|
const auto checked = !row->checked();
|
||||||
|
if (checked
|
||||||
|
&& _checkErrorCallback
|
||||||
|
&& _checkErrorCallback(
|
||||||
|
delegate()->peerListSelectedRowsCount())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
delegate()->peerListSetRowChecked(row, checked);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const Fn<bool(int)> _checkErrorCallback;
|
||||||
|
|
||||||
|
};
|
||||||
|
auto initBox = [=](not_null<PeerListBox*> peersBox) {
|
||||||
|
const auto ignoreClose = peersBox->lifetime().make_state<bool>(0);
|
||||||
|
|
||||||
|
auto process = [=] {
|
||||||
|
const auto selected = peersBox->collectSelectedRows();
|
||||||
|
const auto users = ranges::views::all(
|
||||||
|
selected
|
||||||
|
) | ranges::views::transform([](not_null<PeerData*> p) {
|
||||||
|
return p->asUser();
|
||||||
|
}) | ranges::views::filter([](UserData *u) -> bool {
|
||||||
|
return u;
|
||||||
|
}) | ranges::to<std::vector<not_null<UserData*>>>();
|
||||||
|
if (!users.empty()) {
|
||||||
|
const auto giftBox = show->showBox(
|
||||||
|
Box(GiftsBox, _controller, users, api));
|
||||||
|
giftBox->boxClosing(
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
|
_manyGiftsLifetime.destroy();
|
||||||
|
}, giftBox->lifetime());
|
||||||
|
}
|
||||||
|
(*ignoreClose) = true;
|
||||||
|
peersBox->closeBox();
|
||||||
|
};
|
||||||
|
|
||||||
|
peersBox->setTitle(tr::lng_premium_gift_title());
|
||||||
|
peersBox->addButton(
|
||||||
|
tr::lng_settings_gift_premium_users_confirm(),
|
||||||
|
std::move(process));
|
||||||
|
peersBox->addButton(tr::lng_cancel(), [=] {
|
||||||
|
peersBox->closeBox();
|
||||||
|
});
|
||||||
|
peersBox->boxClosing(
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
|
if (!(*ignoreClose)) {
|
||||||
|
_manyGiftsLifetime.destroy();
|
||||||
|
}
|
||||||
|
}, peersBox->lifetime());
|
||||||
|
};
|
||||||
|
|
||||||
|
auto listController = std::make_unique<Controller>(
|
||||||
|
&_controller->session(),
|
||||||
|
[=](int count) {
|
||||||
|
if (count <= maxAmount) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
show->showToast(tr::lng_settings_gift_premium_users_error(
|
||||||
|
tr::now,
|
||||||
|
lt_count,
|
||||||
|
maxAmount));
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
show->showBox(
|
||||||
|
Box<PeerListBox>(
|
||||||
|
std::move(listController),
|
||||||
|
std::move(initBox)),
|
||||||
|
Ui::LayerOption::KeepOther);
|
||||||
|
|
||||||
|
}, _manyGiftsLifetime);
|
||||||
|
}
|
||||||
|
|
||||||
void GiftPremiumValidator::showBox(not_null<UserData*> user) {
|
void GiftPremiumValidator::showBox(not_null<UserData*> user) {
|
||||||
if (_requestId) {
|
if (_requestId) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -34,6 +34,7 @@ public:
|
||||||
GiftPremiumValidator(not_null<Window::SessionController*> controller);
|
GiftPremiumValidator(not_null<Window::SessionController*> controller);
|
||||||
|
|
||||||
void showBox(not_null<UserData*> user);
|
void showBox(not_null<UserData*> user);
|
||||||
|
void showChoosePeerBox();
|
||||||
void cancel();
|
void cancel();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -42,6 +43,8 @@ private:
|
||||||
|
|
||||||
mtpRequestId _requestId = 0;
|
mtpRequestId _requestId = 0;
|
||||||
|
|
||||||
|
rpl::lifetime _manyGiftsLifetime;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
[[nodiscard]] rpl::producer<QString> GiftDurationValue(int months);
|
[[nodiscard]] rpl::producer<QString> GiftDurationValue(int months);
|
||||||
|
|
|
@ -32,6 +32,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/widgets/buttons.h"
|
#include "ui/widgets/buttons.h"
|
||||||
#include "ui/text/text_utilities.h"
|
#include "ui/text/text_utilities.h"
|
||||||
#include "ui/toast/toast.h"
|
#include "ui/toast/toast.h"
|
||||||
|
#include "ui/new_badges.h"
|
||||||
#include "ui/vertical_list.h"
|
#include "ui/vertical_list.h"
|
||||||
#include "info/profile/info_profile_badge.h"
|
#include "info/profile/info_profile_badge.h"
|
||||||
#include "info/profile/info_profile_emoji_status_panel.h"
|
#include "info/profile/info_profile_emoji_status_panel.h"
|
||||||
|
@ -60,6 +61,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "core/file_utilities.h"
|
#include "core/file_utilities.h"
|
||||||
#include "core/application.h"
|
#include "core/application.h"
|
||||||
#include "base/call_delayed.h"
|
#include "base/call_delayed.h"
|
||||||
|
#include "base/unixtime.h"
|
||||||
#include "base/platform/base_platform_info.h"
|
#include "base/platform/base_platform_info.h"
|
||||||
#include "styles/style_settings.h"
|
#include "styles/style_settings.h"
|
||||||
#include "styles/style_boxes.h"
|
#include "styles/style_boxes.h"
|
||||||
|
@ -417,6 +419,21 @@ void SetupPremium(
|
||||||
controller->setPremiumRef("settings");
|
controller->setPremiumRef("settings");
|
||||||
showOther(PremiumId());
|
showOther(PremiumId());
|
||||||
});
|
});
|
||||||
|
{
|
||||||
|
const auto button = AddButtonWithIcon(
|
||||||
|
container,
|
||||||
|
tr::lng_settings_gift_premium(),
|
||||||
|
st::settingsButton,
|
||||||
|
{ .icon = &st::menuIconGiftPremium }
|
||||||
|
);
|
||||||
|
button->addClickHandler([=] {
|
||||||
|
controller->showGiftPremiumsBox();
|
||||||
|
});
|
||||||
|
constexpr auto kNewExpiresAt = int(1735689600);
|
||||||
|
if (base::unixtime::now() < kNewExpiresAt) {
|
||||||
|
Ui::NewBadge::AddToRight(button);
|
||||||
|
}
|
||||||
|
}
|
||||||
Ui::AddSkip(container);
|
Ui::AddSkip(container);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1216,6 +1216,10 @@ void SessionController::showGiftPremiumBox(UserData *user) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SessionController::showGiftPremiumsBox() {
|
||||||
|
_giftPremiumValidator.showChoosePeerBox();
|
||||||
|
}
|
||||||
|
|
||||||
void SessionController::init() {
|
void SessionController::init() {
|
||||||
if (session().supportMode()) {
|
if (session().supportMode()) {
|
||||||
initSupportMode();
|
initSupportMode();
|
||||||
|
|
|
@ -380,6 +380,7 @@ public:
|
||||||
|
|
||||||
void showEditPeerBox(PeerData *peer);
|
void showEditPeerBox(PeerData *peer);
|
||||||
void showGiftPremiumBox(UserData *user);
|
void showGiftPremiumBox(UserData *user);
|
||||||
|
void showGiftPremiumsBox();
|
||||||
|
|
||||||
void enableGifPauseReason(GifPauseReason reason);
|
void enableGifPauseReason(GifPauseReason reason);
|
||||||
void disableGifPauseReason(GifPauseReason reason);
|
void disableGifPauseReason(GifPauseReason reason);
|
||||||
|
|
Loading…
Add table
Reference in a new issue