From c146d155590b087fe80bf9ac65b870fe01691c53 Mon Sep 17 00:00:00 2001 From: Ali <> Date: Sun, 29 May 2022 04:27:40 +0400 Subject: [PATCH 1/3] Refactoring --- .../Sources/NotificationService.swift | 25 ++++++++ .../Sources/DebugController.swift | 23 +++----- .../LocalizationListControllerNode.swift | 10 ++-- .../InstalledStickerPacksController.swift | 21 +------ .../Auth/TelegramEngineAuth.swift | 7 +++ .../TelegramEngine/Data/Configuration.swift | 21 +++++++ .../ItemCache/TelegramEngineItemCache.swift | 9 +++ .../Localization/LocalizationListState.swift | 3 +- .../TelegramEngineLocalization.swift | 7 +++ .../Messages/TelegramEngineMessages.swift | 14 +++++ .../Stickers/TelegramEngineStickers.swift | 24 ++++++++ .../AuthorizationSequenceController.swift | 40 ++++--------- .../Sources/ChatMediaInputNode.swift | 22 +------ .../Sources/SharedNotificationManager.swift | 7 --- .../Sources/RenderedTotalUnreadCount.swift | 25 -------- .../Sources/WallpaperCache.swift | 58 ++++++++++--------- 16 files changed, 165 insertions(+), 151 deletions(-) diff --git a/Telegram/NotificationService/Sources/NotificationService.swift b/Telegram/NotificationService/Sources/NotificationService.swift index a40754bca4..a63054d8e5 100644 --- a/Telegram/NotificationService/Sources/NotificationService.swift +++ b/Telegram/NotificationService/Sources/NotificationService.swift @@ -577,6 +577,31 @@ private struct NotificationContent: CustomStringConvertible { } } +private func getCurrentRenderedTotalUnreadCount(accountManager: AccountManager, 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 + } 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) + } +} + @available(iOSApplicationExtension 10.0, iOS 10.0, *) private final class NotificationServiceHandler { private let queue: Queue diff --git a/submodules/DebugSettingsUI/Sources/DebugController.swift b/submodules/DebugSettingsUI/Sources/DebugController.swift index 51fa64d722..0de1fc679f 100644 --- a/submodules/DebugSettingsUI/Sources/DebugController.swift +++ b/submodules/DebugSettingsUI/Sources/DebugController.swift @@ -762,11 +762,10 @@ private enum DebugControllerEntry: ItemListNodeEntry { transaction.clearNotices() }).start() if let context = arguments.context { - let _ = (context.account.postbox.transaction { transaction -> Void in - transaction.clearItemCacheCollection(collectionId: Namespaces.CachedItemCollection.cachedPollResults) - - transaction.clearItemCacheCollection(collectionId: Namespaces.CachedItemCollection.cachedStickerPacks) - }).start() + let _ = context.engine.itemCache.clear(collectionIds: [ + Namespaces.CachedItemCollection.cachedPollResults, + Namespaces.CachedItemCollection.cachedStickerPacks + ]).start() let _ = context.engine.peers.unmarkChatListFeaturedFiltersAsSeen() } @@ -846,12 +845,10 @@ private enum DebugControllerEntry: ItemListNodeEntry { let presentationData = arguments.sharedContext.currentPresentationData.with { $0 } let controller = OverlayStatusController(theme: presentationData.theme, type: .loading(cancelled: nil)) arguments.presentController(controller, nil) - let _ = (context.account.postbox.transaction { transaction -> Void in - transaction.addHolesEverywhere(peerNamespaces: [Namespaces.Peer.CloudUser, Namespaces.Peer.CloudGroup, Namespaces.Peer.CloudChannel], holeNamespace: Namespaces.Message.Cloud) - } - |> deliverOnMainQueue).start(completed: { - controller.dismiss() - }) + let _ = (context.engine.messages.debugAddHoles() + |> deliverOnMainQueue).start(completed: { + controller.dismiss() + }) }) case .reindexUnread: return ItemListActionItem(presentationData: presentationData, title: "Reindex Unread Counters", kind: .destructive, alignment: .natural, sectionId: self.section, style: .blocks, action: { @@ -861,9 +858,7 @@ private enum DebugControllerEntry: ItemListNodeEntry { let presentationData = arguments.sharedContext.currentPresentationData.with { $0 } let controller = OverlayStatusController(theme: presentationData.theme, type: .loading(cancelled: nil)) arguments.presentController(controller, nil) - let _ = (context.account.postbox.transaction { transaction -> Void in - transaction.reindexUnreadCounters() - } + let _ = (context.engine.messages.debugReindexUnreadCounters() |> deliverOnMainQueue).start(completed: { controller.dismiss() }) diff --git a/submodules/SettingsUI/Sources/Language Selection/LocalizationListControllerNode.swift b/submodules/SettingsUI/Sources/Language Selection/LocalizationListControllerNode.swift index d2372a841b..74598d3c98 100644 --- a/submodules/SettingsUI/Sources/Language Selection/LocalizationListControllerNode.swift +++ b/submodules/SettingsUI/Sources/Language Selection/LocalizationListControllerNode.swift @@ -389,11 +389,12 @@ final class LocalizationListControllerNode: ViewControllerTracingNode { } let removeItem: (String) -> Void = { id in - let _ = (context.account.postbox.transaction { transaction -> Signal in - removeSavedLocalization(transaction: transaction, languageCode: id) - let state = transaction.getPreferencesEntry(key: PreferencesKeys.localizationListState)?.get(LocalizationListState.self) + let _ = context.engine.localization.removeSavedLocalization(languageCode: id).start() + + let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Configuration.LocalizationList()) + |> mapToSignal { state -> Signal in return context.sharedContext.accountManager.transaction { transaction -> LocalizationInfo? in - if let settings = transaction.getSharedData(SharedDataKeys.localizationSettings)?.get(LocalizationSettings.self), let state = state { + if let settings = transaction.getSharedData(SharedDataKeys.localizationSettings)?.get(LocalizationSettings.self) { if settings.primaryComponent.languageCode == id { for item in state.availableOfficialLocalizations { if item.languageCode == "en" { @@ -405,7 +406,6 @@ final class LocalizationListControllerNode: ViewControllerTracingNode { return nil } } - |> switchToLatest |> deliverOnMainQueue).start(next: { [weak self] info in if revealedCodeValue == id { revealedCodeValue = nil diff --git a/submodules/SettingsUI/Sources/Stickers/InstalledStickerPacksController.swift b/submodules/SettingsUI/Sources/Stickers/InstalledStickerPacksController.swift index a31f272c52..d9db23d840 100644 --- a/submodules/SettingsUI/Sources/Stickers/InstalledStickerPacksController.swift +++ b/submodules/SettingsUI/Sources/Stickers/InstalledStickerPacksController.swift @@ -1148,26 +1148,7 @@ public func installedStickerPacksController(context: AccountContext, mode: Insta break } } - let _ = (context.account.postbox.transaction { transaction -> Void in - let infos = transaction.getItemCollectionsInfos(namespace: namespaceForMode(mode)) - - var packDict: [ItemCollectionId: Int] = [:] - for i in 0 ..< infos.count { - packDict[infos[i].0] = i - } - var tempSortedPacks: [(ItemCollectionId, ItemCollectionInfo)] = [] - var processedPacks = Set() - for id in currentIds { - if let index = packDict[id] { - tempSortedPacks.append(infos[index]) - processedPacks.insert(id) - } - } - let restPacks = infos.filter { !processedPacks.contains($0.0) } - let sortedPacks = restPacks + tempSortedPacks - addSynchronizeInstalledStickerPacksOperation(transaction: transaction, namespace: namespaceForMode(mode), content: .sync, noDelay: false) - transaction.replaceItemCollectionInfos(namespace: namespaceForMode(mode), itemCollectionInfos: sortedPacks) - } + let _ = (context.engine.stickers.reorderStickerPacks(namespace: namespaceForMode(mode), itemIds: currentIds) |> deliverOnMainQueue).start(completed: { temporaryPackOrder.set(.single(nil)) }) diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Auth/TelegramEngineAuth.swift b/submodules/TelegramCore/Sources/TelegramEngine/Auth/TelegramEngineAuth.swift index 307023ceaf..357f3594b6 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Auth/TelegramEngineAuth.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Auth/TelegramEngineAuth.swift @@ -42,6 +42,13 @@ public extension TelegramEngineUnauthorized { public func uploadedPeerVideo(resource: MediaResource) -> Signal { return _internal_uploadedPeerVideo(postbox: self.account.postbox, network: self.account.network, messageMediaPreuploadManager: nil, resource: resource) } + + public func setState(state: UnauthorizedAccountState) -> Signal { + return self.account.postbox.transaction { transaction -> Void in + transaction.setState(state) + } + |> ignoreValues + } } } diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Data/Configuration.swift b/submodules/TelegramCore/Sources/TelegramEngine/Data/Configuration.swift index 8f4b4cb205..a37d93e54f 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Data/Configuration.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Data/Configuration.swift @@ -333,5 +333,26 @@ public extension TelegramEngine.EngineData.Item { return EngineContentSettings(appConfiguration: appConfiguration) } } + + public struct LocalizationList: TelegramEngineDataItem, PostboxViewDataItem { + public typealias Result = LocalizationListState + + public init() { + } + + var key: PostboxViewKey { + return .preferences(keys: Set([PreferencesKeys.localizationListState])) + } + + func extract(view: PostboxView) -> Result { + guard let view = view as? PreferencesView else { + preconditionFailure() + } + guard let localizationListState = view.values[PreferencesKeys.localizationListState]?.get(LocalizationListState.self) else { + return LocalizationListState.defaultSettings + } + return localizationListState + } + } } } diff --git a/submodules/TelegramCore/Sources/TelegramEngine/ItemCache/TelegramEngineItemCache.swift b/submodules/TelegramCore/Sources/TelegramEngine/ItemCache/TelegramEngineItemCache.swift index 8ca176672c..2ea4f81130 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/ItemCache/TelegramEngineItemCache.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/ItemCache/TelegramEngineItemCache.swift @@ -25,5 +25,14 @@ public extension TelegramEngine { } |> ignoreValues } + + public func clear(collectionIds: [Int8]) -> Signal { + return self.account.postbox.transaction { transaction -> Void in + for id in collectionIds { + transaction.clearItemCacheCollection(collectionId: id) + } + } + |> ignoreValues + } } } diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Localization/LocalizationListState.swift b/submodules/TelegramCore/Sources/TelegramEngine/Localization/LocalizationListState.swift index 49c29a186b..99dbcdd728 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Localization/LocalizationListState.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Localization/LocalizationListState.swift @@ -3,8 +3,7 @@ import Postbox import SwiftSignalKit import TelegramApi - -public func removeSavedLocalization(transaction: Transaction, languageCode: String) { +func _internal_removeSavedLocalization(transaction: Transaction, languageCode: String) { updateLocalizationListStateInteractively(transaction: transaction, { state in var state = state state.availableSavedLocalizations = state.availableSavedLocalizations.filter({ $0.languageCode != languageCode }) diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Localization/TelegramEngineLocalization.swift b/submodules/TelegramCore/Sources/TelegramEngine/Localization/TelegramEngineLocalization.swift index f07e4a38d2..9095a39199 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Localization/TelegramEngineLocalization.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Localization/TelegramEngineLocalization.swift @@ -32,6 +32,13 @@ public extension TelegramEngine { public func downloadAndApplyLocalization(accountManager: AccountManager, languageCode: String) -> Signal { return _internal_downloadAndApplyLocalization(accountManager: accountManager, postbox: self.account.postbox, network: self.account.network, languageCode: languageCode) } + + public func removeSavedLocalization(languageCode: String) -> Signal { + return self.account.postbox.transaction { transaction -> Void in + _internal_removeSavedLocalization(transaction: transaction, languageCode: languageCode) + } + |> ignoreValues + } } } diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Messages/TelegramEngineMessages.swift b/submodules/TelegramCore/Sources/TelegramEngine/Messages/TelegramEngineMessages.swift index 7a6ec19451..fa3764d532 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Messages/TelegramEngineMessages.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Messages/TelegramEngineMessages.swift @@ -415,5 +415,19 @@ public extension TelegramEngine { } |> ignoreValues } + + public func debugAddHoles() -> Signal { + return self.account.postbox.transaction { transaction -> Void in + transaction.addHolesEverywhere(peerNamespaces: [Namespaces.Peer.CloudUser, Namespaces.Peer.CloudGroup, Namespaces.Peer.CloudChannel], holeNamespace: Namespaces.Message.Cloud) + } + |> ignoreValues + } + + public func debugReindexUnreadCounters() -> Signal { + return self.account.postbox.transaction { transaction -> Void in + transaction.reindexUnreadCounters() + } + |> ignoreValues + } } } diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Stickers/TelegramEngineStickers.swift b/submodules/TelegramCore/Sources/TelegramEngine/Stickers/TelegramEngineStickers.swift index f82e3afc7a..c064783ab5 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Stickers/TelegramEngineStickers.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Stickers/TelegramEngineStickers.swift @@ -131,5 +131,29 @@ public extension TelegramEngine { } |> ignoreValues } + + public func reorderStickerPacks(namespace: ItemCollectionId.Namespace, itemIds: [ItemCollectionId]) -> Signal { + return self.account.postbox.transaction { transaction -> Void in + let infos = transaction.getItemCollectionsInfos(namespace: namespace) + + var packDict: [ItemCollectionId: Int] = [:] + for i in 0 ..< infos.count { + packDict[infos[i].0] = i + } + var tempSortedPacks: [(ItemCollectionId, ItemCollectionInfo)] = [] + var processedPacks = Set() + for id in itemIds { + if let index = packDict[id] { + tempSortedPacks.append(infos[index]) + processedPacks.insert(id) + } + } + let restPacks = infos.filter { !processedPacks.contains($0.0) } + let sortedPacks = restPacks + tempSortedPacks + addSynchronizeInstalledStickerPacksOperation(transaction: transaction, namespace: namespace, content: .sync, noDelay: false) + transaction.replaceItemCollectionInfos(namespace: namespace, itemCollectionInfos: sortedPacks) + } + |> ignoreValues + } } } diff --git a/submodules/TelegramUI/Sources/AuthorizationSequenceController.swift b/submodules/TelegramUI/Sources/AuthorizationSequenceController.swift index aed01b872d..7562288787 100644 --- a/submodules/TelegramUI/Sources/AuthorizationSequenceController.swift +++ b/submodules/TelegramUI/Sources/AuthorizationSequenceController.swift @@ -122,9 +122,7 @@ public final class AuthorizationSequenceController: NavigationController, MFMail let countryCode = defaultCountryCode() - let _ = (strongSelf.account.postbox.transaction { transaction -> Void in - transaction.setState(UnauthorizedAccountState(isTestingEnvironment: isTestingEnvironment, masterDatacenterId: masterDatacenterId, contents: .phoneEntry(countryCode: countryCode, number: ""))) - }).start() + let _ = TelegramEngineUnauthorized(account: strongSelf.account).auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: isTestingEnvironment, masterDatacenterId: masterDatacenterId, contents: .phoneEntry(countryCode: countryCode, number: ""))).start() } } } @@ -154,9 +152,7 @@ public final class AuthorizationSequenceController: NavigationController, MFMail transaction.removeAuth() }).start() } else { - let _ = strongSelf.account.postbox.transaction({ transaction -> Void in - transaction.setState(UnauthorizedAccountState(isTestingEnvironment: strongSelf.account.testingEnvironment, masterDatacenterId: strongSelf.account.masterDatacenterId, contents: .empty)) - }).start() + let _ = TelegramEngineUnauthorized(account: strongSelf.account).auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: strongSelf.account.testingEnvironment, masterDatacenterId: strongSelf.account.masterDatacenterId, contents: .empty)).start() } }) controller.accountUpdated = { [weak self] updatedAccount in @@ -282,9 +278,7 @@ public final class AuthorizationSequenceController: NavigationController, MFMail } let countryCode = defaultCountryCode() - let _ = (strongSelf.account.postbox.transaction { transaction -> Void in - transaction.setState(UnauthorizedAccountState(isTestingEnvironment: strongSelf.account.testingEnvironment, masterDatacenterId: strongSelf.account.masterDatacenterId, contents: .phoneEntry(countryCode: countryCode, number: ""))) - }).start() + let _ = TelegramEngineUnauthorized(account: strongSelf.account).auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: strongSelf.account.testingEnvironment, masterDatacenterId: strongSelf.account.masterDatacenterId, contents: .phoneEntry(countryCode: countryCode, number: ""))).start() }) controller.loginWithCode = { [weak self, weak controller] code in if let strongSelf = self { @@ -331,9 +325,7 @@ public final class AuthorizationSequenceController: NavigationController, MFMail return } let account = strongSelf.account - let _ = (strongSelf.account.postbox.transaction { transaction -> Void in - transaction.setState(UnauthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, contents: .empty)) - }).start() + let _ = TelegramEngineUnauthorized(account: strongSelf.account).auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, contents: .empty)).start() })]), on: .root, blockInteraction: false, completion: {}) }) ], actionLayout: .vertical, dismissOnOutsideTap: true) @@ -378,9 +370,7 @@ public final class AuthorizationSequenceController: NavigationController, MFMail case .codeExpired: text = strongSelf.presentationData.strings.Login_CodeExpired let account = strongSelf.account - let _ = (strongSelf.account.postbox.transaction { transaction -> Void in - transaction.setState(UnauthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, contents: .empty)) - }).start() + let _ = TelegramEngineUnauthorized(account: strongSelf.account).auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, contents: .empty)).start() } if resetCode { @@ -437,9 +427,7 @@ public final class AuthorizationSequenceController: NavigationController, MFMail controller.reset = { [weak self] in if let strongSelf = self { let account = strongSelf.account - let _ = (strongSelf.account.postbox.transaction { transaction -> Void in - transaction.setState(UnauthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, contents: .empty)) - }).start() + let _ = TelegramEngineUnauthorized(account: strongSelf.account).auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, contents: .empty)).start() } } controller.updateData(number: formatPhoneNumber(number), codeType: type, nextType: nextType, timeout: timeout, termsOfService: termsOfService) @@ -464,9 +452,7 @@ public final class AuthorizationSequenceController: NavigationController, MFMail } let countryCode = defaultCountryCode() - let _ = (strongSelf.account.postbox.transaction { transaction -> Void in - transaction.setState(UnauthorizedAccountState(isTestingEnvironment: strongSelf.account.testingEnvironment, masterDatacenterId: strongSelf.account.masterDatacenterId, contents: .phoneEntry(countryCode: countryCode, number: ""))) - }).start() + let _ = TelegramEngineUnauthorized(account: strongSelf.account).auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: strongSelf.account.testingEnvironment, masterDatacenterId: strongSelf.account.masterDatacenterId, contents: .phoneEntry(countryCode: countryCode, number: ""))).start() }) controller.loginWithPassword = { [weak self, weak controller] password in if let strongSelf = self { @@ -601,9 +587,7 @@ public final class AuthorizationSequenceController: NavigationController, MFMail } let countryCode = defaultCountryCode() - let _ = (strongSelf.account.postbox.transaction { transaction -> Void in - transaction.setState(UnauthorizedAccountState(isTestingEnvironment: strongSelf.account.testingEnvironment, masterDatacenterId: strongSelf.account.masterDatacenterId, contents: .phoneEntry(countryCode: countryCode, number: ""))) - }).start() + let _ = TelegramEngineUnauthorized(account: strongSelf.account).auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: strongSelf.account.testingEnvironment, masterDatacenterId: strongSelf.account.masterDatacenterId, contents: .phoneEntry(countryCode: countryCode, number: ""))).start() }) controller.reset = { [weak self, weak controller] in if let strongSelf = self, let strongController = controller { @@ -637,9 +621,7 @@ public final class AuthorizationSequenceController: NavigationController, MFMail controller.logout = { [weak self] in if let strongSelf = self { let account = strongSelf.account - let _ = (strongSelf.account.postbox.transaction { transaction -> Void in - transaction.setState(UnauthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, contents: .empty)) - }).start() + let _ = TelegramEngineUnauthorized(account: strongSelf.account).auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, contents: .empty)).start() } } } @@ -665,9 +647,7 @@ public final class AuthorizationSequenceController: NavigationController, MFMail } let countryCode = defaultCountryCode() - let _ = (strongSelf.account.postbox.transaction { transaction -> Void in - transaction.setState(UnauthorizedAccountState(isTestingEnvironment: strongSelf.account.testingEnvironment, masterDatacenterId: strongSelf.account.masterDatacenterId, contents: .phoneEntry(countryCode: countryCode, number: ""))) - }).start() + let _ = TelegramEngineUnauthorized(account: strongSelf.account).auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: strongSelf.account.testingEnvironment, masterDatacenterId: strongSelf.account.masterDatacenterId, contents: .phoneEntry(countryCode: countryCode, number: ""))).start() }, displayCancel: displayCancel) controller.signUpWithName = { [weak self, weak controller] firstName, lastName, avatarData, avatarAsset, avatarAdjustments in if let strongSelf = self { diff --git a/submodules/TelegramUI/Sources/ChatMediaInputNode.swift b/submodules/TelegramUI/Sources/ChatMediaInputNode.swift index e1c1ca95e6..6851645a6b 100644 --- a/submodules/TelegramUI/Sources/ChatMediaInputNode.swift +++ b/submodules/TelegramUI/Sources/ChatMediaInputNode.swift @@ -730,27 +730,7 @@ final class ChatMediaInputNode: ChatInputNode { break } } - let _ = (context.account.postbox.transaction { transaction -> Void in - let namespace = Namespaces.ItemCollection.CloudStickerPacks - let infos = transaction.getItemCollectionsInfos(namespace: namespace) - - var packDict: [ItemCollectionId: Int] = [:] - for i in 0 ..< infos.count { - packDict[infos[i].0] = i - } - var tempSortedPacks: [(ItemCollectionId, ItemCollectionInfo)] = [] - var processedPacks = Set() - for id in currentIds { - if let index = packDict[id] { - tempSortedPacks.append(infos[index]) - processedPacks.insert(id) - } - } - let restPacks = infos.filter { !processedPacks.contains($0.0) } - let sortedPacks = restPacks + tempSortedPacks - addSynchronizeInstalledStickerPacksOperation(transaction: transaction, namespace: namespace, content: .sync, noDelay: false) - transaction.replaceItemCollectionInfos(namespace: namespace, itemCollectionInfos: sortedPacks) - } + let _ = (context.engine.stickers.reorderStickerPacks(namespace: Namespaces.ItemCollection.CloudStickerPacks, itemIds: currentIds) |> deliverOnMainQueue).start(completed: { [weak self] in temporaryPackOrder.set(.single(nil)) diff --git a/submodules/TelegramUI/Sources/SharedNotificationManager.swift b/submodules/TelegramUI/Sources/SharedNotificationManager.swift index 6643e32e3f..bfe53b0ebd 100644 --- a/submodules/TelegramUI/Sources/SharedNotificationManager.swift +++ b/submodules/TelegramUI/Sources/SharedNotificationManager.swift @@ -393,10 +393,6 @@ public final class SharedNotificationManager { if let readMessageId = readMessageId { self.clearNotificationsManager?.append(readMessageId) - - let _ = account.postbox.transaction(ignoreDisabled: true, { transaction -> Void in - transaction.applyIncomingReadMaxId(readMessageId) - }).start() } for messageId in messagesDeleted { @@ -404,9 +400,6 @@ public final class SharedNotificationManager { } if !messagesDeleted.isEmpty { - let _ = account.postbox.transaction(ignoreDisabled: true, { transaction -> Void in - TelegramEngine(account: account).messages.deleteMessages(transaction: transaction, ids: messagesDeleted) - }).start() } if readMessageId != nil || !messagesDeleted.isEmpty { diff --git a/submodules/TelegramUIPreferences/Sources/RenderedTotalUnreadCount.swift b/submodules/TelegramUIPreferences/Sources/RenderedTotalUnreadCount.swift index c36a1b7935..613b51444e 100644 --- a/submodules/TelegramUIPreferences/Sources/RenderedTotalUnreadCount.swift +++ b/submodules/TelegramUIPreferences/Sources/RenderedTotalUnreadCount.swift @@ -22,31 +22,6 @@ public func renderedTotalUnreadCount(inAppSettings: InAppNotificationSettings, t return (totalUnreadState.count(for: inAppSettings.totalUnreadCountDisplayStyle.category, in: inAppSettings.totalUnreadCountDisplayCategory.statsType, with: inAppSettings.totalUnreadCountIncludeTags), type) } -public func getCurrentRenderedTotalUnreadCount(accountManager: AccountManager, 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 - } 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) - } -} - public func renderedTotalUnreadCount(accountManager: AccountManager, engine: TelegramEngine) -> Signal<(Int32, RenderedTotalUnreadCountType), NoError> { return combineLatest( accountManager.sharedData(keys: [ApplicationSpecificSharedDataKeys.inAppNotificationSettings]), diff --git a/submodules/WallpaperResources/Sources/WallpaperCache.swift b/submodules/WallpaperResources/Sources/WallpaperCache.swift index 3c293626f9..12d999635e 100644 --- a/submodules/WallpaperResources/Sources/WallpaperCache.swift +++ b/submodules/WallpaperResources/Sources/WallpaperCache.swift @@ -28,10 +28,13 @@ public final class CachedWallpaper: Codable { } public func cachedWallpaper(account: Account, slug: String, settings: WallpaperSettings?, update: Bool = false) -> Signal { - return account.postbox.transaction { transaction -> Signal in - let key = ValueBoxKey(length: 8) - key.setInt64(0, value: Int64(bitPattern: slug.persistentHashValue)) - if !update, let entry = transaction.retrieveItemCacheEntry(id: ItemCacheEntryId(collectionId: ApplicationSpecificItemCacheCollectionId.cachedWallpapers, key: key))?.get(CachedWallpaper.self) { + let engine = TelegramEngine(account: account) + + let slugKey = ValueBoxKey(length: 8) + slugKey.setInt64(0, value: Int64(bitPattern: slug.persistentHashValue)) + return engine.data.get(TelegramEngine.EngineData.Item.ItemCache.Item(collectionId: ApplicationSpecificItemCacheCollectionId.cachedWallpapers, id: slugKey)) + |> mapToSignal { entry -> Signal in + if !update, let entry = entry?.get(CachedWallpaper.self) { if let settings = settings { return .single(CachedWallpaper(wallpaper: entry.wallpaper.withUpdatedSettings(settings))) } else { @@ -44,33 +47,34 @@ public func cachedWallpaper(account: Account, slug: String, settings: WallpaperS return .single(nil) } |> mapToSignal { wallpaper -> Signal in - return account.postbox.transaction { transaction -> CachedWallpaper? in - let key = ValueBoxKey(length: 8) - key.setInt64(0, value: Int64(bitPattern: slug.persistentHashValue)) - let id = ItemCacheEntryId(collectionId: ApplicationSpecificItemCacheCollectionId.cachedWallpapers, key: key) - if var wallpaper = wallpaper { - switch wallpaper { - case let .file(file): - wallpaper = .file(TelegramWallpaper.File(id: file.id, accessHash: file.accessHash, isCreator: file.isCreator, isDefault: file.isDefault, isPattern: file.isPattern, isDark: file.isDark, slug: file.slug, file: file.file.withUpdatedResource(WallpaperDataResource(slug: slug)), settings: file.settings)) - default: - break - } - if let entry = CodableEntry(CachedWallpaper(wallpaper: wallpaper)) { - transaction.putItemCacheEntry(id: id, entry: entry) - } - if let settings = settings { - return CachedWallpaper(wallpaper: wallpaper.withUpdatedSettings(settings)) - } else { - return CachedWallpaper(wallpaper: wallpaper) - } - } else { - transaction.removeItemCacheEntry(id: id) - return nil + let slugKey = ValueBoxKey(length: 8) + slugKey.setInt64(0, value: Int64(bitPattern: slug.persistentHashValue)) + + if var wallpaper = wallpaper { + switch wallpaper { + case let .file(file): + wallpaper = .file(TelegramWallpaper.File(id: file.id, accessHash: file.accessHash, isCreator: file.isCreator, isDefault: file.isDefault, isPattern: file.isPattern, isDark: file.isDark, slug: file.slug, file: file.file.withUpdatedResource(WallpaperDataResource(slug: slug)), settings: file.settings)) + default: + break } + + let result: CachedWallpaper + if let settings = settings { + result = CachedWallpaper(wallpaper: wallpaper.withUpdatedSettings(settings)) + } else { + result = CachedWallpaper(wallpaper: wallpaper) + } + return engine.itemCache.put(collectionId: ApplicationSpecificItemCacheCollectionId.cachedWallpapers, id: slugKey, item: CachedWallpaper(wallpaper: wallpaper)) + |> map { _ -> CachedWallpaper? in } + |> then(.single(result)) + } else { + return engine.itemCache.remove(collectionId: ApplicationSpecificItemCacheCollectionId.cachedWallpapers, id: slugKey) + |> map { _ -> CachedWallpaper? in } + |> then(.single(nil)) } } } - } |> switchToLatest + } } public func updateCachedWallpaper(engine: TelegramEngine, wallpaper: TelegramWallpaper) { From 5eb4bbeaaeb013786bbf2e307a5ad998b34d707e Mon Sep 17 00:00:00 2001 From: Ali <> Date: Sun, 29 May 2022 19:11:14 +0400 Subject: [PATCH 2/3] Refactoring --- .../NotificationViewController.swift | 2 +- Telegram/Share/ShareRootController.swift | 2 +- .../Sources/AccountContext.swift | 9 ++- .../ChatListUI/Sources/ChatContextMenus.swift | 6 +- .../Sources/ChatListController.swift | 21 +------ .../Sources/ChatListSelection.swift | 37 ++++------- .../Sources/DebugAccountsController.swift | 5 +- .../Items/UniversalVideoGalleryItem.swift | 25 +++----- .../Sources/AvatarGalleryController.swift | 10 +-- .../ChannelBannedMemberController.swift | 49 ++++++++------- .../NotificationExceptionControllerNode.swift | 53 +++++++--------- .../NotificationsPeerCategoryController.swift | 55 ++++++++-------- .../PrivacyAndSecurityController.swift | 21 +++++-- .../Sources/Search/SettingsSearchItem.swift | 2 +- .../Search/SettingsSearchRecentQueries.swift | 16 +++-- .../Themes/ThemeGridSearchContentNode.swift | 2 +- .../Themes/WallpaperSearchRecentQueries.swift | 14 ++--- .../Sources/PresentationGroupCall.swift | 25 ++++---- .../Auth/TelegramEngineAuth.swift | 18 ++++++ .../TelegramEngine/Data/ChatListData.swift | 8 +++ ...guration.swift => ConfigurationData.swift} | 0 .../{Contacts.swift => ContactsData.swift} | 0 .../{ItemCache.swift => ItemCacheData.swift} | 0 .../{Messages.swift => MessagesData.swift} | 36 +++++++---- .../Data/{Notices.swift => NoticesData.swift} | 0 .../Data/OrderedListsData.swift | 27 ++++++++ .../{PeerSummary.swift => PeersData.swift} | 0 .../TelegramUI/Sources/AppDelegate.swift | 2 +- .../AuthorizationSequenceController.swift | 34 ++++++---- .../TelegramUI/Sources/ChatController.swift | 17 +++-- .../ChatInterfaceStateContextMenus.swift | 11 ++-- .../Sources/ChatMediaInputGifPane.swift | 22 +++---- ...essageContextControllerContentSource.swift | 39 +++++------- .../Sources/NotificationContentContext.swift | 6 +- .../PeerInfo/Panes/PeerInfoMembersPane.swift | 10 +-- .../Sources/PeerInfo/PeerInfoData.swift | 62 +++++-------------- .../Sources/PeerMessagesMediaPlaylist.swift | 14 ++--- .../Sources/ShareExtensionContext.swift | 6 +- .../Sources/SharedAccountContext.swift | 9 ++- ...annelMemberCategoriesContextsManager.swift | 26 ++++---- .../Sources/WebSearchControllerNode.swift | 2 +- .../Sources/WebSearchRecentQueries.swift | 16 +++-- 42 files changed, 366 insertions(+), 353 deletions(-) create mode 100644 submodules/TelegramCore/Sources/TelegramEngine/Data/ChatListData.swift rename submodules/TelegramCore/Sources/TelegramEngine/Data/{Configuration.swift => ConfigurationData.swift} (100%) rename submodules/TelegramCore/Sources/TelegramEngine/Data/{Contacts.swift => ContactsData.swift} (100%) rename submodules/TelegramCore/Sources/TelegramEngine/Data/{ItemCache.swift => ItemCacheData.swift} (100%) rename submodules/TelegramCore/Sources/TelegramEngine/Data/{Messages.swift => MessagesData.swift} (89%) rename submodules/TelegramCore/Sources/TelegramEngine/Data/{Notices.swift => NoticesData.swift} (100%) create mode 100644 submodules/TelegramCore/Sources/TelegramEngine/Data/OrderedListsData.swift rename submodules/TelegramCore/Sources/TelegramEngine/Data/{PeerSummary.swift => PeersData.swift} (100%) diff --git a/Telegram/NotificationContent/NotificationViewController.swift b/Telegram/NotificationContent/NotificationViewController.swift index 56301732f9..40a9f422d4 100644 --- a/Telegram/NotificationContent/NotificationViewController.swift +++ b/Telegram/NotificationContent/NotificationViewController.swift @@ -38,7 +38,7 @@ class NotificationViewController: UIViewController, UNNotificationContentExtensi let appVersion = (Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String) ?? "unknown" - self.impl = NotificationViewControllerImpl(initializationData: NotificationViewControllerInitializationData(appBundleId: baseAppBundleId, appGroupPath: appGroupUrl.path, apiId: buildConfig.apiId, apiHash: buildConfig.apiHash, languagesCategory: languagesCategory, encryptionParameters: encryptionParameters, appVersion: appVersion, bundleData: buildConfig.bundleData(withAppToken: nil, signatureDict: nil)), setPreferredContentSize: { [weak self] size in + self.impl = NotificationViewControllerImpl(initializationData: NotificationViewControllerInitializationData(appBundleId: baseAppBundleId, appBuildType: buildConfig.isAppStoreBuild ? .public : .internal, appGroupPath: appGroupUrl.path, apiId: buildConfig.apiId, apiHash: buildConfig.apiHash, languagesCategory: languagesCategory, encryptionParameters: encryptionParameters, appVersion: appVersion, bundleData: buildConfig.bundleData(withAppToken: nil, signatureDict: nil)), setPreferredContentSize: { [weak self] size in self?.preferredContentSize = size }) } diff --git a/Telegram/Share/ShareRootController.swift b/Telegram/Share/ShareRootController.swift index 1c53d48b3e..2574c871e3 100644 --- a/Telegram/Share/ShareRootController.swift +++ b/Telegram/Share/ShareRootController.swift @@ -45,7 +45,7 @@ class ShareRootController: UIViewController { let appVersion = (Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String) ?? "unknown" - self.impl = ShareRootControllerImpl(initializationData: ShareRootControllerInitializationData(appBundleId: baseAppBundleId, appGroupPath: appGroupUrl.path, apiId: buildConfig.apiId, apiHash: buildConfig.apiHash, languagesCategory: languagesCategory, encryptionParameters: encryptionParameters, appVersion: appVersion, bundleData: buildConfig.bundleData(withAppToken: nil, signatureDict: nil)), getExtensionContext: { [weak self] in + self.impl = ShareRootControllerImpl(initializationData: ShareRootControllerInitializationData(appBundleId: baseAppBundleId, appBuildType: buildConfig.isAppStoreBuild ? .public : .internal, appGroupPath: appGroupUrl.path, apiId: buildConfig.apiId, apiHash: buildConfig.apiHash, languagesCategory: languagesCategory, encryptionParameters: encryptionParameters, appVersion: appVersion, bundleData: buildConfig.bundleData(withAppToken: nil, signatureDict: nil)), getExtensionContext: { [weak self] in return self?.extensionContext }) } diff --git a/submodules/AccountContext/Sources/AccountContext.swift b/submodules/AccountContext/Sources/AccountContext.swift index 66e45521a0..c50a69b53e 100644 --- a/submodules/AccountContext/Sources/AccountContext.swift +++ b/submodules/AccountContext/Sources/AccountContext.swift @@ -29,9 +29,15 @@ public enum AccessType { case unreachable } +public enum TelegramAppBuildType { + case `internal` + case `public` +} + public final class TelegramApplicationBindings { public let isMainApp: Bool public let appBundleId: String + public let appBuildType: TelegramAppBuildType public let containerPath: String public let appSpecificScheme: String public let openUrl: (String) -> Void @@ -56,9 +62,10 @@ public final class TelegramApplicationBindings { public let requestSetAlternateIconName: (String?, @escaping (Bool) -> Void) -> Void public let forceOrientation: (UIInterfaceOrientation) -> Void - public init(isMainApp: Bool, appBundleId: String, containerPath: String, appSpecificScheme: String, openUrl: @escaping (String) -> Void, openUniversalUrl: @escaping (String, TelegramApplicationOpenUrlCompletion) -> Void, canOpenUrl: @escaping (String) -> Bool, getTopWindow: @escaping () -> UIWindow?, displayNotification: @escaping (String) -> Void, applicationInForeground: Signal, applicationIsActive: Signal, clearMessageNotifications: @escaping ([MessageId]) -> Void, pushIdleTimerExtension: @escaping () -> Disposable, openSettings: @escaping () -> Void, openAppStorePage: @escaping () -> Void, registerForNotifications: @escaping (@escaping (Bool) -> Void) -> Void, requestSiriAuthorization: @escaping (@escaping (Bool) -> Void) -> Void, siriAuthorization: @escaping () -> AccessType, getWindowHost: @escaping () -> WindowHost?, presentNativeController: @escaping (UIViewController) -> Void, dismissNativeController: @escaping () -> Void, getAvailableAlternateIcons: @escaping () -> [PresentationAppIcon], getAlternateIconName: @escaping () -> String?, requestSetAlternateIconName: @escaping (String?, @escaping (Bool) -> Void) -> Void, forceOrientation: @escaping (UIInterfaceOrientation) -> Void) { + public init(isMainApp: Bool, appBundleId: String, appBuildType: TelegramAppBuildType, containerPath: String, appSpecificScheme: String, openUrl: @escaping (String) -> Void, openUniversalUrl: @escaping (String, TelegramApplicationOpenUrlCompletion) -> Void, canOpenUrl: @escaping (String) -> Bool, getTopWindow: @escaping () -> UIWindow?, displayNotification: @escaping (String) -> Void, applicationInForeground: Signal, applicationIsActive: Signal, clearMessageNotifications: @escaping ([MessageId]) -> Void, pushIdleTimerExtension: @escaping () -> Disposable, openSettings: @escaping () -> Void, openAppStorePage: @escaping () -> Void, registerForNotifications: @escaping (@escaping (Bool) -> Void) -> Void, requestSiriAuthorization: @escaping (@escaping (Bool) -> Void) -> Void, siriAuthorization: @escaping () -> AccessType, getWindowHost: @escaping () -> WindowHost?, presentNativeController: @escaping (UIViewController) -> Void, dismissNativeController: @escaping () -> Void, getAvailableAlternateIcons: @escaping () -> [PresentationAppIcon], getAlternateIconName: @escaping () -> String?, requestSetAlternateIconName: @escaping (String?, @escaping (Bool) -> Void) -> Void, forceOrientation: @escaping (UIInterfaceOrientation) -> Void) { self.isMainApp = isMainApp self.appBundleId = appBundleId + self.appBuildType = appBuildType self.containerPath = containerPath self.appSpecificScheme = appSpecificScheme self.openUrl = openUrl diff --git a/submodules/ChatListUI/Sources/ChatContextMenus.swift b/submodules/ChatListUI/Sources/ChatContextMenus.swift index f17e166741..915e07168d 100644 --- a/submodules/ChatListUI/Sources/ChatContextMenus.swift +++ b/submodules/ChatListUI/Sources/ChatContextMenus.swift @@ -94,9 +94,9 @@ func chatContextMenuItems(context: AccountContext, peerId: PeerId, promoInfo: Ch return context.engine.data.get( TelegramEngine.EngineData.Item.Peer.IsContact(id: peer.id), TelegramEngine.EngineData.Item.Peer.NotificationSettings(id: peer.id), - TelegramEngine.EngineData.Item.Messages.ReadState(id: peer.id) + TelegramEngine.EngineData.Item.Messages.PeerReadCounters(id: peer.id) ) - |> map { [weak chatListController] isContact, notificationSettings, readState -> [ContextMenuItem] in + |> map { [weak chatListController] isContact, notificationSettings, readCounters -> [ContextMenuItem] in if promoInfo != nil { return [] } @@ -160,7 +160,7 @@ func chatContextMenuItems(context: AccountContext, peerId: PeerId, promoInfo: Ch } var isUnread = false - if let readState = readState, readState.isUnread { + if readCounters.isUnread { isUnread = true } diff --git a/submodules/ChatListUI/Sources/ChatListController.swift b/submodules/ChatListUI/Sources/ChatListController.swift index d9c1232f4b..9db9819938 100644 --- a/submodules/ChatListUI/Sources/ChatListController.swift +++ b/submodules/ChatListUI/Sources/ChatListController.swift @@ -1954,29 +1954,14 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController private var initializedFilters = false private func reloadFilters(firstUpdate: (() -> Void)? = nil) { - let preferencesKey: PostboxViewKey = .preferences(keys: Set([ - ApplicationSpecificPreferencesKeys.chatListFilterSettings - ])) - let experimentalUISettingsKey: ValueBoxKey = ApplicationSpecificSharedDataKeys.experimentalUISettings - let displayTabsAtBottom = self.context.sharedContext.accountManager.sharedData(keys: Set([experimentalUISettingsKey])) - |> map { sharedData -> Bool in - let settings: ExperimentalUISettings = sharedData.entries[experimentalUISettingsKey]?.get(ExperimentalUISettings.self) ?? ExperimentalUISettings.defaultSettings - return settings.foldersTabAtBottom - } - |> distinctUntilChanged - let filterItems = chatListFilterItems(context: self.context) var notifiedFirstUpdate = false self.filterDisposable.set((combineLatest(queue: .mainQueue(), - self.context.account.postbox.combinedView(keys: [ - preferencesKey - ]), filterItems, - displayTabsAtBottom, self.context.account.postbox.peerView(id: self.context.account.peerId), self.context.engine.data.get(TelegramEngine.EngineData.Item.Configuration.UserLimits(isPremium: false)) ) - |> deliverOnMainQueue).start(next: { [weak self] _, countAndFilterItems, displayTabsAtBottom, peerView, limits in + |> deliverOnMainQueue).start(next: { [weak self] countAndFilterItems, peerView, limits in guard let strongSelf = self else { return } @@ -2044,7 +2029,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController } } let filtersLimit = isPremium == false ? limits.maxFoldersCount : nil - strongSelf.tabContainerData = (resolvedItems, displayTabsAtBottom, filtersLimit) + strongSelf.tabContainerData = (resolvedItems, false, filtersLimit) var availableFilters: [ChatListContainerNodeFilter] = [] var hasAllChats = false for item in items { @@ -2080,7 +2065,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController strongSelf.initializedFilters = true } - let isEmpty = resolvedItems.count <= 1 || displayTabsAtBottom + let isEmpty = resolvedItems.count <= 1 let animated = strongSelf.didSetupTabs strongSelf.didSetupTabs = true diff --git a/submodules/ChatListUI/Sources/ChatListSelection.swift b/submodules/ChatListUI/Sources/ChatListSelection.swift index 18faea4e5f..ff121970ce 100644 --- a/submodules/ChatListUI/Sources/ChatListSelection.swift +++ b/submodules/ChatListUI/Sources/ChatListSelection.swift @@ -29,39 +29,26 @@ func chatListSelectionOptions(context: AccountContext, peerIds: Set, fil } |> distinctUntilChanged } else { - let key = PostboxViewKey.unreadCounts(items: [.total(nil)]) - return context.account.postbox.combinedView(keys: [key]) - |> map { view -> ChatListSelectionOptions in + return context.engine.data.subscribe(TelegramEngine.EngineData.Item.Messages.TotalReadCounters()) + |> map { readCounters -> ChatListSelectionOptions in var hasUnread = false - if let unreadCounts = view.views[key] as? UnreadMessageCountsView, let total = unreadCounts.total() { - for (_, counter) in total.1.absoluteCounters { - if counter.messageCount != 0 { - hasUnread = true - break - } - } + if readCounters.count(for: .filtered, in: .chats, with: .all) != 0 { + hasUnread = true } return ChatListSelectionOptions(read: .all(enabled: hasUnread), delete: false) } |> distinctUntilChanged } } else { - let items: [UnreadMessageCountsItem] = peerIds.map(UnreadMessageCountsItem.peer) - let key = PostboxViewKey.unreadCounts(items: items) - return context.account.postbox.combinedView(keys: [key]) - |> map { view -> ChatListSelectionOptions in + return context.engine.data.subscribe(EngineDataList( + peerIds.map(TelegramEngine.EngineData.Item.Messages.PeerReadCounters.init) + )) + |> map { readCounters -> ChatListSelectionOptions in var hasUnread = false - if let unreadCounts = view.views[key] as? UnreadMessageCountsView { - loop: for entry in unreadCounts.entries { - switch entry { - case let .peer(_, state): - if let state = state, state.isUnread { - hasUnread = true - break loop - } - default: - break - } + for counters in readCounters { + if counters.isUnread { + hasUnread = true + break } } return ChatListSelectionOptions(read: .selective(enabled: hasUnread), delete: true) diff --git a/submodules/DebugSettingsUI/Sources/DebugAccountsController.swift b/submodules/DebugSettingsUI/Sources/DebugAccountsController.swift index 28fb2cf08c..a5e45f7e75 100644 --- a/submodules/DebugSettingsUI/Sources/DebugAccountsController.swift +++ b/submodules/DebugSettingsUI/Sources/DebugAccountsController.swift @@ -120,7 +120,10 @@ public func debugAccountsController(context: AccountContext, accountManager: Acc ActionSheetItemGroup(items: [ ActionSheetButtonItem(title: "Production", color: .accent, action: { dismissAction() - context.sharedContext.beginNewAuth(testingEnvironment: false) + + if case .internal = context.sharedContext.applicationBindings.appBuildType { + context.sharedContext.beginNewAuth(testingEnvironment: false) + } }), ActionSheetButtonItem(title: "Test", color: .accent, action: { dismissAction() diff --git a/submodules/GalleryUI/Sources/Items/UniversalVideoGalleryItem.swift b/submodules/GalleryUI/Sources/Items/UniversalVideoGalleryItem.swift index c567f15efc..dba478408d 100644 --- a/submodules/GalleryUI/Sources/Items/UniversalVideoGalleryItem.swift +++ b/submodules/GalleryUI/Sources/Items/UniversalVideoGalleryItem.swift @@ -608,14 +608,13 @@ private final class PictureInPictureContentImpl: NSObject, PictureInPictureConte } if let (messageId, _) = hiddenMedia { - self.messageRemovedDisposable = (context.account.postbox.combinedView(keys: [PostboxViewKey.messages([messageId])]) - |> map { views -> Bool in - if let view = views.views[PostboxViewKey.messages([messageId])] as? MessagesView { - if view.messages[messageId] == nil { - return true - } + self.messageRemovedDisposable = (context.engine.data.subscribe(TelegramEngine.EngineData.Item.Messages.Message(id: messageId)) + |> map { message -> Bool in + if let _ = message { + return false + } else { + return true } - return false } |> filter { $0 } |> take(1) @@ -2247,16 +2246,12 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode { let shouldBeDismissed: Signal if let contentInfo = item.contentInfo, case let .message(message) = contentInfo { - let viewKey = PostboxViewKey.messages(Set([message.id])) - shouldBeDismissed = context.account.postbox.combinedView(keys: [viewKey]) - |> map { views -> Bool in - guard let view = views.views[viewKey] as? MessagesView else { + shouldBeDismissed = context.engine.data.subscribe(TelegramEngine.EngineData.Item.Messages.Message(id: message.id)) + |> map { message -> Bool in + if let _ = message { return false - } - if view.messages.isEmpty { - return true } else { - return false + return true } } |> distinctUntilChanged diff --git a/submodules/PeerAvatarGalleryUI/Sources/AvatarGalleryController.swift b/submodules/PeerAvatarGalleryUI/Sources/AvatarGalleryController.swift index 8d4019c405..22230f7200 100644 --- a/submodules/PeerAvatarGalleryUI/Sources/AvatarGalleryController.swift +++ b/submodules/PeerAvatarGalleryUI/Sources/AvatarGalleryController.swift @@ -21,13 +21,13 @@ public enum AvatarGalleryEntryId: Hashable { case resource(String) } -public func peerInfoProfilePhotos(context: AccountContext, peerId: PeerId) -> Signal { - return context.account.postbox.combinedView(keys: [.basicPeer(peerId)]) - |> mapToSignal { view -> Signal<[AvatarGalleryEntry]?, NoError> in - guard let peer = (view.views[.basicPeer(peerId)] as? BasicPeerView)?.peer else { +public func peerInfoProfilePhotos(context: AccountContext, peerId: EnginePeer.Id) -> Signal { + return context.engine.data.subscribe(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)) + |> mapToSignal { peer -> Signal<[AvatarGalleryEntry]?, NoError> in + guard let peer = peer else { return .single(nil) } - return initialAvatarGalleryEntries(account: context.account, engine: context.engine, peer: peer) + return initialAvatarGalleryEntries(account: context.account, engine: context.engine, peer: peer._asPeer()) } |> distinctUntilChanged |> mapToSignal { entries -> Signal<(Bool, [AvatarGalleryEntry])?, NoError> in diff --git a/submodules/PeerInfoUI/Sources/ChannelBannedMemberController.swift b/submodules/PeerInfoUI/Sources/ChannelBannedMemberController.swift index 92df566a89..14c2562077 100644 --- a/submodules/PeerInfoUI/Sources/ChannelBannedMemberController.swift +++ b/submodules/PeerInfoUI/Sources/ChannelBannedMemberController.swift @@ -47,7 +47,7 @@ private enum ChannelBannedMemberEntryStableId: Hashable { } private enum ChannelBannedMemberEntry: ItemListNodeEntry { - case info(PresentationTheme, PresentationStrings, PresentationDateTimeFormat, Peer, TelegramUserPresence?) + case info(PresentationTheme, PresentationStrings, PresentationDateTimeFormat, EnginePeer, EnginePeer.Presence?) case rightsHeader(PresentationTheme, String) case rightItem(PresentationTheme, Int, String, TelegramChatBannedRightsFlags, Bool, Bool) case timeout(PresentationTheme, String, String) @@ -97,7 +97,7 @@ private enum ChannelBannedMemberEntry: ItemListNodeEntry { if lhsDateTimeFormat != rhsDateTimeFormat { return false } - if !arePeersEqual(lhsPeer, rhsPeer) { + if lhsPeer != rhsPeer { return false } if lhsPresence != rhsPresence { @@ -207,7 +207,7 @@ private enum ChannelBannedMemberEntry: ItemListNodeEntry { let arguments = arguments as! ChannelBannedMemberControllerArguments switch self { case let .info(_, _, dateTimeFormat, peer, presence): - return ItemListAvatarAndNameInfoItem(accountContext: arguments.context, presentationData: presentationData, dateTimeFormat: dateTimeFormat, mode: .generic, peer: EnginePeer(peer), presence: presence.flatMap(EnginePeer.Presence.init), memberCount: nil, state: ItemListAvatarAndNameInfoItemState(), sectionId: self.section, style: .blocks(withTopInset: true, withExtendedBottomInset: false), editingNameUpdated: { _ in + return ItemListAvatarAndNameInfoItem(accountContext: arguments.context, presentationData: presentationData, dateTimeFormat: dateTimeFormat, mode: .generic, peer: peer, presence: presence, memberCount: nil, state: ItemListAvatarAndNameInfoItemState(), sectionId: self.section, style: .blocks(withTopInset: true, withExtendedBottomInset: false), editingNameUpdated: { _ in }, avatarTapped: { }) case let .rightsHeader(_, text): @@ -256,11 +256,11 @@ func completeRights(_ flags: TelegramChatBannedRightsFlags) -> TelegramChatBanne return result } -private func channelBannedMemberControllerEntries(presentationData: PresentationData, state: ChannelBannedMemberControllerState, accountPeerId: PeerId, channelView: PeerView, memberView: PeerView, initialParticipant: ChannelParticipant?, initialBannedBy: Peer?) -> [ChannelBannedMemberEntry] { +private func channelBannedMemberControllerEntries(presentationData: PresentationData, state: ChannelBannedMemberControllerState, accountPeerId: PeerId, channelPeer: EnginePeer?, memberPeer: EnginePeer?, memberPresence: EnginePeer.Presence?, initialParticipant: ChannelParticipant?, initialBannedBy: EnginePeer?) -> [ChannelBannedMemberEntry] { var entries: [ChannelBannedMemberEntry] = [] - if let channel = channelView.peers[channelView.peerId] as? TelegramChannel, let _ = channelView.cachedData as? CachedChannelData, let defaultBannedRights = channel.defaultBannedRights, let member = memberView.peers[memberView.peerId] { - entries.append(.info(presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, member, memberView.peerPresences[member.id] as? TelegramUserPresence)) + if case let .channel(channel) = channelPeer, let defaultBannedRights = channel.defaultBannedRights, let member = memberPeer { + entries.append(.info(presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, member, memberPresence)) let currentRightsFlags: TelegramChatBannedRightsFlags if let updatedFlags = state.updatedFlags { @@ -300,13 +300,13 @@ private func channelBannedMemberControllerEntries(presentationData: Presentation entries.append(.timeout(presentationData.theme, presentationData.strings.GroupPermission_Duration, currentTimeoutString)) if let initialParticipant = initialParticipant, case let .member(_, _, _, banInfo?, _) = initialParticipant, let initialBannedBy = initialBannedBy { - entries.append(.exceptionInfo(presentationData.theme, presentationData.strings.GroupPermission_AddedInfo(EnginePeer(initialBannedBy).displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder), stringForRelativeSymbolicTimestamp(strings: presentationData.strings, relativeTimestamp: banInfo.timestamp, relativeTo: state.referenceTimestamp, dateTimeFormat: presentationData.dateTimeFormat)).string)) + entries.append(.exceptionInfo(presentationData.theme, presentationData.strings.GroupPermission_AddedInfo(initialBannedBy.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder), stringForRelativeSymbolicTimestamp(strings: presentationData.strings, relativeTimestamp: banInfo.timestamp, relativeTo: state.referenceTimestamp, dateTimeFormat: presentationData.dateTimeFormat)).string)) entries.append(.delete(presentationData.theme, presentationData.strings.GroupPermission_Delete)) } - } else if let group = channelView.peers[channelView.peerId] as? TelegramGroup, let member = memberView.peers[memberView.peerId] { + } else if case let .legacyGroup(group) = channelPeer, let member = memberPeer { let defaultBannedRightsFlags = group.defaultBannedRights?.flags ?? [] - entries.append(.info(presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, member, memberView.peerPresences[member.id] as? TelegramUserPresence)) + entries.append(.info(presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, member, memberPresence)) let currentRightsFlags: TelegramChatBannedRightsFlags if let updatedFlags = state.updatedFlags { @@ -346,7 +346,7 @@ private func channelBannedMemberControllerEntries(presentationData: Presentation entries.append(.timeout(presentationData.theme, presentationData.strings.GroupPermission_Duration, currentTimeoutString)) if let initialParticipant = initialParticipant, case let .member(_, _, _, banInfo?, _) = initialParticipant, let initialBannedBy = initialBannedBy { - entries.append(.exceptionInfo(presentationData.theme, presentationData.strings.GroupPermission_AddedInfo(EnginePeer(initialBannedBy).displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder), stringForRelativeSymbolicTimestamp(strings: presentationData.strings, relativeTimestamp: banInfo.timestamp, relativeTo: state.referenceTimestamp, dateTimeFormat: presentationData.dateTimeFormat)).string)) + entries.append(.exceptionInfo(presentationData.theme, presentationData.strings.GroupPermission_AddedInfo(initialBannedBy.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder), stringForRelativeSymbolicTimestamp(strings: presentationData.strings, relativeTimestamp: banInfo.timestamp, relativeTo: state.referenceTimestamp, dateTimeFormat: presentationData.dateTimeFormat)).string)) entries.append(.delete(presentationData.theme, presentationData.strings.GroupPermission_Delete)) } } @@ -504,24 +504,31 @@ public func channelBannedMemberController(context: AccountContext, updatedPresen presentControllerImpl?(actionSheet, nil) }) - var keys: [PostboxViewKey] = [.peer(peerId: peerId, components: .all), .peer(peerId: memberId, components: .all)] + var peerDataItems: [TelegramEngine.EngineData.Item.Peer.Peer] = [] + peerDataItems.append(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)) + peerDataItems.append(TelegramEngine.EngineData.Item.Peer.Peer(id: memberId)) if let banInfo = initialParticipant?.banInfo { - keys.append(.peer(peerId: banInfo.restrictedBy, components: [])) + peerDataItems.append(TelegramEngine.EngineData.Item.Peer.Peer(id: banInfo.restrictedBy)) } - let combinedView = context.account.postbox.combinedView(keys: keys) + + let peersMap = context.engine.data.subscribe( + EngineDataMap(peerDataItems), + TelegramEngine.EngineData.Item.Peer.Presence(id: memberId) + ) let canEdit = true let presentationData = updatedPresentationData?.signal ?? context.sharedContext.presentationData - let signal = combineLatest(presentationData, statePromise.get(), combinedView) + let signal = combineLatest(presentationData, statePromise.get(), peersMap) |> deliverOnMainQueue - |> map { presentationData, state, combinedView -> (ItemListControllerState, (ItemListNodeState, Any)) in - let channelView = combinedView.views[.peer(peerId: peerId, components: .all)] as! PeerView - let memberView = combinedView.views[.peer(peerId: memberId, components: .all)] as! PeerView - var initialBannedByPeer: Peer? + |> map { presentationData, state, peersMap -> (ItemListControllerState, (ItemListNodeState, Any)) in + let channelPeer = peersMap.0[peerId].flatMap { $0 } + let memberPeer = peersMap.0[memberId].flatMap { $0 } + var initialBannedByPeer: EnginePeer? if let banInfo = initialParticipant?.banInfo { - initialBannedByPeer = (combinedView.views[.peer(peerId: banInfo.restrictedBy, components: [])] as? PeerView)?.peers[banInfo.restrictedBy] + initialBannedByPeer = peersMap.0[banInfo.restrictedBy].flatMap { $0 } } + let memberPresence = peersMap.1 let leftNavigationButton: ItemListNavigationButton leftNavigationButton = ItemListNavigationButton(content: .text(presentationData.strings.Common_Cancel), style: .regular, enabled: true, action: { @@ -590,7 +597,7 @@ public func channelBannedMemberController(context: AccountContext, updatedPresen resolvedRights = TelegramChatBannedRights(flags: completeRights(currentRightsFlags), untilDate: currentTimeout) } - } else if canEdit, let _ = channelView.peers[channelView.peerId] as? TelegramChannel { + } else if canEdit, case .channel = channelPeer { var updateFlags: TelegramChatBannedRightsFlags? var updateTimeout: Int32? updateState { state in @@ -723,7 +730,7 @@ public func channelBannedMemberController(context: AccountContext, updatedPresen let controllerState = ItemListControllerState(presentationData: ItemListPresentationData(presentationData), title: .text(title), leftNavigationButton: leftNavigationButton, rightNavigationButton: rightNavigationButton, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back), animateChanges: false) - let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: channelBannedMemberControllerEntries(presentationData: presentationData, state: state, accountPeerId: context.account.peerId, channelView: channelView, memberView: memberView, initialParticipant: initialParticipant, initialBannedBy: initialBannedByPeer), style: .blocks, emptyStateItem: nil, animateChanges: true) + let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: channelBannedMemberControllerEntries(presentationData: presentationData, state: state, accountPeerId: context.account.peerId, channelPeer: channelPeer, memberPeer: memberPeer, memberPresence: memberPresence, initialParticipant: initialParticipant, initialBannedBy: initialBannedByPeer), style: .blocks, emptyStateItem: nil, animateChanges: true) return (controllerState, (listState, arguments)) } diff --git a/submodules/SettingsUI/Sources/Notifications/Exceptions/NotificationExceptionControllerNode.swift b/submodules/SettingsUI/Sources/Notifications/Exceptions/NotificationExceptionControllerNode.swift index df400fb6e0..280e2063ea 100644 --- a/submodules/SettingsUI/Sources/Notifications/Exceptions/NotificationExceptionControllerNode.swift +++ b/submodules/SettingsUI/Sources/Notifications/Exceptions/NotificationExceptionControllerNode.swift @@ -740,39 +740,34 @@ final class NotificationExceptionsControllerNode: ViewControllerTracingNode { let updateNotificationsView: (@escaping () -> Void) -> Void = { completion in updateState { current in peerIds = peerIds.union(current.mode.peerIds) - let key: PostboxViewKey = .peerNotificationSettings(peerIds: peerIds) - updateNotificationsDisposable.set((context.account.postbox.combinedView(keys: [key]) - |> deliverOnMainQueue).start(next: { view in - if let view = view.views[key] as? PeerNotificationSettingsView { - let _ = (context.engine.data.get( - EngineDataMap(view.notificationSettings.keys.map(TelegramEngine.EngineData.Item.Peer.Peer.init)), - EngineDataMap(view.notificationSettings.keys.map(TelegramEngine.EngineData.Item.Peer.NotificationSettings.init)) - ) - |> deliverOnMainQueue).start(next: { peerMap, notificationSettingsMap in - updateState { current in - var current = current - for (key, value) in view.notificationSettings { - if let value = value as? TelegramPeerNotificationSettings { - if let local = current.mode.settings[key] { - if !value.isEqual(to: local.settings), let maybePeer = peerMap[key], let peer = maybePeer, let settings = notificationSettingsMap[key], !settings._asNotificationSettings().isEqual(to: local.settings) { - current = current.withUpdatedPeerSound(peer._asPeer(), settings.messageSound._asMessageSound()).withUpdatedPeerMuteInterval(peer._asPeer(), settings.muteState.timeInterval).withUpdatedPeerDisplayPreviews(peer._asPeer(), settings.displayPreviews._asDisplayPreviews()) - } - } else if let maybePeer = peerMap[key], let peer = maybePeer { - if case .default = value.messageSound, case .unmuted = value.muteState, case .default = value.displayPreviews { - } else { - current = current.withUpdatedPeerSound(peer._asPeer(), value.messageSound).withUpdatedPeerMuteInterval(peer._asPeer(), EnginePeer.NotificationSettings.MuteState(value.muteState).timeInterval).withUpdatedPeerDisplayPreviews(peer._asPeer(), value.displayPreviews) - } - } + updateNotificationsDisposable.set((context.engine.data.subscribe(EngineDataMap( + peerIds.map(TelegramEngine.EngineData.Item.Peer.NotificationSettings.init) + )) + |> deliverOnMainQueue).start(next: { notificationSettingsMap in + let _ = (context.engine.data.get( + EngineDataMap(notificationSettingsMap.keys.map(TelegramEngine.EngineData.Item.Peer.Peer.init)), + EngineDataMap(notificationSettingsMap.keys.map(TelegramEngine.EngineData.Item.Peer.NotificationSettings.init)) + ) + |> deliverOnMainQueue).start(next: { peerMap, notificationSettingsMap in + updateState { current in + var current = current + for (key, value) in notificationSettingsMap { + if let local = current.mode.settings[key] { + if !value._asNotificationSettings().isEqual(to: local.settings), let maybePeer = peerMap[key], let peer = maybePeer, let settings = notificationSettingsMap[key], !settings._asNotificationSettings().isEqual(to: local.settings) { + current = current.withUpdatedPeerSound(peer._asPeer(), settings.messageSound._asMessageSound()).withUpdatedPeerMuteInterval(peer._asPeer(), settings.muteState.timeInterval).withUpdatedPeerDisplayPreviews(peer._asPeer(), settings.displayPreviews._asDisplayPreviews()) + } + } else if let maybePeer = peerMap[key], let peer = maybePeer { + if case .default = value.messageSound, case .unmuted = value.muteState, case .default = value.displayPreviews { + } else { + current = current.withUpdatedPeerSound(peer._asPeer(), value.messageSound._asMessageSound()).withUpdatedPeerMuteInterval(peer._asPeer(), value.muteState.timeInterval).withUpdatedPeerDisplayPreviews(peer._asPeer(), value.displayPreviews._asDisplayPreviews()) } } - return current } - - completion() - }) - } else { + return current + } + completion() - } + }) })) return current } diff --git a/submodules/SettingsUI/Sources/NotificationsPeerCategoryController.swift b/submodules/SettingsUI/Sources/NotificationsPeerCategoryController.swift index 6dc6dded30..2ec033ce42 100644 --- a/submodules/SettingsUI/Sources/NotificationsPeerCategoryController.swift +++ b/submodules/SettingsUI/Sources/NotificationsPeerCategoryController.swift @@ -455,39 +455,36 @@ public func notificationsPeerCategoryController(context: AccountContext, categor let updateNotificationsView: (@escaping () -> Void) -> Void = { completion in updateState { current in peerIds = peerIds.union(current.mode.peerIds) - let key: PostboxViewKey = .peerNotificationSettings(peerIds: peerIds) - updateNotificationsDisposable.set((context.account.postbox.combinedView(keys: [key]) - |> deliverOnMainQueue).start(next: { view in - if let view = view.views[key] as? PeerNotificationSettingsView { - let _ = (context.engine.data.get( - EngineDataMap(view.notificationSettings.keys.map(TelegramEngine.EngineData.Item.Peer.Peer.init)), - EngineDataMap(view.notificationSettings.keys.map(TelegramEngine.EngineData.Item.Peer.NotificationSettings.init)) - ) - |> deliverOnMainQueue).start(next: { peerMap, notificationSettingsMap in - updateState { current in - var current = current - for (key, value) in view.notificationSettings { - if let value = value as? TelegramPeerNotificationSettings { - if let local = current.mode.settings[key] { - if !value.isEqual(to: local.settings), let maybePeer = peerMap[key], let peer = maybePeer, let settings = notificationSettingsMap[key], !settings._asNotificationSettings().isEqual(to: local.settings) { - current = current.withUpdatedPeerSound(peer._asPeer(), settings.messageSound._asMessageSound()).withUpdatedPeerMuteInterval(peer._asPeer(), settings.muteState.timeInterval).withUpdatedPeerDisplayPreviews(peer._asPeer(), settings.displayPreviews._asDisplayPreviews()) - } - } else if let maybePeer = peerMap[key], let peer = maybePeer { - if case .default = value.messageSound, case .unmuted = value.muteState, case .default = value.displayPreviews { - } else { - current = current.withUpdatedPeerSound(peer._asPeer(), value.messageSound).withUpdatedPeerMuteInterval(peer._asPeer(), EnginePeer.NotificationSettings.MuteState(value.muteState).timeInterval).withUpdatedPeerDisplayPreviews(peer._asPeer(), value.displayPreviews) - } - } + let combinedPeerNotificationSettings = context.engine.data.subscribe(EngineDataMap( + peerIds.map(TelegramEngine.EngineData.Item.Peer.NotificationSettings.init) + )) + + updateNotificationsDisposable.set((combinedPeerNotificationSettings + |> deliverOnMainQueue).start(next: { combinedPeerNotificationSettings in + let _ = (context.engine.data.get( + EngineDataMap(combinedPeerNotificationSettings.keys.map(TelegramEngine.EngineData.Item.Peer.Peer.init)), + EngineDataMap(combinedPeerNotificationSettings.keys.map(TelegramEngine.EngineData.Item.Peer.NotificationSettings.init)) + ) + |> deliverOnMainQueue).start(next: { peerMap, notificationSettingsMap in + updateState { current in + var current = current + for (key, value) in combinedPeerNotificationSettings { + if let local = current.mode.settings[key] { + if !value._asNotificationSettings().isEqual(to: local.settings), let maybePeer = peerMap[key], let peer = maybePeer, let settings = notificationSettingsMap[key], !settings._asNotificationSettings().isEqual(to: local.settings) { + current = current.withUpdatedPeerSound(peer._asPeer(), settings.messageSound._asMessageSound()).withUpdatedPeerMuteInterval(peer._asPeer(), settings.muteState.timeInterval).withUpdatedPeerDisplayPreviews(peer._asPeer(), settings.displayPreviews._asDisplayPreviews()) + } + } else if let maybePeer = peerMap[key], let peer = maybePeer { + if case .default = value.messageSound, case .unmuted = value.muteState, case .default = value.displayPreviews { + } else { + current = current.withUpdatedPeerSound(peer._asPeer(), value.messageSound._asMessageSound()).withUpdatedPeerMuteInterval(peer._asPeer(), value.muteState.timeInterval).withUpdatedPeerDisplayPreviews(peer._asPeer(), value.displayPreviews._asDisplayPreviews()) } } - return current } - - completion() - }) - } else { + return current + } + completion() - } + }) })) return current } diff --git a/submodules/SettingsUI/Sources/Privacy and Security/PrivacyAndSecurityController.swift b/submodules/SettingsUI/Sources/Privacy and Security/PrivacyAndSecurityController.swift index a10d454d88..f594a23db5 100644 --- a/submodules/SettingsUI/Sources/Privacy and Security/PrivacyAndSecurityController.swift +++ b/submodules/SettingsUI/Sources/Privacy and Security/PrivacyAndSecurityController.swift @@ -851,12 +851,23 @@ public func privacyAndSecurityController(context: AccountContext, initialSetting updatedBlockedPeers?(blockedPeersContext) })) - let preferencesKey: PostboxViewKey = .preferences(keys: Set([PreferencesKeys.appConfiguration])) - - let signal = combineLatest(queue: .mainQueue(), context.sharedContext.presentationData, statePromise.get(), privacySettingsPromise.get(), context.sharedContext.accountManager.noticeEntry(key: ApplicationSpecificNotice.secretChatLinkPreviewsKey()), context.sharedContext.accountManager.sharedData(keys: [ApplicationSpecificSharedDataKeys.contactSynchronizationSettings]), context.engine.peers.recentPeers(), blockedPeersState.get(), webSessionsContext.state, context.sharedContext.accountManager.accessChallengeData(), combineLatest(twoStepAuth.get(), twoStepAuthDataValue.get()), context.account.postbox.combinedView(keys: [preferencesKey])) - |> map { presentationData, state, privacySettings, noticeView, sharedData, recentPeers, blockedPeersState, activeWebsitesState, accessChallengeData, twoStepAuth, preferences -> (ItemListControllerState, (ItemListNodeState, Any)) in + let signal = combineLatest( + queue: .mainQueue(), + context.sharedContext.presentationData, + statePromise.get(), + privacySettingsPromise.get(), + context.sharedContext.accountManager.noticeEntry(key: ApplicationSpecificNotice.secretChatLinkPreviewsKey()), + context.sharedContext.accountManager.sharedData(keys: [ApplicationSpecificSharedDataKeys.contactSynchronizationSettings]), + context.engine.peers.recentPeers(), + blockedPeersState.get(), + webSessionsContext.state, + context.sharedContext.accountManager.accessChallengeData(), + combineLatest(twoStepAuth.get(), twoStepAuthDataValue.get()), + context.engine.data.subscribe(TelegramEngine.EngineData.Item.Configuration.App()) + ) + |> map { presentationData, state, privacySettings, noticeView, sharedData, recentPeers, blockedPeersState, activeWebsitesState, accessChallengeData, twoStepAuth, appConfiguration -> (ItemListControllerState, (ItemListNodeState, Any)) in var canAutoarchive = false - if let view = preferences.views[preferencesKey] as? PreferencesView, let appConfiguration = view.values[PreferencesKeys.appConfiguration]?.get(AppConfiguration.self), let data = appConfiguration.data, let hasAutoarchive = data["autoarchive_setting_available"] as? Bool { + if let data = appConfiguration.data, let hasAutoarchive = data["autoarchive_setting_available"] as? Bool { canAutoarchive = hasAutoarchive } diff --git a/submodules/SettingsUI/Sources/Search/SettingsSearchItem.swift b/submodules/SettingsUI/Sources/Search/SettingsSearchItem.swift index 1028217957..71638b64a4 100644 --- a/submodules/SettingsUI/Sources/Search/SettingsSearchItem.swift +++ b/submodules/SettingsUI/Sources/Search/SettingsSearchItem.swift @@ -400,7 +400,7 @@ public final class SettingsSearchContainerNode: SearchDisplayControllerContentNo self.recentListNode.isHidden = false let previousRecentlySearchedItemOrder = Atomic<[SettingsSearchableItemId]>(value: []) - let fixedRecentlySearchedItems = settingsSearchRecentItems(postbox: context.account.postbox) + let fixedRecentlySearchedItems = settingsSearchRecentItems(engine: context.engine) |> map { recentIds -> [SettingsSearchableItemId] in var result: [SettingsSearchableItemId] = [] let _ = previousRecentlySearchedItemOrder.modify { current in diff --git a/submodules/SettingsUI/Sources/Search/SettingsSearchRecentQueries.swift b/submodules/SettingsUI/Sources/Search/SettingsSearchRecentQueries.swift index 5168028286..38c7327b7f 100644 --- a/submodules/SettingsUI/Sources/Search/SettingsSearchRecentQueries.swift +++ b/submodules/SettingsUI/Sources/Search/SettingsSearchRecentQueries.swift @@ -52,16 +52,14 @@ func clearRecentSettingsSearchItems(engine: TelegramEngine) { let _ = engine.orderedLists.clear(collectionId: ApplicationSpecificOrderedItemListCollectionId.settingsSearchRecentItems).start() } -func settingsSearchRecentItems(postbox: Postbox) -> Signal<[SettingsSearchableItemId], NoError> { - return postbox.combinedView(keys: [.orderedItemList(id: ApplicationSpecificOrderedItemListCollectionId.settingsSearchRecentItems)]) - |> map { view -> [SettingsSearchableItemId] in +func settingsSearchRecentItems(engine: TelegramEngine) -> Signal<[SettingsSearchableItemId], NoError> { + return engine.data.subscribe(TelegramEngine.EngineData.Item.OrderedLists.ListItems(collectionId: ApplicationSpecificOrderedItemListCollectionId.settingsSearchRecentItems)) + |> map { items -> [SettingsSearchableItemId] in var result: [SettingsSearchableItemId] = [] - if let view = view.views[.orderedItemList(id: ApplicationSpecificOrderedItemListCollectionId.settingsSearchRecentItems)] as? OrderedItemListView { - for item in view.items { - let index = SettingsSearchRecentQueryItemId(item.id).value - if let itemId = SettingsSearchableItemId(index: index) { - result.append(itemId) - } + for item in items { + let index = SettingsSearchRecentQueryItemId(item.id).value + if let itemId = SettingsSearchableItemId(index: index) { + result.append(itemId) } } return result diff --git a/submodules/SettingsUI/Sources/Themes/ThemeGridSearchContentNode.swift b/submodules/SettingsUI/Sources/Themes/ThemeGridSearchContentNode.swift index d794567dd5..e10768ddbf 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemeGridSearchContentNode.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemeGridSearchContentNode.swift @@ -569,7 +569,7 @@ final class ThemeGridSearchContentNode: SearchDisplayControllerContentNode { } let previousRecentItems = Atomic<[ThemeGridRecentEntry]?>(value: nil) - self.recentDisposable = (combineLatest(wallpaperSearchRecentQueries(postbox: self.context.account.postbox), self.presentationDataPromise.get()) + self.recentDisposable = (combineLatest(wallpaperSearchRecentQueries(engine: self.context.engine), self.presentationDataPromise.get()) |> deliverOnMainQueue).start(next: { [weak self] queries, presentationData in if let strongSelf = self { var entries: [ThemeGridRecentEntry] = [] diff --git a/submodules/SettingsUI/Sources/Themes/WallpaperSearchRecentQueries.swift b/submodules/SettingsUI/Sources/Themes/WallpaperSearchRecentQueries.swift index 179b87ded6..20201b9cd9 100644 --- a/submodules/SettingsUI/Sources/Themes/WallpaperSearchRecentQueries.swift +++ b/submodules/SettingsUI/Sources/Themes/WallpaperSearchRecentQueries.swift @@ -55,15 +55,13 @@ func clearRecentWallpaperSearchQueries(engine: TelegramEngine) -> Signal Signal<[String], NoError> { - return postbox.combinedView(keys: [.orderedItemList(id: ApplicationSpecificOrderedItemListCollectionId.wallpaperSearchRecentQueries)]) - |> map { view -> [String] in +func wallpaperSearchRecentQueries(engine: TelegramEngine) -> Signal<[String], NoError> { + return engine.data.subscribe(TelegramEngine.EngineData.Item.OrderedLists.ListItems(collectionId: ApplicationSpecificOrderedItemListCollectionId.wallpaperSearchRecentQueries)) + |> map { items -> [String] in var result: [String] = [] - if let view = view.views[.orderedItemList(id: ApplicationSpecificOrderedItemListCollectionId.wallpaperSearchRecentQueries)] as? OrderedItemListView { - for item in view.items { - let value = WallpaperSearchRecentQueryItemId(item.id).value - result.append(value) - } + for item in items { + let value = WallpaperSearchRecentQueryItemId(item.id).value + result.append(value) } return result } diff --git a/submodules/TelegramCallsUI/Sources/PresentationGroupCall.swift b/submodules/TelegramCallsUI/Sources/PresentationGroupCall.swift index 151c19a43a..50e39b8f95 100644 --- a/submodules/TelegramCallsUI/Sources/PresentationGroupCall.swift +++ b/submodules/TelegramCallsUI/Sources/PresentationGroupCall.swift @@ -1391,15 +1391,14 @@ public final class PresentationGroupCallImpl: PresentationGroupCall { |> distinctUntilChanged |> runOn(.mainQueue()) } else { - rawAdminIds = accountContext.account.postbox.combinedView(keys: [.cachedPeerData(peerId: peerId)]) - |> map { views -> Set in - guard let view = views.views[.cachedPeerData(peerId: peerId)] as? CachedPeerDataView else { + rawAdminIds = accountContext.engine.data.subscribe( + TelegramEngine.EngineData.Item.Peer.LegacyGroupParticipants(id: peerId) + ) + |> map { participants -> Set in + guard case let .known(participants) = participants else { return Set() } - guard let cachedData = view.cachedPeerData as? CachedGroupData, let participants = cachedData.participants else { - return Set() - } - return Set(participants.participants.compactMap { item -> PeerId? in + return Set(participants.compactMap { item -> PeerId? in switch item { case .creator, .admin: return item.peerId @@ -1413,11 +1412,11 @@ public final class PresentationGroupCallImpl: PresentationGroupCall { let adminIds = combineLatest(queue: .mainQueue(), rawAdminIds, - accountContext.account.postbox.combinedView(keys: [.basicPeer(peerId)]) + accountContext.engine.data.subscribe(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)) ) - |> map { rawAdminIds, view -> Set in + |> map { rawAdminIds, peer -> Set in var rawAdminIds = rawAdminIds - if let peerView = view.views[.basicPeer(peerId)] as? BasicPeerView, let peer = peerView.peer as? TelegramChannel { + if case let .channel(peer) = peer { if peer.hasPermission(.manageCalls) { rawAdminIds.insert(accountContext.account.peerId) } else { @@ -1991,11 +1990,11 @@ public final class PresentationGroupCallImpl: PresentationGroupCall { let adminIds = combineLatest(queue: .mainQueue(), rawAdminIds, - accountContext.account.postbox.combinedView(keys: [.basicPeer(peerId)]) + accountContext.engine.data.subscribe(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)) ) - |> map { rawAdminIds, view -> Set in + |> map { rawAdminIds, peer -> Set in var rawAdminIds = rawAdminIds - if let peerView = view.views[.basicPeer(peerId)] as? BasicPeerView, let peer = peerView.peer as? TelegramChannel { + if case let .channel(peer) = peer { if peer.hasPermission(.manageCalls) { rawAdminIds.insert(accountContext.account.peerId) } else { diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Auth/TelegramEngineAuth.swift b/submodules/TelegramCore/Sources/TelegramEngine/Auth/TelegramEngineAuth.swift index 357f3594b6..e44a0c06a3 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Auth/TelegramEngineAuth.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Auth/TelegramEngineAuth.swift @@ -3,6 +3,11 @@ import Postbox import TelegramApi import MtProtoKit +public enum TelegramEngineAuthorizationState { + case unauthorized(UnauthorizedAccountState) + case authorized +} + public extension TelegramEngineUnauthorized { final class Auth { private let account: UnauthorizedAccount @@ -43,6 +48,19 @@ public extension TelegramEngineUnauthorized { return _internal_uploadedPeerVideo(postbox: self.account.postbox, network: self.account.network, messageMediaPreuploadManager: nil, resource: resource) } + public func state() -> Signal { + return self.account.postbox.stateView() + |> map { view -> TelegramEngineAuthorizationState? in + if let state = view.state as? UnauthorizedAccountState { + return .unauthorized(state) + } else if let _ = view.state as? AuthorizedAccountState { + return .authorized + } else { + return nil + } + } + } + public func setState(state: UnauthorizedAccountState) -> Signal { return self.account.postbox.transaction { transaction -> Void in transaction.setState(state) diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Data/ChatListData.swift b/submodules/TelegramCore/Sources/TelegramEngine/Data/ChatListData.swift new file mode 100644 index 0000000000..e6359c3365 --- /dev/null +++ b/submodules/TelegramCore/Sources/TelegramEngine/Data/ChatListData.swift @@ -0,0 +1,8 @@ +import SwiftSignalKit +import Postbox + +public extension TelegramEngine.EngineData.Item { + enum ChatList { + + } +} diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Data/Configuration.swift b/submodules/TelegramCore/Sources/TelegramEngine/Data/ConfigurationData.swift similarity index 100% rename from submodules/TelegramCore/Sources/TelegramEngine/Data/Configuration.swift rename to submodules/TelegramCore/Sources/TelegramEngine/Data/ConfigurationData.swift diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Data/Contacts.swift b/submodules/TelegramCore/Sources/TelegramEngine/Data/ContactsData.swift similarity index 100% rename from submodules/TelegramCore/Sources/TelegramEngine/Data/Contacts.swift rename to submodules/TelegramCore/Sources/TelegramEngine/Data/ContactsData.swift diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Data/ItemCache.swift b/submodules/TelegramCore/Sources/TelegramEngine/Data/ItemCacheData.swift similarity index 100% rename from submodules/TelegramCore/Sources/TelegramEngine/Data/ItemCache.swift rename to submodules/TelegramCore/Sources/TelegramEngine/Data/ItemCacheData.swift diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Data/Messages.swift b/submodules/TelegramCore/Sources/TelegramEngine/Data/MessagesData.swift similarity index 89% rename from submodules/TelegramCore/Sources/TelegramEngine/Data/Messages.swift rename to submodules/TelegramCore/Sources/TelegramEngine/Data/MessagesData.swift index af5a5064c2..b50b026b22 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Data/Messages.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Data/MessagesData.swift @@ -14,9 +14,9 @@ public final class EngineTotalReadCounters { } public struct EnginePeerReadCounters: Equatable { - private let state: CombinedPeerReadState + private let state: CombinedPeerReadState? - public init(state: CombinedPeerReadState) { + public init(state: CombinedPeerReadState?) { self.state = state } @@ -25,24 +25,38 @@ public struct EnginePeerReadCounters: Equatable { } public var count: Int32 { - return self.state.count + guard let state = self.state else { + return 0 + } + return state.count } public var markedUnread: Bool { - return self.state.markedUnread + guard let state = self.state else { + return false + } + return state.markedUnread } - public var isUnread: Bool { - return self.state.isUnread + guard let state = self.state else { + return false + } + return state.isUnread } public func isOutgoingMessageIndexRead(_ index: EngineMessage.Index) -> Bool { - return self.state.isOutgoingMessageIndexRead(index) + guard let state = self.state else { + return false + } + return state.isOutgoingMessageIndexRead(index) } public func isIncomingMessageIndexRead(_ index: EngineMessage.Index) -> Bool { - return self.state.isIncomingMessageIndexRead(index) + guard let state = self.state else { + return false + } + return state.isIncomingMessageIndexRead(index) } } @@ -128,8 +142,8 @@ public extension TelegramEngine.EngineData.Item { } } - public struct ReadState: TelegramEngineDataItem, TelegramEngineMapKeyDataItem, PostboxViewDataItem { - public typealias Result = CombinedPeerReadState? + public struct PeerReadCounters: TelegramEngineDataItem, TelegramEngineMapKeyDataItem, PostboxViewDataItem { + public typealias Result = EnginePeerReadCounters fileprivate let id: EnginePeer.Id public var mapKey: EnginePeer.Id { @@ -149,7 +163,7 @@ public extension TelegramEngine.EngineData.Item { preconditionFailure() } - return view.state + return EnginePeerReadCounters(state: view.state) } } diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Data/Notices.swift b/submodules/TelegramCore/Sources/TelegramEngine/Data/NoticesData.swift similarity index 100% rename from submodules/TelegramCore/Sources/TelegramEngine/Data/Notices.swift rename to submodules/TelegramCore/Sources/TelegramEngine/Data/NoticesData.swift diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Data/OrderedListsData.swift b/submodules/TelegramCore/Sources/TelegramEngine/Data/OrderedListsData.swift new file mode 100644 index 0000000000..6701b555dd --- /dev/null +++ b/submodules/TelegramCore/Sources/TelegramEngine/Data/OrderedListsData.swift @@ -0,0 +1,27 @@ +import SwiftSignalKit +import Postbox + +public extension TelegramEngine.EngineData.Item { + enum OrderedLists { + public struct ListItems: TelegramEngineDataItem, PostboxViewDataItem { + public typealias Result = [OrderedItemListEntry] + + private let collectionId: Int32 + + public init(collectionId: Int32) { + self.collectionId = collectionId + } + + var key: PostboxViewKey { + return .orderedItemList(id: self.collectionId) + } + + func extract(view: PostboxView) -> Result { + guard let view = view as? OrderedItemListView else { + preconditionFailure() + } + return view.items + } + } + } +} diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Data/PeerSummary.swift b/submodules/TelegramCore/Sources/TelegramEngine/Data/PeersData.swift similarity index 100% rename from submodules/TelegramCore/Sources/TelegramEngine/Data/PeerSummary.swift rename to submodules/TelegramCore/Sources/TelegramEngine/Data/PeersData.swift diff --git a/submodules/TelegramUI/Sources/AppDelegate.swift b/submodules/TelegramUI/Sources/AppDelegate.swift index d1119bc957..3e68f6a460 100644 --- a/submodules/TelegramUI/Sources/AppDelegate.swift +++ b/submodules/TelegramUI/Sources/AppDelegate.swift @@ -526,7 +526,7 @@ private func extractAccountManagerState(records: AccountRecordsView map { view -> InnerState in - if let _ = view.state as? AuthorizedAccountState { + self.stateDisposable = (TelegramEngineUnauthorized(account: self.account).auth.state() + |> map { state -> InnerState in + if case .authorized = state { return .authorized - } else if let state = view.state as? UnauthorizedAccountState { + } else if case let .unauthorized(state) = state { return .state(state.contents) } else { return .state(.empty) @@ -489,11 +489,16 @@ public final class AuthorizationSequenceController: NavigationController, MFMail if let strongSelf = self, let strongController = controller { strongController.inProgress = false - let _ = (strongSelf.account.postbox.transaction { transaction -> Void in - if let state = transaction.getState() as? UnauthorizedAccountState, case let .passwordEntry(hint, number, code, _, syncContacts) = state.contents { - transaction.setState(UnauthorizedAccountState(isTestingEnvironment: strongSelf.account.testingEnvironment, masterDatacenterId: strongSelf.account.masterDatacenterId, contents: .passwordRecovery(hint: hint, number: number, code: code, emailPattern: pattern, syncContacts: syncContacts))) + let _ = (TelegramEngineUnauthorized(account: strongSelf.account).auth.state() + |> take(1) + |> deliverOnMainQueue).start(next: { state in + guard let strongSelf = self else { + return } - }).start() + if case let .unauthorized(state) = state, case let .passwordEntry(hint, number, code, _, syncContacts) = state.contents { + let _ = TelegramEngineUnauthorized(account: strongSelf.account).auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: strongSelf.account.testingEnvironment, masterDatacenterId: strongSelf.account.masterDatacenterId, contents: .passwordRecovery(hint: hint, number: number, code: code, emailPattern: pattern, syncContacts: syncContacts))).start() + } + }) } }, error: { error in guard let strongController = controller else { @@ -560,11 +565,16 @@ public final class AuthorizationSequenceController: NavigationController, MFMail return } - let _ = (strongSelf.account.postbox.transaction { transaction -> Void in - if let state = transaction.getState() as? UnauthorizedAccountState, case let .passwordRecovery(hint, number, code, _, syncContacts) = state.contents { - transaction.setState(UnauthorizedAccountState(isTestingEnvironment: strongSelf.account.testingEnvironment, masterDatacenterId: strongSelf.account.masterDatacenterId, contents: .passwordEntry(hint: hint, number: number, code: code, suggestReset: true, syncContacts: syncContacts))) + let _ = (TelegramEngineUnauthorized(account: strongSelf.account).auth.state() + |> take(1) + |> deliverOnMainQueue).start(next: { state in + guard let strongSelf = self else { + return } - }).start() + if case let .unauthorized(state) = state, case let .passwordRecovery(hint, number, code, _, syncContacts) = state.contents { + let _ = TelegramEngineUnauthorized(account: strongSelf.account).auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: strongSelf.account.testingEnvironment, masterDatacenterId: strongSelf.account.masterDatacenterId, contents: .passwordEntry(hint: hint, number: number, code: code, suggestReset: true, syncContacts: syncContacts))).start() + } + }) } return controller } diff --git a/submodules/TelegramUI/Sources/ChatController.swift b/submodules/TelegramUI/Sources/ChatController.swift index c4684b9a0f..920352583d 100644 --- a/submodules/TelegramUI/Sources/ChatController.swift +++ b/submodules/TelegramUI/Sources/ChatController.swift @@ -547,13 +547,12 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G locationBroadcastPanelSource = .none groupCallPanelSource = .none let promise = Promise() - let key = PostboxViewKey.messages([replyThreadMessage.messageId]) - promise.set(context.account.postbox.combinedView(keys: [key]) - |> map { views -> Message? in - guard let view = views.views[key] as? MessagesView else { + promise.set(context.engine.data.subscribe(TelegramEngine.EngineData.Item.Messages.Message(id: replyThreadMessage.messageId)) + |> map { message -> Message? in + guard let message = message else { return nil } - return view.messages[replyThreadMessage.messageId] + return message._asMessage() }) self.chatLocationInfoData = .replyThread(promise) case .feed: @@ -1075,7 +1074,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G strongSelf.chatDisplayNode.messageTransitionNode.dismissMessageReactionContexts() - let controller = ContextController(account: strongSelf.context.account, presentationData: strongSelf.presentationData, source: .extracted(ChatMessageContextExtractedContentSource(chatNode: strongSelf.chatDisplayNode, postbox: strongSelf.context.account.postbox, message: message, selectAll: selectAll)), items: .single(actions), recognizer: recognizer, gesture: gesture) + let controller = ContextController(account: strongSelf.context.account, presentationData: strongSelf.presentationData, source: .extracted(ChatMessageContextExtractedContentSource(chatNode: strongSelf.chatDisplayNode, engine: strongSelf.context.engine, message: message, selectAll: selectAll)), items: .single(actions), recognizer: recognizer, gesture: gesture) controller.getOverlayViews = { [weak self] in guard let strongSelf = self else { return [] @@ -1207,7 +1206,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G strongSelf.chatDisplayNode.messageTransitionNode.dismissMessageReactionContexts() - let controller = ContextController(account: strongSelf.context.account, presentationData: strongSelf.presentationData, source: .extracted(ChatMessageReactionContextExtractedContentSource(chatNode: strongSelf.chatDisplayNode, postbox: strongSelf.context.account.postbox, message: message, contentView: sourceView)), items: .single(items), recognizer: nil, gesture: gesture) + let controller = ContextController(account: strongSelf.context.account, presentationData: strongSelf.presentationData, source: .extracted(ChatMessageReactionContextExtractedContentSource(chatNode: strongSelf.chatDisplayNode, engine: strongSelf.context.engine, message: message, contentView: sourceView)), items: .single(items), recognizer: nil, gesture: gesture) dismissController = { [weak controller] completion in controller?.dismiss(completion: { @@ -2642,7 +2641,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G strongSelf.chatDisplayNode.messageTransitionNode.dismissMessageReactionContexts() - let controller = ContextController(account: strongSelf.context.account, presentationData: strongSelf.presentationData, source: .extracted(ChatMessageContextExtractedContentSource(chatNode: strongSelf.chatDisplayNode, postbox: strongSelf.context.account.postbox, message: message._asMessage(), selectAll: true)), items: .single(ContextController.Items(content: .list(actions))), recognizer: nil) + let controller = ContextController(account: strongSelf.context.account, presentationData: strongSelf.presentationData, source: .extracted(ChatMessageContextExtractedContentSource(chatNode: strongSelf.chatDisplayNode, engine: strongSelf.context.engine, message: message._asMessage(), selectAll: true)), items: .single(ContextController.Items(content: .list(actions))), recognizer: nil) strongSelf.currentContextController = controller strongSelf.forEachController({ controller in if let controller = controller as? TooltipScreen { @@ -2720,7 +2719,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G strongSelf.chatDisplayNode.messageTransitionNode.dismissMessageReactionContexts() - let controller = ContextController(account: strongSelf.context.account, presentationData: strongSelf.presentationData, source: .extracted(ChatMessageContextExtractedContentSource(chatNode: strongSelf.chatDisplayNode, postbox: strongSelf.context.account.postbox, message: topMessage, selectAll: true)), items: .single(ContextController.Items(content: .list(actions))), recognizer: nil) + let controller = ContextController(account: strongSelf.context.account, presentationData: strongSelf.presentationData, source: .extracted(ChatMessageContextExtractedContentSource(chatNode: strongSelf.chatDisplayNode, engine: strongSelf.context.engine, message: topMessage, selectAll: true)), items: .single(ContextController.Items(content: .list(actions))), recognizer: nil) strongSelf.currentContextController = controller strongSelf.forEachController({ controller in if let controller = controller as? TooltipScreen { diff --git a/submodules/TelegramUI/Sources/ChatInterfaceStateContextMenus.swift b/submodules/TelegramUI/Sources/ChatInterfaceStateContextMenus.swift index 7266ecfdbd..04c0c85716 100644 --- a/submodules/TelegramUI/Sources/ChatInterfaceStateContextMenus.swift +++ b/submodules/TelegramUI/Sources/ChatInterfaceStateContextMenus.swift @@ -575,7 +575,7 @@ func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState ) } - let readState = context.engine.data.get(TelegramEngine.EngineData.Item.Messages.ReadState(id: messages[0].id.peerId)) + let readCounters = context.engine.data.get(TelegramEngine.EngineData.Item.Messages.PeerReadCounters(id: messages[0].id.peerId)) let dataSignal: Signal<(MessageContextMenuData, [MessageId: ChatUpdatingMessageMedia], InfoSummaryData, AppConfiguration, Bool, Int32, AvailableReactions?, TranslationSettings, LoggingSettings, NotificationSoundList?), NoError> = combineLatest( loadLimits, @@ -585,13 +585,13 @@ func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState context.account.pendingUpdateMessageManager.updatingMessageMedia |> take(1), infoSummaryData, - readState, + readCounters, ApplicationSpecificNotice.getMessageViewsPrivacyTips(accountManager: context.sharedContext.accountManager), context.engine.stickers.availableReactions(), context.sharedContext.accountManager.sharedData(keys: [ApplicationSpecificSharedDataKeys.translationSettings, SharedDataKeys.loggingSettings]), context.engine.peers.notificationSoundList() |> take(1) ) - |> map { limitsAndAppConfig, stickerSaveStatus, resourceStatus, messageActions, updatingMessageMedia, infoSummaryData, readState, messageViewsPrivacyTips, availableReactions, sharedData, notificationSoundList -> (MessageContextMenuData, [MessageId: ChatUpdatingMessageMedia], InfoSummaryData, AppConfiguration, Bool, Int32, AvailableReactions?, TranslationSettings, LoggingSettings, NotificationSoundList?) in + |> map { limitsAndAppConfig, stickerSaveStatus, resourceStatus, messageActions, updatingMessageMedia, infoSummaryData, readCounters, messageViewsPrivacyTips, availableReactions, sharedData, notificationSoundList -> (MessageContextMenuData, [MessageId: ChatUpdatingMessageMedia], InfoSummaryData, AppConfiguration, Bool, Int32, AvailableReactions?, TranslationSettings, LoggingSettings, NotificationSoundList?) in let (limitsConfiguration, appConfig) = limitsAndAppConfig var canEdit = false if !isAction { @@ -599,10 +599,7 @@ func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState canEdit = canEditMessage(context: context, limitsConfiguration: limitsConfiguration, message: message) } - var isMessageRead = false - if let readState = readState { - isMessageRead = readState.isOutgoingMessageIndexRead(message.index) - } + let isMessageRead = readCounters.isOutgoingMessageIndexRead(message.index) let translationSettings: TranslationSettings if let current = sharedData.entries[ApplicationSpecificSharedDataKeys.translationSettings]?.get(TranslationSettings.self) { diff --git a/submodules/TelegramUI/Sources/ChatMediaInputGifPane.swift b/submodules/TelegramUI/Sources/ChatMediaInputGifPane.swift index 2285d3eebe..3468153e01 100644 --- a/submodules/TelegramUI/Sources/ChatMediaInputGifPane.swift +++ b/submodules/TelegramUI/Sources/ChatMediaInputGifPane.swift @@ -290,22 +290,16 @@ final class ChatMediaInputGifPane: ChatMediaInputPane, UIScrollViewDelegate { let filesSignal: Signal<(MultiplexedVideoNodeFiles, String?), NoError> switch self.mode { case .recent: - filesSignal = combineLatest(self.trendingPromise.get(), self.context.account.postbox.combinedView(keys: [.orderedItemList(id: Namespaces.OrderedItemList.CloudRecentGifs)])) - |> map { trending, view -> (MultiplexedVideoNodeFiles, String?) in - var recentGifs: OrderedItemListView? - if let orderedView = view.views[.orderedItemList(id: Namespaces.OrderedItemList.CloudRecentGifs)] { - recentGifs = orderedView as? OrderedItemListView - } - + filesSignal = combineLatest( + self.trendingPromise.get(), + self.context.engine.data.subscribe(TelegramEngine.EngineData.Item.OrderedLists.ListItems(collectionId: Namespaces.OrderedItemList.CloudRecentGifs)) + ) + |> map { trending, cloudRecentGifs -> (MultiplexedVideoNodeFiles, String?) in var saved: [MultiplexedVideoNodeFile] = [] - if let recentGifs = recentGifs { - saved = recentGifs.items.map { item in - let file = item.contents.get(RecentMediaItem.self)!.media - return MultiplexedVideoNodeFile(file: .savedGif(media: file), contextResult: nil) - } - } else { - saved = [] + saved = cloudRecentGifs.map { item in + let file = item.contents.get(RecentMediaItem.self)!.media + return MultiplexedVideoNodeFile(file: .savedGif(media: file), contextResult: nil) } return (MultiplexedVideoNodeFiles(saved: saved, trending: trending?.files ?? [], isSearch: false, canLoadMore: false, isStale: false), nil) diff --git a/submodules/TelegramUI/Sources/ChatMessageContextControllerContentSource.swift b/submodules/TelegramUI/Sources/ChatMessageContextControllerContentSource.swift index 22517866f1..61feec2d12 100644 --- a/submodules/TelegramUI/Sources/ChatMessageContextControllerContentSource.swift +++ b/submodules/TelegramUI/Sources/ChatMessageContextControllerContentSource.swift @@ -3,6 +3,7 @@ import UIKit import Display import ContextUI import Postbox +import TelegramCore import SwiftSignalKit final class ChatMessageContextExtractedContentSource: ContextExtractedContentSource { @@ -11,7 +12,7 @@ final class ChatMessageContextExtractedContentSource: ContextExtractedContentSou let blurBackground: Bool = true private weak var chatNode: ChatControllerNode? - private let postbox: Postbox + private let engine: TelegramEngine private let message: Message private let selectAll: Bool @@ -19,24 +20,21 @@ final class ChatMessageContextExtractedContentSource: ContextExtractedContentSou if self.message.adAttribute != nil { return .single(false) } - let viewKey = PostboxViewKey.messages(Set([self.message.id])) - return self.postbox.combinedView(keys: [viewKey]) - |> map { views -> Bool in - guard let view = views.views[viewKey] as? MessagesView else { + + return self.engine.data.subscribe(TelegramEngine.EngineData.Item.Messages.Message(id: self.message.id)) + |> map { message -> Bool in + if let _ = message { return false - } - if view.messages.isEmpty { - return true } else { - return false + return true } } |> distinctUntilChanged } - init(chatNode: ChatControllerNode, postbox: Postbox, message: Message, selectAll: Bool) { + init(chatNode: ChatControllerNode, engine: TelegramEngine, message: Message, selectAll: Bool) { self.chatNode = chatNode - self.postbox = postbox + self.engine = engine self.message = message self.selectAll = selectAll } @@ -89,7 +87,7 @@ final class ChatMessageReactionContextExtractedContentSource: ContextExtractedCo let centerActionsHorizontally: Bool = true private weak var chatNode: ChatControllerNode? - private let postbox: Postbox + private let engine: TelegramEngine private let message: Message private let contentView: ContextExtractedContentContainingView @@ -97,24 +95,21 @@ final class ChatMessageReactionContextExtractedContentSource: ContextExtractedCo if self.message.adAttribute != nil { return .single(false) } - let viewKey = PostboxViewKey.messages(Set([self.message.id])) - return self.postbox.combinedView(keys: [viewKey]) - |> map { views -> Bool in - guard let view = views.views[viewKey] as? MessagesView else { + + return self.engine.data.subscribe(TelegramEngine.EngineData.Item.Messages.Message(id: self.message.id)) + |> map { message -> Bool in + if let _ = message { return false - } - if view.messages.isEmpty { - return true } else { - return false + return true } } |> distinctUntilChanged } - init(chatNode: ChatControllerNode, postbox: Postbox, message: Message, contentView: ContextExtractedContentContainingView) { + init(chatNode: ChatControllerNode, engine: TelegramEngine, message: Message, contentView: ContextExtractedContentContainingView) { self.chatNode = chatNode - self.postbox = postbox + self.engine = engine self.message = message self.contentView = contentView } diff --git a/submodules/TelegramUI/Sources/NotificationContentContext.swift b/submodules/TelegramUI/Sources/NotificationContentContext.swift index b8463210e1..892d7fc27c 100644 --- a/submodules/TelegramUI/Sources/NotificationContentContext.swift +++ b/submodules/TelegramUI/Sources/NotificationContentContext.swift @@ -33,6 +33,7 @@ private func setupSharedLogger(rootPath: String, path: String) { public struct NotificationViewControllerInitializationData { public let appBundleId: String + public let appBuildType: TelegramAppBuildType public let appGroupPath: String public let apiId: Int32 public let apiHash: String @@ -41,8 +42,9 @@ public struct NotificationViewControllerInitializationData { public let appVersion: String public let bundleData: Data? - public init(appBundleId: String, appGroupPath: String, apiId: Int32, apiHash: String, languagesCategory: String, encryptionParameters: (Data, Data), appVersion: String, bundleData: Data?) { + public init(appBundleId: String, appBuildType: TelegramAppBuildType, appGroupPath: String, apiId: Int32, apiHash: String, languagesCategory: String, encryptionParameters: (Data, Data), appVersion: String, bundleData: Data?) { self.appBundleId = appBundleId + self.appBuildType = appBuildType self.appGroupPath = appGroupPath self.apiId = apiId self.apiHash = apiHash @@ -104,7 +106,7 @@ public final class NotificationViewControllerImpl { }) semaphore.wait() - let applicationBindings = TelegramApplicationBindings(isMainApp: false, appBundleId: self.initializationData.appBundleId, containerPath: self.initializationData.appGroupPath, appSpecificScheme: "tgapp", openUrl: { _ in + let applicationBindings = TelegramApplicationBindings(isMainApp: false, appBundleId: self.initializationData.appBundleId, appBuildType: self.initializationData.appBuildType, containerPath: self.initializationData.appGroupPath, appSpecificScheme: "tgapp", openUrl: { _ in }, openUniversalUrl: { _, completion in completion.completion(false) return diff --git a/submodules/TelegramUI/Sources/PeerInfo/Panes/PeerInfoMembersPane.swift b/submodules/TelegramUI/Sources/PeerInfo/Panes/PeerInfoMembersPane.swift index ac983b89d7..36d0fe8fb9 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/Panes/PeerInfoMembersPane.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/Panes/PeerInfoMembersPane.swift @@ -195,16 +195,16 @@ final class PeerInfoMembersPaneNode: ASDisplayNode, PeerInfoPaneNode { self.disposable = (combineLatest(queue: .mainQueue(), membersContext.state, self.presentationDataPromise.get(), - context.account.postbox.combinedView(keys: [.basicPeer(peerId)]) + context.engine.data.subscribe(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)) ) - |> deliverOnMainQueue).start(next: { [weak self] state, presentationData, combinedView in - guard let strongSelf = self, let basicPeerView = combinedView.views[.basicPeer(peerId)] as? BasicPeerView, let enclosingPeer = basicPeerView.peer else { + |> deliverOnMainQueue).start(next: { [weak self] state, presentationData, enclosingPeer in + guard let strongSelf = self, let enclosingPeer = enclosingPeer else { return } - strongSelf.enclosingPeer = enclosingPeer + strongSelf.enclosingPeer = enclosingPeer._asPeer() strongSelf.currentState = state - strongSelf.updateState(enclosingPeer: enclosingPeer, state: state, presentationData: presentationData) + strongSelf.updateState(enclosingPeer: enclosingPeer._asPeer(), state: state, presentationData: presentationData) }) self.listNode.visibleBottomContentOffsetChanged = { [weak self] offset in diff --git a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoData.swift b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoData.swift index d0120fa06d..e187554c76 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoData.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoData.swift @@ -173,7 +173,7 @@ final class PeerInfoScreenData { let cachedData: CachedPeerData? let status: PeerInfoStatusData? let notificationSettings: TelegramPeerNotificationSettings? - let globalNotificationSettings: GlobalNotificationSettings? + let globalNotificationSettings: EngineGlobalNotificationSettings? let isContact: Bool let availablePanes: [PeerInfoPaneKey] let groupsInCommon: GroupsInCommonContext? @@ -191,7 +191,7 @@ final class PeerInfoScreenData { cachedData: CachedPeerData?, status: PeerInfoStatusData?, notificationSettings: TelegramPeerNotificationSettings?, - globalNotificationSettings: GlobalNotificationSettings?, + globalNotificationSettings: EngineGlobalNotificationSettings?, isContact: Bool, availablePanes: [PeerInfoPaneKey], groupsInCommon: GroupsInCommonContext?, @@ -313,13 +313,13 @@ enum PeerInfoMembersData: Equatable { } } -private func peerInfoScreenInputData(context: AccountContext, peerId: PeerId, isSettings: Bool) -> Signal { - return context.account.postbox.combinedView(keys: [.basicPeer(peerId)]) - |> map { view -> PeerInfoScreenInputData in - guard let peer = (view.views[.basicPeer(peerId)] as? BasicPeerView)?.peer else { +private func peerInfoScreenInputData(context: AccountContext, peerId: EnginePeer.Id, isSettings: Bool) -> Signal { + return context.engine.data.subscribe(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)) + |> map { peer -> PeerInfoScreenInputData in + guard let peer = peer else { return .none } - if let user = peer as? TelegramUser { + if case let .user(user) = peer { if isSettings && user.id == context.account.peerId { return .settings } else { @@ -333,15 +333,15 @@ private func peerInfoScreenInputData(context: AccountContext, peerId: PeerId, is } return .user(userId: user.id, secretChatId: nil, kind: kind) } - } else if let channel = peer as? TelegramChannel { + } else if case let .channel(channel) = peer { if case .group = channel.info { return .group(groupId: channel.id) } else { return .channel } - } else if let group = peer as? TelegramGroup { + } else if case let .legacyGroup(group) = peer { return .group(groupId: group.id) - } else if let secretChat = peer as? TelegramSecretChat { + } else if case let .secretChat(secretChat) = peer { return .user(userId: secretChat.regularPeerId, secretChatId: peer.id, kind: .user) } else { return .none @@ -565,26 +565,18 @@ func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: Presen return disposable } |> distinctUntilChanged - let globalNotificationsKey: PostboxViewKey = .preferences(keys: Set([PreferencesKeys.globalNotifications])) var combinedKeys: [PostboxViewKey] = [] - combinedKeys.append(globalNotificationsKey) if let secretChatId = secretChatId { combinedKeys.append(.peerChatState(peerId: secretChatId)) } return combineLatest( context.account.viewTracker.peerView(peerId, updateData: true), peerInfoAvailableMediaPanes(context: context, peerId: peerId), + context.engine.data.subscribe(TelegramEngine.EngineData.Item.NotificationSettings.Global()), context.account.postbox.combinedView(keys: combinedKeys), status ) - |> map { peerView, availablePanes, combinedView, status -> PeerInfoScreenData in - var globalNotificationSettings: GlobalNotificationSettings = .defaultSettings - if let preferencesView = combinedView.views[globalNotificationsKey] as? PreferencesView { - if let settings = preferencesView.values[PreferencesKeys.globalNotifications]?.get(GlobalNotificationSettings.self) { - globalNotificationSettings = settings - } - } - + |> map { peerView, availablePanes, globalNotificationSettings, combinedView, status -> PeerInfoScreenData in var encryptionKeyFingerprint: SecretChatKeyFingerprint? if let secretChatId = secretChatId, let peerChatStateView = combinedView.views[.peerChatState(peerId: secretChatId)] as? PeerChatStateView { if let peerChatState = peerChatStateView.chatState?.getLegacy() as? SecretChatState { @@ -632,10 +624,6 @@ func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: Presen } |> distinctUntilChanged - let globalNotificationsKey: PostboxViewKey = .preferences(keys: Set([PreferencesKeys.globalNotifications])) - var combinedKeys: [PostboxViewKey] = [] - combinedKeys.append(globalNotificationsKey) - let invitationsContextPromise = Promise(nil) let invitationsStatePromise = Promise(nil) @@ -645,21 +633,14 @@ func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: Presen return combineLatest( context.account.viewTracker.peerView(peerId, updateData: true), peerInfoAvailableMediaPanes(context: context, peerId: peerId), - context.account.postbox.combinedView(keys: combinedKeys), + context.engine.data.subscribe(TelegramEngine.EngineData.Item.NotificationSettings.Global()), status, invitationsContextPromise.get(), invitationsStatePromise.get(), requestsContextPromise.get(), requestsStatePromise.get() ) - |> map { peerView, availablePanes, combinedView, status, currentInvitationsContext, invitations, currentRequestsContext, requests -> PeerInfoScreenData in - var globalNotificationSettings: GlobalNotificationSettings = .defaultSettings - if let preferencesView = combinedView.views[globalNotificationsKey] as? PreferencesView { - if let settings = preferencesView.values[PreferencesKeys.globalNotifications]?.get(GlobalNotificationSettings.self) { - globalNotificationSettings = settings - } - } - + |> map { peerView, availablePanes, globalNotificationSettings, status, currentInvitationsContext, invitations, currentRequestsContext, requests -> PeerInfoScreenData in var discussionPeer: Peer? if case let .known(maybeLinkedDiscussionPeerId) = (peerView.cachedData as? CachedChannelData)?.linkedDiscussionPeerId, let linkedDiscussionPeerId = maybeLinkedDiscussionPeerId, let peer = peerView.peers[linkedDiscussionPeerId] { discussionPeer = peer @@ -795,10 +776,6 @@ func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: Presen } |> distinctUntilChanged - let globalNotificationsKey: PostboxViewKey = .preferences(keys: Set([PreferencesKeys.globalNotifications])) - var combinedKeys: [PostboxViewKey] = [] - combinedKeys.append(globalNotificationsKey) - let invitationsContextPromise = Promise(nil) let invitationsStatePromise = Promise(nil) @@ -808,7 +785,7 @@ func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: Presen return combineLatest(queue: .mainQueue(), context.account.viewTracker.peerView(groupId, updateData: true), peerInfoAvailableMediaPanes(context: context, peerId: groupId), - context.account.postbox.combinedView(keys: combinedKeys), + context.engine.data.subscribe(TelegramEngine.EngineData.Item.NotificationSettings.Global()), status, membersData, invitationsContextPromise.get(), @@ -816,14 +793,7 @@ func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: Presen requestsContextPromise.get(), requestsStatePromise.get() ) - |> map { peerView, availablePanes, combinedView, status, membersData, currentInvitationsContext, invitations, currentRequestsContext, requests -> PeerInfoScreenData in - var globalNotificationSettings: GlobalNotificationSettings = .defaultSettings - if let preferencesView = combinedView.views[globalNotificationsKey] as? PreferencesView { - if let settings = preferencesView.values[PreferencesKeys.globalNotifications]?.get(GlobalNotificationSettings.self) { - globalNotificationSettings = settings - } - } - + |> map { peerView, availablePanes, globalNotificationSettings, status, membersData, currentInvitationsContext, invitations, currentRequestsContext, requests -> PeerInfoScreenData in var discussionPeer: Peer? if case let .known(maybeLinkedDiscussionPeerId) = (peerView.cachedData as? CachedChannelData)?.linkedDiscussionPeerId, let linkedDiscussionPeerId = maybeLinkedDiscussionPeerId, let peer = peerView.peers[linkedDiscussionPeerId] { discussionPeer = peer diff --git a/submodules/TelegramUI/Sources/PeerMessagesMediaPlaylist.swift b/submodules/TelegramUI/Sources/PeerMessagesMediaPlaylist.swift index c3d366a32d..afd04a1d17 100644 --- a/submodules/TelegramUI/Sources/PeerMessagesMediaPlaylist.swift +++ b/submodules/TelegramUI/Sources/PeerMessagesMediaPlaylist.swift @@ -444,15 +444,13 @@ final class PeerMessagesMediaPlaylist: SharedMediaPlaylist { if item?.message.id != self.currentlyObservedMessageId { self.currentlyObservedMessageId = item?.message.id if let id = item?.message.id { - let key: PostboxViewKey = .messages(Set([id])) - self.currentlyObservedMessageDisposable.set((self.context.account.postbox.combinedView(keys: [key]) - |> filter { views in - if let view = views.views[key] as? MessagesView { - if !view.messages.isEmpty { - return false - } + self.currentlyObservedMessageDisposable.set((self.context.engine.data.subscribe(TelegramEngine.EngineData.Item.Messages.Message(id: id)) + |> filter { message in + if let _ = message { + return false + } else { + return true } - return true } |> take(1) |> deliverOnMainQueue).start(next: { [weak self] _ in diff --git a/submodules/TelegramUI/Sources/ShareExtensionContext.swift b/submodules/TelegramUI/Sources/ShareExtensionContext.swift index c7bac62bfb..13fb68e647 100644 --- a/submodules/TelegramUI/Sources/ShareExtensionContext.swift +++ b/submodules/TelegramUI/Sources/ShareExtensionContext.swift @@ -56,6 +56,7 @@ private enum ShareAuthorizationError { public struct ShareRootControllerInitializationData { public let appBundleId: String + public let appBuildType: TelegramAppBuildType public let appGroupPath: String public let apiId: Int32 public let apiHash: String @@ -64,8 +65,9 @@ public struct ShareRootControllerInitializationData { public let appVersion: String public let bundleData: Data? - public init(appBundleId: String, appGroupPath: String, apiId: Int32, apiHash: String, languagesCategory: String, encryptionParameters: (Data, Data), appVersion: String, bundleData: Data?) { + public init(appBundleId: String, appBuildType: TelegramAppBuildType, appGroupPath: String, apiId: Int32, apiHash: String, languagesCategory: String, encryptionParameters: (Data, Data), appVersion: String, bundleData: Data?) { self.appBundleId = appBundleId + self.appBuildType = appBuildType self.appGroupPath = appGroupPath self.apiId = apiId self.apiHash = apiHash @@ -178,7 +180,7 @@ public class ShareRootControllerImpl { setupSharedLogger(rootPath: rootPath, path: logsPath) - let applicationBindings = TelegramApplicationBindings(isMainApp: false, appBundleId: self.initializationData.appBundleId, containerPath: self.initializationData.appGroupPath, appSpecificScheme: "tg", openUrl: { _ in + let applicationBindings = TelegramApplicationBindings(isMainApp: false, appBundleId: self.initializationData.appBundleId, appBuildType: self.initializationData.appBuildType, containerPath: self.initializationData.appGroupPath, appSpecificScheme: "tg", openUrl: { _ in }, openUniversalUrl: { _, completion in completion.completion(false) return diff --git a/submodules/TelegramUI/Sources/SharedAccountContext.swift b/submodules/TelegramUI/Sources/SharedAccountContext.swift index a94da1e7c7..48c0ab5a7f 100644 --- a/submodules/TelegramUI/Sources/SharedAccountContext.swift +++ b/submodules/TelegramUI/Sources/SharedAccountContext.swift @@ -575,13 +575,12 @@ public final class SharedAccountContextImpl: SharedAccountContext { self.activeAccountsWithInfoPromise.set(self.activeAccountContexts |> mapToSignal { primary, accounts, _ -> Signal<(primary: AccountRecordId?, accounts: [AccountWithInfo]), NoError> in return combineLatest(accounts.map { _, context, _ -> Signal in - let peerViewKey: PostboxViewKey = .peer(peerId: context.account.peerId, components: []) - return context.account.postbox.combinedView(keys: [peerViewKey]) - |> map { view -> AccountWithInfo? in - guard let peerView = view.views[peerViewKey] as? PeerView, let peer = peerView.peers[peerView.peerId] else { + return context.engine.data.subscribe(TelegramEngine.EngineData.Item.Peer.Peer(id: context.account.peerId)) + |> map { peer -> AccountWithInfo? in + guard let peer = peer else { return nil } - return AccountWithInfo(account: context.account, peer: peer) + return AccountWithInfo(account: context.account, peer: peer._asPeer()) } |> distinctUntilChanged }) diff --git a/submodules/TemporaryCachedPeerDataManager/Sources/PeerChannelMemberCategoriesContextsManager.swift b/submodules/TemporaryCachedPeerDataManager/Sources/PeerChannelMemberCategoriesContextsManager.swift index 39fe42d1b7..32a057e698 100644 --- a/submodules/TemporaryCachedPeerDataManager/Sources/PeerChannelMemberCategoriesContextsManager.swift +++ b/submodules/TemporaryCachedPeerDataManager/Sources/PeerChannelMemberCategoriesContextsManager.swift @@ -511,21 +511,21 @@ public final class PeerChannelMemberCategoriesContextsManager { let updatedIds = Set(idList) if previousIds != updatedIds { previousIds = updatedIds - let key: PostboxViewKey = .peerPresences(peerIds: updatedIds) - statusesDisposable.set((postbox.combinedView(keys: [key]) - |> map { view -> Int32 in + + statusesDisposable.set((engine.data.subscribe(EngineDataMap( + updatedIds.map(TelegramEngine.EngineData.Item.Peer.Presence.init) + )) + |> map { presenceMap -> Int32 in var count: Int32 = 0 let timestamp = CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970 - if let presences = (view.views[key] as? PeerPresencesView)?.presences { - for (_, presence) in presences { - if let presence = presence as? TelegramUserPresence { - let relativeStatus = relativeUserPresenceStatus(EnginePeer.Presence(presence), relativeTo: Int32(timestamp)) - switch relativeStatus { - case .online: - count += 1 - default: - break - } + for (_, presence) in presenceMap { + if let presence = presence { + let relativeStatus = relativeUserPresenceStatus(presence, relativeTo: Int32(timestamp)) + switch relativeStatus { + case .online: + count += 1 + default: + break } } } diff --git a/submodules/WebSearchUI/Sources/WebSearchControllerNode.swift b/submodules/WebSearchUI/Sources/WebSearchControllerNode.swift index f8efce790b..8bfbce42bb 100644 --- a/submodules/WebSearchUI/Sources/WebSearchControllerNode.swift +++ b/submodules/WebSearchUI/Sources/WebSearchControllerNode.swift @@ -282,7 +282,7 @@ class WebSearchControllerNode: ASDisplayNode { if !attachment { let previousRecentItems = Atomic<[WebSearchRecentQueryEntry]?>(value: nil) - self.recentDisposable = (combineLatest(webSearchRecentQueries(postbox: self.context.account.postbox), self.webSearchInterfaceStatePromise.get()) + self.recentDisposable = (combineLatest(webSearchRecentQueries(engine: self.context.engine), self.webSearchInterfaceStatePromise.get()) |> deliverOnMainQueue).start(next: { [weak self] queries, interfaceState in if let strongSelf = self { var entries: [WebSearchRecentQueryEntry] = [] diff --git a/submodules/WebSearchUI/Sources/WebSearchRecentQueries.swift b/submodules/WebSearchUI/Sources/WebSearchRecentQueries.swift index cff5e1c155..22f85a37c9 100644 --- a/submodules/WebSearchUI/Sources/WebSearchRecentQueries.swift +++ b/submodules/WebSearchUI/Sources/WebSearchRecentQueries.swift @@ -56,16 +56,14 @@ func clearRecentWebSearchQueries(engine: TelegramEngine) -> Signal Signal<[String], NoError> { - return postbox.combinedView(keys: [.orderedItemList(id: ApplicationSpecificOrderedItemListCollectionId.webSearchRecentQueries)]) - |> mapToSignal { view -> Signal<[String], NoError> in +func webSearchRecentQueries(engine: TelegramEngine) -> Signal<[String], NoError> { + return engine.data.subscribe(TelegramEngine.EngineData.Item.OrderedLists.ListItems(collectionId: ApplicationSpecificOrderedItemListCollectionId.webSearchRecentQueries)) + |> map { items -> [String] in var result: [String] = [] - if let view = view.views[.orderedItemList(id: ApplicationSpecificOrderedItemListCollectionId.webSearchRecentQueries)] as? OrderedItemListView { - for item in view.items { - let value = WebSearchRecentQueryItemId(item.id).value - result.append(value) - } + for item in items { + let value = WebSearchRecentQueryItemId(item.id).value + result.append(value) } - return .single(result) + return result } } From dfad27f9e8609e30a34f900efcbb368191f56bfa Mon Sep 17 00:00:00 2001 From: Ali <> Date: Sun, 29 May 2022 21:09:11 +0400 Subject: [PATCH 3/3] Refactoring --- .../Sources/ChannelAdminController.swift | 97 ++++++++++--------- .../LocalizationListControllerNode.swift | 16 ++- .../NotificationExceptionControllerNode.swift | 40 ++++---- .../Search/SettingsSearchableItems.swift | 11 ++- .../Sources/ShareController.swift | 20 ++-- .../Sources/ShareControllerNode.swift | 2 +- .../Sources/ShareControllerPeerGridItem.swift | 18 ++-- .../Sources/SharePeersContainerNode.swift | 13 +-- .../Sources/ShareSearchContainerNode.swift | 6 +- .../ShareItems/Sources/ShareItems.swift | 15 ++- .../Sources/PresentationGroupCall.swift | 13 ++- .../TelegramEngine/Data/MessagesData.swift | 72 +++++++++++++- .../TelegramEngine/Data/PeersData.swift | 30 ++++++ .../Data/TelegramEngineData.swift | 31 ++++++ .../TelegramUI/Sources/AccountContext.swift | 7 +- .../TelegramUI/Sources/ChatController.swift | 60 +++++------- .../Sources/ChatHistoryListNode.swift | 30 +++--- .../Sources/ChatMediaInputNode.swift | 12 +-- .../PeerInfo/Panes/PeerInfoListPaneNode.swift | 10 +- .../Panes/PeerInfoVisualMediaPaneNode.swift | 34 ++----- .../Sources/PeerInfo/PeerInfoData.swift | 17 ++-- .../Sources/PeerInfo/PeerInfoScreen.swift | 20 ++-- .../Sources/PeerInfoGifPaneNode.swift | 11 +-- .../Sources/WidgetDataContext.swift | 17 ++-- 24 files changed, 344 insertions(+), 258 deletions(-) diff --git a/submodules/PeerInfoUI/Sources/ChannelAdminController.swift b/submodules/PeerInfoUI/Sources/ChannelAdminController.swift index a5a2c9ef79..15fecf10eb 100644 --- a/submodules/PeerInfoUI/Sources/ChannelAdminController.swift +++ b/submodules/PeerInfoUI/Sources/ChannelAdminController.swift @@ -78,7 +78,7 @@ private enum ChannelAdminEntryStableId: Hashable { } private enum ChannelAdminEntry: ItemListNodeEntry { - case info(PresentationTheme, PresentationStrings, PresentationDateTimeFormat, Peer, TelegramUserPresence?) + case info(PresentationTheme, PresentationStrings, PresentationDateTimeFormat, EnginePeer, EnginePeer.Presence?) case rankTitle(PresentationTheme, String, Int32?, Int32) case rank(PresentationTheme, PresentationStrings, String, String, Bool) case rankInfo(PresentationTheme, String, Bool) @@ -144,7 +144,7 @@ private enum ChannelAdminEntry: ItemListNodeEntry { if lhsDateTimeFormat != rhsDateTimeFormat { return false } - if !arePeersEqual(lhsPeer, rhsPeer) { + if lhsPeer != rhsPeer { return false } if lhsPresence != rhsPresence { @@ -309,7 +309,7 @@ private enum ChannelAdminEntry: ItemListNodeEntry { let arguments = arguments as! ChannelAdminControllerArguments switch self { case let .info(_, _, dateTimeFormat, peer, presence): - return ItemListAvatarAndNameInfoItem(accountContext: arguments.context, presentationData: presentationData, dateTimeFormat: dateTimeFormat, mode: .generic, peer: EnginePeer(peer), presence: presence.flatMap(EnginePeer.Presence.init), memberCount: nil, state: ItemListAvatarAndNameInfoItemState(), sectionId: self.section, style: .blocks(withTopInset: true, withExtendedBottomInset: false), editingNameUpdated: { _ in + return ItemListAvatarAndNameInfoItem(accountContext: arguments.context, presentationData: presentationData, dateTimeFormat: dateTimeFormat, mode: .generic, peer: peer, presence: presence, memberCount: nil, state: ItemListAvatarAndNameInfoItemState(), sectionId: self.section, style: .blocks(withTopInset: true, withExtendedBottomInset: false), editingNameUpdated: { _ in }, avatarTapped: { }) case let .rankTitle(_, text, count, limit): @@ -534,11 +534,11 @@ private func areAllAdminRightsEnabled(_ flags: TelegramChatAdminRightsFlags, gro } } -private func channelAdminControllerEntries(presentationData: PresentationData, state: ChannelAdminControllerState, accountPeerId: PeerId, channelView: PeerView, adminView: PeerView, initialParticipant: ChannelParticipant?, invite: Bool, canEdit: Bool) -> [ChannelAdminEntry] { +private func channelAdminControllerEntries(presentationData: PresentationData, state: ChannelAdminControllerState, accountPeerId: PeerId, channelPeer: EnginePeer?, adminPeer: EnginePeer?, adminPresence: EnginePeer.Presence?, initialParticipant: ChannelParticipant?, invite: Bool, canEdit: Bool) -> [ChannelAdminEntry] { var entries: [ChannelAdminEntry] = [] - if let channel = channelView.peers[channelView.peerId] as? TelegramChannel, let admin = adminView.peers[adminView.peerId] { - entries.append(.info(presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, admin, adminView.peerPresences[admin.id] as? TelegramUserPresence)) + if case let .channel(channel) = channelPeer, let admin = adminPeer { + entries.append(.info(presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, admin, adminPresence)) var isChannel = false if case .broadcast = channel.info { @@ -618,7 +618,7 @@ private func channelAdminControllerEntries(presentationData: PresentationData, s } } } else { - if let adminPeer = adminView.peers[adminView.peerId] as? TelegramUser, adminPeer.botInfo != nil, case .group = channel.info, invite, let channelPeer = channelView.peers[channelView.peerId], canEditAdminRights(accountPeerId: accountPeerId, channelPeer: channelPeer, initialParticipant: initialParticipant) { + if case let .user(adminPeer) = adminPeer, adminPeer.botInfo != nil, case .group = channel.info, invite, let channelPeer = channelPeer, canEditAdminRights(accountPeerId: accountPeerId, channelPeer: channelPeer._asPeer(), initialParticipant: initialParticipant) { if let initialParticipant = initialParticipant, case let .member(_, _, adminInfo, _, _) = initialParticipant, adminInfo != nil { } else { @@ -629,7 +629,7 @@ private func channelAdminControllerEntries(presentationData: PresentationData, s if !invite || state.adminRights { entries.append(.rightsTitle(presentationData.theme, presentationData.strings.Channel_EditAdmin_PermissionsHeader)) - if let channelPeer = channelView.peers[channelView.peerId], canEditAdminRights(accountPeerId: accountPeerId, channelPeer: channelPeer, initialParticipant: initialParticipant) { + if let channelPeer = channelPeer, canEditAdminRights(accountPeerId: accountPeerId, channelPeer: channelPeer._asPeer(), initialParticipant: initialParticipant) { let accountUserRightsFlags: TelegramChatAdminRightsFlags if channel.flags.contains(.isCreator) { accountUserRightsFlags = maskRightsFlags @@ -660,7 +660,7 @@ private func channelAdminControllerEntries(presentationData: PresentationData, s entries.append(.addAdminsInfo(presentationData.theme, currentRightsFlags.contains(.canAddAdmins) ? presentationData.strings.Channel_EditAdmin_PermissinAddAdminOn : presentationData.strings.Channel_EditAdmin_PermissinAddAdminOff)) } - if let admin = admin as? TelegramUser, admin.botInfo == nil && !admin.isDeleted && channel.flags.contains(.isCreator) && areAllAdminRightsEnabled(currentRightsFlags, group: isGroup, except: .canBeAnonymous) { + if case let .user(admin) = admin, admin.botInfo == nil && !admin.isDeleted && channel.flags.contains(.isCreator) && areAllAdminRightsEnabled(currentRightsFlags, group: isGroup, except: .canBeAnonymous) { canTransfer = true } @@ -717,8 +717,8 @@ private func channelAdminControllerEntries(presentationData: PresentationData, s if canDismiss { entries.append(.dismiss(presentationData.theme, presentationData.strings.Channel_Moderator_AccessLevelRevoke)) } - } else if let group = channelView.peers[channelView.peerId] as? TelegramGroup, let admin = adminView.peers[adminView.peerId] { - entries.append(.info(presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, admin, adminView.peerPresences[admin.id] as? TelegramUserPresence)) + } else if case let .legacyGroup(group) = channelPeer, let admin = adminPeer { + entries.append(.info(presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, admin, adminPresence)) var isCreator = false if let initialParticipant = initialParticipant, case .creator = initialParticipant { @@ -738,7 +738,7 @@ private func channelAdminControllerEntries(presentationData: PresentationData, s entries.append(.rankTitle(presentationData.theme, presentationData.strings.Group_EditAdmin_RankTitle.uppercased(), rankEnabled && state.focusedOnRank ? Int32(currentRank?.count ?? 0) : nil, rankMaxLength)) entries.append(.rank(presentationData.theme, presentationData.strings, isCreator ? presentationData.strings.Group_EditAdmin_RankOwnerPlaceholder : presentationData.strings.Group_EditAdmin_RankAdminPlaceholder, currentRank ?? "", rankEnabled)) } else { - if let adminPeer = adminView.peers[adminView.peerId] as? TelegramUser, adminPeer.botInfo != nil, invite { + if case let .user(adminPeer) = adminPeer, adminPeer.botInfo != nil, invite { if let initialParticipant = initialParticipant, case let .member(_, _, adminRights, _, _) = initialParticipant, adminRights != nil { } else { @@ -791,7 +791,7 @@ private func channelAdminControllerEntries(presentationData: PresentationData, s entries.append(.addAdminsInfo(presentationData.theme, currentRightsFlags.contains(.canAddAdmins) ? presentationData.strings.Channel_EditAdmin_PermissinAddAdminOn : presentationData.strings.Channel_EditAdmin_PermissinAddAdminOff)) } - if let admin = admin as? TelegramUser, case .creator = group.role, admin.botInfo == nil && !admin.isDeleted && areAllAdminRightsEnabled(currentRightsFlags, group: true, except: .canBeAnonymous) { + if case let .user(admin) = admin, case .creator = group.role, admin.botInfo == nil && !admin.isDeleted && areAllAdminRightsEnabled(currentRightsFlags, group: true, except: .canBeAnonymous) { entries.append(.transfer(presentationData.theme, presentationData.strings.Group_EditAdmin_TransferOwnership)) } @@ -955,15 +955,23 @@ public func channelAdminController(context: AccountContext, updatedPresentationD errorImpl?() }) - let combinedView = context.account.postbox.combinedView(keys: [.peer(peerId: peerId, components: .all), .peer(peerId: adminId, components: .all)]) - let presentationData = updatedPresentationData?.signal ?? context.sharedContext.presentationData - let signal = combineLatest(presentationData, statePromise.get(), combinedView) + let signal = combineLatest( + queue: .mainQueue(), + presentationData, + statePromise.get(), + context.engine.data.subscribe( + TelegramEngine.EngineData.Item.Peer.Peer(id: peerId), + TelegramEngine.EngineData.Item.Peer.Peer(id: adminId), + TelegramEngine.EngineData.Item.Peer.Presence(id: adminId) + ) + ) |> deliverOnMainQueue - |> map { presentationData, state, combinedView -> (ItemListControllerState, (ItemListNodeState, Any)) in - let channelView = combinedView.views[.peer(peerId: peerId, components: .all)] as! PeerView - let adminView = combinedView.views[.peer(peerId: adminId, components: .all)] as! PeerView - let canEdit = canEditAdminRights(accountPeerId: context.account.peerId, channelPeer: channelView.peers[channelView.peerId]!, initialParticipant: initialParticipant) + |> map { presentationData, state, peerInfoData -> (ItemListControllerState, (ItemListNodeState, Any)) in + let channelPeer = peerInfoData.0.flatMap { $0 } + let adminPeer = peerInfoData.1.flatMap { $0 } + let adminPresence = peerInfoData.2 + let canEdit = canEditAdminRights(accountPeerId: context.account.peerId, channelPeer: channelPeer!._asPeer(), initialParticipant: initialParticipant) let leftNavigationButton: ItemListNavigationButton if canEdit { @@ -986,8 +994,9 @@ public func channelAdminController(context: AccountContext, updatedPresentationD updateState { current in return current.withUpdatedUpdating(true) } - if let channel = channelView.peers[channelView.peerId] as? TelegramChannel { - updateRightsDisposable.set((context.engine.peers.addChannelMember(peerId: peerId, memberId: adminId) |> deliverOnMainQueue).start(error: { error in + if case let .channel(channel) = channelPeer { + updateRightsDisposable.set((context.engine.peers.addChannelMember(peerId: peerId, memberId: adminId) + |> deliverOnMainQueue).start(error: { error in updateState { current in return current.withUpdatedUpdating(false) } @@ -998,12 +1007,12 @@ public func channelAdminController(context: AccountContext, updatedPresentationD case .tooMuchJoined: text = presentationData.strings.Group_ErrorSupergroupConversionNotPossible case .restricted: - if let admin = adminView.peers[adminView.peerId] { + if let admin = adminPeer { switch channel.info { case .broadcast: - text = presentationData.strings.Privacy_GroupsAndChannels_InviteToChannelError(EnginePeer(admin).compactDisplayTitle, EnginePeer(admin).compactDisplayTitle).string + text = presentationData.strings.Privacy_GroupsAndChannels_InviteToChannelError(admin.compactDisplayTitle, admin.compactDisplayTitle).string case .group: - text = presentationData.strings.Privacy_GroupsAndChannels_InviteToGroupError(EnginePeer(admin).compactDisplayTitle, EnginePeer(admin).compactDisplayTitle).string + text = presentationData.strings.Privacy_GroupsAndChannels_InviteToGroupError(admin.compactDisplayTitle, admin.compactDisplayTitle).string } } case .notMutualContact: @@ -1020,20 +1029,20 @@ public func channelAdminController(context: AccountContext, updatedPresentationD updated(nil) dismissImpl?() })) - } else if let _ = channelView.peers[channelView.peerId] as? TelegramGroup { + } else if case .legacyGroup = channelPeer { updateRightsDisposable.set((context.engine.peers.addGroupMember(peerId: peerId, memberId: adminId) |> deliverOnMainQueue).start(error: { error in updateState { current in return current.withUpdatedUpdating(false) } - if case .privacy = error, let admin = adminView.peers[adminView.peerId] { - presentControllerImpl?(textAlertController(context: context, updatedPresentationData: updatedPresentationData, title: nil, text: presentationData.strings.Privacy_GroupsAndChannels_InviteToGroupError(EnginePeer(admin).compactDisplayTitle, EnginePeer(admin).compactDisplayTitle).string, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), nil) + if case .privacy = error, let admin = adminPeer { + presentControllerImpl?(textAlertController(context: context, updatedPresentationData: updatedPresentationData, title: nil, text: presentationData.strings.Privacy_GroupsAndChannels_InviteToGroupError(admin.compactDisplayTitle, admin.compactDisplayTitle).string, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), nil) } }, completed: { updated(nil) dismissImpl?() })) } - } else if let channel = channelView.peers[channelView.peerId] as? TelegramChannel { + } else if case let .channel(channel) = channelPeer { if let initialParticipant = initialParticipant { var updateFlags: TelegramChatAdminRightsFlags? var updateRank: String? @@ -1105,12 +1114,12 @@ public func channelAdminController(context: AccountContext, updatedPresentationD case .tooMuchJoined: text = presentationData.strings.Group_ErrorSupergroupConversionNotPossible case .restricted: - if let admin = adminView.peers[adminView.peerId] { + if let admin = adminPeer { switch channel.info { case .broadcast: - text = presentationData.strings.Privacy_GroupsAndChannels_InviteToChannelError(EnginePeer(admin).compactDisplayTitle, EnginePeer(admin).compactDisplayTitle).string + text = presentationData.strings.Privacy_GroupsAndChannels_InviteToChannelError(admin.compactDisplayTitle, admin.compactDisplayTitle).string case .group: - text = presentationData.strings.Privacy_GroupsAndChannels_InviteToGroupError(EnginePeer(admin).compactDisplayTitle, EnginePeer(admin).compactDisplayTitle).string + text = presentationData.strings.Privacy_GroupsAndChannels_InviteToGroupError(admin.compactDisplayTitle, admin.compactDisplayTitle).string } } case .notMutualContact: @@ -1184,7 +1193,7 @@ public func channelAdminController(context: AccountContext, updatedPresentationD return current.withUpdatedUpdating(true) } updateRightsDisposable.set((context.peerChannelMemberCategoriesContextsManager.updateMemberAdminRights(engine: context.engine, peerId: peerId, memberId: adminId, adminRights: TelegramChatAdminRights(rights: updateFlags), rank: updateRank) |> deliverOnMainQueue).start(error: { error in - if case let .addMemberError(addMemberError) = error, let admin = adminView.peers[adminView.peerId] { + if case let .addMemberError(addMemberError) = error, let admin = adminPeer { var text = presentationData.strings.Login_UnknownError switch addMemberError { case .tooMuchJoined: @@ -1192,9 +1201,9 @@ public func channelAdminController(context: AccountContext, updatedPresentationD case .restricted: switch channel.info { case .broadcast: - text = presentationData.strings.Privacy_GroupsAndChannels_InviteToChannelError(EnginePeer(admin).compactDisplayTitle, EnginePeer(admin).compactDisplayTitle).string + text = presentationData.strings.Privacy_GroupsAndChannels_InviteToChannelError(admin.compactDisplayTitle, admin.compactDisplayTitle).string case .group: - text = presentationData.strings.Privacy_GroupsAndChannels_InviteToGroupError(EnginePeer(admin).compactDisplayTitle, EnginePeer(admin).compactDisplayTitle).string + text = presentationData.strings.Privacy_GroupsAndChannels_InviteToGroupError(admin.compactDisplayTitle, admin.compactDisplayTitle).string } case .notMutualContact: if case .broadcast = channel.info { @@ -1222,7 +1231,7 @@ public func channelAdminController(context: AccountContext, updatedPresentationD })) } } - } else if let _ = channelView.peers[channelView.peerId] as? TelegramGroup { + } else if case .legacyGroup = channelPeer { var updateFlags: TelegramChatAdminRightsFlags? var updateRank: String? updateState { current in @@ -1252,8 +1261,8 @@ public func channelAdminController(context: AccountContext, updatedPresentationD } updateRightsDisposable.set((context.engine.peers.addGroupAdmin(peerId: peerId, adminId: adminId) |> deliverOnMainQueue).start(error: { error in - if case let .addMemberError(error) = error, case .privacy = error, let admin = adminView.peers[adminView.peerId] { - presentControllerImpl?(textAlertController(context: context, updatedPresentationData: updatedPresentationData, title: nil, text: presentationData.strings.Privacy_GroupsAndChannels_InviteToGroupError(EnginePeer(admin).compactDisplayTitle, EnginePeer(admin).compactDisplayTitle).string, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), nil) + if case let .addMemberError(error) = error, case .privacy = error, let admin = adminPeer { + presentControllerImpl?(textAlertController(context: context, updatedPresentationData: updatedPresentationData, title: nil, text: presentationData.strings.Privacy_GroupsAndChannels_InviteToGroupError(admin.compactDisplayTitle, admin.compactDisplayTitle).string, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), nil) } else if case .adminsTooMuch = error { presentControllerImpl?(textAlertController(context: context, updatedPresentationData: updatedPresentationData, title: nil, text: presentationData.strings.Group_ErrorAdminsTooMuch, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), nil) } @@ -1312,8 +1321,8 @@ public func channelAdminController(context: AccountContext, updatedPresentationD case let .direct(error): if case let .addMemberError(error) = error { var text = presentationData.strings.Login_UnknownError - if case .restricted = error, let admin = adminView.peers[adminView.peerId] { - text = presentationData.strings.Privacy_GroupsAndChannels_InviteToGroupError(EnginePeer(admin).compactDisplayTitle, EnginePeer(admin).compactDisplayTitle).string + if case .restricted = error, let admin = adminPeer { + text = presentationData.strings.Privacy_GroupsAndChannels_InviteToGroupError(admin.compactDisplayTitle, admin.compactDisplayTitle).string } else if case .tooMuchJoined = error { text = presentationData.strings.Invite_ChannelsTooMuch } else if case .kicked = error { @@ -1353,17 +1362,17 @@ public func channelAdminController(context: AccountContext, updatedPresentationD if initialParticipant?.adminInfo == nil { var isGroup: Bool = false var peerTitle: String = "" - if let peer = channelView.peers[channelView.peerId] as? TelegramGroup { + if case let .legacyGroup(peer) = channelPeer { isGroup = true peerTitle = peer.title - } else if let peer = channelView.peers[channelView.peerId] as? TelegramChannel { + } else if case let .channel(peer) = channelPeer { if case .group = peer.info { isGroup = true } peerTitle = peer.title } - if let admin = adminView.peers[adminView.peerId] as? TelegramUser, admin.botInfo != nil && invite { + if case let .user(admin) = adminPeer, admin.botInfo != nil && invite { title = presentationData.strings.Bot_AddToChat_Add_Title rightNavigationButton = nil footerItem = ChannelAdminAddBotFooterItem(theme: presentationData.theme, title: state.adminRights ? presentationData.strings.Bot_AddToChat_Add_AddAsAdmin : presentationData.strings.Bot_AddToChat_Add_AddAsMember, action: { @@ -1395,7 +1404,7 @@ public func channelAdminController(context: AccountContext, updatedPresentationD let controllerState = ItemListControllerState(presentationData: ItemListPresentationData(presentationData), title: .text(title), leftNavigationButton: leftNavigationButton, rightNavigationButton: rightNavigationButton, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back), animateChanges: false) - let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: channelAdminControllerEntries(presentationData: presentationData, state: state, accountPeerId: context.account.peerId, channelView: channelView, adminView: adminView, initialParticipant: initialParticipant, invite: invite, canEdit: canEdit), style: .blocks, focusItemTag: focusItemTag, ensureVisibleItemTag: nil, emptyStateItem: nil, footerItem: footerItem, animateChanges: true) + let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: channelAdminControllerEntries(presentationData: presentationData, state: state, accountPeerId: context.account.peerId, channelPeer: channelPeer, adminPeer: adminPeer, adminPresence: adminPresence, initialParticipant: initialParticipant, invite: invite, canEdit: canEdit), style: .blocks, focusItemTag: focusItemTag, ensureVisibleItemTag: nil, emptyStateItem: nil, footerItem: footerItem, animateChanges: true) return (controllerState, (listState, arguments)) } diff --git a/submodules/SettingsUI/Sources/Language Selection/LocalizationListControllerNode.swift b/submodules/SettingsUI/Sources/Language Selection/LocalizationListControllerNode.swift index 74598d3c98..c27429b812 100644 --- a/submodules/SettingsUI/Sources/Language Selection/LocalizationListControllerNode.swift +++ b/submodules/SettingsUI/Sources/Language Selection/LocalizationListControllerNode.swift @@ -417,10 +417,17 @@ final class LocalizationListControllerNode: ViewControllerTracingNode { }) } - let preferencesKey: PostboxViewKey = .preferences(keys: Set([PreferencesKeys.localizationListState])) let previousState = Atomic(value: nil) let previousEntriesHolder = Atomic<([LanguageListEntry], PresentationTheme, PresentationStrings)?>(value: nil) - self.listDisposable = combineLatest(queue: .mainQueue(), context.account.postbox.combinedView(keys: [preferencesKey]), context.sharedContext.accountManager.sharedData(keys: [SharedDataKeys.localizationSettings, ApplicationSpecificSharedDataKeys.translationSettings]), self.presentationDataValue.get(), self.applyingCode.get(), revealedCode.get(), self.isEditing.get()).start(next: { [weak self] view, sharedData, presentationData, applyingCode, revealedCode, isEditing in + self.listDisposable = combineLatest( + queue: .mainQueue(), + context.engine.data.subscribe(TelegramEngine.EngineData.Item.Configuration.LocalizationList()), + context.sharedContext.accountManager.sharedData(keys: [SharedDataKeys.localizationSettings, ApplicationSpecificSharedDataKeys.translationSettings]), + self.presentationDataValue.get(), + self.applyingCode.get(), + revealedCode.get(), + self.isEditing.get() + ).start(next: { [weak self] localizationListState, sharedData, presentationData, applyingCode, revealedCode, isEditing in guard let strongSelf = self else { return } @@ -449,8 +456,7 @@ final class LocalizationListControllerNode: ViewControllerTracingNode { } } - let localizationListState = (view.views[preferencesKey] as? PreferencesView)?.values[PreferencesKeys.localizationListState]?.get(LocalizationListState.self) - if let localizationListState = localizationListState, !localizationListState.availableOfficialLocalizations.isEmpty { + if !localizationListState.availableOfficialLocalizations.isEmpty { strongSelf.currentListState = localizationListState if #available(iOS 12.0, *) { @@ -520,7 +526,7 @@ final class LocalizationListControllerNode: ViewControllerTracingNode { if let strongSelf = self { strongSelf.push(translationSettingsController(context: strongSelf.context)) } - }, selectLocalization: { [weak self] info in self?.selectLocalization(info) }, setItemWithRevealedOptions: setItemWithRevealedOptions, removeItem: removeItem, firstTime: previousEntriesAndPresentationData == nil, isLoading: entries.isEmpty, forceUpdate: previousEntriesAndPresentationData?.1 !== presentationData.theme || previousEntriesAndPresentationData?.2 !== presentationData.strings, animated: (previousEntriesAndPresentationData?.0.count ?? 0) != entries.count, crossfade: (previousState == nil) != (localizationListState == nil)) + }, selectLocalization: { [weak self] info in self?.selectLocalization(info) }, setItemWithRevealedOptions: setItemWithRevealedOptions, removeItem: removeItem, firstTime: previousEntriesAndPresentationData == nil, isLoading: entries.isEmpty, forceUpdate: previousEntriesAndPresentationData?.1 !== presentationData.theme || previousEntriesAndPresentationData?.2 !== presentationData.strings, animated: (previousEntriesAndPresentationData?.0.count ?? 0) != entries.count, crossfade: (previousState == nil || previousState!.availableOfficialLocalizations.isEmpty) != localizationListState.availableOfficialLocalizations.isEmpty) strongSelf.enqueueTransition(transition) }) self.updatedDisposable = context.engine.localization.synchronizedLocalizationListState().start() diff --git a/submodules/SettingsUI/Sources/Notifications/Exceptions/NotificationExceptionControllerNode.swift b/submodules/SettingsUI/Sources/Notifications/Exceptions/NotificationExceptionControllerNode.swift index 280e2063ea..e58d5cf3a7 100644 --- a/submodules/SettingsUI/Sources/Notifications/Exceptions/NotificationExceptionControllerNode.swift +++ b/submodules/SettingsUI/Sources/Notifications/Exceptions/NotificationExceptionControllerNode.swift @@ -1170,32 +1170,28 @@ private final class NotificationExceptionsSearchContainerNode: SearchDisplayCont let updateNotificationsDisposable = self.updateNotificationsDisposable let updateNotificationsView: (@escaping () -> Void) -> Void = { completion in - let key: PostboxViewKey = .peerNotificationSettings(peerIds: Set(mode.peerIds)) - - updateNotificationsDisposable.set(context.account.postbox.combinedView(keys: [key]).start(next: { view in - if let view = view.views[key] as? PeerNotificationSettingsView { - let _ = (context.engine.data.get( - EngineDataMap(view.notificationSettings.keys.map(TelegramEngine.EngineData.Item.Peer.Peer.init)), - EngineDataMap(view.notificationSettings.keys.map(TelegramEngine.EngineData.Item.Peer.NotificationSettings.init)) - ) - |> deliverOnMainQueue).start(next: { peerMap, notificationSettingsMap in - updateState { current in - var current = current - for (key, value) in view.notificationSettings { - if let value = value as? TelegramPeerNotificationSettings,let local = current.mode.settings[key] { - if !value.isEqual(to: local.settings), let maybePeer = peerMap[key], let peer = maybePeer, let settings = notificationSettingsMap[key], !settings._asNotificationSettings().isEqual(to: local.settings) { - current = current.withUpdatedPeerSound(peer._asPeer(), settings.messageSound._asMessageSound()).withUpdatedPeerMuteInterval(peer._asPeer(), settings.muteState.timeInterval) - } + updateNotificationsDisposable.set(context.engine.data.subscribe(EngineDataMap( + mode.peerIds.map(TelegramEngine.EngineData.Item.Peer.NotificationSettings.init) + )).start(next: { notificationSettingsMap in + let _ = (context.engine.data.get( + EngineDataMap(notificationSettingsMap.keys.map(TelegramEngine.EngineData.Item.Peer.Peer.init)), + EngineDataMap(notificationSettingsMap.keys.map(TelegramEngine.EngineData.Item.Peer.NotificationSettings.init)) + ) + |> deliverOnMainQueue).start(next: { peerMap, notificationSettingsMap in + updateState { current in + var current = current + for (key, value) in notificationSettingsMap { + if let local = current.mode.settings[key] { + if !value._asNotificationSettings().isEqual(to: local.settings), let maybePeer = peerMap[key], let peer = maybePeer, let settings = notificationSettingsMap[key], !settings._asNotificationSettings().isEqual(to: local.settings) { + current = current.withUpdatedPeerSound(peer._asPeer(), settings.messageSound._asMessageSound()).withUpdatedPeerMuteInterval(peer._asPeer(), settings.muteState.timeInterval) } } - return current } - - completion() - }) - } else { + return current + } + completion() - } + }) })) } diff --git a/submodules/SettingsUI/Sources/Search/SettingsSearchableItems.swift b/submodules/SettingsUI/Sources/Search/SettingsSearchableItems.swift index 49a101158e..1b141cb6c1 100644 --- a/submodules/SettingsUI/Sources/Search/SettingsSearchableItems.swift +++ b/submodules/SettingsUI/Sources/Search/SettingsSearchableItems.swift @@ -775,11 +775,12 @@ func settingsSearchableItems(context: AccountContext, notificationExceptionsList return settings.servers } - let localizationPreferencesKey: PostboxViewKey = .preferences(keys: Set([PreferencesKeys.localizationListState])) - let localizations = combineLatest(context.account.postbox.combinedView(keys: [localizationPreferencesKey]), context.sharedContext.accountManager.sharedData(keys: [SharedDataKeys.localizationSettings])) - |> map { view, sharedData -> [LocalizationInfo] in - if let localizationListState = (view.views[localizationPreferencesKey] as? PreferencesView)?.values[PreferencesKeys.localizationListState]?.get(LocalizationListState.self), !localizationListState.availableOfficialLocalizations.isEmpty { - + let localizations = combineLatest( + context.engine.data.subscribe(TelegramEngine.EngineData.Item.Configuration.LocalizationList()), + context.sharedContext.accountManager.sharedData(keys: [SharedDataKeys.localizationSettings]) + ) + |> map { localizationListState, sharedData -> [LocalizationInfo] in + if !localizationListState.availableOfficialLocalizations.isEmpty { var existingIds = Set() let availableSavedLocalizations = localizationListState.availableSavedLocalizations.filter({ info in !localizationListState.availableOfficialLocalizations.contains(where: { $0.languageCode == info.languageCode }) }) diff --git a/submodules/ShareController/Sources/ShareController.swift b/submodules/ShareController/Sources/ShareController.swift index 2986094052..db524dc28e 100644 --- a/submodules/ShareController/Sources/ShareController.swift +++ b/submodules/ShareController/Sources/ShareController.swift @@ -313,7 +313,7 @@ public final class ShareController: ViewController { private let segmentedValues: [ShareControllerSegmentedValue]? private let fromForeignApp: Bool - private let peers = Promise<([(EngineRenderedPeer, PeerPresence?)], EnginePeer)>() + private let peers = Promise<([(EngineRenderedPeer, EnginePeer.Presence?)], EnginePeer)>() private let peersDisposable = MetaDisposable() private let readyDisposable = MetaDisposable() private let accountActiveDisposable = MetaDisposable() @@ -966,7 +966,7 @@ public final class ShareController: ViewController { self.currentAccount.viewTracker.tailChatListView(groupId: .root, count: 150) |> take(1) ) - |> mapToSignal { maybeAccountPeer, view -> Signal<([(EngineRenderedPeer, PeerPresence?)], EnginePeer), NoError> in + |> mapToSignal { maybeAccountPeer, view -> Signal<([(EngineRenderedPeer, EnginePeer.Presence?)], EnginePeer), NoError> in let accountPeer = maybeAccountPeer! var peers: [EngineRenderedPeer] = [] @@ -980,14 +980,14 @@ public final class ShareController: ViewController { break } } - let key = PostboxViewKey.peerPresences(peerIds: Set(peers.map { $0.peerId })) - return account.postbox.combinedView(keys: [key]) - |> map { views -> ([(EngineRenderedPeer, PeerPresence?)], EnginePeer) in - var resultPeers: [(EngineRenderedPeer, PeerPresence?)] = [] - if let presencesView = views.views[key] as? PeerPresencesView { - for peer in peers { - resultPeers.append((peer, presencesView.presences[peer.peerId])) - } + + return TelegramEngine(account: account).data.subscribe(EngineDataMap( + peers.map { TelegramEngine.EngineData.Item.Peer.Presence(id: $0.peerId) } + )) + |> map { presenceMap -> ([(EngineRenderedPeer, EnginePeer.Presence?)], EnginePeer) in + var resultPeers: [(EngineRenderedPeer, EnginePeer.Presence?)] = [] + for peer in peers { + resultPeers.append((peer, presenceMap[peer.peerId].flatMap { $0 })) } return (resultPeers, accountPeer) } diff --git a/submodules/ShareController/Sources/ShareControllerNode.swift b/submodules/ShareController/Sources/ShareControllerNode.swift index 452a0ec17b..64ccea13ea 100644 --- a/submodules/ShareController/Sources/ShareControllerNode.swift +++ b/submodules/ShareController/Sources/ShareControllerNode.swift @@ -804,7 +804,7 @@ final class ShareControllerNode: ViewControllerTracingNode, UIScrollViewDelegate } } - func updatePeers(context: AccountContext, switchableAccounts: [AccountWithInfo], peers: [(EngineRenderedPeer, PeerPresence?)], accountPeer: EnginePeer, defaultAction: ShareControllerAction?) { + func updatePeers(context: AccountContext, switchableAccounts: [AccountWithInfo], peers: [(EngineRenderedPeer, EnginePeer.Presence?)], accountPeer: EnginePeer, defaultAction: ShareControllerAction?) { self.context = context if let peersContentNode = self.peersContentNode, peersContentNode.accountPeer.id == accountPeer.id { diff --git a/submodules/ShareController/Sources/ShareControllerPeerGridItem.swift b/submodules/ShareController/Sources/ShareControllerPeerGridItem.swift index 62d7eb5b16..fe273dfda5 100644 --- a/submodules/ShareController/Sources/ShareControllerPeerGridItem.swift +++ b/submodules/ShareController/Sources/ShareControllerPeerGridItem.swift @@ -91,13 +91,13 @@ final class ShareControllerPeerGridItem: GridItem { let theme: PresentationTheme let strings: PresentationStrings let peer: EngineRenderedPeer? - let presence: PeerPresence? + let presence: EnginePeer.Presence? let controllerInteraction: ShareControllerInteraction let search: Bool let section: GridSection? - init(context: AccountContext, theme: PresentationTheme, strings: PresentationStrings, peer: EngineRenderedPeer?, presence: PeerPresence?, controllerInteraction: ShareControllerInteraction, sectionTitle: String? = nil, search: Bool = false) { + init(context: AccountContext, theme: PresentationTheme, strings: PresentationStrings, peer: EngineRenderedPeer?, presence: EnginePeer.Presence?, controllerInteraction: ShareControllerInteraction, sectionTitle: String? = nil, search: Bool = false) { self.context = context self.theme = theme self.strings = strings @@ -131,7 +131,7 @@ final class ShareControllerPeerGridItem: GridItem { } final class ShareControllerPeerGridItemNode: GridItemNode { - private var currentState: (AccountContext, PresentationTheme, PresentationStrings, EngineRenderedPeer?, Bool, PeerPresence?)? + private var currentState: (AccountContext, PresentationTheme, PresentationStrings, EngineRenderedPeer?, Bool, EnginePeer.Presence?)? private let peerNode: SelectablePeerNode private var presenceManager: PeerPresenceStatusManager? @@ -171,14 +171,14 @@ final class ShareControllerPeerGridItemNode: GridItemNode { } } - func setup(context: AccountContext, theme: PresentationTheme, strings: PresentationStrings, peer: EngineRenderedPeer?, presence: PeerPresence?, search: Bool, synchronousLoad: Bool, force: Bool) { - if force || self.currentState == nil || self.currentState!.0 !== context || self.currentState!.3 != peer || !arePeerPresencesEqual(self.currentState!.5, presence) { + func setup(context: AccountContext, theme: PresentationTheme, strings: PresentationStrings, peer: EngineRenderedPeer?, presence: EnginePeer.Presence?, search: Bool, synchronousLoad: Bool, force: Bool) { + if force || self.currentState == nil || self.currentState!.0 !== context || self.currentState!.3 != peer || self.currentState!.5 != presence { let itemTheme = SelectablePeerNodeTheme(textColor: theme.actionSheet.primaryTextColor, secretTextColor: theme.chatList.secretTitleColor, selectedTextColor: theme.actionSheet.controlAccentColor, checkBackgroundColor: theme.actionSheet.opaqueItemBackgroundColor, checkFillColor: theme.actionSheet.controlAccentColor, checkColor: theme.actionSheet.checkContentColor, avatarPlaceholderColor: theme.list.mediaPlaceholderColor) let timestamp = Int32(CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970) var online = false - if case let .user(peer) = peer?.peer, let presence = presence as? TelegramUserPresence, !isServicePeer(peer) && !peer.flags.contains(.isSupport) && peer.id != context.account.peerId { - let relativeStatus = relativeUserPresenceStatus(EnginePeer.Presence(presence), relativeTo: timestamp) + if case let .user(peer) = peer?.peer, let presence = presence, !isServicePeer(peer) && !peer.flags.contains(.isSupport) && peer.id != context.account.peerId { + let relativeStatus = relativeUserPresenceStatus(presence, relativeTo: timestamp) if case .online = relativeStatus { online = true } @@ -220,8 +220,8 @@ final class ShareControllerPeerGridItemNode: GridItemNode { } self.currentState = (context, theme, strings, peer, search, presence) self.setNeedsLayout() - if let presence = presence as? TelegramUserPresence { - self.presenceManager?.reset(presence: EnginePeer.Presence(presence)) + if let presence = presence { + self.presenceManager?.reset(presence: presence) } } self.updateSelection(animated: false) diff --git a/submodules/ShareController/Sources/SharePeersContainerNode.swift b/submodules/ShareController/Sources/SharePeersContainerNode.swift index ae3dcff4d3..aa1c8595a8 100644 --- a/submodules/ShareController/Sources/SharePeersContainerNode.swift +++ b/submodules/ShareController/Sources/SharePeersContainerNode.swift @@ -20,7 +20,7 @@ private let subtitleFont = Font.regular(12.0) private struct SharePeerEntry: Comparable, Identifiable { let index: Int32 let peer: EngineRenderedPeer - let presence: PeerPresence? + let presence: EnginePeer.Presence? let theme: PresentationTheme let strings: PresentationStrings @@ -35,13 +35,10 @@ private struct SharePeerEntry: Comparable, Identifiable { if lhs.peer != rhs.peer { return false } - if let lhsPresence = lhs.presence, let rhsPresence = rhs.presence { - if !lhsPresence.isEqual(to: rhsPresence) { - return false - } - } else if (lhs.presence != nil) != (rhs.presence != nil) { + if lhs.presence != rhs.presence { return false } + return true } @@ -115,9 +112,9 @@ final class SharePeersContainerNode: ASDisplayNode, ShareContentContainerNode { private var validLayout: (CGSize, CGFloat)? private var overrideGridOffsetTransition: ContainedViewLayoutTransition? - let peersValue = Promise<[(EngineRenderedPeer, PeerPresence?)]>() + let peersValue = Promise<[(EngineRenderedPeer, EnginePeer.Presence?)]>() - init(sharedContext: SharedAccountContext, context: AccountContext, switchableAccounts: [AccountWithInfo], theme: PresentationTheme, strings: PresentationStrings, nameDisplayOrder: PresentationPersonNameOrder, peers: [(EngineRenderedPeer, PeerPresence?)], accountPeer: EnginePeer, controllerInteraction: ShareControllerInteraction, externalShare: Bool, switchToAnotherAccount: @escaping () -> Void, debugAction: @escaping () -> Void, extendedInitialReveal: Bool, segmentedValues: [ShareControllerSegmentedValue]?) { + init(sharedContext: SharedAccountContext, context: AccountContext, switchableAccounts: [AccountWithInfo], theme: PresentationTheme, strings: PresentationStrings, nameDisplayOrder: PresentationPersonNameOrder, peers: [(EngineRenderedPeer, EnginePeer.Presence?)], accountPeer: EnginePeer, controllerInteraction: ShareControllerInteraction, externalShare: Bool, switchToAnotherAccount: @escaping () -> Void, debugAction: @escaping () -> Void, extendedInitialReveal: Bool, segmentedValues: [ShareControllerSegmentedValue]?) { self.sharedContext = sharedContext self.context = context self.theme = theme diff --git a/submodules/ShareController/Sources/ShareSearchContainerNode.swift b/submodules/ShareController/Sources/ShareSearchContainerNode.swift index b057dbb658..78d8ef9720 100644 --- a/submodules/ShareController/Sources/ShareSearchContainerNode.swift +++ b/submodules/ShareController/Sources/ShareSearchContainerNode.swift @@ -36,7 +36,7 @@ private enum ShareSearchRecentEntryStableId: Hashable { private enum ShareSearchRecentEntry: Comparable, Identifiable { case topPeers(PresentationTheme, PresentationStrings) - case peer(index: Int, theme: PresentationTheme, peer: Peer, associatedPeer: Peer?, presence: PeerPresence?, PresentationStrings) + case peer(index: Int, theme: PresentationTheme, peer: Peer, associatedPeer: Peer?, presence: EnginePeer.Presence?, PresentationStrings) var stableId: ShareSearchRecentEntryStableId { switch self { @@ -62,7 +62,7 @@ private enum ShareSearchRecentEntry: Comparable, Identifiable { return false } case let .peer(lhsIndex, lhsTheme, lhsPeer, lhsAssociatedPeer, lhsPresence, lhsStrings): - if case let .peer(rhsIndex, rhsTheme, rhsPeer, rhsAssociatedPeer, rhsPresence, rhsStrings) = rhs, lhsPeer.isEqual(rhsPeer) && arePeersEqual(lhsAssociatedPeer, rhsAssociatedPeer) && lhsIndex == rhsIndex && lhsStrings === rhsStrings && lhsTheme === rhsTheme && arePeerPresencesEqual(lhsPresence, rhsPresence) { + if case let .peer(rhsIndex, rhsTheme, rhsPeer, rhsAssociatedPeer, rhsPresence, rhsStrings) = rhs, lhsPeer.isEqual(rhsPeer) && arePeersEqual(lhsAssociatedPeer, rhsAssociatedPeer) && lhsIndex == rhsIndex && lhsStrings === rhsStrings && lhsTheme === rhsTheme && lhsPresence == rhsPresence { return true } else { return false @@ -102,7 +102,7 @@ private enum ShareSearchRecentEntry: Comparable, Identifiable { private struct ShareSearchPeerEntry: Comparable, Identifiable { let index: Int32 let peer: EngineRenderedPeer? - let presence: PeerPresence? + let presence: EnginePeer.Presence? let theme: PresentationTheme let strings: PresentationStrings diff --git a/submodules/ShareItems/Sources/ShareItems.swift b/submodules/ShareItems/Sources/ShareItems.swift index 5ca8f2193a..33ddb6af04 100644 --- a/submodules/ShareItems/Sources/ShareItems.swift +++ b/submodules/ShareItems/Sources/ShareItems.swift @@ -464,15 +464,14 @@ public func sentShareItems(account: Account, to peerIds: [PeerId], items: [Prepa return enqueueMessagesToMultiplePeers(account: account, peerIds: peerIds, messages: messages) |> castError(Void.self) |> mapToSignal { messageIds -> Signal in - let key: PostboxViewKey = .messages(Set(messageIds)) - return account.postbox.combinedView(keys: [key]) + return TelegramEngine(account: account).data.subscribe(EngineDataMap( + messageIds.map(TelegramEngine.EngineData.Item.Messages.Message.init) + )) |> castError(Void.self) - |> mapToSignal { view -> Signal in - if let messagesView = view.views[key] as? MessagesView { - for (_, message) in messagesView.messages { - if message.flags.contains(.Unsent) { - return .complete() - } + |> mapToSignal { messages -> Signal in + for (_, message) in messages { + if let message = message, message.flags.contains(.Unsent) { + return .complete() } } return .single(1.0) diff --git a/submodules/TelegramCallsUI/Sources/PresentationGroupCall.swift b/submodules/TelegramCallsUI/Sources/PresentationGroupCall.swift index 50e39b8f95..369a610dff 100644 --- a/submodules/TelegramCallsUI/Sources/PresentationGroupCall.swift +++ b/submodules/TelegramCallsUI/Sources/PresentationGroupCall.swift @@ -1968,15 +1968,14 @@ public final class PresentationGroupCallImpl: PresentationGroupCall { |> distinctUntilChanged |> runOn(.mainQueue()) } else { - rawAdminIds = accountContext.account.postbox.combinedView(keys: [.cachedPeerData(peerId: peerId)]) - |> map { views -> Set in - guard let view = views.views[.cachedPeerData(peerId: peerId)] as? CachedPeerDataView else { + rawAdminIds = accountContext.engine.data.subscribe( + TelegramEngine.EngineData.Item.Peer.LegacyGroupParticipants(id: peerId) + ) + |> map { participants -> Set in + guard case let .known(participants) = participants else { return Set() } - guard let cachedData = view.cachedPeerData as? CachedGroupData, let participants = cachedData.participants else { - return Set() - } - return Set(participants.participants.compactMap { item -> PeerId? in + return Set(participants.compactMap { item -> PeerId? in switch item { case .creator, .admin: return item.peerId diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Data/MessagesData.swift b/submodules/TelegramCore/Sources/TelegramEngine/Data/MessagesData.swift index b50b026b22..299988aac2 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Data/MessagesData.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Data/MessagesData.swift @@ -2,7 +2,7 @@ import SwiftSignalKit import Postbox public final class EngineTotalReadCounters { - private let state: ChatListTotalUnreadState + fileprivate let state: ChatListTotalUnreadState public init(state: ChatListTotalUnreadState) { self.state = state @@ -13,8 +13,14 @@ public final class EngineTotalReadCounters { } } +public extension EngineTotalReadCounters { + func _asCounters() -> ChatListTotalUnreadState { + return self.state + } +} + public struct EnginePeerReadCounters: Equatable { - private let state: CombinedPeerReadState? + fileprivate let state: CombinedPeerReadState? public init(state: CombinedPeerReadState?) { self.state = state @@ -64,6 +70,10 @@ public extension EnginePeerReadCounters { init(incomingReadId: EngineMessage.Id.Id, outgoingReadId: EngineMessage.Id.Id, count: Int32, markedUnread: Bool) { self.init(state: CombinedPeerReadState(states: [(Namespaces.Message.Cloud, .idBased(maxIncomingReadId: incomingReadId, maxOutgoingReadId: outgoingReadId, maxKnownId: max(incomingReadId, outgoingReadId), count: count, markedUnread: markedUnread))])) } + + func _asReadCounters() -> CombinedPeerReadState? { + return self.state + } } public extension TelegramEngine.EngineData.Item { @@ -260,5 +270,63 @@ public extension TelegramEngine.EngineData.Item { return view.inclusion.groupId.flatMap(EngineChatList.Group.init) } } + + public struct MessageCount: TelegramEngineDataItem, TelegramEngineMapKeyDataItem, PostboxViewDataItem { + public struct ItemKey: Hashable { + public var peerId: EnginePeer.Id + public var tag: MessageTags + } + + public typealias Result = Int? + + fileprivate var peerId: EnginePeer.Id + fileprivate var tag: MessageTags + public var mapKey: ItemKey { + return ItemKey(peerId: self.peerId, tag: self.tag) + } + + public init(peerId: EnginePeer.Id, tag: MessageTags) { + self.peerId = peerId + self.tag = tag + } + + var key: PostboxViewKey { + return .historyTagSummaryView(tag: tag, peerId: peerId, namespace: Namespaces.Message.Cloud) + } + + func extract(view: PostboxView) -> Result { + guard let view = view as? MessageHistoryTagSummaryView else { + preconditionFailure() + } + return view.count.flatMap(Int.init) + } + } + + public struct TopMessage: TelegramEngineDataItem, TelegramEngineMapKeyDataItem, PostboxViewDataItem { + public typealias Result = EngineMessage? + + fileprivate var id: EnginePeer.Id + public var mapKey: EnginePeer.Id { + return self.id + } + + public init(id: EnginePeer.Id) { + self.id = id + } + + var key: PostboxViewKey { + return .topChatMessage(peerIds: [self.id]) + } + + func extract(view: PostboxView) -> Result { + guard let view = view as? TopChatMessageView else { + preconditionFailure() + } + guard let message = view.messages[self.id] else { + return nil + } + return EngineMessage(message) + } + } } } diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Data/PeersData.swift b/submodules/TelegramCore/Sources/TelegramEngine/Data/PeersData.swift index ce1435d5e8..38c107076e 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Data/PeersData.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Data/PeersData.swift @@ -2,6 +2,7 @@ import SwiftSignalKit import Postbox public typealias EngineExportedPeerInvitation = ExportedInvitation +public typealias EngineSecretChatKeyFingerprint = SecretChatKeyFingerprint public enum EnginePeerCachedInfoItem { case known(T) @@ -782,5 +783,34 @@ public extension TelegramEngine.EngineData.Item { } } } + + public struct SecretChatKeyFingerprint: TelegramEngineDataItem, TelegramEngineMapKeyDataItem, PostboxViewDataItem { + public typealias Result = EngineSecretChatKeyFingerprint? + + fileprivate var id: EnginePeer.Id + public var mapKey: EnginePeer.Id { + return self.id + } + + public init(id: EnginePeer.Id) { + self.id = id + } + + var key: PostboxViewKey { + return .peerChatState(peerId: self.id) + } + + func extract(view: PostboxView) -> Result { + guard let view = view as? PeerChatStateView else { + preconditionFailure() + } + + if let peerChatState = view.chatState?.getLegacy() as? SecretChatState { + return peerChatState.keyFingerprint + } else { + return nil + } + } + } } } diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Data/TelegramEngineData.swift b/submodules/TelegramCore/Sources/TelegramEngine/Data/TelegramEngineData.swift index 283c603cbf..bf03182201 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Data/TelegramEngineData.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Data/TelegramEngineData.swift @@ -95,6 +95,37 @@ public final class EngineDataList: TelegramEngineDataItem, AnyPostboxViewDataItem { + public typealias Result = Item.Result? + + private let item: Item? + + public init(_ item: Item?) { + self.item = item + } + + var keys: [PostboxViewKey] { + var keys = Set() + if let item = self.item { + for key in (item as! AnyPostboxViewDataItem).keys { + keys.insert(key) + } + } + return Array(keys) + } + + func _extract(views: [PostboxViewKey: PostboxView]) -> Any { + var result: [Item.Result] = [] + + if let item = self.item { + let itemResult = (item as! AnyPostboxViewDataItem)._extract(views: views) + result.append(itemResult as! Item.Result) + } + + return result + } +} + public extension TelegramEngine { final class EngineData { public struct Item { diff --git a/submodules/TelegramUI/Sources/AccountContext.swift b/submodules/TelegramUI/Sources/AccountContext.swift index 52350c0d03..b5462b4557 100644 --- a/submodules/TelegramUI/Sources/AccountContext.swift +++ b/submodules/TelegramUI/Sources/AccountContext.swift @@ -59,10 +59,9 @@ private final class DeviceSpecificContactImportContexts { if context.reference != reference { context.reference = reference - let key: PostboxViewKey = .basicPeer(peerId) - let signal = account.postbox.combinedView(keys: [key]) - |> map { view -> String? in - if let user = (view.views[key] as? BasicPeerView)?.peer as? TelegramUser { + let signal = TelegramEngine(account: account).data.subscribe(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)) + |> map { peer -> String? in + if case let .user(user) = peer { return user.phone } else { return nil diff --git a/submodules/TelegramUI/Sources/ChatController.swift b/submodules/TelegramUI/Sources/ChatController.swift index 920352583d..d1c0836a78 100644 --- a/submodules/TelegramUI/Sources/ChatController.swift +++ b/submodules/TelegramUI/Sources/ChatController.swift @@ -8567,42 +8567,34 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G }) if case let .peer(peerId) = self.chatLocation { - let unreadCountsKey: PostboxViewKey = .unreadCounts(items: [.peer(peerId), .total(nil)]) - let notificationSettingsKey: PostboxViewKey = .peerNotificationSettings(peerIds: Set([peerId])) - self.chatUnreadCountDisposable = (self.context.account.postbox.combinedView(keys: [unreadCountsKey, notificationSettingsKey]) - |> deliverOnMainQueue).start(next: { [weak self] views in - if let strongSelf = self { - var unreadCount: Int32 = 0 - var totalChatCount: Int32 = 0 - - let inAppSettings = strongSelf.context.sharedContext.currentInAppNotificationSettings.with { $0 } - if let view = views.views[unreadCountsKey] as? UnreadMessageCountsView { - if let count = view.count(for: .peer(peerId)) { - unreadCount = count - } - if let (_, state) = view.total() { - let (count, _) = renderedTotalUnreadCount(inAppSettings: inAppSettings, totalUnreadState: state) - totalChatCount = count - } - } - - if let view = views.views[notificationSettingsKey] as? PeerNotificationSettingsView, let notificationSettings = view.notificationSettings[peerId] { - var globalRemainingUnreadChatCount = totalChatCount - if !notificationSettings.isRemovedFromTotalUnreadCount(default: false) && unreadCount > 0 { - if case .messages = inAppSettings.totalUnreadCountDisplayCategory { - globalRemainingUnreadChatCount -= unreadCount - } else { - globalRemainingUnreadChatCount -= 1 - } - } - - if globalRemainingUnreadChatCount > 0 { - strongSelf.navigationItem.badge = "\(globalRemainingUnreadChatCount)" - } else { - strongSelf.navigationItem.badge = "" - } + self.chatUnreadCountDisposable = (self.context.engine.data.subscribe( + TelegramEngine.EngineData.Item.Messages.PeerUnreadCount(id: peerId), + TelegramEngine.EngineData.Item.Messages.TotalReadCounters(), + TelegramEngine.EngineData.Item.Peer.NotificationSettings(id: peerId) + ) + |> deliverOnMainQueue).start(next: { [weak self] peerUnreadCount, totalReadCounters, notificationSettings in + guard let strongSelf = self else { + return + } + let unreadCount: Int32 = Int32(peerUnreadCount) + + let inAppSettings = strongSelf.context.sharedContext.currentInAppNotificationSettings.with { $0 } + let totalChatCount: Int32 = renderedTotalUnreadCount(inAppSettings: inAppSettings, totalUnreadState: totalReadCounters._asCounters()).0 + + var globalRemainingUnreadChatCount = totalChatCount + if !notificationSettings._asNotificationSettings().isRemovedFromTotalUnreadCount(default: false) && unreadCount > 0 { + if case .messages = inAppSettings.totalUnreadCountDisplayCategory { + globalRemainingUnreadChatCount -= unreadCount + } else { + globalRemainingUnreadChatCount -= 1 } } + + if globalRemainingUnreadChatCount > 0 { + strongSelf.navigationItem.badge = "\(globalRemainingUnreadChatCount)" + } else { + strongSelf.navigationItem.badge = "" + } }) self.chatUnreadMentionCountDisposable = (self.context.account.viewTracker.unseenPersonalMessagesAndReactionCount(peerId: peerId) |> deliverOnMainQueue).start(next: { [weak self] mentionCount, reactionCount in diff --git a/submodules/TelegramUI/Sources/ChatHistoryListNode.swift b/submodules/TelegramUI/Sources/ChatHistoryListNode.swift index a622aaa073..180406aec3 100644 --- a/submodules/TelegramUI/Sources/ChatHistoryListNode.swift +++ b/submodules/TelegramUI/Sources/ChatHistoryListNode.swift @@ -931,20 +931,15 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { let customChannelDiscussionReadState: Signal if case let .peer(peerId) = chatLocation, peerId.namespace == Namespaces.Peer.CloudChannel { - let cachedDataKey = PostboxViewKey.cachedPeerData(peerId: peerId) - let peerKey = PostboxViewKey.basicPeer(peerId) - customChannelDiscussionReadState = context.account.postbox.combinedView(keys: [cachedDataKey, peerKey]) - |> mapToSignal { views -> Signal in - guard let view = views.views[cachedDataKey] as? CachedPeerDataView else { + customChannelDiscussionReadState = context.engine.data.subscribe( + TelegramEngine.EngineData.Item.Peer.LinkedDiscussionPeerId(id: peerId), + TelegramEngine.EngineData.Item.Peer.Peer(id: peerId) + ) + |> mapToSignal { linkedDiscussionPeerId, peer -> Signal in + guard case let .channel(peer) = peer, case .broadcast = peer.info else { return .single(nil) } - guard let peer = (views.views[peerKey] as? BasicPeerView)?.peer as? TelegramChannel, case .broadcast = peer.info else { - return .single(nil) - } - guard let cachedData = view.cachedPeerData as? CachedChannelData else { - return .single(nil) - } - guard case let .known(value) = cachedData.linkedDiscussionPeerId else { + guard case let .known(value) = linkedDiscussionPeerId else { return .single(nil) } return .single(value) @@ -954,13 +949,10 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { guard let discussionPeerId = discussionPeerId else { return .single(nil) } - let key = PostboxViewKey.combinedReadState(peerId: discussionPeerId) - return context.account.postbox.combinedView(keys: [key]) - |> map { views -> MessageId? in - guard let view = views.views[key] as? CombinedReadStateView else { - return nil - } - guard let state = view.state else { + + return context.engine.data.subscribe(TelegramEngine.EngineData.Item.Messages.PeerReadCounters(id: discussionPeerId)) + |> map { readCounters -> MessageId? in + guard let state = readCounters._asReadCounters() else { return nil } for (namespace, namespaceState) in state.states { diff --git a/submodules/TelegramUI/Sources/ChatMediaInputNode.swift b/submodules/TelegramUI/Sources/ChatMediaInputNode.swift index 6851645a6b..3a4a10ea53 100644 --- a/submodules/TelegramUI/Sources/ChatMediaInputNode.swift +++ b/submodules/TelegramUI/Sources/ChatMediaInputNode.swift @@ -1071,16 +1071,10 @@ final class ChatMediaInputNode: ChatInputNode { }) self.trendingInteraction = trendingInteraction - let preferencesViewKey: PostboxViewKey = .preferences(keys: Set([PreferencesKeys.appConfiguration])) - let reactions: Signal<[String], NoError> = context.account.postbox.combinedView(keys: [preferencesViewKey]) - |> map { views -> [String] in + let reactions: Signal<[String], NoError> = context.engine.data.subscribe(TelegramEngine.EngineData.Item.Configuration.App()) + |> map { appConfiguration -> [String] in let defaultReactions: [String] = ["👍", "👎", "😍", "😂", "😯", "😕", "😢", "😡", "💪", "👏", "🙈", "😒"] - guard let view = views.views[preferencesViewKey] as? PreferencesView else { - return defaultReactions - } - guard let appConfiguration = view.values[PreferencesKeys.appConfiguration]?.get(AppConfiguration.self) else { - return defaultReactions - } + guard let data = appConfiguration.data, let emojis = data["gif_search_emojies"] as? [String] else { return defaultReactions } diff --git a/submodules/TelegramUI/Sources/PeerInfo/Panes/PeerInfoListPaneNode.swift b/submodules/TelegramUI/Sources/PeerInfo/Panes/PeerInfoListPaneNode.swift index 313b8ce1bc..fb9e5e0534 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/Panes/PeerInfoListPaneNode.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/Panes/PeerInfoListPaneNode.swift @@ -141,10 +141,12 @@ final class PeerInfoListPaneNode: ASDisplayNode, PeerInfoPaneNode { } }) } - - self.statusPromise.set(context.account.postbox.combinedView(keys: [PostboxViewKey.historyTagSummaryView(tag: tagMask, peerId: peerId, namespace: Namespaces.Message.Cloud)]) - |> map { views -> PeerInfoStatusData? in - let count: Int32 = (views.views[PostboxViewKey.historyTagSummaryView(tag: tagMask, peerId: peerId, namespace: Namespaces.Message.Cloud)] as? MessageHistoryTagSummaryView)?.count ?? 0 + + self.statusPromise.set(context.engine.data.subscribe( + TelegramEngine.EngineData.Item.Messages.MessageCount(peerId: peerId, tag: tagMask) + ) + |> map { count -> PeerInfoStatusData? in + let count: Int = count ?? 0 if count == 0 { return nil } diff --git a/submodules/TelegramUI/Sources/PeerInfo/Panes/PeerInfoVisualMediaPaneNode.swift b/submodules/TelegramUI/Sources/PeerInfo/Panes/PeerInfoVisualMediaPaneNode.swift index 3a8f17e9da..2878a8e50b 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/Panes/PeerInfoVisualMediaPaneNode.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/Panes/PeerInfoVisualMediaPaneNode.swift @@ -2015,34 +2015,14 @@ final class PeerInfoVisualMediaPaneNode: ASDisplayNode, PeerInfoPaneNode, UIScro case .music: summaries.append(.music) } - return context.account.postbox.combinedView(keys: summaries.map { tag in - return PostboxViewKey.historyTagSummaryView(tag: tag, peerId: peerId, namespace: Namespaces.Message.Cloud) - }) - |> map { views -> (ContentType, [MessageTags: Int32]) in - switch contentType { - case .photoOrVideo: - summaries.append(.photo) - summaries.append(.video) - case .photo: - summaries.append(.photo) - case .video: - summaries.append(.video) - case .gifs: - summaries.append(.gif) - case .files: - summaries.append(.file) - case .voiceAndVideoMessages: - summaries.append(.voiceOrInstantVideo) - case .music: - summaries.append(.music) - } + + return context.engine.data.subscribe(EngineDataMap( + summaries.map { TelegramEngine.EngineData.Item.Messages.MessageCount(peerId: peerId, tag: $0) } + )) + |> map { summaries -> (ContentType, [MessageTags: Int32]) in var result: [MessageTags: Int32] = [:] - for tag in summaries { - if let view = views.views[PostboxViewKey.historyTagSummaryView(tag: tag, peerId: peerId, namespace: Namespaces.Message.Cloud)] as? MessageHistoryTagSummaryView { - result[tag] = view.count ?? 0 - } else { - result[tag] = 0 - } + for (key, count) in summaries { + result[key.tag] = count.flatMap(Int32.init) ?? 0 } return (contentType, result) } diff --git a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoData.swift b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoData.swift index e187554c76..d9ce03b4a3 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoData.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoData.swift @@ -565,25 +565,20 @@ func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: Presen return disposable } |> distinctUntilChanged - var combinedKeys: [PostboxViewKey] = [] + + var secretChatKeyFingerprint: Signal = .single(nil) if let secretChatId = secretChatId { - combinedKeys.append(.peerChatState(peerId: secretChatId)) + secretChatKeyFingerprint = context.engine.data.subscribe(TelegramEngine.EngineData.Item.Peer.SecretChatKeyFingerprint(id: secretChatId)) } + return combineLatest( context.account.viewTracker.peerView(peerId, updateData: true), peerInfoAvailableMediaPanes(context: context, peerId: peerId), context.engine.data.subscribe(TelegramEngine.EngineData.Item.NotificationSettings.Global()), - context.account.postbox.combinedView(keys: combinedKeys), + secretChatKeyFingerprint, status ) - |> map { peerView, availablePanes, globalNotificationSettings, combinedView, status -> PeerInfoScreenData in - var encryptionKeyFingerprint: SecretChatKeyFingerprint? - if let secretChatId = secretChatId, let peerChatStateView = combinedView.views[.peerChatState(peerId: secretChatId)] as? PeerChatStateView { - if let peerChatState = peerChatStateView.chatState?.getLegacy() as? SecretChatState { - encryptionKeyFingerprint = peerChatState.keyFingerprint - } - } - + |> map { peerView, availablePanes, globalNotificationSettings, encryptionKeyFingerprint, status -> PeerInfoScreenData in var availablePanes = availablePanes if availablePanes != nil, groupsInCommon != nil, let cachedData = peerView.cachedData as? CachedUserData { if cachedData.commonGroupCount != 0 { diff --git a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift index 5ccfad7f4e..6b97eda603 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift @@ -6766,24 +6766,20 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate } private func displayMediaGalleryContextMenu(source: ContextReferenceContentNode, gesture: ContextGesture?) { - let summaryTags: [MessageTags] = [.photo, .video] let peerId = self.peerId - let _ = (context.account.postbox.combinedView(keys: summaryTags.map { tag in - return PostboxViewKey.historyTagSummaryView(tag: tag, peerId: peerId, namespace: Namespaces.Message.Cloud) - }) - |> take(1) - |> deliverOnMainQueue).start(next: { [weak self] views in + + let _ = (self.context.engine.data.get(EngineDataMap([ + TelegramEngine.EngineData.Item.Messages.MessageCount(peerId: peerId, tag: .photo), + TelegramEngine.EngineData.Item.Messages.MessageCount(peerId: peerId, tag: .video) + ])) + |> deliverOnMainQueue).start(next: { [weak self] messageCounts in guard let strongSelf = self else { return } var mediaCount: [MessageTags: Int32] = [:] - for tag in summaryTags { - if let view = views.views[PostboxViewKey.historyTagSummaryView(tag: tag, peerId: peerId, namespace: Namespaces.Message.Cloud)] as? MessageHistoryTagSummaryView { - mediaCount[tag] = view.count ?? 0 - } else { - mediaCount[tag] = 0 - } + for (key, count) in messageCounts { + mediaCount[key.tag] = count.flatMap(Int32.init) ?? 0 } let photoCount: Int32 = mediaCount[.photo] ?? 0 diff --git a/submodules/TelegramUI/Sources/PeerInfoGifPaneNode.swift b/submodules/TelegramUI/Sources/PeerInfoGifPaneNode.swift index eea5dbe70d..e2d4f5c3f7 100644 --- a/submodules/TelegramUI/Sources/PeerInfoGifPaneNode.swift +++ b/submodules/TelegramUI/Sources/PeerInfoGifPaneNode.swift @@ -875,12 +875,11 @@ final class PeerInfoGifPaneNode: ASDisplayNode, PeerInfoPaneNode, UIScrollViewDe self.animationTimer = animationTimer animationTimer.start() - self.statusPromise.set(context.account.postbox.combinedView(keys: [PostboxViewKey.historyTagSummaryView(tag: tagMaskForType(self.contentType), peerId: peerId, namespace: Namespaces.Message.Cloud)]) - |> map { [weak self] views -> PeerInfoStatusData? in - guard let strongSelf = self else { - return nil - } - let count: Int32 = (views.views[PostboxViewKey.historyTagSummaryView(tag: tagMaskForType(strongSelf.contentType), peerId: peerId, namespace: Namespaces.Message.Cloud)] as? MessageHistoryTagSummaryView)?.count ?? 0 + self.statusPromise.set(context.engine.data.subscribe( + TelegramEngine.EngineData.Item.Messages.MessageCount(peerId: peerId, tag: tagMaskForType(self.contentType)) + ) + |> map { count -> PeerInfoStatusData? in + let count: Int = count ?? 0 if count == 0 { return nil } diff --git a/submodules/TelegramUI/Sources/WidgetDataContext.swift b/submodules/TelegramUI/Sources/WidgetDataContext.swift index 2877f3ae6a..40d9b5b36d 100644 --- a/submodules/TelegramUI/Sources/WidgetDataContext.swift +++ b/submodules/TelegramUI/Sources/WidgetDataContext.swift @@ -198,15 +198,16 @@ final class WidgetDataContext { if peerIds.isEmpty { continue } - let topMessagesKey: PostboxViewKey = .topChatMessage(peerIds: Array(peerIds)) - accountSignals.append(account.postbox.combinedView(keys: [topMessagesKey]) - |> map { combinedView -> [WidgetDataPeer] in - guard let topMessages = combinedView.views[topMessagesKey] as? TopChatMessageView else { - return [] - } + accountSignals.append(TelegramEngine(account: account).data.subscribe(EngineDataMap( + peerIds.map(TelegramEngine.EngineData.Item.Messages.TopMessage.init) + )) + |> map { topMessages -> [WidgetDataPeer] in var result: [WidgetDataPeer] = [] - for (peerId, message) in topMessages.messages { + for (peerId, message) in topMessages { + guard let message = message else { + continue + } guard let peer = message.peers[message.id.peerId] else { continue } @@ -227,7 +228,7 @@ final class WidgetDataContext { name = peer.debugDisplayTitle } - result.append(WidgetDataPeer(id: peerId.toInt64(), name: name, lastName: lastName, letters: [], avatarPath: nil, badge: nil, message: WidgetDataPeer.Message(accountPeerId: account.peerId, message: EngineMessage(message)))) + result.append(WidgetDataPeer(id: peerId.toInt64(), name: name, lastName: lastName, letters: [], avatarPath: nil, badge: nil, message: WidgetDataPeer.Message(accountPeerId: account.peerId, message: message))) } result.sort(by: { lhs, rhs in return lhs.id < rhs.id