185 lines
		
	
	
	
		
			5.1 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			185 lines
		
	
	
	
		
			5.1 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /*
 | |
| 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_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"
 | |
| #include "history/history.h"
 | |
| #include "history/history_item.h"
 | |
| #include "history/history_item_helpers.h"
 | |
| #include "main/main_account.h"
 | |
| #include "main/main_app_config.h"
 | |
| #include "main/main_session.h"
 | |
| 
 | |
| namespace Api {
 | |
| 
 | |
| Transcribes::Transcribes(not_null<ApiWrap*> api)
 | |
| : _session(&api->session())
 | |
| , _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>(
 | |
| 			u"transcribe_audio_trial_weekly_number"_q,
 | |
| 			0);
 | |
| 		const auto until = _session->account().appConfig().get<int>(
 | |
| 			u"transcribe_audio_trial_cooldown_until"_q,
 | |
| 			0);
 | |
| 		_trialsSupport = (count > 0) || (until > 0);
 | |
| 	}
 | |
| 	return *_trialsSupport;
 | |
| }
 | |
| 
 | |
| TimeId Transcribes::trialsRefreshAt() {
 | |
| 	if (_trialsRefreshAt < 0) {
 | |
| 		_trialsRefreshAt = _session->account().appConfig().get<int>(
 | |
| 			u"transcribe_audio_trial_cooldown_until"_q,
 | |
| 			0);
 | |
| 	}
 | |
| 	return _trialsRefreshAt;
 | |
| }
 | |
| 
 | |
| int Transcribes::trialsCount() {
 | |
| 	if (_trialsCount < 0) {
 | |
| 		_trialsCount = _session->account().appConfig().get<int>(
 | |
| 			u"transcribe_audio_trial_weekly_number"_q,
 | |
| 			-1);
 | |
| 		return std::max(_trialsCount, 0);
 | |
| 	}
 | |
| 	return _trialsCount;
 | |
| }
 | |
| 
 | |
| crl::time Transcribes::trialsMaxLengthMs() const {
 | |
| 	return 1000 * _session->account().appConfig().get<int>(
 | |
| 		u"transcribe_audio_trial_duration_max"_q,
 | |
| 		300);
 | |
| }
 | |
| 
 | |
| void Transcribes::toggle(not_null<HistoryItem*> item) {
 | |
| 	const auto id = item->fullId();
 | |
| 	auto i = _map.find(id);
 | |
| 	if (i == _map.end()) {
 | |
| 		load(item);
 | |
| 		//_session->data().requestItemRepaint(item);
 | |
| 		_session->data().requestItemResize(item);
 | |
| 	} else if (!i->second.requestId) {
 | |
| 		i->second.shown = !i->second.shown;
 | |
| 		if (i->second.roundview) {
 | |
| 			_session->data().requestItemViewRefresh(item);
 | |
| 		}
 | |
| 		_session->data().requestItemResize(item);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| const Transcribes::Entry &Transcribes::entry(
 | |
| 		not_null<HistoryItem*> item) const {
 | |
| 	static auto empty = Entry();
 | |
| 	const auto i = _map.find(item->fullId());
 | |
| 	return (i != _map.end()) ? i->second : empty;
 | |
| }
 | |
| 
 | |
| void Transcribes::apply(const MTPDupdateTranscribedAudio &update) {
 | |
| 	const auto id = update.vtranscription_id().v;
 | |
| 	const auto i = _ids.find(id);
 | |
| 	if (i == _ids.end()) {
 | |
| 		return;
 | |
| 	}
 | |
| 	const auto j = _map.find(i->second);
 | |
| 	if (j == _map.end()) {
 | |
| 		return;
 | |
| 	}
 | |
| 	const auto text = qs(update.vtext());
 | |
| 	j->second.result = text;
 | |
| 	j->second.pending = update.is_pending();
 | |
| 	if (const auto item = _session->data().message(i->second)) {
 | |
| 		if (j->second.roundview) {
 | |
| 			_session->data().requestItemViewRefresh(item);
 | |
| 		}
 | |
| 		_session->data().requestItemResize(item);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| void Transcribes::load(not_null<HistoryItem*> item) {
 | |
| 	if (!item->isHistoryEntry() || item->isLocal()) {
 | |
| 		return;
 | |
| 	}
 | |
| 	const auto toggleRound = [](not_null<HistoryItem*> item, Entry &entry) {
 | |
| 		if (const auto media = item->media()) {
 | |
| 			if (const auto document = media->document()) {
 | |
| 				if (document->isVideoMessage()) {
 | |
| 					entry.roundview = true;
 | |
| 					document->owner().requestItemViewRefresh(item);
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 	};
 | |
| 	const auto id = item->fullId();
 | |
| 	const auto requestId = _api.request(MTPmessages_TranscribeAudio(
 | |
| 		item->history()->peer->input,
 | |
| 		MTP_int(item->id)
 | |
| 	)).done([=](const MTPmessages_TranscribedAudio &result) {
 | |
| 		const auto &data = result.data();
 | |
| 
 | |
| 		{
 | |
| 			const auto trialsCountChanged = data.vtrial_remains_num()
 | |
| 				&& (_trialsCount != data.vtrial_remains_num()->v);
 | |
| 			if (trialsCountChanged) {
 | |
| 				_trialsCount = data.vtrial_remains_num()->v;
 | |
| 			}
 | |
| 			const auto refreshAtChanged = data.vtrial_remains_until_date()
 | |
| 				&& (_trialsRefreshAt != data.vtrial_remains_until_date()->v);
 | |
| 			if (refreshAtChanged) {
 | |
| 				_trialsRefreshAt = data.vtrial_remains_until_date()->v;
 | |
| 			}
 | |
| 			if (trialsCountChanged) {
 | |
| 				ShowTrialTranscribesToast(_trialsCount, _trialsRefreshAt);
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		auto &entry = _map[id];
 | |
| 		entry.requestId = 0;
 | |
| 		entry.pending = data.is_pending();
 | |
| 		entry.result = qs(data.vtext());
 | |
| 		_ids.emplace(data.vtranscription_id().v, id);
 | |
| 		if (const auto item = _session->data().message(id)) {
 | |
| 			toggleRound(item, entry);
 | |
| 			_session->data().requestItemResize(item);
 | |
| 		}
 | |
| 	}).fail([=](const MTP::Error &error) {
 | |
| 		auto &entry = _map[id];
 | |
| 		entry.requestId = 0;
 | |
| 		entry.pending = false;
 | |
| 		entry.failed = true;
 | |
| 		if (error.type() == u"MSG_VOICE_TOO_LONG"_q) {
 | |
| 			entry.toolong = true;
 | |
| 		}
 | |
| 		if (const auto item = _session->data().message(id)) {
 | |
| 			toggleRound(item, entry);
 | |
| 			_session->data().requestItemResize(item);
 | |
| 		}
 | |
| 	}).send();
 | |
| 	auto &entry = _map.emplace(id).first->second;
 | |
| 	entry.requestId = requestId;
 | |
| 	entry.shown = true;
 | |
| 	entry.failed = false;
 | |
| 	entry.pending = false;
 | |
| }
 | |
| 
 | |
| } // namespace Api
 | 
