"Fossies" - the Fresh Open Source Software Archive

Member "tdesktop-4.8.3/Telegram/SourceFiles/api/api_editing.cpp" (1 Jun 2023, 6319 Bytes) of package /linux/misc/tdesktop-4.8.3.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "api_editing.cpp" see the Fossies "Dox" file reference documentation.

    1 /*
    2 This file is part of Telegram Desktop,
    3 the official desktop application for the Telegram messaging service.
    4 
    5 For license and copyright information please follow this link:
    6 https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
    7 */
    8 #include "api/api_editing.h"
    9 
   10 #include "apiwrap.h"
   11 #include "api/api_media.h"
   12 #include "api/api_text_entities.h"
   13 #include "ui/boxes/confirm_box.h"
   14 #include "data/data_scheduled_messages.h"
   15 #include "data/data_session.h"
   16 #include "history/history.h"
   17 #include "history/history_item.h"
   18 #include "lang/lang_keys.h"
   19 #include "main/main_session.h"
   20 #include "mtproto/mtproto_response.h"
   21 #include "boxes/abstract_box.h" // Ui::show().
   22 
   23 namespace Api {
   24 namespace {
   25 
   26 using namespace rpl::details;
   27 
   28 template <typename T>
   29 constexpr auto WithId =
   30     is_callable_plain_v<T, Fn<void()>, mtpRequestId>;
   31 template <typename T>
   32 constexpr auto WithoutId =
   33     is_callable_plain_v<T, Fn<void()>>;
   34 template <typename T>
   35 constexpr auto WithoutCallback =
   36     is_callable_plain_v<T>;
   37 template <typename T>
   38 constexpr auto ErrorWithId =
   39     is_callable_plain_v<T, QString, mtpRequestId>;
   40 template <typename T>
   41 constexpr auto ErrorWithoutId =
   42     is_callable_plain_v<T, QString>;
   43 
   44 template <typename DoneCallback, typename FailCallback>
   45 mtpRequestId EditMessage(
   46         not_null<HistoryItem*> item,
   47         const TextWithEntities &textWithEntities,
   48         SendOptions options,
   49         DoneCallback &&done,
   50         FailCallback &&fail,
   51         std::optional<MTPInputMedia> inputMedia = std::nullopt) {
   52     const auto session = &item->history()->session();
   53     const auto api = &session->api();
   54 
   55     const auto text = textWithEntities.text;
   56     const auto sentEntities = EntitiesToMTP(
   57         session,
   58         textWithEntities.entities,
   59         ConvertOption::SkipLocal);
   60     const auto media = item->media();
   61 
   62     const auto updateRecentStickers = inputMedia.has_value()
   63         ? Api::HasAttachedStickers(*inputMedia)
   64         : false;
   65 
   66     const auto emptyFlag = MTPmessages_EditMessage::Flag(0);
   67     const auto flags = emptyFlag
   68     | (!text.isEmpty() || media
   69         ? MTPmessages_EditMessage::Flag::f_message
   70         : emptyFlag)
   71     | ((media && inputMedia.has_value())
   72         ? MTPmessages_EditMessage::Flag::f_media
   73         : emptyFlag)
   74     | (options.removeWebPageId
   75         ? MTPmessages_EditMessage::Flag::f_no_webpage
   76         : emptyFlag)
   77     | (!sentEntities.v.isEmpty()
   78         ? MTPmessages_EditMessage::Flag::f_entities
   79         : emptyFlag)
   80     | (options.scheduled
   81         ? MTPmessages_EditMessage::Flag::f_schedule_date
   82         : emptyFlag);
   83 
   84     const auto id = item->isScheduled()
   85         ? session->data().scheduledMessages().lookupId(item)
   86         : item->id;
   87     return api->request(MTPmessages_EditMessage(
   88         MTP_flags(flags),
   89         item->history()->peer->input,
   90         MTP_int(id),
   91         MTP_string(text),
   92         inputMedia.value_or(MTPInputMedia()),
   93         MTPReplyMarkup(),
   94         sentEntities,
   95         MTP_int(options.scheduled)
   96     )).done([=](
   97             const MTPUpdates &result,
   98             [[maybe_unused]] mtpRequestId requestId) {
   99         const auto apply = [=] { api->applyUpdates(result); };
  100 
  101         if constexpr (WithId<DoneCallback>) {
  102             done(apply, requestId);
  103         } else if constexpr (WithoutId<DoneCallback>) {
  104             done(apply);
  105         } else if constexpr (WithoutCallback<DoneCallback>) {
  106             done();
  107             apply();
  108         } else {
  109             t_bad_callback(done);
  110         }
  111 
  112         if (updateRecentStickers) {
  113             api->requestRecentStickersForce(true);
  114         }
  115     }).fail([=](const MTP::Error &error, mtpRequestId requestId) {
  116         if constexpr (ErrorWithId<FailCallback>) {
  117             fail(error.type(), requestId);
  118         } else if constexpr (ErrorWithoutId<FailCallback>) {
  119             fail(error.type());
  120         } else if constexpr (WithoutCallback<FailCallback>) {
  121             fail();
  122         } else {
  123             t_bad_callback(fail);
  124         }
  125     }).send();
  126 }
  127 
  128 template <typename DoneCallback, typename FailCallback>
  129 mtpRequestId EditMessage(
  130         not_null<HistoryItem*> item,
  131         SendOptions options,
  132         DoneCallback &&done,
  133         FailCallback &&fail,
  134         std::optional<MTPInputMedia> inputMedia = std::nullopt) {
  135     const auto &text = item->originalText();
  136     return EditMessage(
  137         item,
  138         text,
  139         options,
  140         std::forward<DoneCallback>(done),
  141         std::forward<FailCallback>(fail),
  142         inputMedia);
  143 }
  144 
  145 void EditMessageWithUploadedMedia(
  146         not_null<HistoryItem*> item,
  147         SendOptions options,
  148         MTPInputMedia media) {
  149     const auto done = [=](Fn<void()> applyUpdates) {
  150         if (item) {
  151             item->removeFromSharedMediaIndex();
  152             item->clearSavedMedia();
  153             item->setIsLocalUpdateMedia(true);
  154             applyUpdates();
  155             item->setIsLocalUpdateMedia(false);
  156         }
  157     };
  158     const auto fail = [=](const QString &error) {
  159         const auto session = &item->history()->session();
  160         const auto notModified = (error == u"MESSAGE_NOT_MODIFIED"_q);
  161         const auto mediaInvalid = (error == u"MEDIA_NEW_INVALID"_q);
  162         if (notModified || mediaInvalid) {
  163             item->returnSavedMedia();
  164             session->data().sendHistoryChangeNotifications();
  165             if (mediaInvalid) {
  166                 Ui::show(
  167                     Ui::MakeInformBox(tr::lng_edit_media_invalid_file()),
  168                     Ui::LayerOption::KeepOther);
  169             }
  170         } else {
  171             session->api().sendMessageFail(error, item->history()->peer);
  172         }
  173     };
  174 
  175     EditMessage(item, options, done, fail, media);
  176 }
  177 
  178 } // namespace
  179 
  180 void RescheduleMessage(
  181         not_null<HistoryItem*> item,
  182         SendOptions options) {
  183     const auto empty = [] {};
  184     EditMessage(item, options, empty, empty);
  185 }
  186 
  187 void EditMessageWithUploadedDocument(
  188         HistoryItem *item,
  189         RemoteFileInfo info,
  190         SendOptions options) {
  191     if (!item || !item->media() || !item->media()->document()) {
  192         return;
  193     }
  194     EditMessageWithUploadedMedia(
  195         item,
  196         options,
  197         PrepareUploadedDocument(item, std::move(info)));
  198 }
  199 
  200 void EditMessageWithUploadedPhoto(
  201         HistoryItem *item,
  202         RemoteFileInfo info,
  203         SendOptions options) {
  204     if (!item || !item->media() || !item->media()->photo()) {
  205         return;
  206     }
  207     EditMessageWithUploadedMedia(
  208         item,
  209         options,
  210         PrepareUploadedPhoto(item, std::move(info)));
  211 }
  212 
  213 mtpRequestId EditCaption(
  214         not_null<HistoryItem*> item,
  215         const TextWithEntities &caption,
  216         SendOptions options,
  217         Fn<void()> done,
  218         Fn<void(const QString &)> fail) {
  219     return EditMessage(item, caption, options, done, fail);
  220 }
  221 
  222 mtpRequestId EditTextMessage(
  223         not_null<HistoryItem*> item,
  224         const TextWithEntities &caption,
  225         SendOptions options,
  226         Fn<void(mtpRequestId requestId)> done,
  227         Fn<void(const QString &, mtpRequestId requestId)> fail) {
  228     const auto callback = [=](Fn<void()> applyUpdates, mtpRequestId id) {
  229         applyUpdates();
  230         done(id);
  231     };
  232     return EditMessage(item, caption, options, callback, fail);
  233 }
  234 
  235 } // namespace Api