diff --git a/Telegram/SourceFiles/data/data_scheduled_messages.cpp b/Telegram/SourceFiles/data/data_scheduled_messages.cpp index 7ec49c9e2..81fbf669a 100644 --- a/Telegram/SourceFiles/data/data_scheduled_messages.cpp +++ b/Telegram/SourceFiles/data/data_scheduled_messages.cpp @@ -527,4 +527,19 @@ int32 ScheduledMessages::countListHash(const List &list) const { return HashFinalize(hash); } +HistoryItem *ScheduledMessages::lastSentMessage(not_null history) { + const auto i = _data.find(history); + if (i == end(_data)) { + return nullptr; + } + auto &list = i->second; + + sort(list); + const auto items = ranges::view::reverse(list.items); + const auto it = ranges::find_if( + items, + &HistoryItem::canBeEditedFromHistory); + return (it == end(items)) ? nullptr : (*it).get(); +} + } // namespace Data diff --git a/Telegram/SourceFiles/data/data_scheduled_messages.h b/Telegram/SourceFiles/data/data_scheduled_messages.h index b6656f23f..3391cd382 100644 --- a/Telegram/SourceFiles/data/data_scheduled_messages.h +++ b/Telegram/SourceFiles/data/data_scheduled_messages.h @@ -32,6 +32,7 @@ public: [[nodiscard]] HistoryItem *lookupItem(PeerId peer, MsgId msg) const; [[nodiscard]] HistoryItem *lookupItem(FullMsgId itemId) const; [[nodiscard]] int count(not_null history) const; + [[nodiscard]] HistoryItem *lastSentMessage(not_null history); void checkEntitiesAndUpdate(const MTPDmessage &data); void apply(const MTPDupdateNewScheduledMessage &update); diff --git a/Telegram/SourceFiles/history/history.cpp b/Telegram/SourceFiles/history/history.cpp index ace095dba..d90e6b643 100644 --- a/Telegram/SourceFiles/history/history.cpp +++ b/Telegram/SourceFiles/history/history.cpp @@ -2895,20 +2895,7 @@ HistoryItem *History::lastSentMessage() const { for (const auto &block : ranges::view::reverse(blocks)) { for (const auto &message : ranges::view::reverse(block->messages)) { const auto item = message->data(); - // Skip if message is editing media. - if (item->isEditingMedia()) { - continue; - } - // Skip if message is video message or sticker. - if (const auto media = item->media()) { - // Skip only if media is not webpage. - if (!media->webpage() && !media->allowsEditCaption()) { - continue; - } - } - if (IsServerMsgId(item->id) - && !item->serviceMsg() - && (item->out() || peer->isSelf())) { + if (item->canBeEditedFromHistory()) { return item; } } diff --git a/Telegram/SourceFiles/history/history_item.cpp b/Telegram/SourceFiles/history/history_item.cpp index 5cac457a0..f4a99f29a 100644 --- a/Telegram/SourceFiles/history/history_item.cpp +++ b/Telegram/SourceFiles/history/history_item.cpp @@ -721,6 +721,26 @@ bool HistoryItem::canUpdateDate() const { return isScheduled(); } +bool HistoryItem::canBeEditedFromHistory() const { + // Skip if message is editing media. + if (isEditingMedia()) { + return false; + } + // Skip if message is video message or sticker. + if (const auto m = media()) { + // Skip only if media is not webpage. + if (!m->webpage() && !m->allowsEditCaption()) { + return false; + } + } + if ((IsServerMsgId(id) || isScheduled()) + && !serviceMsg() + && (out() || history()->peer->isSelf())) { + return true; + } + return false; +} + void HistoryItem::sendFailed() { Expects(_clientFlags & MTPDmessage_ClientFlag::f_sending); Expects(!(_clientFlags & MTPDmessage_ClientFlag::f_failed)); diff --git a/Telegram/SourceFiles/history/history_item.h b/Telegram/SourceFiles/history/history_item.h index 64ef662fc..7b29ce7fe 100644 --- a/Telegram/SourceFiles/history/history_item.h +++ b/Telegram/SourceFiles/history/history_item.h @@ -335,6 +335,8 @@ public: void updateDate(TimeId newDate); [[nodiscard]] bool canUpdateDate() const; + [[nodiscard]] bool canBeEditedFromHistory() const; + virtual ~HistoryItem(); MsgId id; diff --git a/Telegram/SourceFiles/history/view/history_view_compose_controls.cpp b/Telegram/SourceFiles/history/view/history_view_compose_controls.cpp index c1a59b249..4da762360 100644 --- a/Telegram/SourceFiles/history/view/history_view_compose_controls.cpp +++ b/Telegram/SourceFiles/history/view/history_view_compose_controls.cpp @@ -460,6 +460,15 @@ rpl::producer<> ComposeControls::cancelRequests() const { return _cancelRequests.events(); } +rpl::producer> ComposeControls::keyEvents() const { + return _wrap->events( + ) | rpl::map([=](not_null e) -> not_null { + return static_cast(e.get()); + }) | rpl::filter([=](not_null event) { + return (event->type() == QEvent::KeyPress); + }); +} + rpl::producer<> ComposeControls::sendRequests() const { auto filter = rpl::filter([=] { return _send->type() == Ui::SendButton::Type::Schedule; @@ -1027,4 +1036,8 @@ rpl::producer ComposeControls::scrollRequests() const { }); } +bool ComposeControls::isEditingMessage() const { + return _header->isEditingMessage(); +} + } // namespace HistoryView diff --git a/Telegram/SourceFiles/history/view/history_view_compose_controls.h b/Telegram/SourceFiles/history/view/history_view_compose_controls.h index f4533c831..32b8fd80d 100644 --- a/Telegram/SourceFiles/history/view/history_view_compose_controls.h +++ b/Telegram/SourceFiles/history/view/history_view_compose_controls.h @@ -88,6 +88,7 @@ public: [[nodiscard]] rpl::producer> fileChosen() const; [[nodiscard]] rpl::producer> photoChosen() const; [[nodiscard]] rpl::producer scrollRequests() const; + [[nodiscard]] rpl::producer> keyEvents() const; [[nodiscard]] auto inlineResultChosen() const -> rpl::producer; @@ -101,6 +102,8 @@ public: const Window::SectionShow ¶ms); bool returnTabbedSelector(); + bool isEditingMessage() const; + void showForGrab(); void showStarted(); void showFinished(); diff --git a/Telegram/SourceFiles/history/view/history_view_context_menu.cpp b/Telegram/SourceFiles/history/view/history_view_context_menu.cpp index 81b4388bf..ac99088a4 100644 --- a/Telegram/SourceFiles/history/view/history_view_context_menu.cpp +++ b/Telegram/SourceFiles/history/view/history_view_context_menu.cpp @@ -24,7 +24,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/ui_utility.h" #include "chat_helpers/message_field.h" #include "boxes/confirm_box.h" -#include "boxes/edit_caption_box.h" #include "boxes/sticker_set_box.h" #include "data/data_photo.h" #include "data/data_photo_media.h" @@ -477,16 +476,7 @@ bool AddEditMessageAction( if (!item) { return; } - const auto media = item->media(); - if (media && !media->webpage()) { - if (media->allowsEditCaption()) { - Ui::show(Box( - App::wnd()->sessionController(), - item)); - } - } else { - list->editMessageRequestNotify(item->fullId()); - } + list->editMessageRequestNotify(item->fullId()); }); return true; } diff --git a/Telegram/SourceFiles/history/view/history_view_scheduled_section.cpp b/Telegram/SourceFiles/history/view/history_view_scheduled_section.cpp index e1acf6404..60c60f434 100644 --- a/Telegram/SourceFiles/history/view/history_view_scheduled_section.cpp +++ b/Telegram/SourceFiles/history/view/history_view_scheduled_section.cpp @@ -26,6 +26,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "api/api_sending.h" #include "apiwrap.h" #include "boxes/confirm_box.h" +#include "boxes/edit_caption_box.h" #include "boxes/send_files_box.h" #include "window/window_session_controller.h" #include "window/window_peer_menu.h" @@ -134,8 +135,17 @@ ScheduledWidget::ScheduledWidget( connect(_scroll, &Ui::ScrollArea::scrolled, [=] { onScroll(); }); _inner->editMessageRequested( - ) | rpl::start_with_next([=](auto id) { - _composeControls->editMessage(id); + ) | rpl::start_with_next([=](auto fullId) { + if (const auto item = session().data().message(fullId)) { + const auto media = item->media(); + if (media && !media->webpage()) { + if (media->allowsEditCaption()) { + Ui::show(Box(controller, item)); + } + } else { + _composeControls->editMessage(fullId); + } + } }, _inner->lifetime()); setupScrollDownButton(); @@ -207,6 +217,26 @@ void ScheduledWidget::setupComposeControls() { showAtPosition(pos); }, lifetime()); + _composeControls->keyEvents( + ) | rpl::start_with_next([=](not_null e) { + if (e->key() == Qt::Key_Up) { + if (!_composeControls->isEditingMessage()) { + auto &messages = session().data().scheduledMessages(); + if (const auto item = messages.lastSentMessage(_history)) { + _inner->editMessageRequestNotify(item->fullId()); + } else { + _scroll->keyPressEvent(e); + } + } else { + _scroll->keyPressEvent(e); + } + e->accept(); + } else if (e->key() == Qt::Key_Down) { + _scroll->keyPressEvent(e); + e->accept(); + } + }, lifetime()); + _composeControls->setMimeDataHook([=]( not_null data, Ui::InputField::MimeAction action) {