mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-18 15:17:07 +02:00
Support replying to a different chat.
This commit is contained in:
parent
4240568ea5
commit
394883b986
5 changed files with 173 additions and 18 deletions
Telegram/SourceFiles/history
|
@ -325,7 +325,7 @@ bool HistoryMessageReply::updateData(
|
|||
bool force) {
|
||||
const auto guard = gsl::finally([&] { refreshReplyToMedia(); });
|
||||
if (!force) {
|
||||
if (resolvedMessage || resolvedStory || _deleted) {
|
||||
if (resolvedMessage || resolvedStory || _unavailable) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -365,7 +365,9 @@ bool HistoryMessageReply::updateData(
|
|||
|
||||
const auto external = _fields.externalSenderId
|
||||
|| !_fields.externalSenderName.isEmpty();
|
||||
if (resolvedMessage || resolvedStory || (external && force)) {
|
||||
if (resolvedMessage
|
||||
|| resolvedStory
|
||||
|| (external && (!_fields.messageId || force))) {
|
||||
const auto repaint = [=] { holder->customEmojiRepaint(); };
|
||||
const auto context = Core::MarkedTextContext{
|
||||
.session = &holder->history()->session(),
|
||||
|
@ -403,8 +405,8 @@ bool HistoryMessageReply::updateData(
|
|||
&& resolvedMessage->from()->isUser())
|
||||
? resolvedMessage->from()->id
|
||||
: PeerId();
|
||||
} else {
|
||||
resolvedMessage = 0;
|
||||
} else if (!resolvedStory) {
|
||||
_unavailable = true;
|
||||
}
|
||||
|
||||
const auto media = resolvedMessage
|
||||
|
@ -417,7 +419,7 @@ bool HistoryMessageReply::updateData(
|
|||
}
|
||||
} else if (force) {
|
||||
if (_fields.messageId || _fields.storyId) {
|
||||
_deleted = true;
|
||||
_unavailable = true;
|
||||
}
|
||||
_colorKey = 0;
|
||||
spoiler = nullptr;
|
||||
|
@ -428,7 +430,7 @@ bool HistoryMessageReply::updateData(
|
|||
return resolvedMessage
|
||||
|| resolvedStory
|
||||
|| (external && !_fields.messageId)
|
||||
|| _deleted;
|
||||
|| _unavailable;
|
||||
}
|
||||
|
||||
void HistoryMessageReply::set(ReplyFields fields) {
|
||||
|
@ -500,7 +502,7 @@ void HistoryMessageReply::clearData(not_null<HistoryItem*> holder) {
|
|||
resolvedStory.get());
|
||||
resolvedStory = nullptr;
|
||||
}
|
||||
_deleted = true;
|
||||
_unavailable = true;
|
||||
refreshReplyToMedia();
|
||||
}
|
||||
|
||||
|
@ -693,7 +695,7 @@ void HistoryMessageReply::paint(
|
|||
const auto pausedSpoiler = context.paused
|
||||
|| On(PowerSaving::kChatSpoiler);
|
||||
if (w > st::msgReplyBarSkip) {
|
||||
if (resolvedMessage || resolvedStory) {
|
||||
if (resolvedMessage || resolvedStory || !_text.isEmpty()) {
|
||||
const auto media = resolvedMessage ? resolvedMessage->media() : nullptr;
|
||||
auto hasPreview = (media && media->hasReplyPreview())
|
||||
|| (resolvedStory && resolvedStory->hasReplyPreview());
|
||||
|
@ -791,7 +793,7 @@ void HistoryMessageReply::unloadPersistentAnimation() {
|
|||
}
|
||||
|
||||
QString HistoryMessageReply::statePhrase() const {
|
||||
return ((_fields.messageId || _fields.storyId) && !_deleted)
|
||||
return ((_fields.messageId || _fields.storyId) && !_unavailable)
|
||||
? tr::lng_profile_loading(tr::now)
|
||||
: _fields.storyId
|
||||
? tr::lng_deleted_story(tr::now)
|
||||
|
|
|
@ -344,7 +344,7 @@ private:
|
|||
mutable PeerData *_externalSender = nullptr;
|
||||
mutable int _maxWidth = 0;
|
||||
mutable int _nameVersion = 0;
|
||||
bool _deleted = false;
|
||||
bool _unavailable = false;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -1656,7 +1656,9 @@ void HistoryWidget::saveDraft(bool delayed) {
|
|||
}
|
||||
|
||||
void HistoryWidget::saveFieldToHistoryLocalDraft() {
|
||||
if (!_history) return;
|
||||
if (!_history) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto topicRootId = MsgId();
|
||||
if (_editMsgId) {
|
||||
|
@ -6219,13 +6221,16 @@ void HistoryWidget::mousePressEvent(QMouseEvent *e) {
|
|||
} else {
|
||||
_forwardPanel->editOptions(controller()->uiShow());
|
||||
}
|
||||
} else if (replyTo() && replyTo().messageId.peer != _peer->id) {
|
||||
// edit options
|
||||
} else {
|
||||
} else if (const auto reply = replyTo()) {
|
||||
HistoryView::Controls::EditReplyOptions(
|
||||
controller(),
|
||||
reply,
|
||||
_history);
|
||||
} else if (_editMsgId) {
|
||||
controller()->showPeerHistory(
|
||||
_peer,
|
||||
Window::SectionShow::Way::Forward,
|
||||
_editMsgId ? _editMsgId : replyTo().messageId.msg);
|
||||
_editMsgId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7096,6 +7101,7 @@ void HistoryWidget::processReply() {
|
|||
_processingReplyTo.messageId.msg,
|
||||
processContinue());
|
||||
return;
|
||||
#if 0 // Now we can "reply" to old legacy group messages.
|
||||
} else if (_processingReplyItem->history() == _migrated) {
|
||||
if (_processingReplyItem->isService()) {
|
||||
controller()->showToast(tr::lng_reply_cant(tr::now));
|
||||
|
@ -7113,10 +7119,11 @@ void HistoryWidget::processReply() {
|
|||
}));
|
||||
}
|
||||
return processCancel();
|
||||
} else if (_processingReplyItem->history() != _history
|
||||
|| !_processingReplyItem->isRegular()) {
|
||||
#endif
|
||||
} else if (!_processingReplyItem->isRegular()) {
|
||||
return processCancel();
|
||||
} else if (const auto forum = _peer->forum()) {
|
||||
} else if (const auto forum = _peer->forum()
|
||||
; forum && _processingReplyItem->history() == _history) {
|
||||
const auto topicRootId = _processingReplyItem->topicRootId();
|
||||
if (forum->topicDeleted(topicRootId)) {
|
||||
return processCancel();
|
||||
|
|
|
@ -29,6 +29,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "styles/style_chat.h"
|
||||
#include "styles/style_chat_helpers.h"
|
||||
|
||||
#include "apiwrap.h"
|
||||
#include "boxes/peer_list_controllers.h"
|
||||
#include "data/data_changes.h"
|
||||
#include "settings/settings_common.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "styles/style_menu_icons.h"
|
||||
#include "styles/style_settings.h"
|
||||
|
||||
namespace HistoryView::Controls {
|
||||
namespace {
|
||||
|
||||
|
@ -395,4 +403,137 @@ void ForwardPanel::paint(
|
|||
});
|
||||
}
|
||||
|
||||
void ShowReplyToChatBox(
|
||||
not_null<Window::SessionController*> window,
|
||||
FullReplyTo reply,
|
||||
base::weak_ptr<Data::Thread> oldThread) {
|
||||
class Controller final : public ChooseRecipientBoxController {
|
||||
public:
|
||||
using Chosen = not_null<Data::Thread*>;
|
||||
|
||||
Controller(not_null<Main::Session*> session)
|
||||
: ChooseRecipientBoxController(
|
||||
session,
|
||||
[=](Chosen thread) mutable { _singleChosen.fire_copy(thread); },
|
||||
nullptr) {
|
||||
}
|
||||
|
||||
void rowClicked(not_null<PeerListRow*> row) override final {
|
||||
ChooseRecipientBoxController::rowClicked(row);
|
||||
}
|
||||
|
||||
[[nodiscard]] rpl::producer<Chosen> singleChosen() const{
|
||||
return _singleChosen.events();
|
||||
}
|
||||
|
||||
private:
|
||||
rpl::event_stream<Chosen> _singleChosen;
|
||||
|
||||
};
|
||||
|
||||
struct State {
|
||||
not_null<PeerListBox*> box;
|
||||
not_null<Controller*> controller;
|
||||
base::unique_qptr<Ui::PopupMenu> menu;
|
||||
};
|
||||
const auto session = &window->session();
|
||||
const auto state = [&] {
|
||||
auto controller = std::make_unique<Controller>(session);
|
||||
const auto controllerRaw = controller.get();
|
||||
auto box = Box<PeerListBox>(std::move(controller), nullptr);
|
||||
const auto boxRaw = box.data();
|
||||
window->uiShow()->show(std::move(box));
|
||||
auto state = State{ boxRaw, controllerRaw };
|
||||
return boxRaw->lifetime().make_state<State>(std::move(state));
|
||||
}();
|
||||
|
||||
auto chosen = [=](not_null<Data::Thread*> thread) mutable {
|
||||
const auto history = thread->owningHistory();
|
||||
const auto topicRootId = thread->topicRootId();
|
||||
const auto draft = history->localDraft(topicRootId);
|
||||
const auto textWithTags = draft
|
||||
? draft->textWithTags
|
||||
: TextWithTags();
|
||||
const auto cursor = draft ? draft->cursor : MessageCursor();
|
||||
reply.topicRootId = topicRootId;
|
||||
history->setLocalDraft(std::make_unique<Data::Draft>(
|
||||
textWithTags,
|
||||
reply,
|
||||
cursor,
|
||||
Data::PreviewState::Allowed));
|
||||
history->clearLocalEditDraft(topicRootId);
|
||||
history->session().changes().entryUpdated(
|
||||
thread,
|
||||
Data::EntryUpdate::Flag::LocalDraftSet);
|
||||
|
||||
// Clear old one.
|
||||
crl::on_main(oldThread, [=] {
|
||||
const auto old = oldThread.get();
|
||||
const auto history = old->owningHistory();
|
||||
const auto topicRootId = old->topicRootId();
|
||||
if (const auto local = history->localDraft(topicRootId)) {
|
||||
if (local->reply.messageId == reply.messageId) {
|
||||
auto draft = *local;
|
||||
draft.reply = { .topicRootId = topicRootId };
|
||||
if (Data::DraftIsNull(&draft)) {
|
||||
history->clearLocalDraft(topicRootId);
|
||||
} else {
|
||||
history->setLocalDraft(
|
||||
std::make_unique<Data::Draft>(
|
||||
std::move(draft)));
|
||||
}
|
||||
old->session().api().saveDraftToCloudDelayed(old);
|
||||
}
|
||||
}
|
||||
});
|
||||
return true;
|
||||
};
|
||||
auto callback = [=, chosen = std::move(chosen)](
|
||||
Controller::Chosen thread) mutable {
|
||||
const auto weak = Ui::MakeWeak(state->box);
|
||||
if (!chosen(thread)) {
|
||||
return;
|
||||
} else if (const auto strong = weak.data()) {
|
||||
strong->closeBox();
|
||||
}
|
||||
};
|
||||
state->controller->singleChosen(
|
||||
) | rpl::start_with_next(std::move(callback), state->box->lifetime());
|
||||
}
|
||||
|
||||
void EditReplyOptions(
|
||||
not_null<Window::SessionController*> controller,
|
||||
FullReplyTo reply,
|
||||
not_null<Data::Thread*> thread) {
|
||||
const auto weak = base::make_weak(thread);
|
||||
controller->uiShow()->show(Box([=](not_null<Ui::GenericBox*> box) {
|
||||
box->setTitle(rpl::single(u"Reply to Message"_q));
|
||||
|
||||
Settings::AddButton(
|
||||
box->verticalLayout(),
|
||||
rpl::single(u"Reply in another chat"_q),
|
||||
st::settingsButton,
|
||||
{ &st::menuIconReply }
|
||||
)->setClickedCallback([=] {
|
||||
ShowReplyToChatBox(controller, reply, weak);
|
||||
});
|
||||
|
||||
Settings::AddButton(
|
||||
box->verticalLayout(),
|
||||
rpl::single(u"Show message"_q),
|
||||
st::settingsButton,
|
||||
{ &st::menuIconShowInChat }
|
||||
)->setClickedCallback([=] {
|
||||
controller->showPeerHistory(
|
||||
reply.messageId.peer,
|
||||
Window::SectionShow::Way::Forward,
|
||||
reply.messageId.msg);
|
||||
});
|
||||
|
||||
box->addButton(tr::lng_box_ok(), [=] {
|
||||
box->closeBox();
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
} // namespace HistoryView::Controls
|
||||
|
|
|
@ -71,4 +71,9 @@ private:
|
|||
|
||||
};
|
||||
|
||||
void EditReplyOptions(
|
||||
not_null<Window::SessionController*> controller,
|
||||
FullReplyTo reply,
|
||||
not_null<Data::Thread*> thread);
|
||||
|
||||
} // namespace HistoryView::Controls
|
||||
|
|
Loading…
Add table
Reference in a new issue