Support free transcribes in groups.

This commit is contained in:
John Preston 2024-02-09 18:09:48 +04:00
parent cfaef4c441
commit fc6f2520b7
8 changed files with 41 additions and 22 deletions

View File

@ -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<ApiWrap*> api)
, _api(&api->instance()) {
}
bool Transcribes::freeFor(not_null<HistoryItem*> 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<int>(

View File

@ -36,6 +36,8 @@ public:
void apply(const MTPDupdateTranscribedAudio &update);
[[nodiscard]] bool freeFor(not_null<HistoryItem*> item) const;
[[nodiscard]] bool trialsSupport();
[[nodiscard]] TimeId trialsRefreshAt();
[[nodiscard]] int trialsCount();

View File

@ -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()));

View File

@ -649,7 +649,7 @@ bool ChannelData::canEditStickers() const {
}
bool ChannelData::canEditEmoji() const {
return amCreator(); AssertIsDebug();
return amCreator() || (adminRights() & ChatAdminRight::ChangeInfo);
}
bool ChannelData::canDelete() const {

View File

@ -238,6 +238,12 @@ Session::Session(not_null<Main::Session*> session)
, _bigFileCache(Core::App().databases().get(
_session->local().cacheBigFilePath(),
_session->local().cacheBigFileSettings()))
, _groupFreeTranscribeLevel(session->account().appConfig().value(
) | rpl::map([=] {
return session->account().appConfig().get<int>(
u"group_transcribe_level_min"_q,
6);
}))
, _chatsList(
session,
FilterId(),
@ -2178,8 +2184,7 @@ rpl::producer<int> 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<int> 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<int> Session::maxPinnedChatsLimitValue(
rpl::producer<int> Session::maxPinnedChatsLimitValue(
not_null<Data::Forum*> 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<int> 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<Dialogs::Key> &Session::pinnedChatsOrder(
Data::Folder *folder) const {
return chatsList(folder)->pinned()->order();

View File

@ -367,6 +367,7 @@ public:
not_null<Forum*> forum) const;
[[nodiscard]] rpl::producer<int> maxPinnedChatsLimitValue(
not_null<SavedMessages*> saved) const;
[[nodiscard]] int groupFreeTranscribeLevel() const;
[[nodiscard]] const std::vector<Dialogs::Key> &pinnedChatsOrder(
Folder *folder) const;
[[nodiscard]] const std::vector<Dialogs::Key> &pinnedChatsOrder(
@ -887,6 +888,7 @@ private:
QPointer<Ui::BoxContent> _exportSuggestion;
rpl::variable<bool> _contactsLoaded = false;
rpl::variable<int> _groupFreeTranscribeLevel;
rpl::event_stream<Folder*> _chatsListLoadedEvents;
rpl::event_stream<Folder*> _chatsListChanged;
rpl::event_stream<not_null<UserData*>> _userIsBotChanges;

View File

@ -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;
}

View File

@ -439,10 +439,13 @@ QSize Document::countOptimalSize() {
auto hasTranscribe = false;
const auto voice = Get<HistoryDocumentVoice>();
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),