Instantly jump-to-message on reply bar ctrl+click.

This commit is contained in:
John Preston 2023-11-01 22:13:21 +04:00
parent 7d5d086ade
commit cc97093c5a
8 changed files with 47 additions and 32 deletions

View file

@ -6279,6 +6279,8 @@ void HistoryWidget::mousePressEvent(QMouseEvent *e) {
} else { } else {
_forwardPanel->editOptions(controller()->uiShow()); _forwardPanel->editOptions(controller()->uiShow());
} }
} else if (_replyTo && (e->modifiers() & Qt::ControlModifier)) {
jumpToReply(_replyTo);
} else if (_replyTo) { } else if (_replyTo) {
editDraftOptions(); editDraftOptions();
} else if (_kbReplyTo) { } else if (_kbReplyTo) {
@ -6307,12 +6309,9 @@ void HistoryWidget::editDraftOptions() {
_preview->apply(webpage); _preview->apply(webpage);
}; };
const auto replyToId = reply.messageId; const auto replyToId = reply.messageId;
const auto highlight = [=] { const auto highlight = crl::guard(this, [=](FullReplyTo to) {
controller()->showPeerHistory( jumpToReply(to);
replyToId.peer, });
Window::SectionShow::Way::Forward,
replyToId.msg);
};
using namespace HistoryView::Controls; using namespace HistoryView::Controls;
EditDraftOptions({ EditDraftOptions({
@ -6328,6 +6327,12 @@ void HistoryWidget::editDraftOptions() {
}); });
} }
void HistoryWidget::jumpToReply(FullReplyTo to) {
if (const auto item = session().data().message(to.messageId)) {
JumpToMessageClickHandler(item, {}, to.quote)->onClick({});
}
}
void HistoryWidget::keyPressEvent(QKeyEvent *e) { void HistoryWidget::keyPressEvent(QKeyEvent *e) {
if (!_history) return; if (!_history) return;

View file

@ -550,6 +550,7 @@ private:
void setupPreview(); void setupPreview();
void editDraftOptions(); void editDraftOptions();
void jumpToReply(FullReplyTo to);
void messagesReceived(not_null<PeerData*> peer, const MTPmessages_Messages &messages, int requestId); void messagesReceived(not_null<PeerData*> peer, const MTPmessages_Messages &messages, int requestId);
void messagesFailed(const MTP::Error &error, int requestId); void messagesFailed(const MTP::Error &error, int requestId);

View file

@ -130,7 +130,7 @@ public:
[[nodiscard]] FullReplyTo replyingToMessage() const; [[nodiscard]] FullReplyTo replyingToMessage() const;
[[nodiscard]] FullMsgId editMsgId() const; [[nodiscard]] FullMsgId editMsgId() const;
[[nodiscard]] rpl::producer<FullMsgId> editMsgIdValue() const; [[nodiscard]] rpl::producer<FullMsgId> editMsgIdValue() const;
[[nodiscard]] rpl::producer<FullMsgId> scrollToItemRequests() const; [[nodiscard]] rpl::producer<FullReplyTo> jumpToItemRequests() const;
[[nodiscard]] rpl::producer<> editPhotoRequests() const; [[nodiscard]] rpl::producer<> editPhotoRequests() const;
[[nodiscard]] rpl::producer<> editOptionsRequests() const; [[nodiscard]] rpl::producer<> editOptionsRequests() const;
[[nodiscard]] MessageToEdit queryToEdit(); [[nodiscard]] MessageToEdit queryToEdit();
@ -206,7 +206,7 @@ private:
QRect _shownMessagePreviewRect; QRect _shownMessagePreviewRect;
rpl::event_stream<bool> _visibleChanged; rpl::event_stream<bool> _visibleChanged;
rpl::event_stream<FullMsgId> _scrollToItemRequests; rpl::event_stream<FullReplyTo> _jumpToItemRequests;
rpl::event_stream<> _editOptionsRequests; rpl::event_stream<> _editOptionsRequests;
rpl::event_stream<> _editPhotoRequests; rpl::event_stream<> _editPhotoRequests;
@ -372,9 +372,14 @@ void FieldHeader::init() {
if (_preview.parsed) { if (_preview.parsed) {
_editOptionsRequests.fire({}); _editOptionsRequests.fire({});
} else if (isEditingMessage()) { } else if (isEditingMessage()) {
_scrollToItemRequests.fire(_editMsgId.current()); _jumpToItemRequests.fire(FullReplyTo{
.messageId = _editMsgId.current()
});
} else if (readyToForward()) { } else if (readyToForward()) {
_forwardPanel->editOptions(_show); _forwardPanel->editOptions(_show);
} else if (reply
&& (e->modifiers() & Qt::ControlModifier)) {
_jumpToItemRequests.fire_copy(reply);
} else if (reply) { } else if (reply) {
_editOptionsRequests.fire({}); _editOptionsRequests.fire({});
} }
@ -729,8 +734,8 @@ rpl::producer<FullMsgId> FieldHeader::editMsgIdValue() const {
return _editMsgId.value(); return _editMsgId.value();
} }
rpl::producer<FullMsgId> FieldHeader::scrollToItemRequests() const { rpl::producer<FullReplyTo> FieldHeader::jumpToItemRequests() const {
return _scrollToItemRequests.events(); return _jumpToItemRequests.events();
} }
rpl::producer<> FieldHeader::editPhotoRequests() const { rpl::producer<> FieldHeader::editPhotoRequests() const {
@ -1358,8 +1363,8 @@ void ComposeControls::init() {
_field->setFocus(); _field->setFocus();
}; };
const auto replyToId = reply.messageId; const auto replyToId = reply.messageId;
const auto highlight = crl::guard(_wrap.get(), [=] { const auto highlight = crl::guard(_wrap.get(), [=](FullReplyTo to) {
_scrollToItemRequests.fire_copy(replyToId); _jumpToItemRequests.fire_copy(to);
}); });
using namespace HistoryView::Controls; using namespace HistoryView::Controls;
@ -2888,16 +2893,10 @@ Data::WebPageDraft ComposeControls::webPageDraft() const {
return _preview ? _preview->draft() : Data::WebPageDraft(); return _preview ? _preview->draft() : Data::WebPageDraft();
} }
rpl::producer<Data::MessagePosition> ComposeControls::scrollRequests() const { rpl::producer<FullReplyTo> ComposeControls::jumpToItemRequests() const {
return rpl::merge( return rpl::merge(
_header->scrollToItemRequests(), _header->jumpToItemRequests(),
_scrollToItemRequests.events() _jumpToItemRequests.events());
) | rpl::map([=](FullMsgId id) -> Data::MessagePosition {
if (const auto item = session().data().message(id)) {
return item->position();
}
return {};
});
} }
bool ComposeControls::isEditingMessage() const { bool ComposeControls::isEditingMessage() const {

View file

@ -159,7 +159,7 @@ public:
[[nodiscard]] rpl::producer<std::optional<bool>> attachRequests() const; [[nodiscard]] rpl::producer<std::optional<bool>> attachRequests() const;
[[nodiscard]] rpl::producer<FileChosen> fileChosen() const; [[nodiscard]] rpl::producer<FileChosen> fileChosen() const;
[[nodiscard]] rpl::producer<PhotoChosen> photoChosen() const; [[nodiscard]] rpl::producer<PhotoChosen> photoChosen() const;
[[nodiscard]] rpl::producer<Data::MessagePosition> scrollRequests() const; [[nodiscard]] rpl::producer<FullReplyTo> jumpToItemRequests() const;
[[nodiscard]] rpl::producer<InlineChosen> inlineResultChosen() const; [[nodiscard]] rpl::producer<InlineChosen> inlineResultChosen() const;
[[nodiscard]] rpl::producer<SendActionUpdate> sendActionUpdates() const; [[nodiscard]] rpl::producer<SendActionUpdate> sendActionUpdates() const;
[[nodiscard]] rpl::producer<not_null<QEvent*>> viewportEvents() const; [[nodiscard]] rpl::producer<not_null<QEvent*>> viewportEvents() const;
@ -358,7 +358,7 @@ private:
const std::unique_ptr<Ui::RpWidget> _wrap; const std::unique_ptr<Ui::RpWidget> _wrap;
const std::unique_ptr<Ui::RpWidget> _writeRestricted; const std::unique_ptr<Ui::RpWidget> _writeRestricted;
rpl::event_stream<FullMsgId> _scrollToItemRequests; rpl::event_stream<FullReplyTo> _jumpToItemRequests;
std::optional<Ui::RoundRect> _backgroundRect; std::optional<Ui::RoundRect> _backgroundRect;

View file

@ -673,7 +673,9 @@ void DraftOptionsBox(
tr::lng_reply_show_in_chat(), tr::lng_reply_show_in_chat(),
st::settingsButton, st::settingsButton,
{ &st::menuIconShowInChat } { &st::menuIconShowInChat }
)->setClickedCallback(highlight); )->setClickedCallback([=] {
highlight(resolveReply());
});
Settings::AddButton( Settings::AddButton(
bottom, bottom,

View file

@ -32,7 +32,7 @@ struct EditDraftOptionsArgs {
std::vector<MessageLinkRange> links; std::vector<MessageLinkRange> links;
std::shared_ptr<WebpageResolver> resolver; std::shared_ptr<WebpageResolver> resolver;
Fn<void(FullReplyTo, Data::WebPageDraft)> done; Fn<void(FullReplyTo, Data::WebPageDraft)> done;
Fn<void()> highlight; Fn<void(FullReplyTo)> highlight;
Fn<void()> clearOldDraft; Fn<void()> clearOldDraft;
}; };

View file

@ -791,9 +791,11 @@ void RepliesWidget::setupComposeControls() {
sendInlineResult(chosen.result, chosen.bot, chosen.options, localId); sendInlineResult(chosen.result, chosen.bot, chosen.options, localId);
}, lifetime()); }, lifetime());
_composeControls->scrollRequests( _composeControls->jumpToItemRequests(
) | rpl::start_with_next([=](Data::MessagePosition pos) { ) | rpl::start_with_next([=](FullReplyTo to) {
showAtPosition(pos); if (const auto item = session().data().message(to.messageId)) {
JumpToMessageClickHandler(item, {}, to.quote)->onClick({});
}
}, lifetime()); }, lifetime());
_composeControls->scrollKeyEvents( _composeControls->scrollKeyEvents(

View file

@ -274,9 +274,15 @@ void ScheduledWidget::setupComposeControls() {
sendInlineResult(chosen.result, chosen.bot); sendInlineResult(chosen.result, chosen.bot);
}, lifetime()); }, lifetime());
_composeControls->scrollRequests( _composeControls->jumpToItemRequests(
) | rpl::start_with_next([=](Data::MessagePosition pos) { ) | rpl::start_with_next([=](FullReplyTo to) {
showAtPosition(pos); if (const auto item = session().data().message(to.messageId)) {
if (item->isScheduled() && item->history() == _history) {
showAtPosition(item->position());
} else {
JumpToMessageClickHandler(item, {}, to.quote)->onClick({});
}
}
}, lifetime()); }, lifetime());
_composeControls->scrollKeyEvents( _composeControls->scrollKeyEvents(