Refactoring

This commit is contained in:
Ali 2022-05-29 19:11:14 +04:00
parent 70227e7cf1
commit 5eb4bbeaae
42 changed files with 366 additions and 353 deletions

View File

@ -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
})
}

View File

@ -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
})
}

View File

@ -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<Bool, NoError>, applicationIsActive: Signal<Bool, NoError>, 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<Bool, NoError>, applicationIsActive: Signal<Bool, NoError>, 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

View File

@ -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
}

View File

@ -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

View File

@ -29,41 +29,28 @@ func chatListSelectionOptions(context: AccountContext, peerIds: Set<PeerId>, 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 {
if readCounters.count(for: .filtered, in: .chats, with: .all) != 0 {
hasUnread = true
break
}
}
}
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 {
for counters in readCounters {
if counters.isUnread {
hasUnread = true
break loop
}
default:
break
}
}
}
return ChatListSelectionOptions(read: .selective(enabled: hasUnread), delete: true)
}
|> distinctUntilChanged

View File

@ -120,7 +120,10 @@ public func debugAccountsController(context: AccountContext, accountManager: Acc
ActionSheetItemGroup(items: [
ActionSheetButtonItem(title: "Production", color: .accent, action: {
dismissAction()
if case .internal = context.sharedContext.applicationBindings.appBuildType {
context.sharedContext.beginNewAuth(testingEnvironment: false)
}
}),
ActionSheetButtonItem(title: "Test", color: .accent, action: {
dismissAction()

View File

@ -608,15 +608,14 @@ 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 {
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)
|> deliverOnMainQueue).start(next: { [weak self] _ in
@ -2247,16 +2246,12 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode {
let shouldBeDismissed: Signal<Bool, NoError>
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

View File

@ -21,13 +21,13 @@ public enum AvatarGalleryEntryId: Hashable {
case resource(String)
}
public func peerInfoProfilePhotos(context: AccountContext, peerId: PeerId) -> Signal<Any, NoError> {
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<Any, NoError> {
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

View File

@ -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))
}

View File

@ -740,28 +740,26 @@ 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 {
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(view.notificationSettings.keys.map(TelegramEngine.EngineData.Item.Peer.Peer.init)),
EngineDataMap(view.notificationSettings.keys.map(TelegramEngine.EngineData.Item.Peer.NotificationSettings.init))
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 view.notificationSettings {
if let value = value as? TelegramPeerNotificationSettings {
for (key, value) in notificationSettingsMap {
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) {
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).withUpdatedPeerMuteInterval(peer._asPeer(), EnginePeer.NotificationSettings.MuteState(value.muteState).timeInterval).withUpdatedPeerDisplayPreviews(peer._asPeer(), value.displayPreviews)
}
current = current.withUpdatedPeerSound(peer._asPeer(), value.messageSound._asMessageSound()).withUpdatedPeerMuteInterval(peer._asPeer(), value.muteState.timeInterval).withUpdatedPeerDisplayPreviews(peer._asPeer(), value.displayPreviews._asDisplayPreviews())
}
}
}
@ -770,9 +768,6 @@ final class NotificationExceptionsControllerNode: ViewControllerTracingNode {
completion()
})
} else {
completion()
}
}))
return current
}

View File

@ -455,28 +455,28 @@ 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 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(view.notificationSettings.keys.map(TelegramEngine.EngineData.Item.Peer.Peer.init)),
EngineDataMap(view.notificationSettings.keys.map(TelegramEngine.EngineData.Item.Peer.NotificationSettings.init))
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 view.notificationSettings {
if let value = value as? TelegramPeerNotificationSettings {
for (key, value) in combinedPeerNotificationSettings {
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) {
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).withUpdatedPeerMuteInterval(peer._asPeer(), EnginePeer.NotificationSettings.MuteState(value.muteState).timeInterval).withUpdatedPeerDisplayPreviews(peer._asPeer(), value.displayPreviews)
}
current = current.withUpdatedPeerSound(peer._asPeer(), value.messageSound._asMessageSound()).withUpdatedPeerMuteInterval(peer._asPeer(), value.muteState.timeInterval).withUpdatedPeerDisplayPreviews(peer._asPeer(), value.displayPreviews._asDisplayPreviews())
}
}
}
@ -485,9 +485,6 @@ public func notificationsPeerCategoryController(context: AccountContext, categor
completion()
})
} else {
completion()
}
}))
return current
}

View File

@ -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
}

View File

@ -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

View File

@ -52,18 +52,16 @@ 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 {
for item in items {
let index = SettingsSearchRecentQueryItemId(item.id).value
if let itemId = SettingsSearchableItemId(index: index) {
result.append(itemId)
}
}
}
return result
}
}

View File

@ -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] = []

View File

