mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-02-23 00:36:53 +00:00
Improve context menu in pinned section.
This commit is contained in:
parent
ebbe75ac0a
commit
61d335469f
@ -316,6 +316,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_settings_events_title" = "Events";
|
||||
"lng_settings_events_joined" = "Contact joined Telegram";
|
||||
"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_reply" = "Reply";
|
||||
|
@ -1572,13 +1572,10 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
|
||||
}
|
||||
if (item->canPin()) {
|
||||
const auto isPinned = item->isPinned();
|
||||
_menu->addAction(isPinned ? tr::lng_context_unpin_msg(tr::now) : tr::lng_context_pin_msg(tr::now), [=] {
|
||||
if (isPinned) {
|
||||
_widget->unpinMessage(itemId);
|
||||
} else {
|
||||
_widget->pinMessage(itemId);
|
||||
}
|
||||
});
|
||||
const auto controller = _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);
|
||||
}));
|
||||
}
|
||||
};
|
||||
const auto addPhotoActions = [&](not_null<PhotoData*> photo) {
|
||||
|
@ -5552,39 +5552,6 @@ void HistoryWidget::editMessage(not_null<HistoryItem*> item) {
|
||||
_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() {
|
||||
Expects(_pinnedBar != nullptr);
|
||||
|
||||
@ -5593,7 +5560,10 @@ void HistoryWidget::hidePinnedMessage() {
|
||||
return;
|
||||
}
|
||||
if (_peer->canPinMessages()) {
|
||||
unpinMessage({ peerToChannel(_peer->id), id.message });
|
||||
Window::ToggleMessagePinned(
|
||||
controller(),
|
||||
{ peerToChannel(_peer->id), id.message },
|
||||
false);
|
||||
} else {
|
||||
const auto top = Data::ResolveTopPinnedId(_peer);
|
||||
if (top) {
|
||||
|
@ -183,8 +183,6 @@ public:
|
||||
void replyToMessage(not_null<HistoryItem*> item);
|
||||
void editMessage(FullMsgId itemId);
|
||||
void editMessage(not_null<HistoryItem*> item);
|
||||
void pinMessage(FullMsgId itemId);
|
||||
void unpinMessage(FullMsgId itemId);
|
||||
|
||||
MsgId replyToId() const;
|
||||
bool lastForceReplyReplied(const FullMsgId &replyTo) const;
|
||||
@ -517,8 +515,6 @@ private:
|
||||
void addMessagesToFront(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 updateListSize();
|
||||
|
||||
|
@ -496,10 +496,12 @@ bool AddReplyToMessageAction(
|
||||
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->history()->peer->canWrite()) {
|
||||
|| !item->history()->peer->canWrite()
|
||||
|| (context != Context::History && context != Context::Replies)) {
|
||||
return false;
|
||||
}
|
||||
const auto owner = &item->history()->owner();
|
||||
@ -514,6 +516,37 @@ bool AddReplyToMessageAction(
|
||||
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(
|
||||
not_null<Ui::PopupMenu*> menu,
|
||||
const ContextMenuRequest &request,
|
||||
@ -537,6 +570,27 @@ bool AddEditMessageAction(
|
||||
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(
|
||||
not_null<Ui::PopupMenu*> menu,
|
||||
const ContextMenuRequest &request,
|
||||
@ -720,7 +774,9 @@ void AddTopMessageActions(
|
||||
const ContextMenuRequest &request,
|
||||
not_null<ListWidget*> list) {
|
||||
AddReplyToMessageAction(menu, request, list);
|
||||
AddViewRepliesAction(menu, request, list);
|
||||
AddEditMessageAction(menu, request, list);
|
||||
AddPinMessageAction(menu, request, list);
|
||||
}
|
||||
|
||||
void AddMessageActions(
|
||||
|
@ -33,6 +33,7 @@ class Media;
|
||||
enum class Context : char {
|
||||
History,
|
||||
Replies,
|
||||
Pinned,
|
||||
//Feed, // #feed
|
||||
AdminLog,
|
||||
ContactPreview
|
||||
|
@ -1214,6 +1214,7 @@ bool Message::hasFromPhoto() const {
|
||||
//case Context::Feed: // #feed
|
||||
return true;
|
||||
case Context::History:
|
||||
case Context::Pinned:
|
||||
case Context::Replies: {
|
||||
const auto item = message();
|
||||
if (item->isPost()
|
||||
@ -2051,6 +2052,7 @@ bool Message::hasFromName() const {
|
||||
//case Context::Feed: // #feed
|
||||
return true;
|
||||
case Context::History:
|
||||
case Context::Pinned:
|
||||
case Context::Replies: {
|
||||
const auto item = message();
|
||||
return (!hasOutLayout() || item->from()->isMegagroup())
|
||||
@ -2216,6 +2218,9 @@ bool Message::displayFastShare() const {
|
||||
}
|
||||
|
||||
bool Message::displayGoToOriginal() const {
|
||||
if (context() == Context::Pinned) {
|
||||
return true;
|
||||
}
|
||||
const auto item = message();
|
||||
if (const auto forwarded = item->Get<HistoryMessageForwarded>()) {
|
||||
return forwarded->savedFromPeer
|
||||
@ -2277,7 +2282,10 @@ void Message::drawRightAction(
|
||||
|
||||
ClickHandlerPtr Message::rightActionLink() const {
|
||||
if (!_rightActionLink) {
|
||||
if (displayRightActionComments()) {
|
||||
if (context() == Context::Pinned) {
|
||||
_rightActionLink = goToMessageClickHandler(data());
|
||||
return _rightActionLink;
|
||||
} else if (displayRightActionComments()) {
|
||||
_rightActionLink = createGoToCommentsLink();
|
||||
return _rightActionLink;
|
||||
}
|
||||
|
@ -102,6 +102,7 @@ PinnedWidget::PinnedWidget(
|
||||
_topBar->move(0, 0);
|
||||
_topBar->resizeToWidth(width());
|
||||
_topBar->show();
|
||||
_topBar->setCustomTitle(tr::lng_contacts_loading(tr::now));
|
||||
|
||||
_topBar->deleteSelectionRequest(
|
||||
) | rpl::start_with_next([=] {
|
||||
@ -285,10 +286,7 @@ QPixmap PinnedWidget::grabForShowAnimation(const Window::SectionSlideParams &par
|
||||
}
|
||||
|
||||
void PinnedWidget::doSetInnerFocus() {
|
||||
if (!_inner->getSelectedText().rich.text.isEmpty()
|
||||
|| !_inner->getSelectedItems().empty()) {
|
||||
_inner->setFocus();
|
||||
}
|
||||
_inner->setFocus();
|
||||
}
|
||||
|
||||
bool PinnedWidget::showInternal(
|
||||
@ -321,33 +319,7 @@ bool PinnedWidget::showMessage(
|
||||
PeerId peerId,
|
||||
const Window::SectionShow ¶ms,
|
||||
MsgId messageId) {
|
||||
if (peerId != _history->peer->id) {
|
||||
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;
|
||||
return false; // We want 'Go to original' to work.
|
||||
}
|
||||
|
||||
void PinnedWidget::saveState(not_null<PinnedMemento*> memento) {
|
||||
@ -463,7 +435,7 @@ QRect PinnedWidget::floatPlayerAvailableRect() {
|
||||
}
|
||||
|
||||
Context PinnedWidget::listContext() {
|
||||
return Context::Replies;
|
||||
return Context::Pinned;
|
||||
}
|
||||
|
||||
void PinnedWidget::listScrollTo(int top) {
|
||||
@ -502,7 +474,19 @@ rpl::producer<Data::MessagesSlice> PinnedWidget::listSource(
|
||||
messageId),
|
||||
limitBefore,
|
||||
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();
|
||||
result.fullCount = slice.fullCount();
|
||||
result.skippedAfter = slice.skippedAfter();
|
||||
|
@ -138,6 +138,7 @@ private:
|
||||
|
||||
bool _skipScrollEvent = false;
|
||||
std::unique_ptr<Ui::ScrollArea> _scroll;
|
||||
object_ptr<Ui::FlatButton> _clearButton = { nullptr };
|
||||
|
||||
Ui::Animations::Simple _scrollDownShown;
|
||||
bool _scrollDownIsShown = false;
|
||||
|
@ -343,7 +343,7 @@ void TopBarWidget::paintTopBar(Painter &p) {
|
||||
? tr::lng_reminder_messages(tr::now)
|
||||
: tr::lng_scheduled_messages(tr::now))
|
||||
: (_section == Section::Pinned)
|
||||
? "Pinned messages" // #TODO pinned
|
||||
? _customTitleText
|
||||
: folder
|
||||
? folder->chatListName()
|
||||
: 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(
|
||||
not_null<PeerData*> peer,
|
||||
const PeerMenuCallback &addAction) {
|
||||
|
@ -111,4 +111,9 @@ QPointer<Ui::RpWidget> ShowSendNowMessagesBox(
|
||||
MessageIdsList &&items,
|
||||
FnMut<void()> &&successCallback = nullptr);
|
||||
|
||||
void ToggleMessagePinned(
|
||||
not_null<Window::SessionNavigation*> navigation,
|
||||
FullMsgId itemId,
|
||||
bool pin);
|
||||
|
||||
} // namespace Window
|
||||
|
Loading…
Reference in New Issue
Block a user