mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Improve context menu in pinned section.
This commit is contained in:
parent
ebbe75ac0a
commit
61d335469f
12 changed files with 127 additions and 81 deletions
|
@ -316,6 +316,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_settings_events_title" = "Events";
|
"lng_settings_events_title" = "Events";
|
||||||
"lng_settings_events_joined" = "Contact joined Telegram";
|
"lng_settings_events_joined" = "Contact joined Telegram";
|
||||||
"lng_settings_events_pinned" = "Pinned messages";
|
"lng_settings_events_pinned" = "Pinned messages";
|
||||||
|
"lng_pinned_messages_title#one" = "{count} pinned message";
|
||||||
|
"lng_pinned_messages_title#other" = "{count} pinned messages";
|
||||||
|
|
||||||
"lng_notification_preview" = "You have a new message";
|
"lng_notification_preview" = "You have a new message";
|
||||||
"lng_notification_reply" = "Reply";
|
"lng_notification_reply" = "Reply";
|
||||||
|
|
|
@ -1572,13 +1572,10 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
|
||||||
}
|
}
|
||||||
if (item->canPin()) {
|
if (item->canPin()) {
|
||||||
const auto isPinned = item->isPinned();
|
const auto isPinned = item->isPinned();
|
||||||
_menu->addAction(isPinned ? tr::lng_context_unpin_msg(tr::now) : tr::lng_context_pin_msg(tr::now), [=] {
|
const auto controller = _controller;
|
||||||
if (isPinned) {
|
_menu->addAction(isPinned ? tr::lng_context_unpin_msg(tr::now) : tr::lng_context_pin_msg(tr::now), crl::guard(controller, [=] {
|
||||||
_widget->unpinMessage(itemId);
|
Window::ToggleMessagePinned(controller, itemId, !isPinned);
|
||||||
} else {
|
}));
|
||||||
_widget->pinMessage(itemId);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const auto addPhotoActions = [&](not_null<PhotoData*> photo) {
|
const auto addPhotoActions = [&](not_null<PhotoData*> photo) {
|
||||||
|
|
|
@ -5552,39 +5552,6 @@ void HistoryWidget::editMessage(not_null<HistoryItem*> item) {
|
||||||
_field->setFocus();
|
_field->setFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::pinMessage(FullMsgId itemId) {
|
|
||||||
if (const auto item = session().data().message(itemId)) {
|
|
||||||
if (item->canPin()) {
|
|
||||||
Ui::show(Box<PinMessageBox>(item->history()->peer, item->id));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void HistoryWidget::unpinMessage(FullMsgId itemId) {
|
|
||||||
if (!_peer) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
UnpinMessage(_peer, itemId.msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
void HistoryWidget::UnpinMessage(not_null<PeerData*> peer, MsgId msgId) {
|
|
||||||
if (!peer) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto session = &peer->session();
|
|
||||||
Ui::show(Box<ConfirmBox>(tr::lng_pinned_unpin_sure(tr::now), tr::lng_pinned_unpin(tr::now), crl::guard(session, [=] {
|
|
||||||
Ui::hideLayer();
|
|
||||||
session->api().request(MTPmessages_UpdatePinnedMessage(
|
|
||||||
MTP_flags(MTPmessages_UpdatePinnedMessage::Flag::f_unpin),
|
|
||||||
peer->input,
|
|
||||||
MTP_int(msgId)
|
|
||||||
)).done([=](const MTPUpdates &result) {
|
|
||||||
session->api().applyUpdates(result);
|
|
||||||
}).send();
|
|
||||||
})));
|
|
||||||
}
|
|
||||||
|
|
||||||
void HistoryWidget::hidePinnedMessage() {
|
void HistoryWidget::hidePinnedMessage() {
|
||||||
Expects(_pinnedBar != nullptr);
|
Expects(_pinnedBar != nullptr);
|
||||||
|
|
||||||
|
@ -5593,7 +5560,10 @@ void HistoryWidget::hidePinnedMessage() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (_peer->canPinMessages()) {
|
if (_peer->canPinMessages()) {
|
||||||
unpinMessage({ peerToChannel(_peer->id), id.message });
|
Window::ToggleMessagePinned(
|
||||||
|
controller(),
|
||||||
|
{ peerToChannel(_peer->id), id.message },
|
||||||
|
false);
|
||||||
} else {
|
} else {
|
||||||
const auto top = Data::ResolveTopPinnedId(_peer);
|
const auto top = Data::ResolveTopPinnedId(_peer);
|
||||||
if (top) {
|
if (top) {
|
||||||
|
|
|
@ -183,8 +183,6 @@ public:
|
||||||
void replyToMessage(not_null<HistoryItem*> item);
|
void replyToMessage(not_null<HistoryItem*> item);
|
||||||
void editMessage(FullMsgId itemId);
|
void editMessage(FullMsgId itemId);
|
||||||
void editMessage(not_null<HistoryItem*> item);
|
void editMessage(not_null<HistoryItem*> item);
|
||||||
void pinMessage(FullMsgId itemId);
|
|
||||||
void unpinMessage(FullMsgId itemId);
|
|
||||||
|
|
||||||
MsgId replyToId() const;
|
MsgId replyToId() const;
|
||||||
bool lastForceReplyReplied(const FullMsgId &replyTo) const;
|
bool lastForceReplyReplied(const FullMsgId &replyTo) const;
|
||||||
|
@ -517,8 +515,6 @@ private:
|
||||||
void addMessagesToFront(PeerData *peer, const QVector<MTPMessage> &messages);
|
void addMessagesToFront(PeerData *peer, const QVector<MTPMessage> &messages);
|
||||||
void addMessagesToBack(PeerData *peer, const QVector<MTPMessage> &messages);
|
void addMessagesToBack(PeerData *peer, const QVector<MTPMessage> &messages);
|
||||||
|
|
||||||
static void UnpinMessage(not_null<PeerData*> peer, MsgId msgId);
|
|
||||||
|
|
||||||
void updateHistoryGeometry(bool initial = false, bool loadedDown = false, const ScrollChange &change = { ScrollChangeNone, 0 });
|
void updateHistoryGeometry(bool initial = false, bool loadedDown = false, const ScrollChange &change = { ScrollChangeNone, 0 });
|
||||||
void updateListSize();
|
void updateListSize();
|
||||||
|
|
||||||
|
|
|
@ -496,10 +496,12 @@ bool AddReplyToMessageAction(
|
||||||
not_null<Ui::PopupMenu*> menu,
|
not_null<Ui::PopupMenu*> menu,
|
||||||
const ContextMenuRequest &request,
|
const ContextMenuRequest &request,
|
||||||
not_null<ListWidget*> list) {
|
not_null<ListWidget*> list) {
|
||||||
|
const auto context = list->elementContext();
|
||||||
const auto item = request.item;
|
const auto item = request.item;
|
||||||
if (!item
|
if (!item
|
||||||
|| !IsServerMsgId(item->id)
|
|| !IsServerMsgId(item->id)
|
||||||
|| !item->history()->peer->canWrite()) {
|
|| !item->history()->peer->canWrite()
|
||||||
|
|| (context != Context::History && context != Context::Replies)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const auto owner = &item->history()->owner();
|
const auto owner = &item->history()->owner();
|
||||||
|
@ -514,6 +516,37 @@ bool AddReplyToMessageAction(
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AddViewRepliesAction(
|
||||||
|
not_null<Ui::PopupMenu*> menu,
|
||||||
|
const ContextMenuRequest &request,
|
||||||
|
not_null<ListWidget*> list) {
|
||||||
|
const auto context = list->elementContext();
|
||||||
|
const auto item = request.item;
|
||||||
|
if (!item
|
||||||
|
|| !IsServerMsgId(item->id)
|
||||||
|
|| (context != Context::History && context != Context::Pinned)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const auto repliesCount = item->repliesCount();
|
||||||
|
const auto withReplies = (repliesCount > 0);
|
||||||
|
if (!withReplies || !item->history()->peer->isMegagroup()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const auto rootId = repliesCount ? item->id : item->replyToTop();
|
||||||
|
const auto phrase = (repliesCount > 0)
|
||||||
|
? tr::lng_replies_view(
|
||||||
|
tr::now,
|
||||||
|
lt_count,
|
||||||
|
repliesCount)
|
||||||
|
: tr::lng_replies_view_thread(tr::now);
|
||||||
|
const auto controller = list->controller();
|
||||||
|
const auto history = item->history();
|
||||||
|
menu->addAction(phrase, crl::guard(controller, [=] {
|
||||||
|
controller->showRepliesForMessage(history, rootId);
|
||||||
|
}));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool AddEditMessageAction(
|
bool AddEditMessageAction(
|
||||||
not_null<Ui::PopupMenu*> menu,
|
not_null<Ui::PopupMenu*> menu,
|
||||||
const ContextMenuRequest &request,
|
const ContextMenuRequest &request,
|
||||||
|
@ -537,6 +570,27 @@ bool AddEditMessageAction(
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AddPinMessageAction(
|
||||||
|
not_null<Ui::PopupMenu*> menu,
|
||||||
|
const ContextMenuRequest &request,
|
||||||
|
not_null<ListWidget*> list) {
|
||||||
|
const auto context = list->elementContext();
|
||||||
|
const auto item = request.item;
|
||||||
|
if (!item
|
||||||
|
|| !IsServerMsgId(item->id)
|
||||||
|
|| !item->canPin()
|
||||||
|
|| (context != Context::History && context != Context::Pinned)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const auto itemId = item->fullId();
|
||||||
|
const auto isPinned = item->isPinned();
|
||||||
|
const auto controller = list->controller();
|
||||||
|
menu->addAction(isPinned ? tr::lng_context_unpin_msg(tr::now) : tr::lng_context_pin_msg(tr::now), crl::guard(controller, [=] {
|
||||||
|
Window::ToggleMessagePinned(controller, itemId, !isPinned);
|
||||||
|
}));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void AddSendNowAction(
|
void AddSendNowAction(
|
||||||
not_null<Ui::PopupMenu*> menu,
|
not_null<Ui::PopupMenu*> menu,
|
||||||
const ContextMenuRequest &request,
|
const ContextMenuRequest &request,
|
||||||
|
@ -720,7 +774,9 @@ void AddTopMessageActions(
|
||||||
const ContextMenuRequest &request,
|
const ContextMenuRequest &request,
|
||||||
not_null<ListWidget*> list) {
|
not_null<ListWidget*> list) {
|
||||||
AddReplyToMessageAction(menu, request, list);
|
AddReplyToMessageAction(menu, request, list);
|
||||||
|
AddViewRepliesAction(menu, request, list);
|
||||||
AddEditMessageAction(menu, request, list);
|
AddEditMessageAction(menu, request, list);
|
||||||
|
AddPinMessageAction(menu, request, list);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddMessageActions(
|
void AddMessageActions(
|
||||||
|
|
|
@ -33,6 +33,7 @@ class Media;
|
||||||
enum class Context : char {
|
enum class Context : char {
|
||||||
History,
|
History,
|
||||||
Replies,
|
Replies,
|
||||||
|
Pinned,
|
||||||
//Feed, // #feed
|
//Feed, // #feed
|
||||||
AdminLog,
|
AdminLog,
|
||||||
ContactPreview
|
ContactPreview
|
||||||
|
|
|
@ -1214,6 +1214,7 @@ bool Message::hasFromPhoto() const {
|
||||||
//case Context::Feed: // #feed
|
//case Context::Feed: // #feed
|
||||||
return true;
|
return true;
|
||||||
case Context::History:
|
case Context::History:
|
||||||
|
case Context::Pinned:
|
||||||
case Context::Replies: {
|
case Context::Replies: {
|
||||||
const auto item = message();
|
const auto item = message();
|
||||||
if (item->isPost()
|
if (item->isPost()
|
||||||
|
@ -2051,6 +2052,7 @@ bool Message::hasFromName() const {
|
||||||
//case Context::Feed: // #feed
|
//case Context::Feed: // #feed
|
||||||
return true;
|
return true;
|
||||||
case Context::History:
|
case Context::History:
|
||||||
|
case Context::Pinned:
|
||||||
case Context::Replies: {
|
case Context::Replies: {
|
||||||
const auto item = message();
|
const auto item = message();
|
||||||
return (!hasOutLayout() || item->from()->isMegagroup())
|
return (!hasOutLayout() || item->from()->isMegagroup())
|
||||||
|
@ -2216,6 +2218,9 @@ bool Message::displayFastShare() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Message::displayGoToOriginal() const {
|
bool Message::displayGoToOriginal() const {
|
||||||
|
if (context() == Context::Pinned) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
const auto item = message();
|
const auto item = message();
|
||||||
if (const auto forwarded = item->Get<HistoryMessageForwarded>()) {
|
if (const auto forwarded = item->Get<HistoryMessageForwarded>()) {
|
||||||
return forwarded->savedFromPeer
|
return forwarded->savedFromPeer
|
||||||
|
@ -2277,7 +2282,10 @@ void Message::drawRightAction(
|
||||||
|
|
||||||
ClickHandlerPtr Message::rightActionLink() const {
|
ClickHandlerPtr Message::rightActionLink() const {
|
||||||
if (!_rightActionLink) {
|
if (!_rightActionLink) {
|
||||||
if (displayRightActionComments()) {
|
if (context() == Context::Pinned) {
|
||||||
|
_rightActionLink = goToMessageClickHandler(data());
|
||||||
|
return _rightActionLink;
|
||||||
|
} else if (displayRightActionComments()) {
|
||||||
_rightActionLink = createGoToCommentsLink();
|
_rightActionLink = createGoToCommentsLink();
|
||||||
return _rightActionLink;
|
return _rightActionLink;
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,6 +102,7 @@ PinnedWidget::PinnedWidget(
|
||||||
_topBar->move(0, 0);
|
_topBar->move(0, 0);
|
||||||
_topBar->resizeToWidth(width());
|
_topBar->resizeToWidth(width());
|
||||||
_topBar->show();
|
_topBar->show();
|
||||||
|
_topBar->setCustomTitle(tr::lng_contacts_loading(tr::now));
|
||||||
|
|
||||||
_topBar->deleteSelectionRequest(
|
_topBar->deleteSelectionRequest(
|
||||||
) | rpl::start_with_next([=] {
|
) | rpl::start_with_next([=] {
|
||||||
|
@ -285,10 +286,7 @@ QPixmap PinnedWidget::grabForShowAnimation(const Window::SectionSlideParams &par
|
||||||
}
|
}
|
||||||
|
|
||||||
void PinnedWidget::doSetInnerFocus() {
|
void PinnedWidget::doSetInnerFocus() {
|
||||||
if (!_inner->getSelectedText().rich.text.isEmpty()
|
_inner->setFocus();
|
||||||
|| !_inner->getSelectedItems().empty()) {
|
|
||||||
_inner->setFocus();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PinnedWidget::showInternal(
|
bool PinnedWidget::showInternal(
|
||||||
|
@ -321,33 +319,7 @@ bool PinnedWidget::showMessage(
|
||||||
PeerId peerId,
|
PeerId peerId,
|
||||||
const Window::SectionShow ¶ms,
|
const Window::SectionShow ¶ms,
|
||||||
MsgId messageId) {
|
MsgId messageId) {
|
||||||
if (peerId != _history->peer->id) {
|
return false; // We want 'Go to original' to work.
|
||||||
return false;
|
|
||||||
}
|
|
||||||
const auto id = FullMsgId{
|
|
||||||
_history->channelId(),
|
|
||||||
messageId
|
|
||||||
};
|
|
||||||
const auto message = _history->owner().message(id);
|
|
||||||
if (!message || !message->isPinned()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto originItem = [&]() -> HistoryItem* {
|
|
||||||
using OriginMessage = Window::SectionShow::OriginMessage;
|
|
||||||
if (const auto origin = std::get_if<OriginMessage>(¶ms.origin)) {
|
|
||||||
if (const auto returnTo = session().data().message(origin->id)) {
|
|
||||||
if (returnTo->history() == _history && returnTo->isPinned()) {
|
|
||||||
return returnTo;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}();
|
|
||||||
showAtPosition(
|
|
||||||
Data::MessagePosition{ .fullId = id, .date = message->date() },
|
|
||||||
originItem);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PinnedWidget::saveState(not_null<PinnedMemento*> memento) {
|
void PinnedWidget::saveState(not_null<PinnedMemento*> memento) {
|
||||||
|
@ -463,7 +435,7 @@ QRect PinnedWidget::floatPlayerAvailableRect() {
|
||||||
}
|
}
|
||||||
|
|
||||||
Context PinnedWidget::listContext() {
|
Context PinnedWidget::listContext() {
|
||||||
return Context::Replies;
|
return Context::Pinned;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PinnedWidget::listScrollTo(int top) {
|
void PinnedWidget::listScrollTo(int top) {
|
||||||
|
@ -502,7 +474,19 @@ rpl::producer<Data::MessagesSlice> PinnedWidget::listSource(
|
||||||
messageId),
|
messageId),
|
||||||
limitBefore,
|
limitBefore,
|
||||||
limitAfter
|
limitAfter
|
||||||
) | rpl::map([=](SparseIdsSlice &&slice) {
|
) | rpl::filter([=](const SparseIdsSlice &slice) {
|
||||||
|
const auto count = slice.fullCount();
|
||||||
|
if (!count.has_value()) {
|
||||||
|
return true;
|
||||||
|
} else if (*count != 0) {
|
||||||
|
_topBar->setCustomTitle(
|
||||||
|
tr::lng_pinned_messages_title(tr::now, lt_count, *count));
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
controller()->showBackFromStack();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}) | rpl::map([=](SparseIdsSlice &&slice) {
|
||||||
auto result = Data::MessagesSlice();
|
auto result = Data::MessagesSlice();
|
||||||
result.fullCount = slice.fullCount();
|
result.fullCount = slice.fullCount();
|
||||||
result.skippedAfter = slice.skippedAfter();
|
result.skippedAfter = slice.skippedAfter();
|
||||||
|
|
|
@ -138,6 +138,7 @@ private:
|
||||||
|
|
||||||
bool _skipScrollEvent = false;
|
bool _skipScrollEvent = false;
|
||||||
std::unique_ptr<Ui::ScrollArea> _scroll;
|
std::unique_ptr<Ui::ScrollArea> _scroll;
|
||||||
|
object_ptr<Ui::FlatButton> _clearButton = { nullptr };
|
||||||
|
|
||||||
Ui::Animations::Simple _scrollDownShown;
|
Ui::Animations::Simple _scrollDownShown;
|
||||||
bool _scrollDownIsShown = false;
|
bool _scrollDownIsShown = false;
|
||||||
|
|
|
@ -343,7 +343,7 @@ void TopBarWidget::paintTopBar(Painter &p) {
|
||||||
? tr::lng_reminder_messages(tr::now)
|
? tr::lng_reminder_messages(tr::now)
|
||||||
: tr::lng_scheduled_messages(tr::now))
|
: tr::lng_scheduled_messages(tr::now))
|
||||||
: (_section == Section::Pinned)
|
: (_section == Section::Pinned)
|
||||||
? "Pinned messages" // #TODO pinned
|
? _customTitleText
|
||||||
: folder
|
: folder
|
||||||
? folder->chatListName()
|
? folder->chatListName()
|
||||||
: history->peer->isSelf()
|
: history->peer->isSelf()
|
||||||
|
|
|
@ -1124,6 +1124,32 @@ void PeerMenuAddChannelMembers(
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ToggleMessagePinned(
|
||||||
|
not_null<Window::SessionNavigation*> navigation,
|
||||||
|
FullMsgId itemId,
|
||||||
|
bool pin) {
|
||||||
|
const auto item = navigation->session().data().message(itemId);
|
||||||
|
if (!item || !item->canPin()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (pin) {
|
||||||
|
Ui::show(Box<PinMessageBox>(item->history()->peer, item->id));
|
||||||
|
} else {
|
||||||
|
const auto peer = item->history()->peer;
|
||||||
|
const auto session = &peer->session();
|
||||||
|
Ui::show(Box<ConfirmBox>(tr::lng_pinned_unpin_sure(tr::now), tr::lng_pinned_unpin(tr::now), crl::guard(session, [=] {
|
||||||
|
Ui::hideLayer();
|
||||||
|
session->api().request(MTPmessages_UpdatePinnedMessage(
|
||||||
|
MTP_flags(MTPmessages_UpdatePinnedMessage::Flag::f_unpin),
|
||||||
|
peer->input,
|
||||||
|
MTP_int(itemId.msg)
|
||||||
|
)).done([=](const MTPUpdates &result) {
|
||||||
|
session->api().applyUpdates(result);
|
||||||
|
}).send();
|
||||||
|
})));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void PeerMenuAddMuteAction(
|
void PeerMenuAddMuteAction(
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
const PeerMenuCallback &addAction) {
|
const PeerMenuCallback &addAction) {
|
||||||
|
|
|
@ -111,4 +111,9 @@ QPointer<Ui::RpWidget> ShowSendNowMessagesBox(
|
||||||
MessageIdsList &&items,
|
MessageIdsList &&items,
|
||||||
FnMut<void()> &&successCallback = nullptr);
|
FnMut<void()> &&successCallback = nullptr);
|
||||||
|
|
||||||
|
void ToggleMessagePinned(
|
||||||
|
not_null<Window::SessionNavigation*> navigation,
|
||||||
|
FullMsgId itemId,
|
||||||
|
bool pin);
|
||||||
|
|
||||||
} // namespace Window
|
} // namespace Window
|
||||||
|
|
Loading…
Add table
Reference in a new issue