Improve context menu in pinned section.

This commit is contained in:
John Preston 2020-10-21 17:41:13 +03:00
parent ebbe75ac0a
commit 61d335469f
12 changed files with 127 additions and 81 deletions

View File

@ -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";

View File

@ -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) {

View File

@ -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) {

View File

@ -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();

View File

@ -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(

View File

@ -33,6 +33,7 @@ class Media;
enum class Context : char {
History,
Replies,
Pinned,
//Feed, // #feed
AdminLog,
ContactPreview

View File

@ -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;
}

View File

@ -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 &params,
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>(&params.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();

View File

@ -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;

View File

@ -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()

View File

@ -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) {

View File

@ -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