@ -55,16 +55,14 @@ func clearRecentWallpaperSearchQueries(engine: TelegramEngine) -> Signal<Never,
return engine.orderedLists.clear(collectionId: ApplicationSpecificOrderedItemListCollectionId.wallpaperSearchRecentQueries)
}
func wallpaperSearchRecentQueries(postbox: Postbox) -> 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 {
for item in items {
let value = WallpaperSearchRecentQueryItemId(item.id).value
result.append(value)
}
}
return result
}
}

View File

@ -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<PeerId> 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<PeerId> 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<PeerId> in
|> map { rawAdminIds, peer -> Set<PeerId> 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<PeerId> in
|> map { rawAdminIds, peer -> Set<PeerId> 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 {

View File

@ -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<TelegramEngineAuthorizationState?, NoError> {
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<Never, NoError> {
return self.account.postbox.transaction { transaction -> Void in
transaction.setState(state)

View File

@ -0,0 +1,8 @@
import SwiftSignalKit
import Postbox
public extension TelegramEngine.EngineData.Item {
enum ChatList {
}
}

View File

@ -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)
}
}

View File

@ -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
}
}
}
}

View File

@ -526,7 +526,7 @@ private func extractAccountManagerState(records: AccountRecordsView<TelegramAcco
self.hasActiveAudioSession.set(MediaManagerImpl.globalAudioSession.isActive())
let applicationBindings = TelegramApplicationBindings(isMainApp: true, appBundleId: baseAppBundleId, containerPath: appGroupUrl.path, appSpecificScheme: buildConfig.appSpecificUrlScheme, openUrl: { url in
let applicationBindings = TelegramApplicationBindings(isMainApp: true, appBundleId: baseAppBundleId, appBuildType: buildConfig.isAppStoreBuild ? .public : .internal, containerPath: appGroupUrl.path, appSpecificScheme: buildConfig.appSpecificUrlScheme, openUrl: { url in
var parsedUrl = URL(string: url)
if let parsed = parsedUrl {
if parsed.scheme == nil || parsed.scheme!.isEmpty {

View File

@ -69,11 +69,11 @@ public final class AuthorizationSequenceController: NavigationController, MFMail
super.init(mode: .single, theme: NavigationControllerTheme(statusBar: navigationStatusBar, navigationBar: AuthorizationSequenceController.navigationBarTheme(presentationData.theme), emptyAreaColor: .black))
self.stateDisposable = (account.postbox.stateView()
|> 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
}

View File

@ -547,13 +547,12 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
locationBroadcastPanelSource = .none
groupCallPanelSource = .none
let promise = Promise<Message?>()
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 {

View File

@ -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) {

View File

@ -290,23 +290,17 @@ 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
saved = cloudRecentGifs.map { item in
let file = item.contents.get(RecentMediaItem.self)!.media
return MultiplexedVideoNodeFile(file: .savedGif(media: file), contextResult: nil)
}
} else {
saved = []
}
return (MultiplexedVideoNodeFiles(saved: saved, trending: trending?.files ?? [], isSearch: false, canLoadMore: false, isStale: false), nil)
}

View File

@ -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
}

View File

@ -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

View File

@ -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

View File

@ -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<PeerInfoScreenInputData, NoError> {
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<PeerInfoScreenInputData, NoError> {
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<ValueBoxKey>([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<ValueBoxKey>([PreferencesKeys.globalNotifications]))
var combinedKeys: [PostboxViewKey] = []
combinedKeys.append(globalNotificationsKey)
let invitationsContextPromise = Promise<PeerExportedInvitationsContext?>(nil)
let invitationsStatePromise = Promise<PeerExportedInvitationsState?>(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<ValueBoxKey>([PreferencesKeys.globalNotifications]))
var combinedKeys: [PostboxViewKey] = []
combinedKeys.append(globalNotificationsKey)
let invitationsContextPromise = Promise<PeerExportedInvitationsContext?>(nil)
let invitationsStatePromise = Promise<PeerExportedInvitationsState?>(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

View File

@ -444,16 +444,14 @@ 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 {
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
}
}
|> take(1)
|> deliverOnMainQueue).start(next: { [weak self] _ in
self?.currentItemDisappeared?()

View File

@ -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

View File

@ -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<AccountWithInfo?, NoError> 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
})

View File

@ -511,15 +511,16 @@ 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))
for (_, presence) in presenceMap {
if let presence = presence {
let relativeStatus = relativeUserPresenceStatus(presence, relativeTo: Int32(timestamp))
switch relativeStatus {
case .online:
count += 1
@ -528,7 +529,6 @@ public final class PeerChannelMemberCategoriesContextsManager {
}
}
}
}
return count
}
|> distinctUntilChanged

View File

@ -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] = []

View File

@ -56,16 +56,14 @@ func clearRecentWebSearchQueries(engine: TelegramEngine) -> Signal<Never, NoErro
return engine.orderedLists.clear(collectionId: ApplicationSpecificOrderedItemListCollectionId.webSearchRecentQueries)
}
func webSearchRecentQueries(postbox: Postbox) -> 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 {
for item in items {
let value = WebSearchRecentQueryItemId(item.id).value
result.append(value)
}
}
return .single(result)
return result
}
}