From 852ab19760dffee9256c1adc43fbabd17a750517 Mon Sep 17 00:00:00 2001 From: John Preston Date: Tue, 18 Feb 2025 12:54:24 +0400 Subject: [PATCH] Update API scheme, track stars-per-message. --- Telegram/SourceFiles/api/api_premium.cpp | 120 +++++++++++------- Telegram/SourceFiles/api/api_premium.h | 23 ++-- .../boxes/peer_list_controllers.cpp | 43 ++++--- .../SourceFiles/boxes/peer_list_controllers.h | 16 +-- .../boxes/peers/add_participants_box.cpp | 6 +- .../boxes/peers/edit_peer_invite_link.cpp | 4 +- Telegram/SourceFiles/boxes/share_box.cpp | 51 ++++---- Telegram/SourceFiles/boxes/share_box.h | 11 +- .../calls/group/calls_group_settings.cpp | 4 +- Telegram/SourceFiles/data/data_channel.cpp | 2 - .../data/data_chat_participant_status.cpp | 4 +- Telegram/SourceFiles/data/data_peer.cpp | 2 +- .../SourceFiles/data/data_peer_values.cpp | 4 +- Telegram/SourceFiles/data/data_session.cpp | 38 ++++-- Telegram/SourceFiles/data/data_user.cpp | 30 +++-- Telegram/SourceFiles/data/data_user.h | 18 +-- .../history/history_inner_widget.cpp | 13 +- .../SourceFiles/history/history_widget.cpp | 2 +- .../controls/history_view_draft_options.cpp | 9 +- .../history/view/history_view_about_view.cpp | 4 +- .../history/view/history_view_fake_items.cpp | 3 +- Telegram/SourceFiles/main/main_account.cpp | 3 +- .../media/stories/media_stories_reply.cpp | 2 +- .../media/stories/media_stories_share.cpp | 8 +- .../SourceFiles/menu/menu_ttl_validator.cpp | 3 +- Telegram/SourceFiles/mtproto/scheme/api.tl | 12 +- .../SourceFiles/window/window_peer_menu.cpp | 11 +- 27 files changed, 256 insertions(+), 190 deletions(-) diff --git a/Telegram/SourceFiles/api/api_premium.cpp b/Telegram/SourceFiles/api/api_premium.cpp index 3bd36b40c..26913462b 100644 --- a/Telegram/SourceFiles/api/api_premium.cpp +++ b/Telegram/SourceFiles/api/api_premium.cpp @@ -377,15 +377,15 @@ const Data::PremiumSubscriptionOptions &Premium::subscriptionOptions() const { return _subscriptionOptions; } -rpl::producer<> Premium::somePremiumRequiredResolved() const { - return _somePremiumRequiredResolved.events(); +rpl::producer<> Premium::someMessageMoneyRestrictionsResolved() const { + return _someMessageMoneyRestrictionsResolved.events(); } -void Premium::resolvePremiumRequired(not_null user) { - _resolvePremiumRequiredUsers.emplace(user); - if (!_premiumRequiredRequestScheduled - && _resolvePremiumRequestedUsers.empty()) { - _premiumRequiredRequestScheduled = true; +void Premium::resolveMessageMoneyRestrictions(not_null user) { + _resolveMessageMoneyRequiredUsers.emplace(user); + if (!_messageMoneyRequestScheduled + && _resolveMessageMoneyRequestedUsers.empty()) { + _messageMoneyRequestScheduled = true; crl::on_main(_session, [=] { requestPremiumRequiredSlice(); }); @@ -393,50 +393,65 @@ void Premium::resolvePremiumRequired(not_null user) { } void Premium::requestPremiumRequiredSlice() { - _premiumRequiredRequestScheduled = false; - if (!_resolvePremiumRequestedUsers.empty() - || _resolvePremiumRequiredUsers.empty()) { + _messageMoneyRequestScheduled = false; + if (!_resolveMessageMoneyRequestedUsers.empty() + || _resolveMessageMoneyRequiredUsers.empty()) { return; } constexpr auto kPerRequest = 100; - auto users = MTP_vector_from_range(_resolvePremiumRequiredUsers + auto users = MTP_vector_from_range(_resolveMessageMoneyRequiredUsers | ranges::views::transform(&UserData::inputUser)); if (users.v.size() > kPerRequest) { auto shortened = users.v; shortened.resize(kPerRequest); users = MTP_vector(std::move(shortened)); - const auto from = begin(_resolvePremiumRequiredUsers); - _resolvePremiumRequestedUsers = { from, from + kPerRequest }; - _resolvePremiumRequiredUsers.erase(from, from + kPerRequest); + const auto from = begin(_resolveMessageMoneyRequiredUsers); + _resolveMessageMoneyRequestedUsers = { from, from + kPerRequest }; + _resolveMessageMoneyRequiredUsers.erase(from, from + kPerRequest); } else { - _resolvePremiumRequestedUsers - = base::take(_resolvePremiumRequiredUsers); + _resolveMessageMoneyRequestedUsers + = base::take(_resolveMessageMoneyRequiredUsers); } - const auto finish = [=](const QVector &list) { - constexpr auto me = UserDataFlag::MeRequiresPremiumToWrite; - constexpr auto known = UserDataFlag::RequirePremiumToWriteKnown; - constexpr auto mask = me | known; + const auto finish = [=](const QVector &list) { auto index = 0; - for (const auto &user : base::take(_resolvePremiumRequestedUsers)) { - const auto require = (index < list.size()) - && mtpIsTrue(list[index++]); - user->setFlags((user->flags() & ~mask) - | known - | (require ? me : UserDataFlag())); + for (const auto &user : base::take(_resolveMessageMoneyRequestedUsers)) { + const auto set = [&](bool requirePremium, int stars) { + using Flag = UserDataFlag; + constexpr auto me = Flag::RequiresPremiumToWrite; + constexpr auto known = Flag::MessageMoneyRestrictionsKnown; + constexpr auto hasPrem = Flag::HasRequirePremiumToWrite; + constexpr auto hasStars = Flag::HasStarsPerMessage; + user->setStarsPerMessage(stars); + user->setFlags((user->flags() & ~(me | hasPrem | hasStars)) + | known + | (requirePremium ? (me | hasPrem) : Flag()) + | (stars ? hasStars : Flag())); + }; + if (index >= list.size()) { + set(false, 0); + continue; + } + list[index++].match([&](const MTPDrequirementToContactEmpty &) { + set(false, 0); + }, [&](const MTPDrequirementToContactPremium &) { + set(true, 0); + }, [&](const MTPDrequirementToContactPaidMessages &data) { + set(false, data.vstars_amount().v); + }); } - if (!_premiumRequiredRequestScheduled - && !_resolvePremiumRequiredUsers.empty()) { - _premiumRequiredRequestScheduled = true; + if (!_messageMoneyRequestScheduled + && !_resolveMessageMoneyRequiredUsers.empty()) { + _messageMoneyRequestScheduled = true; crl::on_main(_session, [=] { requestPremiumRequiredSlice(); }); } - _somePremiumRequiredResolved.fire({}); + _someMessageMoneyRestrictionsResolved.fire({}); }; _session->api().request( - MTPusers_GetIsPremiumRequiredToContact(std::move(users)) - ).done([=](const MTPVector &result) { + MTPusers_GetRequirementsToContact(std::move(users)) + ).done([=](const MTPVector &result) { finish(result.v); }).fail([=] { finish({}); @@ -694,28 +709,32 @@ rpl::producer SponsoredToggle::setToggled(bool v) { }; } -RequirePremiumState ResolveRequiresPremiumToWrite( +MessageMoneyRestriction ResolveMessageMoneyRestrictions( not_null peer, History *maybeHistory) { const auto user = peer->asUser(); - if (!user - || !user->someRequirePremiumToWrite() - || user->session().premium()) { - return RequirePremiumState::No; - } else if (user->requirePremiumToWriteKnown()) { - return user->meRequiresPremiumToWrite() - ? RequirePremiumState::Yes - : RequirePremiumState::No; + if (!user) { + return { .known = true }; + } else if (user->messageMoneyRestrictionsKnown()) { + return { + .starsPerMessage = user->starsPerMessage(), + .premiumRequired = (user->requiresPremiumToWrite() + && !user->session().premium()), + .known = true, + }; + } else if (user->hasStarsPerMessage()) { + return {}; + } else if (!user->hasRequirePremiumToWrite()) { + return { .known = true }; } else if (user->flags() & UserDataFlag::MutualContact) { - return RequirePremiumState::No; + return { .known = true }; } else if (!maybeHistory) { - return RequirePremiumState::Unknown; + return {}; } - const auto update = [&](bool require) { using Flag = UserDataFlag; - constexpr auto known = Flag::RequirePremiumToWriteKnown; - constexpr auto me = Flag::MeRequiresPremiumToWrite; + constexpr auto known = Flag::MessageMoneyRestrictionsKnown; + constexpr auto me = Flag::RequiresPremiumToWrite; user->setFlags((user->flags() & ~me) | known | (require ? me : Flag())); @@ -727,16 +746,19 @@ RequirePremiumState ResolveRequiresPremiumToWrite( const auto item = view->data(); if (!item->out() && !item->isService()) { update(false); - return RequirePremiumState::No; + return { .known = true }; } } } if (user->isContact() // Here we know, that we're not in his contacts. && maybeHistory->loadedAtTop() // And no incoming messages. && maybeHistory->loadedAtBottom()) { - update(true); + return { + .premiumRequired = !user->session().premium(), + .known = true, + }; } - return RequirePremiumState::Unknown; + return {}; } rpl::producer RandomHelloStickerValue( diff --git a/Telegram/SourceFiles/api/api_premium.h b/Telegram/SourceFiles/api/api_premium.h index a7757a490..0430c754b 100644 --- a/Telegram/SourceFiles/api/api_premium.h +++ b/Telegram/SourceFiles/api/api_premium.h @@ -116,8 +116,9 @@ public: [[nodiscard]] auto subscriptionOptions() const -> const Data::PremiumSubscriptionOptions &; - [[nodiscard]] rpl::producer<> somePremiumRequiredResolved() const; - void resolvePremiumRequired(not_null user); + [[nodiscard]] auto someMessageMoneyRestrictionsResolved() const + -> rpl::producer<>; + void resolveMessageMoneyRestrictions(not_null user); private: void reloadPromo(); @@ -166,10 +167,10 @@ private: Data::PremiumSubscriptionOptions _subscriptionOptions; - rpl::event_stream<> _somePremiumRequiredResolved; - base::flat_set> _resolvePremiumRequiredUsers; - base::flat_set> _resolvePremiumRequestedUsers; - bool _premiumRequiredRequestScheduled = false; + rpl::event_stream<> _someMessageMoneyRestrictionsResolved; + base::flat_set> _resolveMessageMoneyRequiredUsers; + base::flat_set> _resolveMessageMoneyRequestedUsers; + bool _messageMoneyRequestScheduled = false; }; @@ -244,12 +245,12 @@ private: }; -enum class RequirePremiumState { - Unknown, - Yes, - No, +struct MessageMoneyRestriction { + int starsPerMessage = 0; + bool premiumRequired = false; + bool known = false; }; -[[nodiscard]] RequirePremiumState ResolveRequiresPremiumToWrite( +[[nodiscard]] MessageMoneyRestriction ResolveMessageMoneyRestrictions( not_null peer, History *maybeHistory); diff --git a/Telegram/SourceFiles/boxes/peer_list_controllers.cpp b/Telegram/SourceFiles/boxes/peer_list_controllers.cpp index ff3e2722a..95105ee60 100644 --- a/Telegram/SourceFiles/boxes/peer_list_controllers.cpp +++ b/Telegram/SourceFiles/boxes/peer_list_controllers.cpp @@ -283,8 +283,9 @@ RecipientRow::RecipientRow( , _maybeHistory(maybeHistory) , _resolvePremiumRequired(maybeLockedSt != nullptr) { if (maybeLockedSt - && (Api::ResolveRequiresPremiumToWrite(peer, maybeHistory) - == Api::RequirePremiumState::Yes)) { + && Api::ResolveMessageMoneyRestrictions( + peer, + maybeHistory).premiumRequired) { _lockedSt = maybeLockedSt; } } @@ -305,8 +306,9 @@ bool RecipientRow::refreshLock( not_null maybeLockedSt) { if (const auto user = peer()->asUser()) { const auto locked = _resolvePremiumRequired - && (Api::ResolveRequiresPremiumToWrite(user, _maybeHistory) - == Api::RequirePremiumState::Yes); + && Api::ResolveMessageMoneyRestrictions( + user, + _maybeHistory).premiumRequired; if (this->locked() != locked) { setLocked(locked ? maybeLockedSt.get() : nullptr); return true; @@ -320,20 +322,22 @@ void RecipientRow::preloadUserpic() { if (!_resolvePremiumRequired) { return; - } else if (Api::ResolveRequiresPremiumToWrite(peer(), _maybeHistory) - == Api::RequirePremiumState::Unknown) { + } else if (!Api::ResolveMessageMoneyRestrictions( + peer(), + _maybeHistory).known) { const auto user = peer()->asUser(); - user->session().api().premium().resolvePremiumRequired(user); + user->session().api().premium().resolveMessageMoneyRestrictions( + user); } } -void TrackPremiumRequiredChanges( +void TrackMessageMoneyRestrictionsChanges( not_null controller, rpl::lifetime &lifetime) { const auto session = &controller->session(); rpl::merge( Data::AmPremiumValue(session) | rpl::to_empty, - session->api().premium().somePremiumRequiredResolved() + session->api().premium().someMessageMoneyRestrictionsResolved() ) | rpl::start_with_next([=] { const auto st = &controller->computeListSt().item; const auto delegate = controller->delegate(); @@ -726,7 +730,7 @@ std::unique_ptr ContactsBoxController::createRow( return std::make_unique(user); } -RecipientPremiumRequiredError WritePremiumRequiredError( +RecipientMoneyRestrictionError WriteMoneyRestrictionError( not_null user) { return { .text = tr::lng_send_non_premium_message_toast( @@ -759,7 +763,7 @@ ChooseRecipientBoxController::ChooseRecipientBoxController( , _session(args.session) , _callback(std::move(args.callback)) , _filter(std::move(args.filter)) -, _premiumRequiredError(std::move(args.premiumRequiredError)) { +, _moneyRestrictionError(std::move(args.moneyRestrictionError)) { } Main::Session &ChooseRecipientBoxController::session() const { @@ -769,14 +773,17 @@ Main::Session &ChooseRecipientBoxController::session() const { void ChooseRecipientBoxController::prepareViewHook() { delegate()->peerListSetTitle(tr::lng_forward_choose()); - if (_premiumRequiredError) { - TrackPremiumRequiredChanges(this, lifetime()); + if (_moneyRestrictionError) { + TrackMessageMoneyRestrictionsChanges(this, lifetime()); } } bool ChooseRecipientBoxController::showLockedError( not_null row) { - return RecipientRow::ShowLockedError(this, row, _premiumRequiredError); + return RecipientRow::ShowLockedError( + this, + row, + _moneyRestrictionError); } void ChooseRecipientBoxController::rowClicked(not_null row) { @@ -836,7 +843,7 @@ void ChooseRecipientBoxController::rowClicked(not_null row) { bool RecipientRow::ShowLockedError( not_null controller, not_null row, - Fn)> error) { + Fn)> error) { if (!static_cast(row.get())->locked()) { return false; } @@ -860,15 +867,15 @@ auto ChooseRecipientBoxController::createRow( : ((peer->isBroadcast() && !Data::CanSendAnything(peer)) || peer->isRepliesChat() || peer->isVerifyCodes() - || (peer->isUser() && (_premiumRequiredError - ? !peer->asUser()->canSendIgnoreRequirePremium() + || (peer->isUser() && (_moneyRestrictionError + ? !peer->asUser()->canSendIgnoreMoneyRestrictions() : !Data::CanSendAnything(peer)))); if (skip) { return nullptr; } auto result = std::make_unique( history, - _premiumRequiredError ? &computeListSt().item : nullptr); + _moneyRestrictionError ? &computeListSt().item : nullptr); return result; } diff --git a/Telegram/SourceFiles/boxes/peer_list_controllers.h b/Telegram/SourceFiles/boxes/peer_list_controllers.h index 07f71534a..9bec5a98e 100644 --- a/Telegram/SourceFiles/boxes/peer_list_controllers.h +++ b/Telegram/SourceFiles/boxes/peer_list_controllers.h @@ -93,11 +93,11 @@ private: }; -struct RecipientPremiumRequiredError { +struct RecipientMoneyRestrictionError { TextWithEntities text; }; -[[nodiscard]] RecipientPremiumRequiredError WritePremiumRequiredError( +[[nodiscard]] RecipientMoneyRestrictionError WriteMoneyRestrictionError( not_null user); class RecipientRow : public PeerListRow { @@ -112,7 +112,7 @@ public: [[nodiscard]] static bool ShowLockedError( not_null controller, not_null row, - Fn)> error); + Fn)> error); [[nodiscard]] History *maybeHistory() const { return _maybeHistory; @@ -135,7 +135,7 @@ private: }; -void TrackPremiumRequiredChanges( +void TrackMessageMoneyRestrictionsChanges( not_null controller, rpl::lifetime &lifetime); @@ -261,8 +261,8 @@ struct ChooseRecipientArgs { FnMut)> callback; Fn)> filter; - using PremiumRequiredError = RecipientPremiumRequiredError; - Fn)> premiumRequiredError; + using MoneyRestrictionError = RecipientMoneyRestrictionError; + Fn)> moneyRestrictionError; }; class ChooseRecipientBoxController @@ -290,8 +290,8 @@ private: const not_null _session; FnMut)> _callback; Fn)> _filter; - Fn)> _premiumRequiredError; + Fn)> _moneyRestrictionError; }; diff --git a/Telegram/SourceFiles/boxes/peers/add_participants_box.cpp b/Telegram/SourceFiles/boxes/peers/add_participants_box.cpp index ab48b6b8d..c2b6ff565 100644 --- a/Telegram/SourceFiles/boxes/peers/add_participants_box.cpp +++ b/Telegram/SourceFiles/boxes/peers/add_participants_box.cpp @@ -584,8 +584,8 @@ void AddParticipantsBoxController::subscribeToMigration() { } void AddParticipantsBoxController::rowClicked(not_null row) { - const auto premiumRequiredError = WritePremiumRequiredError; - if (RecipientRow::ShowLockedError(this, row, premiumRequiredError)) { + const auto moneyRestrictionError = WriteMoneyRestrictionError; + if (RecipientRow::ShowLockedError(this, row, moneyRestrictionError)) { return; } const auto &serverConfig = session().serverConfig(); @@ -614,7 +614,7 @@ void AddParticipantsBoxController::itemDeselectedHook( void AddParticipantsBoxController::prepareViewHook() { updateTitle(); - TrackPremiumRequiredChanges(this, lifetime()); + TrackMessageMoneyRestrictionsChanges(this, lifetime()); } int AddParticipantsBoxController::alreadyInCount() const { diff --git a/Telegram/SourceFiles/boxes/peers/edit_peer_invite_link.cpp b/Telegram/SourceFiles/boxes/peers/edit_peer_invite_link.cpp index 2797b5394..f37bda892 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_peer_invite_link.cpp +++ b/Telegram/SourceFiles/boxes/peers/edit_peer_invite_link.cpp @@ -1530,7 +1530,7 @@ object_ptr ShareInviteLinkBox( }; auto filterCallback = [](not_null thread) { if (const auto user = thread->peer()->asUser()) { - if (user->canSendIgnoreRequirePremium()) { + if (user->canSendIgnoreMoneyRestrictions()) { return true; } } @@ -1541,7 +1541,7 @@ object_ptr ShareInviteLinkBox( .copyCallback = std::move(copyCallback), .submitCallback = std::move(submitCallback), .filterCallback = std::move(filterCallback), - .premiumRequiredError = SharePremiumRequiredError(), + .moneyRestrictionError = ShareMessageMoneyRestrictionError(), }); *box = Ui::MakeWeak(object.data()); return object; diff --git a/Telegram/SourceFiles/boxes/share_box.cpp b/Telegram/SourceFiles/boxes/share_box.cpp index c88a39f6b..ebf25e08f 100644 --- a/Telegram/SourceFiles/boxes/share_box.cpp +++ b/Telegram/SourceFiles/boxes/share_box.cpp @@ -721,11 +721,11 @@ ShareBox::Inner::Inner( _rowHeight = st::shareRowHeight; setAttribute(Qt::WA_OpaquePaintEvent); - if (_descriptor.premiumRequiredError) { + if (_descriptor.moneyRestrictionError) { const auto session = _descriptor.session; rpl::merge( Data::AmPremiumValue(session) | rpl::to_empty, - session->api().premium().somePremiumRequiredResolved() + session->api().premium().someMessageMoneyRestrictionsResolved() ) | rpl::start_with_next([=] { refreshLockedRows(); }, lifetime()); @@ -794,7 +794,7 @@ bool ShareBox::Inner::showLockedError(not_null chat) { ::Settings::ShowPremiumPromoToast( Main::MakeSessionShow(_show, _descriptor.session), ChatHelpers::ResolveWindowDefault(), - _descriptor.premiumRequiredError(chat->peer->asUser()).text, + _descriptor.moneyRestrictionError(chat->peer->asUser()).text, u"require_premium"_q); return true; } @@ -803,10 +803,9 @@ void ShareBox::Inner::refreshLockedRows() { auto changed = false; for (const auto &[peer, data] : _dataMap) { const auto history = data->history; - const auto locked = (Api::ResolveRequiresPremiumToWrite( + const auto locked = Api::ResolveMessageMoneyRestrictions( history->peer, - history - ) == Api::RequirePremiumState::Yes); + history).premiumRequired; if (data->locked != locked) { data->locked = locked; changed = true; @@ -814,10 +813,9 @@ void ShareBox::Inner::refreshLockedRows() { } for (const auto &data : d_byUsernameFiltered) { const auto history = data->history; - const auto locked = (Api::ResolveRequiresPremiumToWrite( + const auto locked = Api::ResolveMessageMoneyRestrictions( history->peer, - history - ) == Api::RequirePremiumState::Yes); + history).premiumRequired; if (data->locked != locked) { data->locked = locked; changed = true; @@ -887,12 +885,11 @@ void ShareBox::Inner::updateChatName(not_null chat) { } void ShareBox::Inner::initChatLocked(not_null chat) { - if (_descriptor.premiumRequiredError) { + if (_descriptor.moneyRestrictionError) { const auto history = chat->history; - if (Api::ResolveRequiresPremiumToWrite( - history->peer, - history - ) == Api::RequirePremiumState::Yes) { + if (Api::ResolveMessageMoneyRestrictions( + history->peer, + history).premiumRequired) { chat->locked = true; } } @@ -1019,14 +1016,14 @@ void ShareBox::Inner::loadProfilePhotos() { void ShareBox::Inner::preloadUserpic(not_null entry) { entry->chatListPreloadData(); const auto history = entry->asHistory(); - if (!_descriptor.premiumRequiredError || !history) { + if (!_descriptor.moneyRestrictionError || !history) { return; - } else if (Api::ResolveRequiresPremiumToWrite( - history->peer, - history - ) == Api::RequirePremiumState::Unknown) { + } else if (!Api::ResolveMessageMoneyRestrictions( + history->peer, + history).known) { const auto user = history->peer->asUser(); - _descriptor.session->api().premium().resolvePremiumRequired(user); + _descriptor.session->api().premium().resolveMessageMoneyRestrictions( + user); } } @@ -1707,7 +1704,7 @@ void FastShareMessage( const auto requiresInline = item->requiresSendInlineRight(); auto filterCallback = [=](not_null thread) { if (const auto user = thread->peer()->asUser()) { - if (user->canSendIgnoreRequirePremium()) { + if (user->canSendIgnoreMoneyRestrictions()) { return true; } } @@ -1733,7 +1730,7 @@ void FastShareMessage( .captionsCount = ItemsForwardCaptionsCount(items), .show = !hasOnlyForcedForwardedInfo, }, - .premiumRequiredError = SharePremiumRequiredError(), + .moneyRestrictionError = ShareMessageMoneyRestrictionError(), }), Ui::LayerOption::CloseOther); } @@ -1806,7 +1803,7 @@ void FastShareLink( }; auto filterCallback = [](not_null<::Data::Thread*> thread) { if (const auto user = thread->peer()->asUser()) { - if (user->canSendIgnoreRequirePremium()) { + if (user->canSendIgnoreMoneyRestrictions()) { return true; } } @@ -1819,13 +1816,13 @@ void FastShareLink( .submitCallback = std::move(submitCallback), .filterCallback = std::move(filterCallback), .st = st, - .premiumRequiredError = SharePremiumRequiredError(), + .moneyRestrictionError = ShareMessageMoneyRestrictionError(), }), Ui::LayerOption::KeepOther, anim::type::normal); } -auto SharePremiumRequiredError() --> Fn)> { - return WritePremiumRequiredError; +auto ShareMessageMoneyRestrictionError() +-> Fn)> { + return WriteMoneyRestrictionError; } diff --git a/Telegram/SourceFiles/boxes/share_box.h b/Telegram/SourceFiles/boxes/share_box.h index 779a60e0a..83cdbcb4f 100644 --- a/Telegram/SourceFiles/boxes/share_box.h +++ b/Telegram/SourceFiles/boxes/share_box.h @@ -87,9 +87,9 @@ void FastShareLink( const QString &url, ShareBoxStyleOverrides st = {}); -struct RecipientPremiumRequiredError; -[[nodiscard]] auto SharePremiumRequiredError() --> Fn)>; +struct RecipientMoneyRestrictionError; +[[nodiscard]] auto ShareMessageMoneyRestrictionError() +-> Fn)>; class ShareBox final : public Ui::BoxContent { public: @@ -123,8 +123,9 @@ public: bool show = false; } forwardOptions; - using PremiumRequiredError = RecipientPremiumRequiredError; - Fn)> premiumRequiredError; + using MoneyRestrictionError = RecipientMoneyRestrictionError; + Fn)> moneyRestrictionError; }; ShareBox(QWidget*, Descriptor &&descriptor); diff --git a/Telegram/SourceFiles/calls/group/calls_group_settings.cpp b/Telegram/SourceFiles/calls/group/calls_group_settings.cpp index 7ae977bfd..672d6d4a1 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_settings.cpp +++ b/Telegram/SourceFiles/calls/group/calls_group_settings.cpp @@ -178,7 +178,7 @@ object_ptr ShareInviteLinkBox( }; auto filterCallback = [](not_null thread) { if (const auto user = thread->peer()->asUser()) { - if (user->canSendIgnoreRequirePremium()) { + if (user->canSendIgnoreMoneyRestrictions()) { return true; } } @@ -199,7 +199,7 @@ object_ptr ShareInviteLinkBox( tr::lng_group_call_copy_speaker_link(), tr::lng_group_call_copy_listener_link()), .st = st.shareBox ? *st.shareBox : ShareBoxStyleOverrides(), - .premiumRequiredError = SharePremiumRequiredError(), + .moneyRestrictionError = ShareMessageMoneyRestrictionError(), }); *box = result.data(); return result; diff --git a/Telegram/SourceFiles/data/data_channel.cpp b/Telegram/SourceFiles/data/data_channel.cpp index 909823794..e4f3dc831 100644 --- a/Telegram/SourceFiles/data/data_channel.cpp +++ b/Telegram/SourceFiles/data/data_channel.cpp @@ -1272,8 +1272,6 @@ void ApplyChannelUpdate( } else { channel->setLinkedChat(nullptr); } - channel->setStarsPerMessage( - update.vsend_paid_messages_stars().value_or_empty()); if (const auto history = channel->owner().historyLoaded(channel)) { if (const auto available = update.vavailable_min_id()) { history->clearUpTill(available->v); diff --git a/Telegram/SourceFiles/data/data_chat_participant_status.cpp b/Telegram/SourceFiles/data/data_chat_participant_status.cpp index 537663a36..10ffb3847 100644 --- a/Telegram/SourceFiles/data/data_chat_participant_status.cpp +++ b/Telegram/SourceFiles/data/data_chat_participant_status.cpp @@ -120,7 +120,7 @@ bool CanSendAnyOf( || user->isRepliesChat() || user->isVerifyCodes()) { return false; - } else if (user->meRequiresPremiumToWrite() + } else if (user->requiresPremiumToWrite() && !user->session().premium()) { return false; } else if (rights @@ -177,7 +177,7 @@ SendError RestrictionError( using Flag = ChatRestriction; if (const auto restricted = peer->amRestricted(restriction)) { if (const auto user = peer->asUser()) { - if (user->meRequiresPremiumToWrite() + if (user->requiresPremiumToWrite() && !user->session().premium()) { return SendError({ .text = tr::lng_restricted_send_non_premium( diff --git a/Telegram/SourceFiles/data/data_peer.cpp b/Telegram/SourceFiles/data/data_peer.cpp index 05e07ef26..96185bfa2 100644 --- a/Telegram/SourceFiles/data/data_peer.cpp +++ b/Telegram/SourceFiles/data/data_peer.cpp @@ -1331,7 +1331,7 @@ Data::RestrictionCheckResult PeerData::amRestricted( } }; if (const auto user = asUser()) { - if (user->meRequiresPremiumToWrite() && !user->session().premium()) { + if (user->requiresPremiumToWrite() && !user->session().premium()) { return Result::Explicit(); } return (right == ChatRestriction::SendVoiceMessages diff --git a/Telegram/SourceFiles/data/data_peer_values.cpp b/Telegram/SourceFiles/data/data_peer_values.cpp index 73d041c08..b79b1dbe8 100644 --- a/Telegram/SourceFiles/data/data_peer_values.cpp +++ b/Telegram/SourceFiles/data/data_peer_values.cpp @@ -224,11 +224,11 @@ inline auto DefaultRestrictionValue( | ChatRestriction::SendVideoMessages); auto allowedAny = PeerFlagsValue( user, - (UserDataFlag::Deleted | UserDataFlag::MeRequiresPremiumToWrite) + (UserDataFlag::Deleted | UserDataFlag::RequiresPremiumToWrite) ) | rpl::map([=](UserDataFlags flags) { return (flags & UserDataFlag::Deleted) ? rpl::single(false) - : !(flags & UserDataFlag::MeRequiresPremiumToWrite) + : !(flags & UserDataFlag::RequiresPremiumToWrite) ? rpl::single(true) : AmPremiumValue(&user->session()); }) | rpl::flatten_latest(); diff --git a/Telegram/SourceFiles/data/data_session.cpp b/Telegram/SourceFiles/data/data_session.cpp index edfc3ec99..1114873bb 100644 --- a/Telegram/SourceFiles/data/data_session.cpp +++ b/Telegram/SourceFiles/data/data_session.cpp @@ -532,14 +532,22 @@ not_null Session::processUser(const MTPUser &data) { | Flag::BotInlineGeo | Flag::Premium | Flag::Support - | Flag::SomeRequirePremiumToWrite - | Flag::RequirePremiumToWriteKnown + | Flag::HasRequirePremiumToWrite + | Flag::HasStarsPerMessage + | Flag::MessageMoneyRestrictionsKnown | (!minimal ? Flag::Contact | Flag::MutualContact | Flag::DiscardMinPhoto | Flag::StoriesHidden : Flag()); + const auto hasRequirePremiumToWrite + = data.is_contact_require_premium(); + const auto hasStarsPerMessage + = data.vsend_paid_messages_stars().has_value(); + if (!hasStarsPerMessage) { + result->setStarsPerMessage(0); + } const auto storiesState = minimal ? std::optional() : data.is_stories_unavailable() @@ -554,14 +562,25 @@ not_null Session::processUser(const MTPUser &data) { | (data.is_bot_inline_geo() ? Flag::BotInlineGeo : Flag()) | (data.is_premium() ? Flag::Premium : Flag()) | (data.is_support() ? Flag::Support : Flag()) - | (data.is_contact_require_premium() - ? (Flag::SomeRequirePremiumToWrite - | (result->someRequirePremiumToWrite() - ? (result->requirePremiumToWriteKnown() - ? Flag::RequirePremiumToWriteKnown + | (hasRequirePremiumToWrite + ? (Flag::HasRequirePremiumToWrite + | (result->hasRequirePremiumToWrite() + ? (result->messageMoneyRestrictionsKnown() + ? Flag::MessageMoneyRestrictionsKnown : Flag()) : Flag())) : Flag()) + | (hasStarsPerMessage + ? (Flag::HasStarsPerMessage + | (result->hasStarsPerMessage() + ? (result->messageMoneyRestrictionsKnown() + ? Flag::MessageMoneyRestrictionsKnown + : Flag()) + : Flag())) + : Flag()) + | ((!hasRequirePremiumToWrite && !hasStarsPerMessage) + ? Flag::MessageMoneyRestrictionsKnown + : Flag()) | (!minimal ? (data.is_contact() ? Flag::Contact : Flag()) | (data.is_mutual_contact() ? Flag::MutualContact : Flag()) @@ -999,6 +1018,8 @@ not_null Session::processChat(const MTPChat &data) { } channel->setPhoto(data.vphoto()); + channel->setStarsPerMessage( + data.vsend_paid_messages_stars().value_or_empty()); if (wasInChannel != channel->amIn()) { flags |= UpdateFlag::ChannelAmIn; @@ -4631,7 +4652,8 @@ void Session::serviceNotification( MTPPeerColor(), // color MTPPeerColor(), // profile_color MTPint(), // bot_active_users - MTPlong())); // bot_verification_icon + MTPlong(), // bot_verification_icon + MTPlong())); // send_paid_messages_stars } const auto history = this->history(PeerData::kServiceNotificationsId); const auto insert = [=] { diff --git a/Telegram/SourceFiles/data/data_user.cpp b/Telegram/SourceFiles/data/data_user.cpp index af333ed6e..514e75b2a 100644 --- a/Telegram/SourceFiles/data/data_user.cpp +++ b/Telegram/SourceFiles/data/data_user.cpp @@ -513,19 +513,23 @@ bool UserData::hasStoriesHidden() const { return (flags() & UserDataFlag::StoriesHidden); } -bool UserData::someRequirePremiumToWrite() const { - return (flags() & UserDataFlag::SomeRequirePremiumToWrite); +bool UserData::hasRequirePremiumToWrite() const { + return (flags() & UserDataFlag::HasRequirePremiumToWrite); } -bool UserData::meRequiresPremiumToWrite() const { - return !isSelf() && (flags() & UserDataFlag::MeRequiresPremiumToWrite); +bool UserData::hasStarsPerMessage() const { + return (flags() & UserDataFlag::HasStarsPerMessage); } -bool UserData::requirePremiumToWriteKnown() const { - return (flags() & UserDataFlag::RequirePremiumToWriteKnown); +bool UserData::requiresPremiumToWrite() const { + return !isSelf() && (flags() & UserDataFlag::RequiresPremiumToWrite); } -bool UserData::canSendIgnoreRequirePremium() const { +bool UserData::messageMoneyRestrictionsKnown() const { + return (flags() & UserDataFlag::MessageMoneyRestrictionsKnown); +} + +bool UserData::canSendIgnoreMoneyRestrictions() const { return !isInaccessible() && !isRepliesChat() && !isVerifyCodes(); } @@ -732,6 +736,8 @@ void ApplyUserUpdate(not_null user, const MTPDuserFull &update) { if (const auto pinned = update.vpinned_msg_id()) { SetTopPinnedMessageId(user, pinned->v); } + user->setStarsPerMessage( + update.vsend_paid_messages_stars().value_or_empty()); using Flag = UserDataFlag; const auto mask = Flag::Blocked | Flag::HasPhoneCalls @@ -739,8 +745,8 @@ void ApplyUserUpdate(not_null user, const MTPDuserFull &update) { | Flag::CanPinMessages | Flag::VoiceMessagesForbidden | Flag::ReadDatesPrivate - | Flag::RequirePremiumToWriteKnown - | Flag::MeRequiresPremiumToWrite; + | Flag::MessageMoneyRestrictionsKnown + | Flag::RequiresPremiumToWrite; user->setFlags((user->flags() & ~mask) | (update.is_phone_calls_private() ? Flag::PhoneCallsPrivate @@ -752,9 +758,9 @@ void ApplyUserUpdate(not_null user, const MTPDuserFull &update) { ? Flag::VoiceMessagesForbidden : Flag()) | (update.is_read_dates_private() ? Flag::ReadDatesPrivate : Flag()) - | Flag::RequirePremiumToWriteKnown + | Flag::MessageMoneyRestrictionsKnown | (update.is_contact_require_premium() - ? Flag::MeRequiresPremiumToWrite + ? Flag::RequiresPremiumToWrite : Flag())); user->setIsBlocked(update.is_blocked()); user->setCallsStatus(update.is_phone_calls_private() @@ -770,8 +776,6 @@ void ApplyUserUpdate(not_null user, const MTPDuserFull &update) { user->setTranslationDisabled(update.is_translations_disabled()); user->setPrivateForwardName( update.vprivate_forward_name().value_or_empty()); - user->setStarsPerMessage( - update.vsend_paid_messages_stars().value_or_empty()); if (const auto info = user->botInfo.get()) { const auto group = update.vbot_group_admin_rights() diff --git a/Telegram/SourceFiles/data/data_user.h b/Telegram/SourceFiles/data/data_user.h index 54c647033..7bac7de75 100644 --- a/Telegram/SourceFiles/data/data_user.h +++ b/Telegram/SourceFiles/data/data_user.h @@ -110,10 +110,11 @@ enum class UserDataFlag : uint32 { StoriesHidden = (1 << 18), HasActiveStories = (1 << 19), HasUnreadStories = (1 << 20), - MeRequiresPremiumToWrite = (1 << 21), - SomeRequirePremiumToWrite = (1 << 22), - RequirePremiumToWriteKnown = (1 << 23), - ReadDatesPrivate = (1 << 24), + RequiresPremiumToWrite = (1 << 21), + HasRequirePremiumToWrite = (1 << 22), + HasStarsPerMessage = (1 << 23), + MessageMoneyRestrictionsKnown = (1 << 24), + ReadDatesPrivate = (1 << 25), }; inline constexpr bool is_flag_type(UserDataFlag) { return true; }; using UserDataFlags = base::flags; @@ -174,10 +175,11 @@ public: [[nodiscard]] bool applyMinPhoto() const; [[nodiscard]] bool hasPersonalPhoto() const; [[nodiscard]] bool hasStoriesHidden() const; - [[nodiscard]] bool someRequirePremiumToWrite() const; - [[nodiscard]] bool meRequiresPremiumToWrite() const; - [[nodiscard]] bool requirePremiumToWriteKnown() const; - [[nodiscard]] bool canSendIgnoreRequirePremium() const; + [[nodiscard]] bool hasRequirePremiumToWrite() const; + [[nodiscard]] bool hasStarsPerMessage() const; + [[nodiscard]] bool requiresPremiumToWrite() const; + [[nodiscard]] bool messageMoneyRestrictionsKnown() const; + [[nodiscard]] bool canSendIgnoreMoneyRestrictions() const; [[nodiscard]] bool readDatesPrivate() const; void setStarsPerMessage(int stars); diff --git a/Telegram/SourceFiles/history/history_inner_widget.cpp b/Telegram/SourceFiles/history/history_inner_widget.cpp index c8192f37a..61ac0fa4e 100644 --- a/Telegram/SourceFiles/history/history_inner_widget.cpp +++ b/Telegram/SourceFiles/history/history_inner_widget.cpp @@ -4350,15 +4350,14 @@ void HistoryInner::refreshAboutView(bool force) { if (!info->inited) { session().api().requestFullPeer(user); } - } else if (user->meRequiresPremiumToWrite() - && !user->session().premium() - && !historyHeight()) { - refresh(); } else if (!historyHeight()) { - if (!user->isFullLoaded()) { - session().api().requestFullPeer(user); - } else { + if (user->starsPerMessage() > 0 + || (user->requiresPremiumToWrite() + && !user->session().premium()) + || user->isFullLoaded()) { refresh(); + } else { + session().api().requestFullPeer(user); } } } diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index bb8da7dfd..2334826f6 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -780,7 +780,7 @@ HistoryWidget::HistoryWidget( ) | rpl::start_with_next([=](UserData::Flags::Change change) { if (change.diff & UserData::Flag::Premium) { if (const auto user = _peer ? _peer->asUser() : nullptr) { - if (user->meRequiresPremiumToWrite()) { + if (user->requiresPremiumToWrite()) { handlePeerUpdate(); } } diff --git a/Telegram/SourceFiles/history/view/controls/history_view_draft_options.cpp b/Telegram/SourceFiles/history/view/controls/history_view_draft_options.cpp index 2d03f6dfa..549d25233 100644 --- a/Telegram/SourceFiles/history/view/controls/history_view_draft_options.cpp +++ b/Telegram/SourceFiles/history/view/controls/history_view_draft_options.cpp @@ -1199,12 +1199,15 @@ struct AuthorSelector { _peer->owner().history(_peer), &computeListSt().item)); delegate()->peerListRefreshRows(); - TrackPremiumRequiredChanges(this, _lifetime); + TrackMessageMoneyRestrictionsChanges(this, _lifetime); } void loadMoreRows() override { } void rowClicked(not_null row) override { - if (RecipientRow::ShowLockedError(this, row, WritePremiumRequiredError)) { + if (RecipientRow::ShowLockedError( + this, + row, + WriteMoneyRestrictionError)) { return; } else if (const auto onstack = _click) { onstack(); @@ -1298,7 +1301,7 @@ void ShowReplyToChatBox( .callback = [=](Chosen thread) { _singleChosen.fire_copy(thread); }, - .premiumRequiredError = WritePremiumRequiredError, + .moneyRestrictionError = WriteMoneyRestrictionError, }) { _authorRow = AuthorRowSelector( session, diff --git a/Telegram/SourceFiles/history/view/history_view_about_view.cpp b/Telegram/SourceFiles/history/view/history_view_about_view.cpp index 452f595ac..bcf978e52 100644 --- a/Telegram/SourceFiles/history/view/history_view_about_view.cpp +++ b/Telegram/SourceFiles/history/view/history_view_about_view.cpp @@ -259,7 +259,9 @@ bool AboutView::refresh() { if (user && !user->isSelf() && _history->isDisplayedEmpty()) { if (_item) { return false; - } else if (user->meRequiresPremiumToWrite() + //} else if (user->starsPerMessage() > 0) { + // setItem(makeStarsPerMessage(), nullptr); + } else if (user->requiresPremiumToWrite() && !user->session().premium()) { setItem(makePremiumRequired(), nullptr); } else if (user->isBlocked()) { diff --git a/Telegram/SourceFiles/history/view/history_view_fake_items.cpp b/Telegram/SourceFiles/history/view/history_view_fake_items.cpp index ef7b2674f..49a310aa2 100644 --- a/Telegram/SourceFiles/history/view/history_view_fake_items.cpp +++ b/Telegram/SourceFiles/history/view/history_view_fake_items.cpp @@ -61,7 +61,8 @@ PeerId GenerateUser(not_null history, const QString &name) { MTPPeerColor(), // color MTPPeerColor(), // profile_color MTPint(), // bot_active_users - MTPlong())); // bot_verification_icon + MTPlong(), // bot_verification_icon + MTPlong())); // send_paid_messages_stars return peerId; } diff --git a/Telegram/SourceFiles/main/main_account.cpp b/Telegram/SourceFiles/main/main_account.cpp index 9a4190f34..5a2f894ed 100644 --- a/Telegram/SourceFiles/main/main_account.cpp +++ b/Telegram/SourceFiles/main/main_account.cpp @@ -174,7 +174,8 @@ void Account::createSession( MTPPeerColor(), // color MTPPeerColor(), // profile_color MTPint(), // bot_active_users - MTPlong()), // bot_verification_icon + MTPlong(), // bot_verification_icon + MTPlong()), // send_paid_messages_stars serialized, streamVersion, std::move(settings)); diff --git a/Telegram/SourceFiles/media/stories/media_stories_reply.cpp b/Telegram/SourceFiles/media/stories/media_stories_reply.cpp index 09e222737..934d86243 100644 --- a/Telegram/SourceFiles/media/stories/media_stories_reply.cpp +++ b/Telegram/SourceFiles/media/stories/media_stories_reply.cpp @@ -705,7 +705,7 @@ void ReplyArea::show( using namespace HistoryView::Controls; return (can || !user - || !user->meRequiresPremiumToWrite() + || !user->requiresPremiumToWrite() || user->session().premium()) ? WriteRestriction() : WriteRestriction{ diff --git a/Telegram/SourceFiles/media/stories/media_stories_share.cpp b/Telegram/SourceFiles/media/stories/media_stories_share.cpp index 630cfacaf..37e881f38 100644 --- a/Telegram/SourceFiles/media/stories/media_stories_share.cpp +++ b/Telegram/SourceFiles/media/stories/media_stories_share.cpp @@ -66,7 +66,7 @@ namespace Media::Stories { const auto state = std::make_shared(); auto filterCallback = [=](not_null thread) { if (const auto user = thread->peer()->asUser()) { - if (user->canSendIgnoreRequirePremium()) { + if (user->canSendIgnoreMoneyRestrictions()) { return true; } } @@ -183,7 +183,7 @@ namespace Media::Stories { .submitCallback = std::move(submitCallback), .filterCallback = std::move(filterCallback), .st = st.shareBox ? *st.shareBox : ShareBoxStyleOverrides(), - .premiumRequiredError = SharePremiumRequiredError(), + .moneyRestrictionError = ShareMessageMoneyRestrictionError(), }); } @@ -232,7 +232,7 @@ object_ptr PrepareShareAtTimeBox( const auto requiresInline = item->requiresSendInlineRight(); auto filterCallback = [=](not_null thread) { if (const auto user = thread->peer()->asUser()) { - if (user->canSendIgnoreRequirePremium()) { + if (user->canSendIgnoreMoneyRestrictions()) { return true; } } @@ -262,7 +262,7 @@ object_ptr PrepareShareAtTimeBox( .captionsCount = ItemsForwardCaptionsCount({ item }), .show = !hasOnlyForcedForwardedInfo, }, - .premiumRequiredError = SharePremiumRequiredError(), + .moneyRestrictionError = ShareMessageMoneyRestrictionError(), }); } diff --git a/Telegram/SourceFiles/menu/menu_ttl_validator.cpp b/Telegram/SourceFiles/menu/menu_ttl_validator.cpp index 1ea9d4095..9221e7907 100644 --- a/Telegram/SourceFiles/menu/menu_ttl_validator.cpp +++ b/Telegram/SourceFiles/menu/menu_ttl_validator.cpp @@ -113,7 +113,8 @@ bool TTLValidator::can() const { && !_peer->isSelf() && !_peer->isNotificationsUser() && !_peer->asUser()->isInaccessible() - && (!_peer->asUser()->meRequiresPremiumToWrite() + && !_peer->asUser()->starsPerMessage() + && (!_peer->asUser()->requiresPremiumToWrite() || _peer->session().premium())) || (_peer->isChat() && _peer->asChat()->canEditInformation() diff --git a/Telegram/SourceFiles/mtproto/scheme/api.tl b/Telegram/SourceFiles/mtproto/scheme/api.tl index 8f912fbe5..452671035 100644 --- a/Telegram/SourceFiles/mtproto/scheme/api.tl +++ b/Telegram/SourceFiles/mtproto/scheme/api.tl @@ -84,7 +84,7 @@ storage.fileMp4#b3cea0e4 = storage.FileType; storage.fileWebp#1081464c = storage.FileType; userEmpty#d3bc4b7a id:long = User; -user#4b46c37e flags:# self:flags.10?true contact:flags.11?true mutual_contact:flags.12?true deleted:flags.13?true bot:flags.14?true bot_chat_history:flags.15?true bot_nochats:flags.16?true verified:flags.17?true restricted:flags.18?true min:flags.20?true bot_inline_geo:flags.21?true support:flags.23?true scam:flags.24?true apply_min_photo:flags.25?true fake:flags.26?true bot_attach_menu:flags.27?true premium:flags.28?true attach_menu_enabled:flags.29?true flags2:# bot_can_edit:flags2.1?true close_friend:flags2.2?true stories_hidden:flags2.3?true stories_unavailable:flags2.4?true contact_require_premium:flags2.10?true bot_business:flags2.11?true bot_has_main_app:flags2.13?true id:long access_hash:flags.0?long first_name:flags.1?string last_name:flags.2?string username:flags.3?string phone:flags.4?string photo:flags.5?UserProfilePhoto status:flags.6?UserStatus bot_info_version:flags.14?int restriction_reason:flags.18?Vector bot_inline_placeholder:flags.19?string lang_code:flags.22?string emoji_status:flags.30?EmojiStatus usernames:flags2.0?Vector stories_max_id:flags2.5?int color:flags2.8?PeerColor profile_color:flags2.9?PeerColor bot_active_users:flags2.12?int bot_verification_icon:flags2.14?long = User; +user#20b1422 flags:# self:flags.10?true contact:flags.11?true mutual_contact:flags.12?true deleted:flags.13?true bot:flags.14?true bot_chat_history:flags.15?true bot_nochats:flags.16?true verified:flags.17?true restricted:flags.18?true min:flags.20?true bot_inline_geo:flags.21?true support:flags.23?true scam:flags.24?true apply_min_photo:flags.25?true fake:flags.26?true bot_attach_menu:flags.27?true premium:flags.28?true attach_menu_enabled:flags.29?true flags2:# bot_can_edit:flags2.1?true close_friend:flags2.2?true stories_hidden:flags2.3?true stories_unavailable:flags2.4?true contact_require_premium:flags2.10?true bot_business:flags2.11?true bot_has_main_app:flags2.13?true id:long access_hash:flags.0?long first_name:flags.1?string last_name:flags.2?string username:flags.3?string phone:flags.4?string photo:flags.5?UserProfilePhoto status:flags.6?UserStatus bot_info_version:flags.14?int restriction_reason:flags.18?Vector bot_inline_placeholder:flags.19?string lang_code:flags.22?string emoji_status:flags.30?EmojiStatus usernames:flags2.0?Vector stories_max_id:flags2.5?int color:flags2.8?PeerColor profile_color:flags2.9?PeerColor bot_active_users:flags2.12?int bot_verification_icon:flags2.14?long send_paid_messages_stars:flags2.15?long = User; userProfilePhotoEmpty#4f11bae1 = UserProfilePhoto; userProfilePhoto#82d1f706 flags:# has_video:flags.0?true personal:flags.2?true photo_id:long stripped_thumb:flags.1?bytes dc_id:int = UserProfilePhoto; @@ -99,11 +99,11 @@ userStatusLastMonth#65899777 flags:# by_me:flags.0?true = UserStatus; chatEmpty#29562865 id:long = Chat; chat#41cbf256 flags:# creator:flags.0?true left:flags.2?true deactivated:flags.5?true call_active:flags.23?true call_not_empty:flags.24?true noforwards:flags.25?true id:long title:string photo:ChatPhoto participants_count:int date:int version:int migrated_to:flags.6?InputChannel admin_rights:flags.14?ChatAdminRights default_banned_rights:flags.18?ChatBannedRights = Chat; chatForbidden#6592a1a7 id:long title:string = Chat; -channel#e00998b7 flags:# creator:flags.0?true left:flags.2?true broadcast:flags.5?true verified:flags.7?true megagroup:flags.8?true restricted:flags.9?true signatures:flags.11?true min:flags.12?true scam:flags.19?true has_link:flags.20?true has_geo:flags.21?true slowmode_enabled:flags.22?true call_active:flags.23?true call_not_empty:flags.24?true fake:flags.25?true gigagroup:flags.26?true noforwards:flags.27?true join_to_send:flags.28?true join_request:flags.29?true forum:flags.30?true flags2:# stories_hidden:flags2.1?true stories_hidden_min:flags2.2?true stories_unavailable:flags2.3?true signature_profiles:flags2.12?true id:long access_hash:flags.13?long title:string username:flags.6?string photo:ChatPhoto date:int restriction_reason:flags.9?Vector admin_rights:flags.14?ChatAdminRights banned_rights:flags.15?ChatBannedRights default_banned_rights:flags.18?ChatBannedRights participants_count:flags.17?int usernames:flags2.0?Vector stories_max_id:flags2.4?int color:flags2.7?PeerColor profile_color:flags2.8?PeerColor emoji_status:flags2.9?EmojiStatus level:flags2.10?int subscription_until_date:flags2.11?int bot_verification_icon:flags2.13?long = Chat; +channel#7482147e flags:# creator:flags.0?true left:flags.2?true broadcast:flags.5?true verified:flags.7?true megagroup:flags.8?true restricted:flags.9?true signatures:flags.11?true min:flags.12?true scam:flags.19?true has_link:flags.20?true has_geo:flags.21?true slowmode_enabled:flags.22?true call_active:flags.23?true call_not_empty:flags.24?true fake:flags.25?true gigagroup:flags.26?true noforwards:flags.27?true join_to_send:flags.28?true join_request:flags.29?true forum:flags.30?true flags2:# stories_hidden:flags2.1?true stories_hidden_min:flags2.2?true stories_unavailable:flags2.3?true signature_profiles:flags2.12?true id:long access_hash:flags.13?long title:string username:flags.6?string photo:ChatPhoto date:int restriction_reason:flags.9?Vector admin_rights:flags.14?ChatAdminRights banned_rights:flags.15?ChatBannedRights default_banned_rights:flags.18?ChatBannedRights participants_count:flags.17?int usernames:flags2.0?Vector stories_max_id:flags2.4?int color:flags2.7?PeerColor profile_color:flags2.8?PeerColor emoji_status:flags2.9?EmojiStatus level:flags2.10?int subscription_until_date:flags2.11?int bot_verification_icon:flags2.13?long send_paid_messages_stars:flags2.14?long = Chat; channelForbidden#17d493d5 flags:# broadcast:flags.5?true megagroup:flags.8?true id:long access_hash:long title:string until_date:flags.16?int = Chat; chatFull#2633421b flags:# can_set_username:flags.7?true has_scheduled:flags.8?true translations_disabled:flags.19?true id:long about:string participants:ChatParticipants chat_photo:flags.2?Photo notify_settings:PeerNotifySettings exported_invite:flags.13?ExportedChatInvite bot_info:flags.3?Vector pinned_msg_id:flags.6?int folder_id:flags.11?int call:flags.12?InputGroupCall ttl_period:flags.14?int groupcall_default_join_as:flags.15?Peer theme_emoticon:flags.16?string requests_pending:flags.17?int recent_requesters:flags.17?Vector available_reactions:flags.18?ChatReactions reactions_limit:flags.20?int = ChatFull; -channelFull#67d2e29d flags:# can_view_participants:flags.3?true can_set_username:flags.6?true can_set_stickers:flags.7?true hidden_prehistory:flags.10?true can_set_location:flags.16?true has_scheduled:flags.19?true can_view_stats:flags.20?true blocked:flags.22?true flags2:# can_delete_channel:flags2.0?true antispam:flags2.1?true participants_hidden:flags2.2?true translations_disabled:flags2.3?true stories_pinned_available:flags2.5?true view_forum_as_messages:flags2.6?true restricted_sponsored:flags2.11?true can_view_revenue:flags2.12?true paid_media_allowed:flags2.14?true can_view_stars_revenue:flags2.15?true paid_reactions_available:flags2.16?true stargifts_available:flags2.19?true id:long about:string participants_count:flags.0?int admins_count:flags.1?int kicked_count:flags.2?int banned_count:flags.2?int online_count:flags.13?int read_inbox_max_id:int read_outbox_max_id:int unread_count:int chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:flags.23?ExportedChatInvite bot_info:Vector migrated_from_chat_id:flags.4?long migrated_from_max_id:flags.4?int pinned_msg_id:flags.5?int stickerset:flags.8?StickerSet available_min_id:flags.9?int folder_id:flags.11?int linked_chat_id:flags.14?long location:flags.15?ChannelLocation slowmode_seconds:flags.17?int slowmode_next_send_date:flags.18?int stats_dc:flags.12?int pts:int call:flags.21?InputGroupCall ttl_period:flags.24?int pending_suggestions:flags.25?Vector groupcall_default_join_as:flags.26?Peer theme_emoticon:flags.27?string requests_pending:flags.28?int recent_requesters:flags.28?Vector default_send_as:flags.29?Peer available_reactions:flags.30?ChatReactions reactions_limit:flags2.13?int stories:flags2.4?PeerStories wallpaper:flags2.7?WallPaper boosts_applied:flags2.8?int boosts_unrestrict:flags2.9?int emojiset:flags2.10?StickerSet bot_verification:flags2.17?BotVerification stargifts_count:flags2.18?int send_paid_messages_stars:flags2.20?long = ChatFull; +channelFull#52d6806b flags:# can_view_participants:flags.3?true can_set_username:flags.6?true can_set_stickers:flags.7?true hidden_prehistory:flags.10?true can_set_location:flags.16?true has_scheduled:flags.19?true can_view_stats:flags.20?true blocked:flags.22?true flags2:# can_delete_channel:flags2.0?true antispam:flags2.1?true participants_hidden:flags2.2?true translations_disabled:flags2.3?true stories_pinned_available:flags2.5?true view_forum_as_messages:flags2.6?true restricted_sponsored:flags2.11?true can_view_revenue:flags2.12?true paid_media_allowed:flags2.14?true can_view_stars_revenue:flags2.15?true paid_reactions_available:flags2.16?true stargifts_available:flags2.19?true id:long about:string participants_count:flags.0?int admins_count:flags.1?int kicked_count:flags.2?int banned_count:flags.2?int online_count:flags.13?int read_inbox_max_id:int read_outbox_max_id:int unread_count:int chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:flags.23?ExportedChatInvite bot_info:Vector migrated_from_chat_id:flags.4?long migrated_from_max_id:flags.4?int pinned_msg_id:flags.5?int stickerset:flags.8?StickerSet available_min_id:flags.9?int folder_id:flags.11?int linked_chat_id:flags.14?long location:flags.15?ChannelLocation slowmode_seconds:flags.17?int slowmode_next_send_date:flags.18?int stats_dc:flags.12?int pts:int call:flags.21?InputGroupCall ttl_period:flags.24?int pending_suggestions:flags.25?Vector groupcall_default_join_as:flags.26?Peer theme_emoticon:flags.27?string requests_pending:flags.28?int recent_requesters:flags.28?Vector default_send_as:flags.29?Peer available_reactions:flags.30?ChatReactions reactions_limit:flags2.13?int stories:flags2.4?PeerStories wallpaper:flags2.7?WallPaper boosts_applied:flags2.8?int boosts_unrestrict:flags2.9?int emojiset:flags2.10?StickerSet bot_verification:flags2.17?BotVerification stargifts_count:flags2.18?int = ChatFull; chatParticipant#c02d4007 user_id:long inviter_id:long date:int = ChatParticipant; chatParticipantCreator#e46bcee4 user_id:long = ChatParticipant; @@ -1942,6 +1942,10 @@ paidReactionPrivacyPeer#dc6cfcf0 peer:InputPeer = PaidReactionPrivacy; account.paidMessagesRevenue#1e109708 stars_amount:long = account.PaidMessagesRevenue; +requirementToContactEmpty#50a9839 = RequirementToContact; +requirementToContactPremium#e581e4e9 = RequirementToContact; +requirementToContactPaidMessages#b4f67e93 stars_amount:long = RequirementToContact; + ---functions--- invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X; @@ -2099,7 +2103,7 @@ account.getPaidMessagesRevenue#f1266f38 user_id:InputUser = account.PaidMessages users.getUsers#d91a548 id:Vector = Vector; users.getFullUser#b60f5918 id:InputUser = users.UserFull; users.setSecureValueErrors#90c894b5 id:InputUser errors:Vector = Bool; -users.getIsPremiumRequiredToContact#a622aa10 id:Vector = Vector; +users.getRequirementsToContact#d89a83a3 id:Vector = Vector; contacts.getContactIDs#7adc669d hash:long = Vector; contacts.getStatuses#c4a353ee = Vector; diff --git a/Telegram/SourceFiles/window/window_peer_menu.cpp b/Telegram/SourceFiles/window/window_peer_menu.cpp index f5ea985ae..655ddc6dd 100644 --- a/Telegram/SourceFiles/window/window_peer_menu.cpp +++ b/Telegram/SourceFiles/window/window_peer_menu.cpp @@ -1201,7 +1201,8 @@ void Filler::addThemeEdit() { if (!user || user->isInaccessible()) { return; } - if (user->meRequiresPremiumToWrite() && !user->session().premium()) { + if ((user->requiresPremiumToWrite() && !user->session().premium()) + || user->starsPerMessage() > 0) { return; } const auto controller = _controller; @@ -1709,7 +1710,7 @@ void PeerMenuShareContactBox( ChooseRecipientArgs{ .session = &navigation->session(), .callback = std::move(callback), - .premiumRequiredError = WritePremiumRequiredError, + .moneyRestrictionError = WriteMoneyRestrictionError, }), [](not_null box) { box->addButton(tr::lng_cancel(), [=] { @@ -1924,7 +1925,7 @@ object_ptr PrepareChooseRecipientBox( .session = session, .callback = std::move(callback), .filter = filter, - .premiumRequiredError = WritePremiumRequiredError, + .moneyRestrictionError = WriteMoneyRestrictionError, }) , _selectable(selectable) { } @@ -2145,7 +2146,7 @@ QPointer ShowForwardMessagesBox( .callback = [=](Chosen thread) { _singleChosen.fire_copy(thread); }, - .premiumRequiredError = WritePremiumRequiredError, + .moneyRestrictionError = WriteMoneyRestrictionError, }) { } @@ -2555,7 +2556,7 @@ QPointer ShowShareGameBox( .session = &navigation->session(), .callback = std::move(chosen), .filter = std::move(filter), - .premiumRequiredError = WritePremiumRequiredError, + .moneyRestrictionError = WriteMoneyRestrictionError, }), std::move(initBox))); return weak->data();