@@ -74,6 +74,7 @@ For license and copyright information please follow this link:
7474#include " data/notify/data_notify_settings.h"
7575#include " data/data_changes.h"
7676#include " data/data_drafts.h"
77+ #include " data/data_groups.h"
7778#include " data/data_session.h"
7879#include " data/data_todo_list.h"
7980#include " data/data_web_page.h"
@@ -223,6 +224,12 @@ constexpr auto kCommonModifiers = 0
223224 | Qt::ShiftModifier
224225 | Qt::MetaModifier
225226 | Qt::ControlModifier;
227+
228+ [[nodiscard]] bool IsEditCycleModifiers (Qt::KeyboardModifiers modifiers) {
229+ return (modifiers & (kCommonModifiers | Qt::AltModifier))
230+ == (Qt::AltModifier | Qt::ShiftModifier);
231+ }
232+
226233const auto kPsaAboutPrefix = " cloud_lng_about_psa_" ;
227234
228235[[nodiscard]] rpl::producer<PeerData*> ActivePeerValue (
@@ -5857,6 +5864,12 @@ bool HistoryWidget::eventFilter(QObject *obj, QEvent *e) {
58575864#endif
58585865 return replyToNextMessage ();
58595866 }
5867+ } else if (IsEditCycleModifiers (k->modifiers ())) {
5868+ if (k->key () == Qt::Key_Up) {
5869+ return editPreviousMessage ();
5870+ } else if (k->key () == Qt::Key_Down) {
5871+ return editNextMessage ();
5872+ }
58605873 }
58615874 }
58625875 return RpWidget::eventFilter (obj, e);
@@ -8119,6 +8132,16 @@ void HistoryWidget::keyPressEvent(QKeyEvent *e) {
81198132 if (!replyToNextMessage ()) {
81208133 e->ignore ();
81218134 }
8135+ } else if (e->key () == Qt::Key_Up
8136+ && IsEditCycleModifiers (e->modifiers ())) {
8137+ if (!editPreviousMessage ()) {
8138+ e->ignore ();
8139+ }
8140+ } else if (e->key () == Qt::Key_Down
8141+ && IsEditCycleModifiers (e->modifiers ())) {
8142+ if (!editNextMessage ()) {
8143+ e->ignore ();
8144+ }
81228145 } else if (e->key () == Qt::Key_Return || e->key () == Qt::Key_Enter) {
81238146 if (!_botStart->isHidden ()) {
81248147 sendBotStartCommand ();
@@ -8249,6 +8272,87 @@ bool HistoryWidget::replyToNextMessage() {
82498272 return false ;
82508273}
82518274
8275+ bool HistoryWidget::editPreviousMessage () {
8276+ if (!_history) {
8277+ return false ;
8278+ }
8279+ const auto target = [&]() -> HistoryItem* {
8280+ if (!_editMsgId || !_replyEditMsg) {
8281+ return _history->lastEditableMessage ();
8282+ }
8283+ const auto view = _replyEditMsg->mainView ();
8284+ if (!view) {
8285+ return nullptr ;
8286+ }
8287+ const auto now = base::unixtime::now ();
8288+ auto previous = view->previousDisplayedInBlocks ();
8289+ while (previous && !previous->data ()->allowsEdit (now)) {
8290+ previous = previous->previousDisplayedInBlocks ();
8291+ }
8292+ if (!previous) {
8293+ return nullptr ;
8294+ }
8295+ return session ().data ().groups ().findItemToEdit (previous->data ());
8296+ }();
8297+ if (!target) {
8298+ return false ;
8299+ }
8300+ const auto id = target->fullId ();
8301+ confirmDiscardEdit (crl::guard (this , [=] {
8302+ if (const auto item = session ().data ().message (id)) {
8303+ editMessage (item, {});
8304+ }
8305+ }));
8306+ return true ;
8307+ }
8308+
8309+ bool HistoryWidget::editNextMessage () {
8310+ if (!_history || !_editMsgId || !_replyEditMsg) {
8311+ return false ;
8312+ }
8313+ const auto view = _replyEditMsg->mainView ();
8314+ if (!view) {
8315+ return false ;
8316+ }
8317+ const auto now = base::unixtime::now ();
8318+ auto next = view->nextDisplayedInBlocks ();
8319+ while (next && !next->data ()->allowsEdit (now)) {
8320+ next = next->nextDisplayedInBlocks ();
8321+ }
8322+ if (next) {
8323+ const auto id = session ().data ().groups ().findItemToEdit (
8324+ next->data ())->fullId ();
8325+ confirmDiscardEdit (crl::guard (this , [=] {
8326+ if (const auto item = session ().data ().message (id)) {
8327+ editMessage (item, {});
8328+ }
8329+ }));
8330+ } else {
8331+ confirmDiscardEdit (crl::guard (this , [=] {
8332+ cancelEdit ();
8333+ }));
8334+ }
8335+ return true ;
8336+ }
8337+
8338+ void HistoryWidget::confirmDiscardEdit (Fn<void ()> proceed) {
8339+ if (_editMsgId
8340+ && _replyEditMsg
8341+ && EditTextChanged (_replyEditMsg, _field->getTextWithTags ())) {
8342+ controller ()->show (Ui::MakeConfirmBox ({
8343+ .text = tr::lng_cancel_edit_post_sure (),
8344+ .confirmed = crl::guard (this , [=](Fn<void ()> &&close) {
8345+ proceed ();
8346+ close ();
8347+ }),
8348+ .confirmText = tr::lng_cancel_edit_post_yes (),
8349+ .cancelText = tr::lng_cancel_edit_post_no (),
8350+ }));
8351+ } else {
8352+ proceed ();
8353+ }
8354+ }
8355+
82528356bool HistoryWidget::showSlowmodeError () {
82538357 const auto text = [&] {
82548358 if (const auto left = _peer->slowmodeSecondsLeft ()) {
0 commit comments