From aecdc01e41bdea02a018079666dbb41cc47d38a0 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Thu, 17 Sep 2020 17:56:01 +0300 Subject: [PATCH] Added ability to mark all chats as read. --- Telegram/Resources/langs/lang.strings | 2 + .../window/window_filters_menu.cpp | 1 - .../SourceFiles/window/window_main_menu.cpp | 19 +++- .../SourceFiles/window/window_peer_menu.cpp | 98 +++++++++++-------- .../SourceFiles/window/window_peer_menu.h | 7 +- 5 files changed, 79 insertions(+), 48 deletions(-) diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index cebdc4f086..d045626dda 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -1458,6 +1458,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_context_mark_unread" = "Mark as unread"; "lng_context_mark_read" = "Mark as read"; "lng_context_mark_read_sure" = "Are you sure you want to mark all chats from this folder as read?"; +"lng_context_mark_read_all" = "Mark all chats as read"; +"lng_context_mark_read_all_sure" = "Are you sure you want to mark all chats as read?"; "lng_context_archive_expand" = "Expand"; "lng_context_archive_collapse" = "Collapse"; "lng_context_archive_to_menu" = "Move to main menu"; diff --git a/Telegram/SourceFiles/window/window_filters_menu.cpp b/Telegram/SourceFiles/window/window_filters_menu.cpp index bb9c31e704..0a7902ef1b 100644 --- a/Telegram/SourceFiles/window/window_filters_menu.cpp +++ b/Telegram/SourceFiles/window/window_filters_menu.cpp @@ -322,7 +322,6 @@ void FiltersMenu::showMenu(QPoint position, FilterId id) { return _session->session().data().chatsFilters().chatsList(id); }; Window::MenuAddMarkAsReadChatListAction( - &_session->session().data(), std::move(filteredChats), addAction); diff --git a/Telegram/SourceFiles/window/window_main_menu.cpp b/Telegram/SourceFiles/window/window_main_menu.cpp index ee13f9d173..cea57e096b 100644 --- a/Telegram/SourceFiles/window/window_main_menu.cpp +++ b/Telegram/SourceFiles/window/window_main_menu.cpp @@ -90,6 +90,10 @@ constexpr auto kMinDiffIntensity = 0.25; || Data::IsLegacy1DefaultWallPaper(background->paper()); } +[[nodiscard]] bool IsAltShift(Qt::KeyboardModifiers modifiers) { + return (modifiers & Qt::ShiftModifier) && (modifiers & Qt::AltModifier); +} + } // namespace namespace Window { @@ -273,6 +277,17 @@ void MainMenu::AccountButton::paintEvent(QPaintEvent *e) { } void MainMenu::AccountButton::contextMenuEvent(QContextMenuEvent *e) { + if (!_menu && IsAltShift(e->modifiers())) { + _menu = base::make_unique_q(this); + const auto addAction = [&](const QString &text, Fn callback) { + return _menu->addAction( + text, + crl::guard(this, std::move(callback))); + }; + MenuAddMarkAsReadAllChatsAction(&_session->data(), addAction); + _menu->popup(QCursor::pos()); + return; + } if (&_session->account() == &Core::App().activeAccount() || _menu) { return; } @@ -639,7 +654,6 @@ void MainMenu::setupArchiveButton() { addAction(tr::lng_context_archive_to_list(tr::now), std::move(hide)); MenuAddMarkAsReadChatListAction( - &controller->session().data(), [f = folder()] { return f->chatsList(); }, addAction); @@ -807,8 +821,7 @@ not_null*> MainMenu::setupAddAccount( add(MTP::Environment::Production); return; } else if (which != Qt::RightButton - || !(button->clickModifiers() & Qt::ShiftModifier) - || !(button->clickModifiers() & Qt::AltModifier)) { + || !IsAltShift(button->clickModifiers())) { return; } _contextMenu = base::make_unique_q(this); diff --git a/Telegram/SourceFiles/window/window_peer_menu.cpp b/Telegram/SourceFiles/window/window_peer_menu.cpp index ad5f8d74a8..db943a372b 100644 --- a/Telegram/SourceFiles/window/window_peer_menu.cpp +++ b/Telegram/SourceFiles/window/window_peer_menu.cpp @@ -67,6 +67,31 @@ namespace { constexpr auto kArchivedToastDuration = crl::time(5000); constexpr auto kMaxUnreadWithoutConfirmation = 10000; +[[nodiscard]] bool IsUnreadHistory(not_null history) { + return (history->chatListUnreadCount() > 0) + || (history->chatListUnreadMark()); +} + +void MarkAsReadHistory(not_null history) { + const auto read = [&](not_null history) { + if (IsUnreadHistory(history)) { + history->peer->owner().histories().readInbox(history); + } + }; + read(history); + if (const auto migrated = history->migrateSibling()) { + read(migrated); + } +} + +void MarkAsReadChatList(not_null list) { + for (const auto &row : list->indexed()->all()) { + if (const auto history = row->history()) { + MarkAsReadHistory(history); + } + } +} + class Filler { public: Filler( @@ -359,31 +384,19 @@ void Filler::addInfo() { void Filler::addToggleUnreadMark() { const auto peer = _peer; const auto history = peer->owner().history(peer); - const auto isUnread = [=] { - return (history->chatListUnreadCount() > 0) - || (history->chatListUnreadMark()); - }; const auto label = [=] { - return isUnread() + return IsUnreadHistory(history) ? tr::lng_context_mark_read(tr::now) : tr::lng_context_mark_unread(tr::now); }; auto action = _addAction(label(), [=] { - const auto markAsRead = isUnread(); - const auto handle = [&](not_null history) { - if (markAsRead) { - peer->owner().histories().readInbox(history); - } else { - peer->owner().histories().changeDialogUnreadMark( - history, - !markAsRead); - } - }; - handle(history); + const auto markAsRead = IsUnreadHistory(history); if (markAsRead) { - if (const auto migrated = history->migrateSibling()) { - handle(migrated); - } + MarkAsReadHistory(history); + } else { + peer->owner().histories().changeDialogUnreadMark( + history, + !markAsRead); } }); @@ -713,7 +726,6 @@ void FolderFiller::addTogglesForArchive() { }); MenuAddMarkAsReadChatListAction( - &controller->session().data(), [folder = _folder] { return folder->chatsList(); }, _addAction); } @@ -1137,44 +1149,46 @@ void PeerMenuAddMuteAction( }, *lifetime); } -void MenuAddMarkAsReadChatListAction( +void MenuAddMarkAsReadAllChatsAction( not_null data, - Fn()> list, const PeerMenuCallback &addAction) { - const auto owner = data; + auto callback = [owner = data] { + auto boxCallback = [=](Fn &&close) { + close(); + + MarkAsReadChatList(owner->chatsList()); + if (const auto folder = owner->folderLoaded(Data::Folder::kId)) { + MarkAsReadChatList(folder->chatsList()); + } + }; + Ui::show(Box( + tr::lng_context_mark_read_all_sure(tr::now), + std::move(boxCallback))); + }; + addAction( + tr::lng_context_mark_read_all(tr::now), + std::move(callback)); +} + +void MenuAddMarkAsReadChatListAction( + Fn()> &&list, + const PeerMenuCallback &addAction) { const auto unreadState = list()->unreadState(); if (unreadState.empty()) { return; } - const auto read = [=](not_null history) { - if ((history->chatListUnreadCount() > 0) - || history->chatListUnreadMark()) { - owner->histories().readInbox(history); - } - }; - const auto markAsRead = [=] { - for (const auto row : list()->indexed()->all()) { - if (const auto history = row->history()) { - read(history); - if (const auto migrated = history->migrateSibling()) { - read(migrated); - } - } - } - }; - auto callback = [=] { if (unreadState.messages > kMaxUnreadWithoutConfirmation) { auto boxCallback = [=](Fn &&close) { - markAsRead(); + MarkAsReadChatList(list()); close(); }; Ui::show(Box( tr::lng_context_mark_read_sure(tr::now), std::move(boxCallback))); } else { - markAsRead(); + MarkAsReadChatList(list()); } }; addAction( diff --git a/Telegram/SourceFiles/window/window_peer_menu.h b/Telegram/SourceFiles/window/window_peer_menu.h index 87f601edcf..52706de669 100644 --- a/Telegram/SourceFiles/window/window_peer_menu.h +++ b/Telegram/SourceFiles/window/window_peer_menu.h @@ -59,9 +59,12 @@ void PeerMenuAddMuteAction( not_null peer, const PeerMenuCallback &addAction); -void MenuAddMarkAsReadChatListAction( +void MenuAddMarkAsReadAllChatsAction( not_null data, - Fn()> list, + const PeerMenuCallback &addAction); + +void MenuAddMarkAsReadChatListAction( + Fn()> &&list, const PeerMenuCallback &addAction); void PeerMenuExportChat(not_null peer);