diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index a5bbddb4e..61f791643 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -283,6 +283,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_settings_notifications_count" = "Notifications count"; "lng_settings_sound_notify" = "Play sound"; "lng_settings_include_muted" = "Include muted chats in unread count"; +"lng_settings_count_unread" = "Count unread messages"; "lng_notification_preview" = "You have a new message"; "lng_notification_reply" = "Reply"; diff --git a/Telegram/SourceFiles/auth_session.cpp b/Telegram/SourceFiles/auth_session.cpp index afd4aaea8..d9042b239 100644 --- a/Telegram/SourceFiles/auth_session.cpp +++ b/Telegram/SourceFiles/auth_session.cpp @@ -85,6 +85,8 @@ QByteArray AuthSessionSettings::serialize() const { stream << qint32(_variables.supportFixChatsOrder ? 1 : 0); stream << qint32(_variables.supportTemplatesAutocomplete ? 1 : 0); stream << qint32(_variables.supportChatsTimeSlice.current()); + stream << qint32(_variables.includeMutedCounter ? 1 : 0); + stream << qint32(_variables.countUnreadMessages ? 1 : 0); } return result; } @@ -116,6 +118,8 @@ void AuthSessionSettings::constructFromSerialized(const QByteArray &serialized) qint32 supportFixChatsOrder = _variables.supportFixChatsOrder ? 1 : 0; qint32 supportTemplatesAutocomplete = _variables.supportTemplatesAutocomplete ? 1 : 0; qint32 supportChatsTimeSlice = _variables.supportChatsTimeSlice.current(); + qint32 includeMutedCounter = _variables.includeMutedCounter ? 1 : 0; + qint32 countUnreadMessages = _variables.countUnreadMessages ? 1 : 0; stream >> selectorTab; stream >> lastSeenWarningSeen; @@ -182,6 +186,10 @@ void AuthSessionSettings::constructFromSerialized(const QByteArray &serialized) if (!stream.atEnd()) { stream >> supportChatsTimeSlice; } + if (!stream.atEnd()) { + stream >> includeMutedCounter; + stream >> countUnreadMessages; + } if (stream.status() != QDataStream::Ok) { LOG(("App Error: " "Bad data for AuthSessionSettings::constructFromSerialized()")); @@ -243,6 +251,8 @@ void AuthSessionSettings::constructFromSerialized(const QByteArray &serialized) _variables.supportTemplatesAutocomplete = (supportTemplatesAutocomplete == 1); _variables.supportChatsTimeSlice = supportChatsTimeSlice; _variables.hadLegacyCallsPeerToPeerNobody = (legacyCallsPeerToPeer == kLegacyCallsPeerToPeerNobody); + _variables.includeMutedCounter = (includeMutedCounter == 1); + _variables.countUnreadMessages = (countUnreadMessages == 1); } void AuthSessionSettings::setSupportChatsTimeSlice(int slice) { diff --git a/Telegram/SourceFiles/auth_session.h b/Telegram/SourceFiles/auth_session.h index 2494d5203..16e79298c 100644 --- a/Telegram/SourceFiles/auth_session.h +++ b/Telegram/SourceFiles/auth_session.h @@ -187,6 +187,19 @@ public: return _variables.hadLegacyCallsPeerToPeerNobody; } + bool includeMutedCounter() const { + return _variables.includeMutedCounter; + } + void setIncludeMutedCounter(bool value) { + _variables.includeMutedCounter = value; + } + bool countUnreadMessages() const { + return _variables.countUnreadMessages; + } + void setCountUnreadMessages(bool value) { + _variables.countUnreadMessages = value; + } + private: struct Variables { Variables(); @@ -212,6 +225,8 @@ private: = kDefaultThirdColumnWidth; // per-window Ui::InputSubmitSettings sendSubmitWay; bool hadLegacyCallsPeerToPeerNobody = false; + bool includeMutedCounter = true; + bool countUnreadMessages = true; static constexpr auto kDefaultSupportChatsLimitSlice = 7 * 24 * 60 * 60; diff --git a/Telegram/SourceFiles/data/data_feed.cpp b/Telegram/SourceFiles/data/data_feed.cpp index 14df12f17..09cf66e9f 100644 --- a/Telegram/SourceFiles/data/data_feed.cpp +++ b/Telegram/SourceFiles/data/data_feed.cpp @@ -361,13 +361,68 @@ bool Feed::unreadCountKnown() const { //} void Feed::changedInChatListHook(Dialogs::Mode list, bool added) { - if (list == Dialogs::Mode::All && unreadCount()) { + if (list != Dialogs::Mode::All) { + return; + } + if (const auto count = unreadCount()) { const auto mutedCount = _unreadMutedCount; - const auto nonMutedCount = unreadCount() - mutedCount; + const auto nonMutedCount = count - mutedCount; const auto mutedDelta = added ? mutedCount : -mutedCount; const auto nonMutedDelta = added ? nonMutedCount : -nonMutedCount; App::histories().unreadIncrement(nonMutedDelta, false); App::histories().unreadIncrement(mutedDelta, true); + + const auto fullMuted = (nonMutedCount == 0); + const auto entriesWithUnreadDelta = added ? 1 : -1; + const auto mutedEntriesWithUnreadDelta = fullMuted + ? entriesWithUnreadDelta + : 0; + App::histories().unreadEntriesChanged( + entriesWithUnreadDelta, + mutedEntriesWithUnreadDelta); + } +} + +template +void Feed::updateUnreadCounts(PerformUpdate &&performUpdate) { + const auto wasUnreadCount = _unreadCount ? *_unreadCount : 0; + const auto wasUnreadMutedCount = _unreadMutedCount; + const auto wasFullMuted = (wasUnreadMutedCount > 0) + && (wasUnreadCount == wasUnreadMutedCount); + + performUpdate(); + Assert(_unreadCount.has_value()); + + _unreadCountChanges.fire(unreadCount()); + updateChatListEntry(); + + if (inChatList(Dialogs::Mode::All)) { + const auto nowUnreadCount = *_unreadCount; + const auto nowUnreadMutedCount = _unreadMutedCount; + const auto nowFullMuted = (nowUnreadMutedCount > 0) + && (nowUnreadCount == nowUnreadMutedCount); + + App::histories().unreadIncrement( + (nowUnreadCount - nowUnreadMutedCount) + - (wasUnreadCount - wasUnreadMutedCount), + false); + App::histories().unreadIncrement( + nowUnreadMutedCount - wasUnreadMutedCount, + true); + + const auto entriesDelta = (nowUnreadCount && !wasUnreadCount) + ? 1 + : (wasUnreadCount && !nowUnreadCount) + ? -1 + : 0; + const auto mutedEntriesDelta = (!wasFullMuted && nowFullMuted) + ? 1 + : (wasFullMuted && !nowFullMuted) + ? -1 + : 0; + App::histories().unreadEntriesChanged( + entriesDelta, + mutedEntriesDelta); } } @@ -377,26 +432,10 @@ void Feed::setUnreadCounts(int unreadNonMutedCount, int unreadMutedCount) { && (_unreadMutedCount == unreadMutedCount)) { return; } - const auto unreadNonMutedCountDelta = _unreadCount | [&](int count) { - return unreadNonMutedCount - (count - _unreadMutedCount); - }; - const auto unreadMutedCountDelta = _unreadCount | [&](int count) { - return unreadMutedCount - _unreadMutedCount; - }; - _unreadCount = unreadNonMutedCount + unreadMutedCount; - _unreadMutedCount = unreadMutedCount; - - _unreadCountChanges.fire(unreadCount()); - updateChatListEntry(); - - if (inChatList(Dialogs::Mode::All)) { - App::histories().unreadIncrement( - unreadNonMutedCountDelta ? *unreadNonMutedCountDelta : unreadNonMutedCount, - false); - App::histories().unreadIncrement( - unreadMutedCountDelta ? *unreadMutedCountDelta : unreadMutedCount, - true); - } + updateUnreadCounts([&] { + _unreadCount = unreadNonMutedCount + unreadMutedCount; + _unreadMutedCount = unreadMutedCount; + }); } void Feed::setUnreadPosition(const MessagePosition &position) { @@ -405,30 +444,20 @@ void Feed::setUnreadPosition(const MessagePosition &position) { } } -void Feed::unreadCountChanged( - int unreadCountDelta, - int mutedCountDelta) { +void Feed::unreadCountChanged(int unreadCountDelta, int mutedCountDelta) { if (!unreadCountKnown()) { return; } - accumulate_max(unreadCountDelta, -*_unreadCount); - *_unreadCount += unreadCountDelta; + updateUnreadCounts([&] { + accumulate_max(unreadCountDelta, -*_unreadCount); + *_unreadCount += unreadCountDelta; - mutedCountDelta = snap( - mutedCountDelta, - -_unreadMutedCount, - *_unreadCount - _unreadMutedCount); - _unreadMutedCount += mutedCountDelta; - - _unreadCountChanges.fire(unreadCount()); - updateChatListEntry(); - - if (inChatList(Dialogs::Mode::All)) { - App::histories().unreadIncrement( - unreadCountDelta, - false); - App::histories().unreadMuteChanged(mutedCountDelta, true); - } + mutedCountDelta = snap( + mutedCountDelta, + -_unreadMutedCount, + *_unreadCount - _unreadMutedCount); + _unreadMutedCount += mutedCountDelta; + }); } MessagePosition Feed::unreadPosition() const { diff --git a/Telegram/SourceFiles/data/data_feed.h b/Telegram/SourceFiles/data/data_feed.h index 1cdf30e2f..8304dea62 100644 --- a/Telegram/SourceFiles/data/data_feed.h +++ b/Telegram/SourceFiles/data/data_feed.h @@ -94,6 +94,9 @@ private: const std::vector> &add, const std::vector> &remove); + template + void updateUnreadCounts(PerformUpdate &&performUpdate); + FeedId _id = 0; not_null _parent; std::vector> _channels; diff --git a/Telegram/SourceFiles/dialogs/dialogs_layout.cpp b/Telegram/SourceFiles/dialogs/dialogs_layout.cpp index 34d31ac78..2c8f323cb 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_layout.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_layout.cpp @@ -784,19 +784,30 @@ void paintImportantSwitch(Painter &p, Mode current, int fullWidth, bool selected p.setFont(st::semiboldFont); p.setPen(st::dialogsNameFg); - int unreadTop = (st::dialogsImportantBarHeight - st::dialogsUnreadHeight) / 2; - bool mutedHidden = (current == Dialogs::Mode::Important); - QString text = lang(mutedHidden ? lng_dialogs_show_all_chats : lng_dialogs_hide_muted_chats); - int textBaseline = unreadTop + (st::dialogsUnreadHeight - st::dialogsUnreadFont->height) / 2 + st::dialogsUnreadFont->ascent; + const auto unreadTop = (st::dialogsImportantBarHeight - st::dialogsUnreadHeight) / 2; + const auto mutedHidden = (current == Dialogs::Mode::Important); + const auto text = lang(mutedHidden + ? lng_dialogs_show_all_chats + : lng_dialogs_hide_muted_chats); + const auto textBaseline = unreadTop + + (st::dialogsUnreadHeight - st::dialogsUnreadFont->height) / 2 + + st::dialogsUnreadFont->ascent; p.drawText(st::dialogsPadding.x(), textBaseline, text); - if (mutedHidden) { - if (int32 unread = App::histories().unreadMutedCount()) { - int unreadRight = fullWidth - st::dialogsPadding.x(); - UnreadBadgeStyle st; - st.muted = true; - paintUnreadCount(p, QString::number(unread), unreadRight, unreadTop, st, nullptr); - } + if (!mutedHidden) { + return; + } + if (const auto unread = App::histories().unreadOnlyMutedBadge()) { + const auto unreadRight = fullWidth - st::dialogsPadding.x(); + UnreadBadgeStyle st; + st.muted = true; + paintUnreadCount( + p, + QString::number(unread), + unreadRight, + unreadTop, + st, + nullptr); } } diff --git a/Telegram/SourceFiles/facades.cpp b/Telegram/SourceFiles/facades.cpp index fc2eea6ed..499e2afff 100644 --- a/Telegram/SourceFiles/facades.cpp +++ b/Telegram/SourceFiles/facades.cpp @@ -639,7 +639,6 @@ struct Data { bool SoundNotify = true; bool DesktopNotify = true; bool RestoreSoundNotifyFromTray = false; - bool IncludeMuted = true; DBINotifyView NotifyView = dbinvShowPreview; bool NativeNotifications = false; int NotificationsCount = 3; @@ -769,7 +768,6 @@ DefineVar(Global, bool, VoiceMsgPlaybackDoubled); DefineVar(Global, bool, SoundNotify); DefineVar(Global, bool, DesktopNotify); DefineVar(Global, bool, RestoreSoundNotifyFromTray); -DefineVar(Global, bool, IncludeMuted); DefineVar(Global, DBINotifyView, NotifyView); DefineVar(Global, bool, NativeNotifications); DefineVar(Global, int, NotificationsCount); diff --git a/Telegram/SourceFiles/facades.h b/Telegram/SourceFiles/facades.h index aa5bca13d..c7bcb61a5 100644 --- a/Telegram/SourceFiles/facades.h +++ b/Telegram/SourceFiles/facades.h @@ -302,7 +302,6 @@ DeclareVar(bool, VoiceMsgPlaybackDoubled); DeclareVar(bool, SoundNotify); DeclareVar(bool, DesktopNotify); DeclareVar(bool, RestoreSoundNotifyFromTray); -DeclareVar(bool, IncludeMuted); DeclareVar(DBINotifyView, NotifyView); DeclareVar(bool, NativeNotifications); DeclareVar(int, NotificationsCount); diff --git a/Telegram/SourceFiles/history/history.cpp b/Telegram/SourceFiles/history/history.cpp index f7f113819..4af5ea2cc 100644 --- a/Telegram/SourceFiles/history/history.cpp +++ b/Telegram/SourceFiles/history/history.cpp @@ -108,6 +108,7 @@ void Histories::clear() { _map.clear(); _unreadFull = _unreadMuted = 0; + _unreadEntriesFull = _unreadEntriesMuted = 0; Notify::unreadCounterUpdated(); App::historyClearItems(); typing.clear(); @@ -164,34 +165,135 @@ HistoryItem *Histories::addNewMessage( } int Histories::unreadBadge() const { - return _unreadFull - (Global::IncludeMuted() ? 0 : _unreadMuted); + return computeUnreadBadge( + _unreadFull, + _unreadMuted, + _unreadEntriesFull, + _unreadEntriesMuted); } -int Histories::unreadMutedCount() const { - return _unreadMuted; +bool Histories::unreadBadgeMuted() const { + return computeUnreadBadgeMuted( + _unreadFull, + _unreadMuted, + _unreadEntriesFull, + _unreadEntriesMuted); +} + +int Histories::unreadBadgeIgnoreOne(History *history) const { + const auto removeCount = (history + && history->inChatList(Dialogs::Mode::All)) + ? history->unreadCount() + : 0; + if (!removeCount) { + return unreadBadge(); + } + const auto removeMuted = history->mute(); + return computeUnreadBadge( + _unreadFull - removeCount, + _unreadMuted - (removeMuted ? removeCount : 0), + _unreadEntriesFull - 1, + _unreadEntriesMuted - (removeMuted ? 1 : 0)); +} + +bool Histories::unreadBadgeMutedIgnoreOne(History *history) const { + const auto removeCount = (history + && history->inChatList(Dialogs::Mode::All)) + ? history->unreadCount() + : 0; + if (!removeCount) { + return unreadBadgeMuted(); + } + const auto removeMuted = history->mute(); + return computeUnreadBadgeMuted( + _unreadFull - removeCount, + _unreadMuted - (removeMuted ? removeCount : 0), + _unreadEntriesFull - 1, + _unreadEntriesMuted - (removeMuted ? 1 : 0)); +} + +int Histories::unreadOnlyMutedBadge() const { + return Auth().settings().countUnreadMessages() + ? _unreadMuted + : _unreadEntriesMuted; +} + +int Histories::computeUnreadBadge( + int full, + int muted, + int entriesFull, + int entriesMuted) const { + const auto withMuted = Auth().settings().includeMutedCounter(); + return Auth().settings().countUnreadMessages() + ? (full - (withMuted ? 0 : muted)) + : (entriesFull - (withMuted ? 0 : entriesMuted)); +} + +bool Histories::computeUnreadBadgeMuted( + int full, + int muted, + int entriesFull, + int entriesMuted) const { + if (!Auth().settings().includeMutedCounter()) { + return false; + } + return Auth().settings().countUnreadMessages() + ? (muted >= full) + : (entriesMuted >= entriesFull); } void Histories::unreadIncrement(int count, bool muted) { + if (!count) { + return; + } _unreadFull += count; if (muted) { _unreadMuted += count; } - if (!muted || Global::IncludeMuted()) { - Notify::unreadCounterUpdated(); + if (Auth().settings().countUnreadMessages()) { + if (!muted || Auth().settings().includeMutedCounter()) { + Notify::unreadCounterUpdated(); + } } } void Histories::unreadMuteChanged(int count, bool muted) { + const auto wasAll = (_unreadMuted == _unreadFull); if (muted) { _unreadMuted += count; } else { _unreadMuted -= count; } - Notify::unreadCounterUpdated(); + if (Auth().settings().countUnreadMessages()) { + const auto nowAll = (_unreadMuted == _unreadFull); + const auto changed = !Auth().settings().includeMutedCounter() + || (wasAll != nowAll); + if (changed) { + Notify::unreadCounterUpdated(); + } + } } -bool Histories::unreadOnlyMuted() const { - return Global::IncludeMuted() ? (_unreadMuted >= _unreadFull) : false; +void Histories::unreadEntriesChanged( + int withUnreadDelta, + int mutedWithUnreadDelta) { + if (!withUnreadDelta && !mutedWithUnreadDelta) { + return; + } + const auto wasAll = (_unreadEntriesMuted == _unreadEntriesFull); + _unreadEntriesFull += withUnreadDelta; + _unreadEntriesMuted += mutedWithUnreadDelta; + if (!Auth().settings().countUnreadMessages()) { + const auto nowAll = (_unreadEntriesMuted == _unreadEntriesFull); + const auto withMuted = Auth().settings().includeMutedCounter(); + const auto withMutedChanged = withMuted + && (withUnreadDelta != 0 || wasAll != nowAll); + const auto withoutMutedChanged = !withMuted + && (withUnreadDelta != mutedWithUnreadDelta); + if (withMutedChanged || withoutMutedChanged) { + Notify::unreadCounterUpdated(); + } + } } void Histories::selfDestructIn(not_null item, TimeMs delay) { @@ -1655,6 +1757,7 @@ bool History::unreadCountKnown() const { void History::setUnreadCount(int newUnreadCount) { if (!_unreadCount || *_unreadCount != newUnreadCount) { + const auto wasUnread = _unreadMark || unreadCount(); const auto unreadCountDelta = _unreadCount | [&](int count) { return newUnreadCount - count; }; @@ -1699,12 +1802,20 @@ void History::setUnreadCount(int newUnreadCount) { } if (inChatList(Dialogs::Mode::All)) { - const auto delta = unreadCountDelta + const auto delta = unreadMarkDelta + (unreadCountDelta ? *unreadCountDelta - : newUnreadCount; - App::histories().unreadIncrement( - delta + unreadMarkDelta, - mute()); + : newUnreadCount); + App::histories().unreadIncrement(delta, mute()); + + const auto nowUnread = (*_unreadCount > 0) || _unreadMark; + const auto entriesDelta = (wasUnread && !nowUnread) + ? -1 + : (nowUnread && !wasUnread) + ? 1 + : 0; + App::histories().unreadEntriesChanged( + entriesDelta, + mute() ? entriesDelta : 0); } Notify::peerUpdatedDelayed( peer, @@ -1722,6 +1833,9 @@ void History::setUnreadMark(bool unread) { if (inChatList(Dialogs::Mode::All)) { const auto delta = _unreadMark ? 1 : -1; App::histories().unreadIncrement(delta, mute()); + App::histories().unreadEntriesChanged( + delta, + mute() ? delta : 0); updateChatListEntry(); } @@ -1776,6 +1890,13 @@ bool History::changeMute(bool newMute) { if (inChatList(Dialogs::Mode::All)) { if (const auto count = historiesUnreadCount()) { App::histories().unreadMuteChanged(count, _mute); + + const auto entriesWithUnreadDelta = 0; + const auto mutedEntriesWithUnreadDelta = _mute ? 1 : -1; + App::histories().unreadEntriesChanged( + entriesWithUnreadDelta, + mutedEntriesWithUnreadDelta); + Notify::unreadCounterUpdated(); } Notify::historyMuteUpdated(this); @@ -2755,6 +2876,11 @@ void History::changedInChatListHook(Dialogs::Mode list, bool added) { if (list == Dialogs::Mode::All) { if (const auto delta = historiesUnreadCount() * (added ? 1 : -1)) { App::histories().unreadIncrement(delta, mute()); + + const auto entriesDelta = added ? 1 : -1; + App::histories().unreadEntriesChanged( + entriesDelta, + mute() ? entriesDelta : 0); } } } diff --git a/Telegram/SourceFiles/history/history.h b/Telegram/SourceFiles/history/history.h index 44de34fbc..a4fc1e869 100644 --- a/Telegram/SourceFiles/history/history.h +++ b/Telegram/SourceFiles/history/history.h @@ -23,6 +23,7 @@ class HistoryItem; class HistoryMessage; class HistoryService; class HistoryMedia; +class AuthSession; namespace Data { struct Draft; @@ -72,10 +73,16 @@ public: BasicAnimation _a_typings; int unreadBadge() const; - int unreadMutedCount() const; - bool unreadOnlyMuted() const; + bool unreadBadgeMuted() const; + int unreadBadgeIgnoreOne(History *history) const; + bool unreadBadgeMutedIgnoreOne(History *history) const; + int unreadOnlyMutedBadge() const; + void unreadIncrement(int count, bool muted); void unreadMuteChanged(int count, bool muted); + void unreadEntriesChanged( + int withUnreadDelta, + int mutedWithUnreadDelta); struct SendActionAnimationUpdate { History *history; @@ -90,11 +97,23 @@ public: private: void checkSelfDestructItems(); + int computeUnreadBadge( + int full, + int muted, + int entriesFull, + int entriesMuted) const; + bool computeUnreadBadgeMuted( + int full, + int muted, + int entriesFull, + int entriesMuted) const; std::unordered_map> _map; int _unreadFull = 0; int _unreadMuted = 0; + int _unreadEntriesFull = 0; + int _unreadEntriesMuted = 0; base::Observable _sendActionAnimationUpdated; base::Timer _selfDestructTimer; diff --git a/Telegram/SourceFiles/history/view/history_view_top_bar_widget.cpp b/Telegram/SourceFiles/history/view/history_view_top_bar_widget.cpp index 6bbebf432..2efb04789 100644 --- a/Telegram/SourceFiles/history/view/history_view_top_bar_widget.cpp +++ b/Telegram/SourceFiles/history/view/history_view_top_bar_widget.cpp @@ -695,28 +695,18 @@ void TopBarWidget::createUnreadBadge() { void TopBarWidget::updateUnreadBadge() { if (!_unreadBadge) return; - auto mutedCount = App::histories().unreadMutedCount(); - auto fullCounter = App::histories().unreadBadge() - + (Global::IncludeMuted() ? 0 : mutedCount); - - // Do not include currently shown chat in the top bar unread counter. - if (const auto history = _activeChat.history()) { - auto shownUnreadCount = history->unreadCount(); - fullCounter -= shownUnreadCount; - if (history->mute()) { - mutedCount -= shownUnreadCount; + const auto history = _activeChat.history(); + const auto active = !App::histories().unreadBadgeMutedIgnoreOne(history); + const auto counter = App::histories().unreadBadgeIgnoreOne(history); + const auto text = [&] { + if (!counter) { + return QString(); } - } - - auto active = (mutedCount < fullCounter); - _unreadBadge->setText([&] { - if (auto counter = (fullCounter - (Global::IncludeMuted() ? 0 : mutedCount))) { - return (counter > 999) - ? qsl("..%1").arg(counter % 100, 2, 10, QChar('0')) - : QString::number(counter); - } - return QString(); - }(), active); + return (counter > 999) + ? qsl("..%1").arg(counter % 100, 2, 10, QChar('0')) + : QString::number(counter); + }(); + _unreadBadge->setText(text, active); } void TopBarWidget::updateInfoToggleActive() { diff --git a/Telegram/SourceFiles/messenger.cpp b/Telegram/SourceFiles/messenger.cpp index 80736d800..85cc09659 100644 --- a/Telegram/SourceFiles/messenger.cpp +++ b/Telegram/SourceFiles/messenger.cpp @@ -740,14 +740,23 @@ void Messenger::authSessionDestroy() { authSessionChanged().notify(true); } +int Messenger::unreadBadge() const { + return _authSession ? App::histories().unreadBadge() : 0; +} + +bool Messenger::unreadBadgeMuted() const { + return _authSession ? App::histories().unreadBadgeMuted() : false; +} + void Messenger::setInternalLinkDomain(const QString &domain) const { - // This domain should start with 'http[s]://' and end with '/', like 'https://t.me/'. - auto validate = [](auto &domain) { - auto prefixes = { + // This domain should start with 'http[s]://' and end with '/'. + // Like 'https://telegram.me/' or 'https://t.me/'. + auto validate = [](const auto &domain) { + const auto prefixes = { qstr("https://"), qstr("http://"), }; - for (auto &prefix : prefixes) { + for (const auto &prefix : prefixes) { if (domain.startsWith(prefix, Qt::CaseInsensitive)) { return domain.endsWith('/'); } diff --git a/Telegram/SourceFiles/messenger.h b/Telegram/SourceFiles/messenger.h index e6e5cc537..c4185b82f 100644 --- a/Telegram/SourceFiles/messenger.h +++ b/Telegram/SourceFiles/messenger.h @@ -153,6 +153,8 @@ public: base::Observable &authSessionChanged() { return _authSessionChanged; } + int unreadBadge() const; + bool unreadBadgeMuted() const; void logOut(); // Media component. diff --git a/Telegram/SourceFiles/platform/linux/main_window_linux.cpp b/Telegram/SourceFiles/platform/linux/main_window_linux.cpp index 3555bed6f..e4dbc47ef 100644 --- a/Telegram/SourceFiles/platform/linux/main_window_linux.cpp +++ b/Telegram/SourceFiles/platform/linux/main_window_linux.cpp @@ -71,8 +71,11 @@ gboolean _trayIconResized(GtkStatusIcon *status_icon, gint size, gpointer popup_ #endif // !TDESKTOP_DISABLE_GTK_INTEGRATION QImage _trayIconImageGen() { - int32 counter = App::histories().unreadBadge(), counterSlice = (counter >= 1000) ? (1000 + (counter % 100)) : counter; - bool muted = App::histories().unreadOnlyMuted(); + const auto counter = Messenger::Instance().unreadBadge(); + const auto muted = Messenger::Instance().unreadBadgeMuted(); + const auto counterSlice = (counter >= 1000) + ? (1000 + (counter % 100)) + : counter; if (_trayIconImage.isNull() || _trayIconImage.width() != _trayIconSize || muted != _trayIconMuted || counterSlice != _trayIconCount) { if (_trayIconImageBack.isNull() || _trayIconImageBack.width() != _trayIconSize) { _trayIconImageBack = Messenger::Instance().logo().scaled(_trayIconSize, _trayIconSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); @@ -109,8 +112,9 @@ QImage _trayIconImageGen() { } QString _trayIconImageFile() { - int32 counter = App::histories().unreadBadge(), counterSlice = (counter >= 1000) ? (1000 + (counter % 100)) : counter; - bool muted = App::histories().unreadOnlyMuted(); + const auto counter = Messenger::Instance().unreadBadge(); + const auto muted = Messenger::Instance().unreadBadgeMuted(); + const auto counterSlice = (counter >= 1000) ? (1000 + (counter % 100)) : counter; QString name = cWorkingDir() + qsl("tdata/ticons/ico%1_%2_%3.png").arg(muted ? "mute" : "").arg(_trayIconSize).arg(counterSlice); QFileInfo info(name); @@ -329,7 +333,7 @@ void MainWindow::unreadCounterChangedHook() { void MainWindow::updateIconCounters() { updateWindowIcon(); - auto counter = App::histories().unreadBadge(); + const auto counter = Messenger::Instance().unreadBadge(); #if !defined(TDESKTOP_DISABLE_GTK_INTEGRATION) && !defined(TDESKTOP_DISABLE_UNITY_INTEGRATION) if (_psUnityLauncherEntry) { @@ -368,8 +372,8 @@ void MainWindow::updateIconCounters() { QByteArray path = QFile::encodeName(iconFile.absoluteFilePath()); icon = QIcon(path.constData()); } else { - int32 counter = App::histories().unreadBadge(); - bool muted = App::histories().unreadOnlyMuted(); + const auto counter = Messenger::Instance().unreadBadge(); + const auto muted = Messenger::Instance().unreadBadgeMuted(); auto &bg = (muted ? st::trayCounterBgMute : st::trayCounterBg); auto &fg = st::trayCounterFg; diff --git a/Telegram/SourceFiles/platform/mac/main_window_mac.mm b/Telegram/SourceFiles/platform/mac/main_window_mac.mm index 961279819..f1b34ee86 100644 --- a/Telegram/SourceFiles/platform/mac/main_window_mac.mm +++ b/Telegram/SourceFiles/platform/mac/main_window_mac.mm @@ -522,15 +522,18 @@ void MainWindow::unreadCounterChangedHook() { } void MainWindow::updateIconCounters() { - auto counter = App::histories().unreadBadge(); + const auto counter = Messenger::Instance().unreadBadge(); + const auto muted = Messenger::Instance().unreadBadgeMuted(); - QString cnt = (counter < 1000) ? QString("%1").arg(counter) : QString("..%1").arg(counter % 100, 2, 10, QChar('0')); - _private->setWindowBadge(counter ? cnt : QString()); + const auto string = !counter + ? QString() + : (counter < 1000) + ? QString("%1").arg(counter) + : QString("..%1").arg(counter % 100, 2, 10, QChar('0')); + _private->setWindowBadge(string); if (trayIcon) { - bool muted = App::histories().unreadOnlyMuted(); bool dm = objc_darkMode(); - auto &bg = (muted ? st::trayCounterBgMute : st::trayCounterBg); QIcon icon; QImage img(psTrayIcon(dm)), imgsel(psTrayIcon(true)); diff --git a/Telegram/SourceFiles/platform/win/main_window_win.cpp b/Telegram/SourceFiles/platform/win/main_window_win.cpp index 9e5fc3bb7..18688de49 100644 --- a/Telegram/SourceFiles/platform/win/main_window_win.cpp +++ b/Telegram/SourceFiles/platform/win/main_window_win.cpp @@ -727,8 +727,8 @@ void MainWindow::unreadCounterChangedHook() { } void MainWindow::updateIconCounters() { - auto counter = App::histories().unreadBadge(); - auto muted = App::histories().unreadOnlyMuted(); + const auto counter = Messenger::Instance().unreadBadge(); + const auto muted = Messenger::Instance().unreadBadgeMuted(); auto iconSizeSmall = QSize(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON)); auto iconSizeBig = QSize(GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON)); diff --git a/Telegram/SourceFiles/settings/settings_notifications.cpp b/Telegram/SourceFiles/settings/settings_notifications.cpp index 641e48542..fdef59180 100644 --- a/Telegram/SourceFiles/settings/settings_notifications.cpp +++ b/Telegram/SourceFiles/settings/settings_notifications.cpp @@ -545,7 +545,10 @@ void SetupNotificationsContent(not_null container) { Global::SoundNotify()); const auto muted = addCheckbox( lng_settings_include_muted, - Global::IncludeMuted()); + Auth().settings().includeMutedCounter()); + const auto count = addCheckbox( + lng_settings_count_unread, + Auth().settings().countUnreadMessages()); const auto nativeNotificationsKey = [&] { if (!Platform::Notifications::Supported()) { @@ -644,12 +647,21 @@ void SetupNotificationsContent(not_null container) { base::ObservableViewer( muted->checkedChanged ) | rpl::filter([](bool checked) { - return (checked != Global::IncludeMuted()); + return (checked != Auth().settings().includeMutedCounter()); }) | rpl::start_with_next([=](bool checked) { - Global::SetIncludeMuted(checked); + Auth().settings().setIncludeMutedCounter(checked); changed(Change::IncludeMuted); }, muted->lifetime()); + base::ObservableViewer( + count->checkedChanged + ) | rpl::filter([](bool checked) { + return (checked != Auth().settings().countUnreadMessages()); + }) | rpl::start_with_next([=](bool checked) { + Auth().settings().setCountUnreadMessages(checked); + changed(Change::CountMessages); + }, muted->lifetime()); + base::ObservableViewer( Auth().notifications().settingsChanged() ) | rpl::start_with_next([=](Change change) { diff --git a/Telegram/SourceFiles/storage/localstorage.cpp b/Telegram/SourceFiles/storage/localstorage.cpp index 06d799a8f..0876bf105 100644 --- a/Telegram/SourceFiles/storage/localstorage.cpp +++ b/Telegram/SourceFiles/storage/localstorage.cpp @@ -563,7 +563,7 @@ enum { dbiTryIPv6 = 0x28, dbiSongVolume = 0x29, dbiWindowsNotificationsOld = 0x30, - dbiIncludeMuted = 0x31, + dbiIncludeMutedOld = 0x31, dbiMegagroupSizeMax = 0x32, dbiDownloadPath = 0x33, dbiAutoDownload = 0x34, @@ -1099,12 +1099,12 @@ bool _readSetting(quint32 blockId, QDataStream &stream, int version, ReadSetting Global::SetModerateModeEnabled(enabled == 1); } break; - case dbiIncludeMuted: { + case dbiIncludeMutedOld: { qint32 v; stream >> v; if (!_checkStreamStatus(stream)) return false; - Global::SetIncludeMuted(v == 1); + GetStoredAuthSessionCache().setIncludeMutedCounter(v == 1); } break; case dbiShowingSavedGifsOld: { @@ -2019,7 +2019,6 @@ void _writeUserSettings() { data.stream << quint32(dbiSuggestEmoji) << qint32(Global::SuggestEmoji() ? 1 : 0); data.stream << quint32(dbiSuggestStickersByEmoji) << qint32(Global::SuggestStickersByEmoji() ? 1 : 0); data.stream << quint32(dbiSoundNotify) << qint32(Global::SoundNotify()); - data.stream << quint32(dbiIncludeMuted) << qint32(Global::IncludeMuted()); data.stream << quint32(dbiDesktopNotify) << qint32(Global::DesktopNotify()); data.stream << quint32(dbiNotifyView) << qint32(Global::NotifyView()); data.stream << quint32(dbiNativeNotifications) << qint32(Global::NativeNotifications()); diff --git a/Telegram/SourceFiles/window/main_window.cpp b/Telegram/SourceFiles/window/main_window.cpp index 9ce639e82..e1bc675c2 100644 --- a/Telegram/SourceFiles/window/main_window.cpp +++ b/Telegram/SourceFiles/window/main_window.cpp @@ -427,7 +427,9 @@ void MainWindow::updateControlsGeometry() { void MainWindow::updateUnreadCounter() { if (!Global::started() || App::quitting()) return; - auto counter = App::histories().unreadBadge(); + const auto counter = AuthSession::Exists() + ? App::histories().unreadBadge() + : 0; _titleText = (counter > 0) ? qsl("Telegram (%1)").arg(counter) : qsl("Telegram"); unreadCounterChangedHook(); diff --git a/Telegram/SourceFiles/window/notifications_manager.cpp b/Telegram/SourceFiles/window/notifications_manager.cpp index 33526049c..2b2bd98cd 100644 --- a/Telegram/SourceFiles/window/notifications_manager.cpp +++ b/Telegram/SourceFiles/window/notifications_manager.cpp @@ -45,7 +45,8 @@ System::System(AuthSession *session) : _authSession(session) { clearAll(); } else if (type == ChangeType::ViewParams) { updateAll(); - } else if (type == ChangeType::IncludeMuted) { + } else if (type == ChangeType::IncludeMuted + || type == ChangeType::CountMessages) { Notify::unreadCounterUpdated(); } }); diff --git a/Telegram/SourceFiles/window/notifications_manager.h b/Telegram/SourceFiles/window/notifications_manager.h index 83a8936be..044b71331 100644 --- a/Telegram/SourceFiles/window/notifications_manager.h +++ b/Telegram/SourceFiles/window/notifications_manager.h @@ -27,6 +27,7 @@ namespace Notifications { enum class ChangeType { SoundEnabled, IncludeMuted, + CountMessages, DesktopEnabled, ViewParams, MaxCount,