Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow usage of Arrow Up and Arrow Down to edit more than just the most recent message #24317

Open
wants to merge 3 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions Telegram/SourceFiles/history/history.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2763,6 +2763,51 @@ HistoryItem *History::lastEditableMessage() const {
return nullptr;
}


HistoryItem *History::editableMessageBefore(MsgId current) const {
if (!loadedAtBottom()) {
return nullptr;
}

bool found = false;
const auto now = base::unixtime::now();
for (const auto &block : ranges::views::reverse(blocks)) {
for (const auto &message : ranges::views::reverse(block->messages)) {
const auto item = message->data();
if (item->allowsEdit(now)) {
if(owner().groups().findItemToEdit(item)->id == current) {
found = true;
} else if(found) {
return owner().groups().findItemToEdit(item);
}
}
}
}
return nullptr;
}

HistoryItem *History::editableMessageAfter(MsgId current) const {
if (!loadedAtBottom()) {
return nullptr;
}

HistoryItem * previous = nullptr;
const auto now = base::unixtime::now();
for (const auto &block : ranges::views::reverse(blocks)) {
for (const auto &message : ranges::views::reverse(block->messages)) {
const auto item = message->data();
if (item->allowsEdit(now)) {
if(owner().groups().findItemToEdit(item)->id == current) {
return previous;
} else {
previous = owner().groups().findItemToEdit(item);
}
}
}
}
return nullptr;
}

void History::resizeToWidth(int newWidth) {
const auto resizeAllItems = (_width != newWidth);

Expand Down
2 changes: 2 additions & 0 deletions Telegram/SourceFiles/history/history.h
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,8 @@ class History final : public Dialogs::Entry {
MsgId maxMsgId() const;
MsgId msgIdForRead() const;
HistoryItem *lastEditableMessage() const;
HistoryItem *editableMessageBefore(MsgId current) const;
HistoryItem *editableMessageAfter(MsgId current) const;

void resizeToWidth(int newWidth);
void forceFullResize();
Expand Down
56 changes: 48 additions & 8 deletions Telegram/SourceFiles/history/history_widget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6093,18 +6093,58 @@ void HistoryWidget::keyPressEvent(QKeyEvent *e) {
} else if (e->key() == Qt::Key_PageUp) {
_scroll->keyPressEvent(e);
} else if (e->key() == Qt::Key_Down && !commonModifiers) {
// If we're in a message being edited, we want to handle the down key by editing the next message.
if (_editMsgId && !_replyToId) {
const auto item = _history ? _history->editableMessageAfter(_editMsgId) : nullptr;
// If a change has been made, show a dialog asking if the user wants to cancel the changes
if (_replyEditMsg && PrepareEditText(_replyEditMsg) != _field->getTextWithTags()) {
controller()->show(Ui::MakeConfirmBox({
.text = tr::lng_cancel_edit_post_sure(),
.confirmed = crl::guard(this, [this, item] {
item ? editMessage(item) : cancelEdit();
Ui::hideLayer();
}),
.confirmText = tr::lng_cancel_edit_post_yes(),
.cancelText = tr::lng_cancel_edit_post_no(),
}));
} else {
item ? editMessage(item) : cancelEdit();
}
return;
}

_scroll->keyPressEvent(e);
} else if (e->key() == Qt::Key_Up && !commonModifiers) {
const auto item = _history
? _history->lastEditableMessage()
: nullptr;
if (item
&& _field->empty()
&& !_editMsgId
&& !_replyToId) {
editMessage(item);
if (_field->empty() && !_editMsgId && !_replyToId) {
// No message is currently being edited.
const auto item = _history ? _history->lastEditableMessage() : nullptr;
if(item) {
editMessage(item);
}
return;
}

// If we're in a message being edited, we want to handle the up key by instead editing the previous message.
if (_editMsgId && !_replyToId) {
const auto item = _history ? _history->editableMessageBefore(_editMsgId) : nullptr;
if(item) {
if (_replyEditMsg && PrepareEditText(_replyEditMsg) != _field->getTextWithTags()) {
controller()->show(Ui::MakeConfirmBox({
.text = tr::lng_cancel_edit_post_sure(),
.confirmed = crl::guard(this, [this, item] {
editMessage(item);
Ui::hideLayer();
}),
.confirmText = tr::lng_cancel_edit_post_yes(),
.cancelText = tr::lng_cancel_edit_post_no(),
}));
} else {
editMessage(item);
}
}
return;
}

_scroll->keyPressEvent(e);
} else if (e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter) {
if (!_botStart->isHidden()) {
Expand Down