api_transcribes.cpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. /*
  2. This file is part of Telegram Desktop,
  3. the official desktop application for the Telegram messaging service.
  4. For license and copyright information please follow this link:
  5. https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
  6. */
  7. #include "api/api_transcribes.h"
  8. #include "apiwrap.h"
  9. #include "data/data_channel.h"
  10. #include "data/data_document.h"
  11. #include "data/data_peer.h"
  12. #include "data/data_session.h"
  13. #include "history/history.h"
  14. #include "history/history_item.h"
  15. #include "history/history_item_helpers.h"
  16. #include "main/main_app_config.h"
  17. #include "main/main_session.h"
  18. namespace Api {
  19. Transcribes::Transcribes(not_null<ApiWrap*> api)
  20. : _session(&api->session())
  21. , _api(&api->instance()) {
  22. }
  23. bool Transcribes::freeFor(not_null<HistoryItem*> item) const {
  24. if (const auto channel = item->history()->peer->asMegagroup()) {
  25. const auto owner = &channel->owner();
  26. return channel->levelHint() >= owner->groupFreeTranscribeLevel();
  27. }
  28. return false;
  29. }
  30. bool Transcribes::trialsSupport() {
  31. if (!_trialsSupport) {
  32. const auto count = _session->appConfig().get<int>(
  33. u"transcribe_audio_trial_weekly_number"_q,
  34. 0);
  35. const auto until = _session->appConfig().get<int>(
  36. u"transcribe_audio_trial_cooldown_until"_q,
  37. 0);
  38. _trialsSupport = (count > 0) || (until > 0);
  39. }
  40. return *_trialsSupport;
  41. }
  42. TimeId Transcribes::trialsRefreshAt() {
  43. if (_trialsRefreshAt < 0) {
  44. _trialsRefreshAt = _session->appConfig().get<int>(
  45. u"transcribe_audio_trial_cooldown_until"_q,
  46. 0);
  47. }
  48. return _trialsRefreshAt;
  49. }
  50. int Transcribes::trialsCount() {
  51. if (_trialsCount < 0) {
  52. _trialsCount = _session->appConfig().get<int>(
  53. u"transcribe_audio_trial_weekly_number"_q,
  54. -1);
  55. return std::max(_trialsCount, 0);
  56. }
  57. return _trialsCount;
  58. }
  59. crl::time Transcribes::trialsMaxLengthMs() const {
  60. return 1000 * _session->appConfig().get<int>(
  61. u"transcribe_audio_trial_duration_max"_q,
  62. 300);
  63. }
  64. void Transcribes::toggle(not_null<HistoryItem*> item) {
  65. const auto id = item->fullId();
  66. auto i = _map.find(id);
  67. if (i == _map.end()) {
  68. load(item);
  69. //_session->data().requestItemRepaint(item);
  70. _session->data().requestItemResize(item);
  71. } else if (!i->second.requestId) {
  72. i->second.shown = !i->second.shown;
  73. if (i->second.roundview) {
  74. _session->data().requestItemViewRefresh(item);
  75. }
  76. _session->data().requestItemResize(item);
  77. }
  78. }
  79. const Transcribes::Entry &Transcribes::entry(
  80. not_null<HistoryItem*> item) const {
  81. static auto empty = Entry();
  82. const auto i = _map.find(item->fullId());
  83. return (i != _map.end()) ? i->second : empty;
  84. }
  85. void Transcribes::apply(const MTPDupdateTranscribedAudio &update) {
  86. const auto id = update.vtranscription_id().v;
  87. const auto i = _ids.find(id);
  88. if (i == _ids.end()) {
  89. return;
  90. }
  91. const auto j = _map.find(i->second);
  92. if (j == _map.end()) {
  93. return;
  94. }
  95. const auto text = qs(update.vtext());
  96. j->second.result = text;
  97. j->second.pending = update.is_pending();
  98. if (const auto item = _session->data().message(i->second)) {
  99. if (j->second.roundview) {
  100. _session->data().requestItemViewRefresh(item);
  101. }
  102. _session->data().requestItemResize(item);
  103. }
  104. }
  105. void Transcribes::load(not_null<HistoryItem*> item) {
  106. if (!item->isHistoryEntry() || item->isLocal()) {
  107. return;
  108. }
  109. const auto toggleRound = [](not_null<HistoryItem*> item, Entry &entry) {
  110. if (const auto media = item->media()) {
  111. if (const auto document = media->document()) {
  112. if (document->isVideoMessage()) {
  113. entry.roundview = true;
  114. document->owner().requestItemViewRefresh(item);
  115. }
  116. }
  117. }
  118. };
  119. const auto id = item->fullId();
  120. const auto requestId = _api.request(MTPmessages_TranscribeAudio(
  121. item->history()->peer->input,
  122. MTP_int(item->id)
  123. )).done([=](const MTPmessages_TranscribedAudio &result) {
  124. const auto &data = result.data();
  125. {
  126. const auto trialsCountChanged = data.vtrial_remains_num()
  127. && (_trialsCount != data.vtrial_remains_num()->v);
  128. if (trialsCountChanged) {
  129. _trialsCount = data.vtrial_remains_num()->v;
  130. }
  131. const auto refreshAtChanged = data.vtrial_remains_until_date()
  132. && (_trialsRefreshAt != data.vtrial_remains_until_date()->v);
  133. if (refreshAtChanged) {
  134. _trialsRefreshAt = data.vtrial_remains_until_date()->v;
  135. }
  136. if (trialsCountChanged) {
  137. ShowTrialTranscribesToast(_trialsCount, _trialsRefreshAt);
  138. }
  139. }
  140. auto &entry = _map[id];
  141. entry.requestId = 0;
  142. entry.pending = data.is_pending();
  143. entry.result = qs(data.vtext());
  144. _ids.emplace(data.vtranscription_id().v, id);
  145. if (const auto item = _session->data().message(id)) {
  146. toggleRound(item, entry);
  147. _session->data().requestItemResize(item);
  148. }
  149. }).fail([=](const MTP::Error &error) {
  150. auto &entry = _map[id];
  151. entry.requestId = 0;
  152. entry.pending = false;
  153. entry.failed = true;
  154. if (error.type() == u"MSG_VOICE_TOO_LONG"_q) {
  155. entry.toolong = true;
  156. }
  157. if (const auto item = _session->data().message(id)) {
  158. toggleRound(item, entry);
  159. _session->data().requestItemResize(item);
  160. }
  161. }).send();
  162. auto &entry = _map.emplace(id).first->second;
  163. entry.requestId = requestId;
  164. entry.shown = true;
  165. entry.failed = false;
  166. entry.pending = false;
  167. }
  168. } // namespace Api