Added ability to mark all chats as read.

This commit is contained in:
23rd 2020-09-17 17:56:01 +03:00 committed by John Preston
parent bdce2d5e25
commit aecdc01e41
5 changed files with 79 additions and 48 deletions

View file

@ -1458,6 +1458,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_context_mark_unread" = "Mark as unread"; "lng_context_mark_unread" = "Mark as unread";
"lng_context_mark_read" = "Mark as read"; "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_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_expand" = "Expand";
"lng_context_archive_collapse" = "Collapse"; "lng_context_archive_collapse" = "Collapse";
"lng_context_archive_to_menu" = "Move to main menu"; "lng_context_archive_to_menu" = "Move to main menu";

View file

@ -322,7 +322,6 @@ void FiltersMenu::showMenu(QPoint position, FilterId id) {
return _session->session().data().chatsFilters().chatsList(id); return _session->session().data().chatsFilters().chatsList(id);
}; };
Window::MenuAddMarkAsReadChatListAction( Window::MenuAddMarkAsReadChatListAction(
&_session->session().data(),
std::move(filteredChats), std::move(filteredChats),
addAction); addAction);

View file

@ -90,6 +90,10 @@ constexpr auto kMinDiffIntensity = 0.25;
|| Data::IsLegacy1DefaultWallPaper(background->paper()); || Data::IsLegacy1DefaultWallPaper(background->paper());
} }
[[nodiscard]] bool IsAltShift(Qt::KeyboardModifiers modifiers) {
return (modifiers & Qt::ShiftModifier) && (modifiers & Qt::AltModifier);
}
} // namespace } // namespace
namespace Window { namespace Window {
@ -273,6 +277,17 @@ void MainMenu::AccountButton::paintEvent(QPaintEvent *e) {
} }
void MainMenu::AccountButton::contextMenuEvent(QContextMenuEvent *e) { void MainMenu::AccountButton::contextMenuEvent(QContextMenuEvent *e) {
if (!_menu && IsAltShift(e->modifiers())) {
_menu = base::make_unique_q<Ui::PopupMenu>(this);
const auto addAction = [&](const QString &text, Fn<void()> 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) { if (&_session->account() == &Core::App().activeAccount() || _menu) {
return; return;
} }
@ -639,7 +654,6 @@ void MainMenu::setupArchiveButton() {
addAction(tr::lng_context_archive_to_list(tr::now), std::move(hide)); addAction(tr::lng_context_archive_to_list(tr::now), std::move(hide));
MenuAddMarkAsReadChatListAction( MenuAddMarkAsReadChatListAction(
&controller->session().data(),
[f = folder()] { return f->chatsList(); }, [f = folder()] { return f->chatsList(); },
addAction); addAction);
@ -807,8 +821,7 @@ not_null<Ui::SlideWrap<Ui::RippleButton>*> MainMenu::setupAddAccount(
add(MTP::Environment::Production); add(MTP::Environment::Production);
return; return;
} else if (which != Qt::RightButton } else if (which != Qt::RightButton
|| !(button->clickModifiers() & Qt::ShiftModifier) || !IsAltShift(button->clickModifiers())) {
|| !(button->clickModifiers() & Qt::AltModifier)) {
return; return;
} }
_contextMenu = base::make_unique_q<Ui::PopupMenu>(this); _contextMenu = base::make_unique_q<Ui::PopupMenu>(this);

View file

@ -67,6 +67,31 @@ namespace {
constexpr auto kArchivedToastDuration = crl::time(5000); constexpr auto kArchivedToastDuration = crl::time(5000);
constexpr auto kMaxUnreadWithoutConfirmation = 10000; constexpr auto kMaxUnreadWithoutConfirmation = 10000;
[[nodiscard]] bool IsUnreadHistory(not_null<History*> history) {
return (history->chatListUnreadCount() > 0)
|| (history->chatListUnreadMark());
}
void MarkAsReadHistory(not_null<History*> history) {
const auto read = [&](not_null<History*> history) {
if (IsUnreadHistory(history)) {
history->peer->owner().histories().readInbox(history);
}
};
read(history);
if (const auto migrated = history->migrateSibling()) {
read(migrated);
}
}
void MarkAsReadChatList(not_null<Dialogs::MainList*> list) {
for (const auto &row : list->indexed()->all()) {
if (const auto history = row->history()) {
MarkAsReadHistory(history);
}
}
}
class Filler { class Filler {
public: public:
Filler( Filler(
@ -359,31 +384,19 @@ void Filler::addInfo() {
void Filler::addToggleUnreadMark() { void Filler::addToggleUnreadMark() {
const auto peer = _peer; const auto peer = _peer;
const auto history = peer->owner().history(peer); const auto history = peer->owner().history(peer);
const auto isUnread = [=] {
return (history->chatListUnreadCount() > 0)
|| (history->chatListUnreadMark());
};
const auto label = [=] { const auto label = [=] {
return isUnread() return IsUnreadHistory(history)
? tr::lng_context_mark_read(tr::now) ? tr::lng_context_mark_read(tr::now)
: tr::lng_context_mark_unread(tr::now); : tr::lng_context_mark_unread(tr::now);
}; };
auto action = _addAction(label(), [=] { auto action = _addAction(label(), [=] {
const auto markAsRead = isUnread(); const auto markAsRead = IsUnreadHistory(history);
const auto handle = [&](not_null<History*> history) {
if (markAsRead) {
peer->owner().histories().readInbox(history);
} else {
peer->owner().histories().changeDialogUnreadMark(
history,
!markAsRead);
}
};
handle(history);
if (markAsRead) { if (markAsRead) {
if (const auto migrated = history->migrateSibling()) { MarkAsReadHistory(history);
handle(migrated); } else {
} peer->owner().histories().changeDialogUnreadMark(
history,
!markAsRead);
} }
}); });
@ -713,7 +726,6 @@ void FolderFiller::addTogglesForArchive() {
}); });
MenuAddMarkAsReadChatListAction( MenuAddMarkAsReadChatListAction(
&controller->session().data(),
[folder = _folder] { return folder->chatsList(); }, [folder = _folder] { return folder->chatsList(); },
_addAction); _addAction);
} }
@ -1137,44 +1149,46 @@ void PeerMenuAddMuteAction(
}, *lifetime); }, *lifetime);
} }
void MenuAddMarkAsReadChatListAction( void MenuAddMarkAsReadAllChatsAction(
not_null<Data::Session*> data, not_null<Data::Session*> data,
Fn<not_null<Dialogs::MainList*>()> list,
const PeerMenuCallback &addAction) { const PeerMenuCallback &addAction) {
const auto owner = data; auto callback = [owner = data] {
auto boxCallback = [=](Fn<void()> &&close) {
close();
MarkAsReadChatList(owner->chatsList());
if (const auto folder = owner->folderLoaded(Data::Folder::kId)) {
MarkAsReadChatList(folder->chatsList());
}
};
Ui::show(Box<ConfirmBox>(
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<not_null<Dialogs::MainList*>()> &&list,
const PeerMenuCallback &addAction) {
const auto unreadState = list()->unreadState(); const auto unreadState = list()->unreadState();
if (unreadState.empty()) { if (unreadState.empty()) {
return; return;
} }
const auto read = [=](not_null<History*> 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 = [=] { auto callback = [=] {
if (unreadState.messages > kMaxUnreadWithoutConfirmation) { if (unreadState.messages > kMaxUnreadWithoutConfirmation) {
auto boxCallback = [=](Fn<void()> &&close) { auto boxCallback = [=](Fn<void()> &&close) {
markAsRead(); MarkAsReadChatList(list());
close(); close();
}; };
Ui::show(Box<ConfirmBox>( Ui::show(Box<ConfirmBox>(
tr::lng_context_mark_read_sure(tr::now), tr::lng_context_mark_read_sure(tr::now),
std::move(boxCallback))); std::move(boxCallback)));
} else { } else {
markAsRead(); MarkAsReadChatList(list());
} }
}; };
addAction( addAction(

View file

@ -59,9 +59,12 @@ void PeerMenuAddMuteAction(
not_null<PeerData*> peer, not_null<PeerData*> peer,
const PeerMenuCallback &addAction); const PeerMenuCallback &addAction);
void MenuAddMarkAsReadChatListAction( void MenuAddMarkAsReadAllChatsAction(
not_null<Data::Session*> data, not_null<Data::Session*> data,
Fn<not_null<Dialogs::MainList*>()> list, const PeerMenuCallback &addAction);
void MenuAddMarkAsReadChatListAction(
Fn<not_null<Dialogs::MainList*>()> &&list,
const PeerMenuCallback &addAction); const PeerMenuCallback &addAction);
void PeerMenuExportChat(not_null<PeerData*> peer); void PeerMenuExportChat(not_null<PeerData*> peer);