Refactoring

This commit is contained in:
Ali 2021-09-22 20:56:50 +03:00
parent c5614c77e4
commit dd19880091
12 changed files with 110 additions and 51 deletions

View File

@ -662,7 +662,7 @@ private final class NotificationServiceHandler {
return
}
let _ = (renderedTotalUnreadCount(
let _ = (getCurrentRenderedTotalUnreadCount(
accountManager: strongSelf.accountManager,
postbox: stateManager.postbox
)
@ -792,7 +792,7 @@ private final class NotificationServiceHandler {
guard let strongSelf = self else {
return
}
let _ = (renderedTotalUnreadCount(
let _ = (getCurrentRenderedTotalUnreadCount(
accountManager: strongSelf.accountManager,
postbox: stateManager.postbox
)
@ -835,7 +835,7 @@ private final class NotificationServiceHandler {
guard let strongSelf = self else {
return
}
let _ = (renderedTotalUnreadCount(
let _ = (getCurrentRenderedTotalUnreadCount(
accountManager: strongSelf.accountManager,
postbox: stateManager.postbox
)

View File

@ -11,7 +11,6 @@ swift_library(
],
deps = [
"//submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit",
"//submodules/Postbox:Postbox",
"//submodules/TelegramCore:TelegramCore",
"//submodules/AccountContext:AccountContext",
"//submodules/TelegramUIPreferences:TelegramUIPreferences",

View File

@ -1,26 +1,31 @@
import Foundation
import SwiftSignalKit
import Postbox
import TelegramCore
import TelegramUIPreferences
import AccountContext
public let maximumNumberOfAccounts = 3
public func activeAccountsAndPeers(context: AccountContext, includePrimary: Bool = false) -> Signal<((AccountContext, Peer)?, [(AccountContext, Peer, Int32)]), NoError> {
public func activeAccountsAndPeers(context: AccountContext, includePrimary: Bool = false) -> Signal<((AccountContext, EnginePeer)?, [(AccountContext, EnginePeer, Int32)]), NoError> {
let sharedContext = context.sharedContext
return context.sharedContext.activeAccountContexts
|> mapToSignal { primary, activeAccounts, _ -> Signal<((AccountContext, Peer)?, [(AccountContext, Peer, Int32)]), NoError> in
var accounts: [Signal<(AccountContext, Peer, Int32)?, NoError>] = []
func accountWithPeer(_ context: AccountContext) -> Signal<(AccountContext, Peer, Int32)?, NoError> {
return combineLatest(context.account.postbox.peerView(id: context.account.peerId), renderedTotalUnreadCount(accountManager: sharedContext.accountManager, postbox: context.account.postbox))
|> map { view, totalUnreadCount -> (Peer?, Int32) in
return (view.peers[view.peerId], totalUnreadCount.0)
|> mapToSignal { primary, activeAccounts, _ -> Signal<((AccountContext, EnginePeer)?, [(AccountContext, EnginePeer, Int32)]), NoError> in
var accounts: [Signal<(AccountContext, EnginePeer, Int32)?, NoError>] = []
func accountWithPeer(_ context: AccountContext) -> Signal<(AccountContext, EnginePeer, Int32)?, NoError> {
return combineLatest(context.account.postbox.peerView(id: context.account.peerId), renderedTotalUnreadCount(accountManager: sharedContext.accountManager, engine: context.engine))
|> map { view, totalUnreadCount -> (EnginePeer?, Int32) in
return (view.peers[view.peerId].flatMap(EnginePeer.init), totalUnreadCount.0)
}
|> distinctUntilChanged { lhs, rhs in
return arePeersEqual(lhs.0, rhs.0) && lhs.1 == rhs.1
if lhs.0 != rhs.0 {
return false
}
if lhs.1 != rhs.1 {
return false
}
return true
}
|> map { peer, totalUnreadCount -> (AccountContext, Peer, Int32)? in
|> map { peer, totalUnreadCount -> (AccountContext, EnginePeer, Int32)? in
if let peer = peer {
return (context, peer, totalUnreadCount)
} else {
@ -33,12 +38,12 @@ public func activeAccountsAndPeers(context: AccountContext, includePrimary: Bool
}
return combineLatest(accounts)
|> map { accounts -> ((AccountContext, Peer)?, [(AccountContext, Peer, Int32)]) in
var primaryRecord: (AccountContext, Peer)?
|> map { accounts -> ((AccountContext, EnginePeer)?, [(AccountContext, EnginePeer, Int32)]) in
var primaryRecord: (AccountContext, EnginePeer)?
if let first = accounts.filter({ $0?.0.account.id == primary?.account.id }).first, let (account, peer, _) = first {
primaryRecord = (account, peer)
}
let accountRecords: [(AccountContext, Peer, Int32)] = (includePrimary ? accounts : accounts.filter({ $0?.0.account.id != primary?.account.id })).compactMap({ $0 })
let accountRecords: [(AccountContext, EnginePeer, Int32)] = (includePrimary ? accounts : accounts.filter({ $0?.0.account.id != primary?.account.id })).compactMap({ $0 })
return (primaryRecord, accountRecords)
}
}

View File

@ -419,7 +419,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
})
}
self.badgeDisposable = (combineLatest(renderedTotalUnreadCount(accountManager: context.sharedContext.accountManager, postbox: context.account.postbox), self.presentationDataValue.get()) |> deliverOnMainQueue).start(next: { [weak self] count, presentationData in
self.badgeDisposable = (combineLatest(renderedTotalUnreadCount(accountManager: context.sharedContext.accountManager, engine: context.engine), self.presentationDataValue.get()) |> deliverOnMainQueue).start(next: { [weak self] count, presentationData in
if let strongSelf = self {
if count.0 == 0 {
strongSelf.tabBarItem.badgeValue = ""

View File

@ -1312,7 +1312,7 @@ public final class ChatListNode: ListView {
}
self.scrollToTopOptionPromise.set(combineLatest(
renderedTotalUnreadCount(accountManager: self.context.sharedContext.accountManager, postbox: self.context.account.postbox) |> deliverOnMainQueue,
renderedTotalUnreadCount(accountManager: self.context.sharedContext.accountManager, engine: self.context.engine) |> deliverOnMainQueue,
self.scrolledAtTop.get()
) |> map { badge, scrolledAtTop -> ChatListGlobalScrollOption in
if scrolledAtTop {

View File

@ -33,7 +33,7 @@ private enum IntentsSettingsSection: Int32 {
private enum IntentsSettingsControllerEntry: ItemListNodeEntry {
case accountHeader(PresentationTheme, String)
case account(PresentationTheme, Peer, Bool, Int32)
case account(PresentationTheme, EnginePeer, Bool, Int32)
case accountInfo(PresentationTheme, String)
case chatsHeader(PresentationTheme, String)
@ -102,7 +102,7 @@ private enum IntentsSettingsControllerEntry: ItemListNodeEntry {
return false
}
case let .account(lhsTheme, lhsPeer, lhsSelected, lhsIndex):
if case let .account(rhsTheme, rhsPeer, rhsSelected, rhsIndex) = rhs, lhsTheme === rhsTheme, arePeersEqual(lhsPeer, rhsPeer), lhsSelected == rhsSelected, lhsIndex == rhsIndex {
if case let .account(rhsTheme, rhsPeer, rhsSelected, rhsIndex) = rhs, lhsTheme === rhsTheme, lhsPeer == rhsPeer, lhsSelected == rhsSelected, lhsIndex == rhsIndex {
return true
} else {
return false
@ -187,7 +187,7 @@ private enum IntentsSettingsControllerEntry: ItemListNodeEntry {
case let .accountHeader(_, text):
return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section)
case let .account(_, peer, selected, _):
return ItemListPeerItem(presentationData: presentationData, dateTimeFormat: PresentationDateTimeFormat(), nameDisplayOrder: .firstLast, context: arguments.context.sharedContext.makeTempAccountContext(account: arguments.context.account), peer: EnginePeer(peer), height: .generic, aliasHandling: .standard, nameStyle: .plain, presence: nil, text: .none, label: .none, editing: ItemListPeerItemEditing(editable: true, editing: false, revealed: false), revealOptions: nil, switchValue: ItemListPeerItemSwitch(value: selected, style: .check), enabled: true, selectable: true, sectionId: self.section, action: {
return ItemListPeerItem(presentationData: presentationData, dateTimeFormat: PresentationDateTimeFormat(), nameDisplayOrder: .firstLast, context: arguments.context.sharedContext.makeTempAccountContext(account: arguments.context.account), peer: peer, height: .generic, aliasHandling: .standard, nameStyle: .plain, presence: nil, text: .none, label: .none, editing: ItemListPeerItemEditing(editable: true, editing: false, revealed: false), revealOptions: nil, switchValue: ItemListPeerItemSwitch(value: selected, style: .check), enabled: true, selectable: true, sectionId: self.section, action: {
arguments.updateSettings { $0.withUpdatedAccount(peer.id) }
}, setPeerIdWithRevealedOptions: { _, _ in}, removePeer: { _ in })
case let .accountInfo(_, text):
@ -231,7 +231,7 @@ private enum IntentsSettingsControllerEntry: ItemListNodeEntry {
}
}
private func intentsSettingsControllerEntries(context: AccountContext, presentationData: PresentationData, settings: IntentsSettings, accounts: [(Account, Peer)]) -> [IntentsSettingsControllerEntry] {
private func intentsSettingsControllerEntries(context: AccountContext, presentationData: PresentationData, settings: IntentsSettings, accounts: [(Account, EnginePeer)]) -> [IntentsSettingsControllerEntry] {
var entries: [IntentsSettingsControllerEntry] = []
if accounts.count > 1 {

View File

@ -1,6 +1,18 @@
import SwiftSignalKit
import Postbox
public final class EngineTotalReadCounters {
private let state: ChatListTotalUnreadState
public init(state: ChatListTotalUnreadState) {
self.state = state
}
public func count(for category: ChatListTotalUnreadStateCategory, in statsType: ChatListTotalUnreadStateStats, with tags: PeerSummaryCounterTags) -> Int32 {
return self.state.count(for: category, in: statsType, with: tags)
}
}
public extension TelegramEngine.EngineData.Item {
enum Messages {
public struct Message: TelegramEngineDataItem, PostboxViewDataItem {
@ -51,5 +63,26 @@ public extension TelegramEngine.EngineData.Item {
return result
}
}
public struct TotalReadCounters: TelegramEngineDataItem, PostboxViewDataItem {
public typealias Result = EngineTotalReadCounters
public init() {
}
var key: PostboxViewKey {
return .unreadCounts(items: [.total(nil)])
}
func extract(view: PostboxView) -> Result {
guard let view = view as? UnreadMessageCountsView else {
preconditionFailure()
}
guard let (_, total) = view.total() else {
return EngineTotalReadCounters(state: ChatListTotalUnreadState(absoluteCounters: [:], filteredCounters: [:]))
}
return EngineTotalReadCounters(state: total)
}
}
}
}

View File

@ -1256,12 +1256,12 @@ final class SharedApplicationContext {
return activeAccountsAndPeers(context: context.context)
|> take(1)
|> map { primaryAndAccounts -> (AccountContext, Peer, Int32)? in
|> map { primaryAndAccounts -> (AccountContext, EnginePeer, Int32)? in
return primaryAndAccounts.1.first
}
|> map { accountAndPeer -> String? in
if let (_, peer, _) = accountAndPeer {
return EnginePeer(peer).displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
return peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
} else {
return nil
}

View File

@ -130,7 +130,7 @@ final class AuthorizedApplicationContext {
}
var applicationBadge: Signal<Int32, NoError> {
return renderedTotalUnreadCount(accountManager: self.context.sharedContext.accountManager, postbox: self.context.account.postbox)
return renderedTotalUnreadCount(accountManager: self.context.sharedContext.accountManager, engine: self.context.engine)
|> map {
$0.0
}
@ -870,7 +870,7 @@ final class AuthorizedApplicationContext {
func switchAccount() {
let _ = (activeAccountsAndPeers(context: self.context)
|> take(1)
|> map { primaryAndAccounts -> (AccountContext, Peer, Int32)? in
|> map { primaryAndAccounts -> (AccountContext, EnginePeer, Int32)? in
return primaryAndAccounts.1.first
}
|> map { accountAndPeer -> AccountContext? in

View File

@ -112,7 +112,7 @@ final class PeerInfoState {
final class TelegramGlobalSettings {
let suggestPhoneNumberConfirmation: Bool
let suggestPasswordConfirmation: Bool
let accountsAndPeers: [(AccountContext, Peer, Int32)]
let accountsAndPeers: [(AccountContext, EnginePeer, Int32)]
let activeSessionsContext: ActiveSessionsContext?
let webSessionsContext: WebSessionsContext?
let otherSessionsCount: Int?
@ -131,7 +131,7 @@ final class TelegramGlobalSettings {
init(
suggestPhoneNumberConfirmation: Bool,
suggestPasswordConfirmation: Bool,
accountsAndPeers: [(AccountContext, Peer, Int32)],
accountsAndPeers: [(AccountContext, EnginePeer, Int32)],
activeSessionsContext: ActiveSessionsContext?,
webSessionsContext: WebSessionsContext?,
otherSessionsCount: Int?,
@ -356,7 +356,7 @@ func keepPeerInfoScreenDataHot(context: AccountContext, peerId: PeerId) -> Signa
}
}
func peerInfoScreenSettingsData(context: AccountContext, peerId: PeerId, accountsAndPeers: Signal<[(AccountContext, Peer, Int32)], NoError>, activeSessionsContextAndCount: Signal<(ActiveSessionsContext, Int, WebSessionsContext)?, NoError>, notificationExceptions: Signal<NotificationExceptionsList?, NoError>, privacySettings: Signal<AccountPrivacySettings?, NoError>, archivedStickerPacks: Signal<[ArchivedStickerPackItem]?, NoError>, hasPassport: Signal<Bool, NoError>) -> Signal<PeerInfoScreenData, NoError> {
func peerInfoScreenSettingsData(context: AccountContext, peerId: EnginePeer.Id, accountsAndPeers: Signal<[(AccountContext, EnginePeer, Int32)], NoError>, activeSessionsContextAndCount: Signal<(ActiveSessionsContext, Int, WebSessionsContext)?, NoError>, notificationExceptions: Signal<NotificationExceptionsList?, NoError>, privacySettings: Signal<AccountPrivacySettings?, NoError>, archivedStickerPacks: Signal<[ArchivedStickerPackItem]?, NoError>, hasPassport: Signal<Bool, NoError>) -> Signal<PeerInfoScreenData, NoError> {
let preferences = context.sharedContext.accountManager.sharedData(keys: [
SharedDataKeys.proxySettings,
ApplicationSpecificSharedDataKeys.inAppNotificationSettings,

View File

@ -723,7 +723,7 @@ private func settingsItems(data: PeerInfoScreenData?, context: AccountContext, p
if !settings.accountsAndPeers.isEmpty {
for (peerAccountContext, peer, badgeCount) in settings.accountsAndPeers {
let member: PeerInfoMember = .account(peer: RenderedPeer(peer: peer))
let member: PeerInfoMember = .account(peer: RenderedPeer(peer: peer._asPeer()))
items[.accounts]!.append(PeerInfoScreenMemberItem(id: member.id, context: context.sharedContext.makeTempAccountContext(account: peerAccountContext.account), enclosingPeer: nil, member: member, badge: badgeCount > 0 ? "\(compactNumericCountString(Int(badgeCount), decimalSeparator: presentationData.dateTimeFormat.decimalSeparator))" : nil, action: { action in
switch action {
case .open:
@ -1550,7 +1550,7 @@ private final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewD
private let displayAsPeersPromise = Promise<[FoundPeer]>([])
fileprivate let accountsAndPeers = Promise<[(AccountContext, Peer, Int32)]>()
fileprivate let accountsAndPeers = Promise<[(AccountContext, EnginePeer, Int32)]>()
fileprivate let activeSessionsContextAndCount = Promise<(ActiveSessionsContext, Int, WebSessionsContext)?>()
private let notificationExceptions = Promise<NotificationExceptionsList?>()
private let privacySettings = Promise<AccountPrivacySettings?>()
@ -6500,8 +6500,8 @@ public final class PeerInfoScreenImpl: ViewController, PeerInfoScreen {
private var presentationDataDisposable: Disposable?
private let cachedDataPromise = Promise<CachedPeerData?>()
private let accountsAndPeers = Promise<((AccountContext, Peer)?, [(AccountContext, Peer, Int32)])>()
private var accountsAndPeersValue: ((AccountContext, Peer)?, [(AccountContext, Peer, Int32)])?
private let accountsAndPeers = Promise<((AccountContext, EnginePeer)?, [(AccountContext, EnginePeer, Int32)])>()
private var accountsAndPeersValue: ((AccountContext, EnginePeer)?, [(AccountContext, EnginePeer, Int32)])?
private var accountsAndPeersDisposable: Disposable?
private let activeSessionsContextAndCount = Promise<(ActiveSessionsContext, Int, WebSessionsContext)?>(nil)
@ -6594,19 +6594,19 @@ public final class PeerInfoScreenImpl: ViewController, PeerInfoScreen {
|> distinctUntilChanged
let accountTabBarAvatar: Signal<(UIImage, UIImage)?, NoError> = combineLatest(self.accountsAndPeers.get(), context.sharedContext.presentationData)
|> map { primaryAndOther, presentationData -> (Account, Peer, PresentationTheme)? in
|> map { primaryAndOther, presentationData -> (Account, EnginePeer, PresentationTheme)? in
if let primary = primaryAndOther.0, !primaryAndOther.1.isEmpty {
return (primary.0.account, primary.1, presentationData.theme)
} else {
return nil
}
}
|> distinctUntilChanged(isEqual: { $0?.0 === $1?.0 && arePeersEqual($0?.1, $1?.1) && $0?.2 === $1?.2 })
|> distinctUntilChanged(isEqual: { $0?.0 === $1?.0 && $0?.1 == $1?.1 && $0?.2 === $1?.2 })
|> mapToSignal { primary -> Signal<(UIImage, UIImage)?, NoError> in
if let primary = primary {
let size = CGSize(width: 31.0, height: 31.0)
let inset: CGFloat = 3.0
if let signal = peerAvatarImage(account: primary.0, peerReference: PeerReference(primary.1), authorOfMessage: nil, representation: primary.1.profileImageRepresentations.first, displayDimensions: size, inset: 3.0, emptyColor: nil, synchronousLoad: false) {
if let signal = peerAvatarImage(account: primary.0, peerReference: PeerReference(primary.1._asPeer()), authorOfMessage: nil, representation: primary.1.profileImageRepresentations.first, displayDimensions: size, inset: 3.0, emptyColor: nil, synchronousLoad: false) {
return signal
|> map { imageVersions -> (UIImage, UIImage)? in
let image = imageVersions?.0
@ -6885,7 +6885,7 @@ public final class PeerInfoScreenImpl: ViewController, PeerInfoScreen {
let avatarSize = CGSize(width: 28.0, height: 28.0)
items.append(.action(ContextMenuActionItem(text: EnginePeer(primary.1).displayTitle(strings: strings, displayOrder: presentationData.nameDisplayOrder), icon: { _ in nil }, iconSource: ContextMenuActionItemIconSource(size: avatarSize, signal: peerAvatarCompleteImage(account: primary.0.account, peer: primary.1, size: avatarSize)), action: { _, f in
items.append(.action(ContextMenuActionItem(text: primary.1.displayTitle(strings: strings, displayOrder: presentationData.nameDisplayOrder), icon: { _ in nil }, iconSource: ContextMenuActionItemIconSource(size: avatarSize, signal: peerAvatarCompleteImage(account: primary.0.account, peer: primary.1._asPeer(), size: avatarSize)), action: { _, f in
f(.default)
})))
@ -6895,7 +6895,7 @@ public final class PeerInfoScreenImpl: ViewController, PeerInfoScreen {
for account in other {
let id = account.0.account.id
items.append(.action(ContextMenuActionItem(text: EnginePeer(account.1).displayTitle(strings: strings, displayOrder: presentationData.nameDisplayOrder), badge: account.2 != 0 ? ContextMenuActionBadge(value: "\(account.2)", color: .accent) : nil, icon: { _ in nil }, iconSource: ContextMenuActionItemIconSource(size: avatarSize, signal: peerAvatarCompleteImage(account: account.0.account, peer: account.1, size: avatarSize)), action: { [weak self] _, f in
items.append(.action(ContextMenuActionItem(text: account.1.displayTitle(strings: strings, displayOrder: presentationData.nameDisplayOrder), badge: account.2 != 0 ? ContextMenuActionBadge(value: "\(account.2)", color: .accent) : nil, icon: { _ in nil }, iconSource: ContextMenuActionItemIconSource(size: avatarSize, signal: peerAvatarCompleteImage(account: account.0.account, peer: account.1._asPeer(), size: avatarSize)), action: { [weak self] _, f in
guard let strongSelf = self else {
return
}

View File

@ -22,17 +22,16 @@ public func renderedTotalUnreadCount(inAppSettings: InAppNotificationSettings, t
return (totalUnreadState.count(for: inAppSettings.totalUnreadCountDisplayStyle.category, in: inAppSettings.totalUnreadCountDisplayCategory.statsType, with: inAppSettings.totalUnreadCountIncludeTags), type)
}
public func renderedTotalUnreadCount(accountManager: AccountManager<TelegramAccountManagerTypes>, postbox: Postbox) -> Signal<(Int32, RenderedTotalUnreadCountType), NoError> {
let unreadCountsKey = PostboxViewKey.unreadCounts(items: [.total(nil)])
return combineLatest(accountManager.sharedData(keys: [ApplicationSpecificSharedDataKeys.inAppNotificationSettings]), postbox.combinedView(keys: [unreadCountsKey]))
|> map { sharedData, view -> (Int32, RenderedTotalUnreadCountType) in
let totalUnreadState: ChatListTotalUnreadState
if let value = view.views[unreadCountsKey] as? UnreadMessageCountsView, let (_, total) = value.total() {
totalUnreadState = total
} else {
totalUnreadState = ChatListTotalUnreadState(absoluteCounters: [:], filteredCounters: [:])
}
public func getCurrentRenderedTotalUnreadCount(accountManager: AccountManager<TelegramAccountManagerTypes>, postbox: Postbox) -> Signal<(Int32, RenderedTotalUnreadCountType), NoError> {
let counters = postbox.transaction { transaction -> ChatListTotalUnreadState in
return transaction.getTotalUnreadState(groupId: .root)
}
return combineLatest(
accountManager.sharedData(keys: [ApplicationSpecificSharedDataKeys.inAppNotificationSettings])
|> take(1),
counters
)
|> map { sharedData, totalReadCounters -> (Int32, RenderedTotalUnreadCountType) in
let inAppSettings: InAppNotificationSettings
if let value = sharedData.entries[ApplicationSpecificSharedDataKeys.inAppNotificationSettings]?.get(InAppNotificationSettings.self) {
inAppSettings = value
@ -44,7 +43,30 @@ public func renderedTotalUnreadCount(accountManager: AccountManager<TelegramAcco
case .filtered:
type = .filtered
}
return (totalUnreadState.count(for: inAppSettings.totalUnreadCountDisplayStyle.category, in: inAppSettings.totalUnreadCountDisplayCategory.statsType, with: inAppSettings.totalUnreadCountIncludeTags), type)
return (totalReadCounters.count(for: inAppSettings.totalUnreadCountDisplayStyle.category, in: inAppSettings.totalUnreadCountDisplayCategory.statsType, with: inAppSettings.totalUnreadCountIncludeTags), type)
}
}
public func renderedTotalUnreadCount(accountManager: AccountManager<TelegramAccountManagerTypes>, engine: TelegramEngine) -> Signal<(Int32, RenderedTotalUnreadCountType), NoError> {
return combineLatest(
accountManager.sharedData(keys: [ApplicationSpecificSharedDataKeys.inAppNotificationSettings]),
engine.data.subscribe(
TelegramEngine.EngineData.Item.Messages.TotalReadCounters()
)
)
|> map { sharedData, totalReadCounters -> (Int32, RenderedTotalUnreadCountType) in
let inAppSettings: InAppNotificationSettings
if let value = sharedData.entries[ApplicationSpecificSharedDataKeys.inAppNotificationSettings]?.get(InAppNotificationSettings.self) {
inAppSettings = value
} else {
inAppSettings = .defaultSettings
}
let type: RenderedTotalUnreadCountType
switch inAppSettings.totalUnreadCountDisplayStyle {
case .filtered:
type = .filtered
}
return (totalReadCounters.count(for: inAppSettings.totalUnreadCountDisplayStyle.category, in: inAppSettings.totalUnreadCountDisplayCategory.statsType, with: inAppSettings.totalUnreadCountIncludeTags), type)
}
|> distinctUntilChanged(isEqual: { lhs, rhs in
return lhs == rhs