diff --git a/Telegram/SourceFiles/api/api_transcribes.cpp b/Telegram/SourceFiles/api/api_transcribes.cpp index ac792883b4..d7064abcdf 100644 --- a/Telegram/SourceFiles/api/api_transcribes.cpp +++ b/Telegram/SourceFiles/api/api_transcribes.cpp @@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "api/api_transcribes.h" #include "apiwrap.h" +#include "data/data_channel.h" #include "data/data_document.h" #include "data/data_peer.h" #include "data/data_session.h" @@ -25,6 +26,14 @@ Transcribes::Transcribes(not_null api) , _api(&api->instance()) { } +bool Transcribes::freeFor(not_null item) const { + if (const auto channel = item->history()->peer->asMegagroup()) { + const auto owner = &channel->owner(); + return channel->levelHint() >= owner->groupFreeTranscribeLevel(); + } + return false; +} + bool Transcribes::trialsSupport() { if (!_trialsSupport) { const auto count = _session->account().appConfig().get( diff --git a/Telegram/SourceFiles/api/api_transcribes.h b/Telegram/SourceFiles/api/api_transcribes.h index a5c5923ec0..b074e42f13 100644 --- a/Telegram/SourceFiles/api/api_transcribes.h +++ b/Telegram/SourceFiles/api/api_transcribes.h @@ -36,6 +36,8 @@ public: void apply(const MTPDupdateTranscribedAudio &update); + [[nodiscard]] bool freeFor(not_null item) const; + [[nodiscard]] bool trialsSupport(); [[nodiscard]] TimeId trialsRefreshAt(); [[nodiscard]] int trialsCount(); diff --git a/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp b/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp index 7b9abb4c10..01bbb02f2f 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp +++ b/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp @@ -1094,9 +1094,7 @@ void Controller::fillManageSection() { && (channel->hasAdminRights() || channel->amCreator()); const auto canEditStickers = isChannel && channel->canEditStickers(); const auto canDeleteChannel = isChannel && channel->canDelete(); - const auto canEditColorIndex = isChannel - && (channel->amCreator() - || (channel->adminRights() & ChatAdminRight::ChangeInfo)); + const auto canEditColorIndex = isChannel && channel->canEditEmoji(); const auto canViewOrEditLinkedChat = isChannel && (channel->linkedChat() || (channel->isBroadcast() && channel->canEditInformation())); diff --git a/Telegram/SourceFiles/data/data_channel.cpp b/Telegram/SourceFiles/data/data_channel.cpp index 0c73b00b61..87d2a53018 100644 --- a/Telegram/SourceFiles/data/data_channel.cpp +++ b/Telegram/SourceFiles/data/data_channel.cpp @@ -649,7 +649,7 @@ bool ChannelData::canEditStickers() const { } bool ChannelData::canEditEmoji() const { - return amCreator(); AssertIsDebug(); + return amCreator() || (adminRights() & ChatAdminRight::ChangeInfo); } bool ChannelData::canDelete() const { diff --git a/Telegram/SourceFiles/data/data_session.cpp b/Telegram/SourceFiles/data/data_session.cpp index f647177943..c8235eac4a 100644 --- a/Telegram/SourceFiles/data/data_session.cpp +++ b/Telegram/SourceFiles/data/data_session.cpp @@ -238,6 +238,12 @@ Session::Session(not_null session) , _bigFileCache(Core::App().databases().get( _session->local().cacheBigFilePath(), _session->local().cacheBigFileSettings())) +, _groupFreeTranscribeLevel(session->account().appConfig().value( +) | rpl::map([=] { + return session->account().appConfig().get( + u"group_transcribe_level_min"_q, + 6); +})) , _chatsList( session, FilterId(), @@ -2178,8 +2184,7 @@ rpl::producer Session::maxPinnedChatsLimitValue( // We always use premium limit in the MainList limit producer, // because it slices the list to that limit. We don't want to slice // premium-ly added chats from the pinned list because of sync issues. - return rpl::single(rpl::empty_value()) | rpl::then( - _session->account().appConfig().refreshed() + return _session->account().appConfig().value( ) | rpl::map([=] { const auto limits = Data::PremiumLimits(_session); return folder @@ -2194,8 +2199,7 @@ rpl::producer Session::maxPinnedChatsLimitValue( // We always use premium limit in the MainList limit producer, // because it slices the list to that limit. We don't want to slice // premium-ly added chats from the pinned list because of sync issues. - return rpl::single(rpl::empty_value()) | rpl::then( - _session->account().appConfig().refreshed() + return _session->account().appConfig().value( ) | rpl::map([=] { const auto limits = Data::PremiumLimits(_session); return limits.dialogFiltersChatsPremium(); @@ -2204,8 +2208,7 @@ rpl::producer Session::maxPinnedChatsLimitValue( rpl::producer Session::maxPinnedChatsLimitValue( not_null forum) const { - return rpl::single(rpl::empty_value()) | rpl::then( - _session->account().appConfig().refreshed() + return _session->account().appConfig().value( ) | rpl::map([=] { const auto limits = Data::PremiumLimits(_session); return limits.topicsPinnedCurrent(); @@ -2218,14 +2221,17 @@ rpl::producer Session::maxPinnedChatsLimitValue( // We always use premium limit in the MainList limit producer, // because it slices the list to that limit. We don't want to slice // premium-ly added chats from the pinned list because of sync issues. - return rpl::single(rpl::empty_value()) | rpl::then( - _session->account().appConfig().refreshed() + return _session->account().appConfig().value( ) | rpl::map([=] { const auto limits = Data::PremiumLimits(_session); return limits.savedSublistsPinnedPremium(); }); } +int Session::groupFreeTranscribeLevel() const { + return _groupFreeTranscribeLevel.current(); +} + const std::vector &Session::pinnedChatsOrder( Data::Folder *folder) const { return chatsList(folder)->pinned()->order(); diff --git a/Telegram/SourceFiles/data/data_session.h b/Telegram/SourceFiles/data/data_session.h index 0a779a4b87..d391d1d318 100644 --- a/Telegram/SourceFiles/data/data_session.h +++ b/Telegram/SourceFiles/data/data_session.h @@ -367,6 +367,7 @@ public: not_null forum) const; [[nodiscard]] rpl::producer maxPinnedChatsLimitValue( not_null saved) const; + [[nodiscard]] int groupFreeTranscribeLevel() const; [[nodiscard]] const std::vector &pinnedChatsOrder( Folder *folder) const; [[nodiscard]] const std::vector &pinnedChatsOrder( @@ -887,6 +888,7 @@ private: QPointer _exportSuggestion; rpl::variable _contactsLoaded = false; + rpl::variable _groupFreeTranscribeLevel; rpl::event_stream _chatsListLoadedEvents; rpl::event_stream _chatsListChanged; rpl::event_stream> _userIsBotChanges; diff --git a/Telegram/SourceFiles/history/view/history_view_transcribe_button.cpp b/Telegram/SourceFiles/history/view/history_view_transcribe_button.cpp index 523cd5ce1f..dccca0f3a7 100644 --- a/Telegram/SourceFiles/history/view/history_view_transcribe_button.cpp +++ b/Telegram/SourceFiles/history/view/history_view_transcribe_button.cpp @@ -221,14 +221,14 @@ void TranscribeButton::paint( } bool TranscribeButton::hasLock() const { - if (_item->history()->session().premium()) { + const auto session = &_item->history()->session(); + const auto transcribes = &session->api().transcribes(); + if (session->premium() + || transcribes->freeFor(_item) + || transcribes->trialsCount()) { return false; } - if (_item->history()->session().api().transcribes().trialsCount()) { - return false; - } - const auto until = _item->history()->session().api().transcribes() - .trialsRefreshAt(); + const auto until = transcribes->trialsRefreshAt(); if (!until || base::unixtime::now() >= until) { return false; } diff --git a/Telegram/SourceFiles/history/view/media/history_view_document.cpp b/Telegram/SourceFiles/history/view/media/history_view_document.cpp index b155b1d291..d884580d57 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_document.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_document.cpp @@ -439,10 +439,13 @@ QSize Document::countOptimalSize() { auto hasTranscribe = false; const auto voice = Get(); if (voice) { - const auto session = &_realParent->history()->session(); + const auto history = _realParent->history(); + const auto session = &history->session(); + const auto transcribes = &session->api().transcribes(); if (_parent->data()->media()->ttlSeconds() || (!session->premium() - && !session->api().transcribes().trialsSupport())) { + && !transcribes->freeFor(_realParent) + && !transcribes->trialsSupport())) { voice->transcribe = nullptr; voice->transcribeText = {}; } else { @@ -452,8 +455,7 @@ QSize Document::countOptimalSize() { _realParent, false); } - const auto &entry = session->api().transcribes().entry( - _realParent); + const auto &entry = transcribes->entry(_realParent); const auto update = [=] { repaint(); }; voice->transcribe->setLoading( entry.shown && (entry.requestId || entry.pending),