Use paid messages values from appConfig.

This commit is contained in:
John Preston 2025-03-01 09:22:07 +04:00
parent 9032489786
commit 827040f487
7 changed files with 142 additions and 102 deletions

View file

@ -45,9 +45,7 @@ namespace {
constexpr auto kPremiumsRowId = PeerId(FakeChatId(BareId(1))).value; constexpr auto kPremiumsRowId = PeerId(FakeChatId(BareId(1))).value;
constexpr auto kMiniAppsRowId = PeerId(FakeChatId(BareId(2))).value; constexpr auto kMiniAppsRowId = PeerId(FakeChatId(BareId(2))).value;
constexpr auto kGetPercent = 85;
constexpr auto kStarsMin = 1; constexpr auto kStarsMin = 1;
constexpr auto kStarsMax = 10000;
constexpr auto kDefaultChargeStars = 10; constexpr auto kDefaultChargeStars = 10;
using Exceptions = Api::UserPrivacy::Exceptions; using Exceptions = Api::UserPrivacy::Exceptions;
@ -466,6 +464,7 @@ auto PrivacyExceptionsBoxController::createRow(not_null<History*> history)
int valuesCount, int valuesCount,
Fn<int(int)> valueByIndex, Fn<int(int)> valueByIndex,
int value, int value,
int maxValue,
Fn<void(int)> valueProgress, Fn<void(int)> valueProgress,
Fn<void(int)> valueFinished) { Fn<void(int)> valueFinished) {
auto result = object_ptr<Ui::VerticalLayout>(parent); auto result = object_ptr<Ui::VerticalLayout>(parent);
@ -478,7 +477,7 @@ auto PrivacyExceptionsBoxController::createRow(not_null<History*> history)
*labelStyle); *labelStyle);
const auto max = Ui::CreateChild<Ui::FlatLabel>( const auto max = Ui::CreateChild<Ui::FlatLabel>(
raw, raw,
QString::number(kStarsMax), QString::number(maxValue),
*labelStyle); *labelStyle);
const auto current = Ui::CreateChild<Ui::FlatLabel>( const auto current = Ui::CreateChild<Ui::FlatLabel>(
raw, raw,
@ -999,7 +998,10 @@ void EditMessagesPrivacyBox(
Ui::AddDividerText(inner, tr::lng_messages_privacy_about()); Ui::AddDividerText(inner, tr::lng_messages_privacy_about());
const auto charged = inner->add( const auto available = session->appConfig().paidMessagesAvailable();
const auto charged = available
? inner->add(
object_ptr<Ui::Radiobutton>( object_ptr<Ui::Radiobutton>(
inner, inner,
group, group,
@ -1010,8 +1012,16 @@ void EditMessagesPrivacyBox(
0, 0,
st::messagePrivacyBottomSkip, st::messagePrivacyBottomSkip,
0, 0,
st::messagePrivacyBottomSkip)); st::messagePrivacyBottomSkip))
: nullptr;
struct State {
rpl::variable<int> stars;
};
const auto state = std::make_shared<State>();
const auto savedValue = privacy->newChargeStarsCurrent();
if (available) {
Ui::AddDividerText(inner, tr::lng_messages_privacy_charge_about()); Ui::AddDividerText(inner, tr::lng_messages_privacy_charge_about());
const auto chargeWrap = inner->add( const auto chargeWrap = inner->add(
@ -1022,12 +1032,6 @@ void EditMessagesPrivacyBox(
Ui::AddSkip(chargeInner); Ui::AddSkip(chargeInner);
struct State {
rpl::variable<int> stars;
};
const auto state = std::make_shared<State>();
const auto savedValue = privacy->newChargeStarsCurrent();
state->stars = SetupChargeSlider( state->stars = SetupChargeSlider(
chargeInner, chargeInner,
session->user(), session->user(),
@ -1070,12 +1074,14 @@ void EditMessagesPrivacyBox(
}); });
}); });
Ui::AddSkip(chargeInner); Ui::AddSkip(chargeInner);
Ui::AddDividerText(chargeInner, tr::lng_messages_privacy_remove_about()); Ui::AddDividerText(
chargeInner,
tr::lng_messages_privacy_remove_about());
using namespace rpl::mappers; using namespace rpl::mappers;
chargeWrap->toggleOn(group->value() | rpl::map(_1 == kOptionCharge)); chargeWrap->toggleOn(group->value() | rpl::map(_1 == kOptionCharge));
chargeWrap->finishAnimating(); chargeWrap->finishAnimating();
}
using WeakToast = base::weak_ptr<Ui::Toast::Instance>; using WeakToast = base::weak_ptr<Ui::Toast::Instance>;
const auto toast = std::make_shared<WeakToast>(); const auto toast = std::make_shared<WeakToast>();
const auto showToast = [=] { const auto showToast = [=] {
@ -1108,7 +1114,9 @@ void EditMessagesPrivacyBox(
if (!allowed()) { if (!allowed()) {
CreateRadiobuttonLock(restricted, st::messagePrivacyCheck); CreateRadiobuttonLock(restricted, st::messagePrivacyCheck);
if (charged) {
CreateRadiobuttonLock(charged, st::messagePrivacyCheck); CreateRadiobuttonLock(charged, st::messagePrivacyCheck);
}
group->setChangedCallback([=](int value) { group->setChangedCallback([=](int value) {
if (value == kOptionPremium || value == kOptionCharge) { if (value == kOptionPremium || value == kOptionCharge) {
@ -1170,19 +1178,20 @@ rpl::producer<int> SetupChargeSlider(
: tr::lng_messages_privacy_price()); : tr::lng_messages_privacy_price());
auto values = std::vector<int>(); auto values = std::vector<int>();
const auto maxStars = peer->session().appConfig().paidMessageStarsMax();
if (chargeStars < kStarsMin) { if (chargeStars < kStarsMin) {
values.push_back(chargeStars); values.push_back(chargeStars);
} }
for (auto i = kStarsMin; i < 100; ++i) { for (auto i = kStarsMin; i < std::min(100, maxStars); ++i) {
values.push_back(i); values.push_back(i);
} }
for (auto i = 100; i < 1000; i += 10) { for (auto i = 100; i < std::min(1000, maxStars); i += 10) {
if (i < chargeStars + 10 && chargeStars < i) { if (i < chargeStars + 10 && chargeStars < i) {
values.push_back(chargeStars); values.push_back(chargeStars);
} }
values.push_back(i); values.push_back(i);
} }
for (auto i = 1000; i < kStarsMax + 1; i += 100) { for (auto i = 1000; i < maxStars + 1; i += 100) {
if (i < chargeStars + 100 && chargeStars < i) { if (i < chargeStars + 100 && chargeStars < i) {
values.push_back(chargeStars); values.push_back(chargeStars);
} }
@ -1200,6 +1209,7 @@ rpl::producer<int> SetupChargeSlider(
valuesCount, valuesCount,
[=](int index) { return values[index]; }, [=](int index) { return values[index]; },
chargeStars, chargeStars,
maxStars,
setStars, setStars,
setStars), setStars),
st::boxRowPadding); st::boxRowPadding);
@ -1208,19 +1218,18 @@ rpl::producer<int> SetupChargeSlider(
Ui::AddSkip(container, skip); Ui::AddSkip(container, skip);
auto dollars = state->stars.value() | rpl::map([=](int stars) { auto dollars = state->stars.value() | rpl::map([=](int stars) {
const auto ratio = peer->session().appConfig().get<float64>( const auto ratio = peer->session().appConfig().starsWithdrawRate();
u"stars_usd_withdraw_rate_x1000"_q, const auto dollars = int(base::SafeRound(stars * ratio));
1200);
const auto dollars = int(base::SafeRound(stars * (ratio / 1000.)));
return '~' + Ui::FillAmountAndCurrency(dollars, u"USD"_q); return '~' + Ui::FillAmountAndCurrency(dollars, u"USD"_q);
}); });
const auto percent = peer->session().appConfig().paidMessageCommission();
Ui::AddDividerText( Ui::AddDividerText(
container, container,
(group (group
? tr::lng_rights_charge_price_about ? tr::lng_rights_charge_price_about
: tr::lng_messages_privacy_price_about)( : tr::lng_messages_privacy_price_about)(
lt_percent, lt_percent,
rpl::single(QString::number(kGetPercent) + '%'), rpl::single(QString::number(percent / 10.) + '%'),
lt_amount, lt_amount,
std::move(dollars))); std::move(dollars)));

View file

@ -1160,14 +1160,18 @@ void ShowEditPeerPermissionsBox(
rpl::variable<int> starsPerMessage; rpl::variable<int> starsPerMessage;
}; };
const auto state = inner->lifetime().make_state<State>(); const auto state = inner->lifetime().make_state<State>();
const auto channel = peer->asChannel();
const auto available = channel && channel->paidMessagesAvailable();
Ui::AddSkip(inner); Ui::AddSkip(inner);
Ui::AddDivider(inner); Ui::AddDivider(inner);
auto charging = (Ui::SettingsButton*)nullptr;
if (available) {
Ui::AddSkip(inner); Ui::AddSkip(inner);
const auto starsPerMessage = peer->isChannel() const auto starsPerMessage = peer->isChannel()
? peer->asChannel()->starsPerMessage() ? peer->asChannel()->starsPerMessage()
: 0; : 0;
const auto charging = inner->add(object_ptr<Ui::SettingsButton>( charging = inner->add(object_ptr<Ui::SettingsButton>(
inner, inner,
tr::lng_rights_charge_stars(), tr::lng_rights_charge_stars(),
st::settingsButtonNoIcon)); st::settingsButtonNoIcon));
@ -1188,6 +1192,7 @@ void ShowEditPeerPermissionsBox(
chargeInner, chargeInner,
peer, peer,
starsPerMessage); starsPerMessage);
}
static constexpr auto kSendRestrictions = Flag::EmbedLinks static constexpr auto kSendRestrictions = Flag::EmbedLinks
| Flag::SendGames | Flag::SendGames
@ -1242,7 +1247,7 @@ void ShowEditPeerPermissionsBox(
const auto boostsUnrestrict = hasRestrictions const auto boostsUnrestrict = hasRestrictions
? state->boostsUnrestrict.current() ? state->boostsUnrestrict.current()
: 0; : 0;
const auto starsPerMessage = charging->toggled() const auto starsPerMessage = (charging && charging->toggled())
? state->starsPerMessage.current() ? state->starsPerMessage.current()
: 0; : 0;
done({ done({

View file

@ -37,10 +37,7 @@ void Credits::apply(const MTPDupdateStarsBalance &data) {
rpl::producer<float64> Credits::rateValue( rpl::producer<float64> Credits::rateValue(
not_null<PeerData*> ownedBotOrChannel) { not_null<PeerData*> ownedBotOrChannel) {
return rpl::single( return rpl::single(_session->appConfig().starsWithdrawRate());
_session->appConfig().get<float64>(
u"stars_usd_withdraw_rate_x1000"_q,
1200) / 1000.);
} }
void Credits::load(bool force) { void Credits::load(bool force) {

View file

@ -1167,7 +1167,8 @@ void ApplyChannelUpdate(
| Flag::CanViewRevenue | Flag::CanViewRevenue
| Flag::PaidMediaAllowed | Flag::PaidMediaAllowed
| Flag::CanViewCreditsRevenue | Flag::CanViewCreditsRevenue
| Flag::StargiftsAvailable; | Flag::StargiftsAvailable
| Flag::PaidMessagesAvailable;
channel->setFlags((channel->flags() & ~mask) channel->setFlags((channel->flags() & ~mask)
| (update.is_can_set_username() ? Flag::CanSetUsername : Flag()) | (update.is_can_set_username() ? Flag::CanSetUsername : Flag())
| (update.is_can_view_participants() | (update.is_can_view_participants()
@ -1191,6 +1192,9 @@ void ApplyChannelUpdate(
: Flag()) : Flag())
| (update.is_stargifts_available() | (update.is_stargifts_available()
? Flag::StargiftsAvailable ? Flag::StargiftsAvailable
: Flag())
| (update.is_paid_messages_available()
? Flag::PaidMessagesAvailable
: Flag())); : Flag()));
channel->setUserpicPhoto(update.vchat_photo()); channel->setUserpicPhoto(update.vchat_photo());
if (const auto migratedFrom = update.vmigrated_from_chat_id()) { if (const auto migratedFrom = update.vmigrated_from_chat_id()) {

View file

@ -72,6 +72,7 @@ enum class ChannelDataFlag : uint64 {
CanViewCreditsRevenue = (1ULL << 34), CanViewCreditsRevenue = (1ULL << 34),
SignatureProfiles = (1ULL << 35), SignatureProfiles = (1ULL << 35),
StargiftsAvailable = (1ULL << 36), StargiftsAvailable = (1ULL << 36),
PaidMessagesAvailable = (1ULL << 37),
}; };
inline constexpr bool is_flag_type(ChannelDataFlag) { return true; }; inline constexpr bool is_flag_type(ChannelDataFlag) { return true; };
using ChannelDataFlags = base::flags<ChannelDataFlag>; using ChannelDataFlags = base::flags<ChannelDataFlag>;
@ -262,6 +263,9 @@ public:
[[nodiscard]] bool stargiftsAvailable() const { [[nodiscard]] bool stargiftsAvailable() const {
return flags() & Flag::StargiftsAvailable; return flags() & Flag::StargiftsAvailable;
} }
[[nodiscard]] bool paidMessagesAvailable() const {
return flags() & Flag::PaidMessagesAvailable;
}
[[nodiscard]] static ChatRestrictionsInfo KickedRestrictedRights( [[nodiscard]] static ChatRestrictionsInfo KickedRestrictedRights(
not_null<PeerData*> participant); not_null<PeerData*> participant);

View file

@ -73,6 +73,22 @@ int AppConfig::starrefCommissionMax() const {
return get<int>(u"starref_max_commission_permille"_q, 900); return get<int>(u"starref_max_commission_permille"_q, 900);
} }
float64 AppConfig::starsWithdrawRate() const {
return get<float64>(u"stars_usd_withdraw_rate_x1000"_q, 1300) / 1000.;
}
bool AppConfig::paidMessagesAvailable() const {
return get<bool>(u"stars_paid_messages_available"_q, false);
}
int AppConfig::paidMessageStarsMax() const {
return get<int>(u"stars_paid_message_amount_max"_q, 10'000);
}
int AppConfig::paidMessageCommission() const {
return get<int>(u"stars_paid_message_commission_permille"_q, 850);
}
void AppConfig::refresh(bool force) { void AppConfig::refresh(bool force) {
if (_requestId || !_api) { if (_requestId || !_api) {
if (force) { if (force) {

View file

@ -72,6 +72,11 @@ public:
[[nodiscard]] int starrefCommissionMin() const; [[nodiscard]] int starrefCommissionMin() const;
[[nodiscard]] int starrefCommissionMax() const; [[nodiscard]] int starrefCommissionMax() const;
[[nodiscard]] float64 starsWithdrawRate() const;
[[nodiscard]] bool paidMessagesAvailable() const;
[[nodiscard]] int paidMessageStarsMax() const;
[[nodiscard]] int paidMessageCommission() const;
void refresh(bool force = false); void refresh(bool force = false);
private: private: