Unified parsing of MTP gift and subscription options in separate file.

This commit is contained in:
23rd 2022-08-25 15:40:00 +03:00 committed by John Preston
parent fc759ac688
commit 6f3d19914d
8 changed files with 149 additions and 73 deletions

View file

@ -140,6 +140,8 @@ PRIVATE
api/api_polls.h
api/api_premium.cpp
api/api_premium.h
api/api_premium_option.cpp
api/api_premium_option.h
api/api_report.cpp
api/api_report.h
api/api_ringtones.cpp

View file

@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "api/api_premium.h"
#include "api/api_premium_option.h"
#include "api/api_text_entities.h"
#include "main/main_session.h"
#include "data/data_peer_values.h"
@ -86,43 +87,43 @@ void Premium::reloadPromo() {
_promoRequestId = _api.request(MTPhelp_GetPremiumPromo(
)).done([=](const MTPhelp_PremiumPromo &result) {
_promoRequestId = 0;
result.match([&](const MTPDhelp_premiumPromo &data) {
_session->data().processUsers(data.vusers());
for (const auto &option : data.vperiod_options().v) {
option.match([&](const MTPDpremiumSubscriptionOption &data) {
if (data.vmonths().v == 1) {
_monthlyAmount = data.vamount().v;
_monthlyCurrency = qs(data.vcurrency());
}
});
const auto &data = result.data();
_session->data().processUsers(data.vusers());
_subscriptionOptions = SubscriptionOptionsFromTL(
data.vperiod_options().v);
for (const auto &option : data.vperiod_options().v) {
if (option.data().vmonths().v == 1) {
_monthlyAmount = option.data().vamount().v;
_monthlyCurrency = qs(option.data().vcurrency());
}
auto text = TextWithEntities{
qs(data.vstatus_text()),
EntitiesFromMTP(_session, data.vstatus_entities().v),
};
_statusText = text;
_statusTextUpdates.fire(std::move(text));
auto videos = base::flat_map<QString, not_null<DocumentData*>>();
const auto count = int(std::min(
data.vvideo_sections().v.size(),
data.vvideos().v.size()));
videos.reserve(count);
for (auto i = 0; i != count; ++i) {
const auto document = _session->data().processDocument(
data.vvideos().v[i]);
if ((!document->isVideoFile() && !document->isGifv())
|| !document->supportsStreaming()) {
document->forceIsStreamedAnimation();
}
videos.emplace(
qs(data.vvideo_sections().v[i]),
document);
}
auto text = TextWithEntities{
qs(data.vstatus_text()),
EntitiesFromMTP(_session, data.vstatus_entities().v),
};
_statusText = text;
_statusTextUpdates.fire(std::move(text));
auto videos = base::flat_map<QString, not_null<DocumentData*>>();
const auto count = int(std::min(
data.vvideo_sections().v.size(),
data.vvideos().v.size()));
videos.reserve(count);
for (auto i = 0; i != count; ++i) {
const auto document = _session->data().processDocument(
data.vvideos().v[i]);
if ((!document->isVideoFile() && !document->isGifv())
|| !document->supportsStreaming()) {
document->forceIsStreamedAnimation();
}
if (_videos != videos) {
_videos = std::move(videos);
_videosUpdated.fire({});
}
});
videos.emplace(
qs(data.vvideo_sections().v[i]),
document);
}
if (_videos != videos) {
_videos = std::move(videos);
_videosUpdated.fire({});
}
}).fail([=] {
_promoRequestId = 0;
}).send();
@ -182,4 +183,8 @@ void Premium::reloadCloudSet() {
}).send();
}
const Data::SubscriptionOptions &Premium::subscriptionOptions() const {
return _subscriptionOptions;
}
} // namespace Api

View file

@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include "data/data_subscription_option.h"
#include "mtproto/sender.h"
class ApiWrap;
@ -39,6 +40,9 @@ public:
[[nodiscard]] int64 monthlyAmount() const;
[[nodiscard]] QString monthlyCurrency() const;
[[nodiscard]] auto subscriptionOptions() const
-> const Data::SubscriptionOptions &;
private:
void reloadPromo();
void reloadStickers();
@ -67,6 +71,8 @@ private:
int64 _monthlyAmount = 0;
QString _monthlyCurrency;
Data::SubscriptionOptions _subscriptionOptions;
};
} // namespace Api

View file

