mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-16 06:07:06 +02:00
Support external reply to channel posts.
This commit is contained in:
parent
394883b986
commit
6c19274eac
7 changed files with 145 additions and 53 deletions
|
@ -13,6 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "history/admin_log/history_admin_log_item.h"
|
||||
#include "history/history_item.h"
|
||||
#include "history/history_item_helpers.h"
|
||||
#include "history/view/controls/history_view_forward_panel.h"
|
||||
#include "history/view/media/history_view_media.h"
|
||||
#include "history/view/media/history_view_sticker.h"
|
||||
#include "history/view/media/history_view_web_page.h"
|
||||
|
@ -2196,7 +2197,7 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
|
|||
return;
|
||||
}
|
||||
const auto itemId = item->fullId();
|
||||
const auto canReply = [&] {
|
||||
const auto canSendReply = [&] {
|
||||
const auto peer = item->history()->peer;
|
||||
const auto topic = item->topic();
|
||||
return topic
|
||||
|
@ -2204,9 +2205,24 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
|
|||
: (Data::CanSendAnything(peer)
|
||||
&& (!peer->isChannel() || peer->asChannel()->amIn()));
|
||||
}();
|
||||
const auto canReply = canSendReply || [&] {
|
||||
const auto peer = item->history()->peer;
|
||||
if (const auto chat = peer->asChat()) {
|
||||
return !chat->isForbidden();
|
||||
} else if (const auto channel = peer->asChannel()) {
|
||||
return !channel->isForbidden();
|
||||
}
|
||||
return true;
|
||||
}();
|
||||
if (canReply) {
|
||||
_menu->addAction(tr::lng_context_reply_msg(tr::now), [=] {
|
||||
_widget->replyToMessage({ itemId });
|
||||
if (canSendReply) {
|
||||
_widget->replyToMessage({ itemId });
|
||||
} else {
|
||||
HistoryView::Controls::ShowReplyToChatBox(
|
||||
controller->uiShow(),
|
||||
{ itemId });
|
||||
}
|
||||
}, &st::menuIconReply);
|
||||
}
|
||||
const auto repliesCount = item->repliesCount();
|
||||
|
|
|
@ -6222,10 +6222,19 @@ void HistoryWidget::mousePressEvent(QMouseEvent *e) {
|
|||
_forwardPanel->editOptions(controller()->uiShow());
|
||||
}
|
||||
} else if (const auto reply = replyTo()) {
|
||||
HistoryView::Controls::EditReplyOptions(
|
||||
controller(),
|
||||
const auto highlight = [=] {
|
||||
controller()->showPeerHistory(
|
||||
reply.messageId.peer,
|
||||
Window::SectionShow::Way::Forward,
|
||||
reply.messageId.msg);
|
||||
};
|
||||
const auto history = _history;
|
||||
using namespace HistoryView::Controls;
|
||||
EditReplyOptions(
|
||||
controller()->uiShow(),
|
||||
reply,
|
||||
_history);
|
||||
highlight,
|
||||
[=] { ClearDraftReplyTo(history, reply.messageId); });
|
||||
} else if (_editMsgId) {
|
||||
controller()->showPeerHistory(
|
||||
_peer,
|
||||
|
@ -7611,7 +7620,10 @@ bool HistoryWidget::updateCanSendMessage() {
|
|||
if (!_peer) {
|
||||
return false;
|
||||
}
|
||||
const auto replyTo = (_replyTo && !_editMsgId) ? _replyEditMsg : 0;
|
||||
const auto checkTopicFromReplyTo = _replyTo
|
||||
&& !_editMsgId
|
||||
&& (_replyTo.messageId.peer == _peer->id);
|
||||
const auto replyTo = checkTopicFromReplyTo ? _replyEditMsg : 0;
|
||||
const auto topic = replyTo ? replyTo->topic() : nullptr;
|
||||
const auto allWithoutPolls = Data::AllSendRestrictions()
|
||||
& ~ChatRestriction::SendPolls;
|
||||
|
|
|
@ -414,6 +414,7 @@ private:
|
|||
|
||||
const std::shared_ptr<ChatHelpers::Show> _show;
|
||||
History *_history = nullptr;
|
||||
MsgId _topicRootId = 0;
|
||||
rpl::variable<QString> _title;
|
||||
rpl::variable<QString> _description;
|
||||
|
||||
|
@ -468,6 +469,7 @@ FieldHeader::FieldHeader(
|
|||
|
||||
void FieldHeader::setHistory(const SetHistoryArgs &args) {
|
||||
_history = *args.history;
|
||||
_topicRootId = args.topicRootId;
|
||||
}
|
||||
|
||||
void FieldHeader::init() {
|
||||
|
@ -619,8 +621,24 @@ void FieldHeader::init() {
|
|||
} else if (isLeftButton && inPhotoEdit) {
|
||||
_editPhotoRequests.fire({});
|
||||
} else if (isLeftButton && inPreviewRect) {
|
||||
const auto reply = replyingToMessage();
|
||||
if (!isEditingMessage() && readyToForward()) {
|
||||
_forwardPanel->editOptions(_show);
|
||||
} else if (!isEditingMessage() && reply) {
|
||||
using namespace Controls;
|
||||
const auto highlight = [=] {
|
||||
_scrollToItemRequests.fire_copy(reply.messageId);
|
||||
};
|
||||
const auto history = _history;
|
||||
const auto topicRootId = _topicRootId;
|
||||
const auto clearOldReplyTo = [=, id = reply.messageId] {
|
||||
ClearDraftReplyTo(history, topicRootId, id);
|
||||
};
|
||||
EditReplyOptions(
|
||||
_show,
|
||||
reply,
|
||||
highlight,
|
||||
clearOldReplyTo);
|
||||
} else {
|
||||
auto id = isEditingMessage()
|
||||
? _editMsgId.current()
|
||||
|
|
|
@ -403,10 +403,38 @@ void ForwardPanel::paint(
|
|||
});
|
||||
}
|
||||
|
||||
void ClearDraftReplyTo(not_null<Data::Thread*> thread, FullMsgId equalTo) {
|
||||
ClearDraftReplyTo(
|
||||
thread->owningHistory(),
|
||||
thread->topicRootId(),
|
||||
equalTo);
|
||||
}
|
||||
|
||||
void ClearDraftReplyTo(
|
||||
not_null<History*> history,
|
||||
MsgId topicRootId,
|
||||
FullMsgId equalTo) {
|
||||
const auto local = history->localDraft(topicRootId);
|
||||
if (!local || (equalTo && local->reply.messageId != equalTo)) {
|
||||
return;
|
||||
}
|
||||
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)));
|
||||
}
|
||||
if (const auto thread = history->threadFor(topicRootId)) {
|
||||
history->session().api().saveDraftToCloudDelayed(thread);
|
||||
}
|
||||
}
|
||||
|
||||
void ShowReplyToChatBox(
|
||||
not_null<Window::SessionController*> window,
|
||||
std::shared_ptr<ChatHelpers::Show> show,
|
||||
FullReplyTo reply,
|
||||
base::weak_ptr<Data::Thread> oldThread) {
|
||||
Fn<void()> clearOldDraft) {
|
||||
class Controller final : public ChooseRecipientBoxController {
|
||||
public:
|
||||
using Chosen = not_null<Data::Thread*>;
|
||||
|
@ -426,7 +454,15 @@ void ShowReplyToChatBox(
|
|||
return _singleChosen.events();
|
||||
}
|
||||
|
||||
bool respectSavedMessagesChat() const override {
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
void prepareViewHook() override {
|
||||
delegate()->peerListSetTitle(rpl::single(u"Reply in..."_q));
|
||||
}
|
||||
|
||||
rpl::event_stream<Chosen> _singleChosen;
|
||||
|
||||
};
|
||||
|
@ -436,13 +472,13 @@ void ShowReplyToChatBox(
|
|||
not_null<Controller*> controller;
|
||||
base::unique_qptr<Ui::PopupMenu> menu;
|
||||
};
|
||||
const auto session = &window->session();
|
||||
const auto session = &show->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));
|
||||
show->show(std::move(box));
|
||||
auto state = State{ boxRaw, controllerRaw };
|
||||
return boxRaw->lifetime().make_state<State>(std::move(state));
|
||||
}();
|
||||
|
@ -466,26 +502,9 @@ void ShowReplyToChatBox(
|
|||
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);
|
||||
}
|
||||
}
|
||||
});
|
||||
if (clearOldDraft) {
|
||||
crl::on_main(&history->session(), clearOldDraft);
|
||||
}
|
||||
return true;
|
||||
};
|
||||
auto callback = [=, chosen = std::move(chosen)](
|
||||
|
@ -502,11 +521,11 @@ void ShowReplyToChatBox(
|
|||
}
|
||||
|
||||
void EditReplyOptions(
|
||||
not_null<Window::SessionController*> controller,
|
||||
std::shared_ptr<ChatHelpers::Show> show,
|
||||
FullReplyTo reply,
|
||||
not_null<Data::Thread*> thread) {
|
||||
const auto weak = base::make_weak(thread);
|
||||
controller->uiShow()->show(Box([=](not_null<Ui::GenericBox*> box) {
|
||||
Fn<void()> highlight,
|
||||
Fn<void()> clearOldDraft) {
|
||||
show->show(Box([=](not_null<Ui::GenericBox*> box) {
|
||||
box->setTitle(rpl::single(u"Reply to Message"_q));
|
||||
|
||||
Settings::AddButton(
|
||||
|
@ -515,7 +534,7 @@ void EditReplyOptions(
|
|||
st::settingsButton,
|
||||
{ &st::menuIconReply }
|
||||
)->setClickedCallback([=] {
|
||||
ShowReplyToChatBox(controller, reply, weak);
|
||||
ShowReplyToChatBox(show, reply, clearOldDraft);
|
||||
});
|
||||
|
||||
Settings::AddButton(
|
||||
|
@ -523,12 +542,7 @@ void EditReplyOptions(
|
|||
rpl::single(u"Show message"_q),
|
||||
st::settingsButton,
|
||||
{ &st::menuIconShowInChat }
|
||||
)->setClickedCallback([=] {
|
||||
controller->showPeerHistory(
|
||||
reply.messageId.peer,
|
||||
Window::SectionShow::Way::Forward,
|
||||
reply.messageId.msg);
|
||||
});
|
||||
)->setClickedCallback(highlight);
|
||||
|
||||
box->addButton(tr::lng_box_ok(), [=] {
|
||||
box->closeBox();
|
||||
|
|
|
@ -71,9 +71,21 @@ private:
|
|||
|
||||
};
|
||||
|
||||
void EditReplyOptions(
|
||||
not_null<Window::SessionController*> controller,
|
||||
void ClearDraftReplyTo(not_null<Data::Thread*> thread, FullMsgId equalTo);
|
||||
void ClearDraftReplyTo(
|
||||
not_null<History*> history,
|
||||
MsgId topicRootId,
|
||||
FullMsgId equalTo);
|
||||
|
||||
void ShowReplyToChatBox(
|
||||
std::shared_ptr<ChatHelpers::Show> show,
|
||||
FullReplyTo reply,
|
||||
not_null<Data::Thread*> thread);
|
||||
Fn<void()> clearOldDraft = nullptr);
|
||||
|
||||
void EditReplyOptions(
|
||||
std::shared_ptr<ChatHelpers::Show> show,
|
||||
FullReplyTo reply,
|
||||
Fn<void()> highlight,
|
||||
Fn<void()> clearOldDraft = nullptr);
|
||||
|
||||
} // namespace HistoryView::Controls
|
||||
|
|
|
@ -51,6 +51,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "data/data_stories.h"
|
||||
#include "data/data_groups.h"
|
||||
#include "data/data_channel.h"
|
||||
#include "data/data_chat.h"
|
||||
#include "data/data_file_click_handler.h"
|
||||
#include "data/data_file_origin.h"
|
||||
#include "data/data_message_reactions.h"
|
||||
|
@ -588,20 +589,33 @@ bool AddReplyToMessageAction(
|
|||
const auto peer = item ? item->history()->peer.get() : nullptr;
|
||||
if (!item
|
||||
|| !item->isRegular()
|
||||
|| !(topic
|
||||
? Data::CanSendAnything(topic)
|
||||
: Data::CanSendAnything(peer))
|
||||
|| (context != Context::History && context != Context::Replies)) {
|
||||
return false;
|
||||
}
|
||||
const auto canSendReply = topic
|
||||
? Data::CanSendAnything(topic)
|
||||
: Data::CanSendAnything(peer);
|
||||
const auto canReply = canSendReply || [&] {
|
||||
const auto peer = item->history()->peer;
|
||||
if (const auto chat = peer->asChat()) {
|
||||
return !chat->isForbidden();
|
||||
} else if (const auto channel = peer->asChannel()) {
|
||||
return !channel->isForbidden();
|
||||
}
|
||||
return true;
|
||||
}();
|
||||
if (!canReply) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto owner = &item->history()->owner();
|
||||
const auto itemId = item->fullId();
|
||||
menu->addAction(tr::lng_context_reply_msg(tr::now), [=] {
|
||||
const auto item = owner->message(itemId);
|
||||
if (!item) {
|
||||
return;
|
||||
} else {
|
||||
list->replyToMessageRequestNotify({ itemId });
|
||||
}
|
||||
list->replyToMessageRequestNotify({ item->fullId() });
|
||||
}, &st::menuIconReply);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "history/view/history_view_replies_section.h"
|
||||
|
||||
#include "history/view/controls/history_view_compose_controls.h"
|
||||
#include "history/view/controls/history_view_forward_panel.h"
|
||||
#include "history/view/history_view_top_bar_widget.h"
|
||||
#include "history/view/history_view_list_widget.h"
|
||||
#include "history/view/history_view_schedule_box.h"
|
||||
|
@ -318,10 +319,15 @@ RepliesWidget::RepliesWidget(
|
|||
}, _inner->lifetime());
|
||||
|
||||
_inner->replyToMessageRequested(
|
||||
) | rpl::filter([=] {
|
||||
return !_joinGroup;
|
||||
}) | rpl::start_with_next([=](auto fullId) {
|
||||
replyToMessage(fullId);
|
||||
) | rpl::start_with_next([=](auto fullId) {
|
||||
const auto canSendReply = _topic
|
||||
? Data::CanSendAnything(_topic)
|
||||
: Data::CanSendAnything(_history->peer);
|
||||
if (_joinGroup || !canSendReply) {
|
||||
Controls::ShowReplyToChatBox(controller->uiShow(), { fullId });
|
||||
} else {
|
||||
replyToMessage(fullId);
|
||||
}
|
||||
}, _inner->lifetime());
|
||||
|
||||
_inner->showMessageRequested(
|
||||
|
|
Loading…
Add table
Reference in a new issue