@ -0,0 +1,40 @@
/*
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 "api/api_premium_option.h"
#include "ui/text/format_values.h"
namespace Api {
constexpr auto kDiscountDivider = 5.;
Data::SubscriptionOption CreateSubscriptionOption(
int months,
int monthlyAmount,
int64 amount,
const QString &currency,
const QString &botUrl) {
const auto discount = [&] {
const auto percent = monthlyAmount * months / float64(amount) - 1.;
return std::round(percent * 100. / kDiscountDivider)
* kDiscountDivider;
}();
return {
.duration = Ui::FormatTTL(months * 86400 * 31),
.discount = discount
? QString::fromUtf8("\xe2\x88\x92%1%").arg(discount)
: QString(),
.costPerMonth = Ui::FillAmountAndCurrency(
amount / float64(months),
currency),
.costTotal = Ui::FillAmountAndCurrency(amount, currency),
.botUrl = botUrl,
};
}
} // namespace Api

View file

@ -0,0 +1,50 @@
/*
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
#include "data/data_subscription_option.h"
namespace Api {
[[nodiscard]] Data::SubscriptionOption CreateSubscriptionOption(
int months,
int monthlyAmount,
int64 amount,
const QString &currency,
const QString &botUrl);
template<typename Option>
[[nodiscard]] Data::SubscriptionOptions SubscriptionOptionsFromTL(
const QVector<Option> &tlOptions) {
auto result = Data::SubscriptionOptions();
const auto monthlyAmount = [&] {
const auto &min = ranges::min_element(
tlOptions,
ranges::less(),
[](const Option &o) { return o.data().vamount().v; }
)->data();
return min.vamount().v / float64(min.vmonths().v);
}();
result.reserve(tlOptions.size());
for (const auto &tlOption : tlOptions) {
const auto &option = tlOption.data();
const auto botUrl = qs(option.vbot_url());
const auto months = option.vmonths().v;
const auto amount = option.vamount().v;
const auto currency = qs(option.vcurrency());
result.push_back(CreateSubscriptionOption(
months,
monthlyAmount,
amount,
currency,
botUrl));
}
return result;
}
} // namespace Api

View file

@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "boxes/gift_premium_box.h"
#include "apiwrap.h"
#include "api/api_premium_option.h"
#include "base/weak_ptr.h"
#include "core/click_handler_types.h" // ClickHandlerContext.
#include "core/local_url_handlers.h" // TryConvertUrlToLocal.
@ -49,41 +50,12 @@ GiftOptions GiftOptionFromTL(const MTPDuserFull &data) {
if (!gifts) {
return result;
}
const auto monthlyAmount = [&] {
const auto &min = ranges::min_element(
gifts->v,
ranges::less(),
[](const MTPPremiumGiftOption &o) { return o.data().vamount().v; }
)->data();
return min.vamount().v / float64(min.vmonths().v);
}();
result.reserve(gifts->v.size());
for (const auto &gift : gifts->v) {
const auto &option = gift.data();
const auto botUrl = qs(option.vbot_url());
const auto months = option.vmonths().v;
const auto amount = option.vamount().v;
const auto currency = qs(option.vcurrency());
const auto discount = [&] {
const auto percent = monthlyAmount * months / float64(amount)
- 1.;
return std::round(percent * 100. / kDiscountDivider)
* kDiscountDivider;
}();
result.push_back({
.duration = Ui::FormatTTL(months * 86400 * 31),
.discount = discount
? QString::fromUtf8("\xe2\x88\x92%1%").arg(discount)
: QString(),
.perMonth = tr::lng_premium_gift_per(
tr::now,
lt_cost,
Ui::FillAmountAndCurrency(
amount / float64(months),
currency)),
.total = Ui::FillAmountAndCurrency(amount, currency),
.botUrl = botUrl,
});
result = Api::SubscriptionOptionsFromTL(gifts->v);
for (auto &option : result) {
option.costPerMonth = tr::lng_premium_gift_per(
tr::now,
lt_cost,
option.costPerMonth);
}
return result;
}

View file

@ -12,7 +12,8 @@ namespace Data {
struct SubscriptionOption {
QString duration;
QString discount;
QString perMonth;
QString costPerMonth;
QString costTotal;
QString total;
QString botUrl;
};

View file

@ -1056,12 +1056,12 @@ void AddGiftOptions(
0);
p.setPen(st::windowSubTextFg);
p.setFont(st::shareBoxListItem.nameStyle.font);
p.drawText(perRect, info.perMonth, style::al_left);
p.drawText(perRect, info.costPerMonth, style::al_left);
const auto totalRect = row->rect()
- QMargins(0, 0, st::premiumGiftRowMargins.right(), 0);
p.setFont(st::normalFont);
p.drawText(totalRect, info.total, style::al_right);
p.drawText(totalRect, info.costTotal, style::al_right);
}, row->lifetime());
row->setClickedCallback([=, duration = st::defaultCheck.duration] {