mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-10-08 19:10:53 +00:00
Memory management issues
This commit is contained in:
parent
5799d7a2d9
commit
62765b241d
@ -34,6 +34,8 @@ def generate_xcodeproj(build_environment: BuildEnvironment, disable_extensions,
|
||||
project_bazel_arguments += ['--//{}:disableExtensions'.format(app_target)]
|
||||
project_bazel_arguments += ['--//{}:disableStripping'.format('Telegram')]
|
||||
|
||||
project_bazel_arguments += ['--features=-swift.debug_prefix_map']
|
||||
|
||||
xcodeproj_bazelrc = os.path.join(build_environment.base_path, 'xcodeproj.bazelrc')
|
||||
if os.path.isfile(xcodeproj_bazelrc):
|
||||
os.unlink(xcodeproj_bazelrc)
|
||||
|
@ -32,7 +32,7 @@ func archiveContextMenuItems(context: AccountContext, groupId: PeerGroupId, chat
|
||||
if !unreadChatListPeerIds.isEmpty {
|
||||
items.append(.action(ContextMenuActionItem(text: strings.ChatList_Context_MarkAllAsRead, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/MarkAsRead"), color: theme.contextMenu.primaryColor) }, action: { _, f in
|
||||
let _ = (context.engine.messages.markAllChatsAsReadInteractively(items: [(groupId: EngineChatList.Group(groupId), filterPredicate: nil)])
|
||||
|> deliverOnMainQueue).start(completed: {
|
||||
|> deliverOnMainQueue).startStandalone(completed: {
|
||||
f(.default)
|
||||
})
|
||||
})))
|
||||
@ -118,7 +118,7 @@ func chatContextMenuItems(context: AccountContext, peerId: PeerId, promoInfo: Ch
|
||||
case .recentPeers:
|
||||
items.append(.action(ContextMenuActionItem(text: strings.ChatList_Context_RemoveFromRecents, textColor: .destructive, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Clear"), color: theme.contextMenu.destructiveColor) }, action: { _, f in
|
||||
let _ = (context.engine.peers.removeRecentPeer(peerId: peerId)
|
||||
|> deliverOnMainQueue).start(completed: {
|
||||
|> deliverOnMainQueue).startStandalone(completed: {
|
||||
f(.default)
|
||||
})
|
||||
})))
|
||||
@ -126,7 +126,7 @@ func chatContextMenuItems(context: AccountContext, peerId: PeerId, promoInfo: Ch
|
||||
case .recentSearch:
|
||||
items.append(.action(ContextMenuActionItem(text: strings.ChatList_Context_RemoveFromRecents, textColor: .destructive, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Clear"), color: theme.contextMenu.destructiveColor) }, action: { _, f in
|
||||
let _ = (context.engine.peers.removeRecentlySearchedPeer(peerId: peerId)
|
||||
|> deliverOnMainQueue).start(completed: {
|
||||
|> deliverOnMainQueue).startStandalone(completed: {
|
||||
f(.default)
|
||||
})
|
||||
})))
|
||||
@ -135,7 +135,7 @@ func chatContextMenuItems(context: AccountContext, peerId: PeerId, promoInfo: Ch
|
||||
if recentlySearchedPeers.contains(where: { $0.peer.peerId == peerId }) {
|
||||
items.append(.action(ContextMenuActionItem(text: strings.ChatList_Context_RemoveFromRecents, textColor: .destructive, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Clear"), color: theme.contextMenu.destructiveColor) }, action: { _, f in
|
||||
let _ = (context.engine.peers.removeRecentlySearchedPeer(peerId: peerId)
|
||||
|> deliverOnMainQueue).start(completed: {
|
||||
|> deliverOnMainQueue).startStandalone(completed: {
|
||||
f(.default)
|
||||
})
|
||||
})))
|
||||
@ -208,7 +208,7 @@ func chatContextMenuItems(context: AccountContext, peerId: PeerId, promoInfo: Ch
|
||||
}
|
||||
return filters
|
||||
}
|
||||
|> deliverOnMainQueue).start(completed: {
|
||||
|> deliverOnMainQueue).startStandalone(completed: {
|
||||
c.dismiss(completion: {
|
||||
chatListController?.present(UndoOverlayController(presentationData: presentationData, content: .chatRemovedFromFolder(chatTitle: peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder), folderTitle: title), elevatedLayout: false, animateInAsReplacement: true, action: { _ in
|
||||
return false
|
||||
@ -316,7 +316,7 @@ func chatContextMenuItems(context: AccountContext, peerId: PeerId, promoInfo: Ch
|
||||
}
|
||||
}
|
||||
return filters
|
||||
}).start()
|
||||
}).startStandalone()
|
||||
|
||||
chatListController?.present(UndoOverlayController(presentationData: presentationData, content: .chatAddedToFolder(chatTitle: peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder), folderTitle: title), elevatedLayout: false, animateInAsReplacement: true, action: { _ in
|
||||
return false
|
||||
@ -340,12 +340,12 @@ func chatContextMenuItems(context: AccountContext, peerId: PeerId, promoInfo: Ch
|
||||
|
||||
if isUnread {
|
||||
items.append(.action(ContextMenuActionItem(text: strings.ChatList_Context_MarkAsRead, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/MarkAsRead"), color: theme.contextMenu.primaryColor) }, action: { _, f in
|
||||
let _ = context.engine.messages.togglePeersUnreadMarkInteractively(peerIds: [peerId], setToValue: nil).start()
|
||||
let _ = context.engine.messages.togglePeersUnreadMarkInteractively(peerIds: [peerId], setToValue: nil).startStandalone()
|
||||
f(.default)
|
||||
})))
|
||||
} else if !isForum {
|
||||
items.append(.action(ContextMenuActionItem(text: strings.ChatList_Context_MarkAsUnread, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/MarkAsUnread"), color: theme.contextMenu.primaryColor) }, action: { _, f in
|
||||
let _ = context.engine.messages.togglePeersUnreadMarkInteractively(peerIds: [peerId], setToValue: nil).start()
|
||||
let _ = context.engine.messages.togglePeersUnreadMarkInteractively(peerIds: [peerId], setToValue: nil).startStandalone()
|
||||
f(.default)
|
||||
})))
|
||||
}
|
||||
@ -357,7 +357,7 @@ func chatContextMenuItems(context: AccountContext, peerId: PeerId, promoInfo: Ch
|
||||
items.append(.action(ContextMenuActionItem(text: isArchived ? strings.ChatList_Context_Unarchive : strings.ChatList_Context_Archive, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: isArchived ? "Chat/Context Menu/Unarchive" : "Chat/Context Menu/Archive"), color: theme.contextMenu.primaryColor) }, action: { _, f in
|
||||
if isArchived {
|
||||
let _ = (context.engine.peers.updatePeersGroupIdInteractively(peerIds: [peerId], groupId: .root)
|
||||
|> deliverOnMainQueue).start(completed: {
|
||||
|> deliverOnMainQueue).startStandalone(completed: {
|
||||
f(.default)
|
||||
})
|
||||
} else {
|
||||
@ -366,7 +366,7 @@ func chatContextMenuItems(context: AccountContext, peerId: PeerId, promoInfo: Ch
|
||||
f(.default)
|
||||
} else {
|
||||
let _ = (context.engine.peers.updatePeersGroupIdInteractively(peerIds: [peerId], groupId: .archive)
|
||||
|> deliverOnMainQueue).start(completed: {
|
||||
|> deliverOnMainQueue).startStandalone(completed: {
|
||||
f(.default)
|
||||
})
|
||||
}
|
||||
@ -377,7 +377,7 @@ func chatContextMenuItems(context: AccountContext, peerId: PeerId, promoInfo: Ch
|
||||
if isPinned || chatListFilter == nil || peerId.namespace != Namespaces.Peer.SecretChat {
|
||||
items.append(.action(ContextMenuActionItem(text: isPinned ? strings.ChatList_Context_Unpin : strings.ChatList_Context_Pin, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: isPinned ? "Chat/Context Menu/Unpin" : "Chat/Context Menu/Pin"), color: theme.contextMenu.primaryColor) }, action: { c, f in
|
||||
let _ = (context.engine.peers.toggleItemPinned(location: location, itemId: .peer(peerId))
|
||||
|> deliverOnMainQueue).start(next: { result in
|
||||
|> deliverOnMainQueue).startStandalone(next: { result in
|
||||
switch result {
|
||||
case .done:
|
||||
f(.default)
|
||||
@ -447,7 +447,7 @@ func chatContextMenuItems(context: AccountContext, peerId: PeerId, promoInfo: Ch
|
||||
}
|
||||
items.append(.action(ContextMenuActionItem(text: isMuted ? strings.ChatList_Context_Unmute : strings.ChatList_Context_Mute, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: isMuted ? "Chat/Context Menu/Unmute" : "Chat/Context Menu/Muted"), color: theme.contextMenu.primaryColor) }, action: { _, f in
|
||||
let _ = (context.engine.peers.togglePeerMuted(peerId: peerId, threadId: nil)
|
||||
|> deliverOnMainQueue).start(completed: {
|
||||
|> deliverOnMainQueue).startStandalone(completed: {
|
||||
f(.default)
|
||||
})
|
||||
})))
|
||||
@ -500,7 +500,7 @@ func chatContextMenuItems(context: AccountContext, peerId: PeerId, promoInfo: Ch
|
||||
}
|
||||
}, completed: {
|
||||
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|
||||
|> deliverOnMainQueue).start(next: { peer in
|
||||
|> deliverOnMainQueue).startStandalone(next: { peer in
|
||||
guard let peer = peer else {
|
||||
return
|
||||
}
|
||||
@ -562,7 +562,7 @@ func chatForumTopicMenuItems(context: AccountContext, peerId: PeerId, threadId:
|
||||
f(.default)
|
||||
|
||||
let _ = (context.engine.peers.toggleForumChannelTopicPinned(id: peerId, threadId: threadId)
|
||||
|> deliverOnMainQueue).start(error: { error in
|
||||
|> deliverOnMainQueue).startStandalone(error: { error in
|
||||
switch error {
|
||||
case let .limitReached(count):
|
||||
if let chatListController = chatListController {
|
||||
@ -585,7 +585,7 @@ func chatForumTopicMenuItems(context: AccountContext, peerId: PeerId, threadId:
|
||||
|
||||
if isUnread {
|
||||
items.append(.action(ContextMenuActionItem(text: strings.ChatList_Context_MarkAsRead, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/MarkAsRead"), color: theme.contextMenu.primaryColor) }, action: { _, f in
|
||||
let _ = context.engine.messages.markForumThreadAsRead(peerId: peerId, threadId: threadId).start()
|
||||
let _ = context.engine.messages.markForumThreadAsRead(peerId: peerId, threadId: threadId).startStandalone()
|
||||
f(.default)
|
||||
})))
|
||||
}
|
||||
@ -610,7 +610,7 @@ func chatForumTopicMenuItems(context: AccountContext, peerId: PeerId, threadId:
|
||||
items.append(.action(ContextMenuActionItem(text: isMuted ? strings.ChatList_Context_Unmute : strings.ChatList_Context_Mute, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: isMuted ? "Chat/Context Menu/Unmute" : "Chat/Context Menu/Muted"), color: theme.contextMenu.primaryColor) }, action: { [weak chatListController] c, f in
|
||||
if isMuted {
|
||||
let _ = (context.engine.peers.updatePeerMuteSetting(peerId: peerId, threadId: threadId, muteInterval: 0)
|
||||
|> deliverOnMainQueue).start(completed: {
|
||||
|> deliverOnMainQueue).startStandalone(completed: {
|
||||
f(.default)
|
||||
})
|
||||
} else {
|
||||
@ -641,7 +641,7 @@ func chatForumTopicMenuItems(context: AccountContext, peerId: PeerId, threadId:
|
||||
}, action: { _, f in
|
||||
f(.default)
|
||||
|
||||
let _ = context.engine.peers.updatePeerMuteSetting(peerId: peerId, threadId: threadId, muteInterval: value).start()
|
||||
let _ = context.engine.peers.updatePeerMuteSetting(peerId: peerId, threadId: threadId, muteInterval: value).startStandalone()
|
||||
|
||||
chatListController?.present(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_mute_for", scale: 0.066, colors: [:], title: nil, text: presentationData.strings.PeerInfo_TooltipMutedFor(mutedForTimeIntervalString(strings: presentationData.strings, value: value)).string, customUndoText: nil, timeout: nil), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current)
|
||||
})))
|
||||
@ -677,7 +677,7 @@ func chatForumTopicMenuItems(context: AccountContext, peerId: PeerId, threadId:
|
||||
}, action: { _, f in
|
||||
f(.default)
|
||||
|
||||
let _ = context.engine.peers.updatePeerMuteSetting(peerId: peerId, threadId: threadId, muteInterval: nil).start()
|
||||
let _ = context.engine.peers.updatePeerMuteSetting(peerId: peerId, threadId: threadId, muteInterval: nil).startStandalone()
|
||||
|
||||
let iconColor: UIColor = .white
|
||||
chatListController?.present(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_profileunmute", scale: 0.075, colors: [
|
||||
@ -694,7 +694,7 @@ func chatForumTopicMenuItems(context: AccountContext, peerId: PeerId, threadId:
|
||||
}, action: { _, f in
|
||||
f(.default)
|
||||
|
||||
let _ = context.engine.peers.updatePeerNotificationSoundInteractive(peerId: peerId, threadId: threadId, sound: .default).start()
|
||||
let _ = context.engine.peers.updatePeerNotificationSoundInteractive(peerId: peerId, threadId: threadId, sound: .default).startStandalone()
|
||||
|
||||
chatListController?.present(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_sound_on", scale: 0.056, colors: [:], title: nil, text: presentationData.strings.PeerInfo_TooltipSoundEnabled, customUndoText: nil, timeout: nil), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current)
|
||||
})))
|
||||
@ -704,7 +704,7 @@ func chatForumTopicMenuItems(context: AccountContext, peerId: PeerId, threadId:
|
||||
}, action: { _, f in
|
||||
f(.default)
|
||||
|
||||
let _ = context.engine.peers.updatePeerNotificationSoundInteractive(peerId: peerId, threadId: threadId, sound: .none).start()
|
||||
let _ = context.engine.peers.updatePeerNotificationSoundInteractive(peerId: peerId, threadId: threadId, sound: .none).startStandalone()
|
||||
|
||||
chatListController?.present(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_sound_off", scale: 0.056, colors: [:], title: nil, text: presentationData.strings.PeerInfo_TooltipSoundDisabled, customUndoText: nil, timeout: nil), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current)
|
||||
})))
|
||||
@ -718,7 +718,7 @@ func chatForumTopicMenuItems(context: AccountContext, peerId: PeerId, threadId:
|
||||
let _ = (context.engine.data.get(
|
||||
TelegramEngine.EngineData.Item.NotificationSettings.Global()
|
||||
)
|
||||
|> deliverOnMainQueue).start(next: { globalSettings in
|
||||
|> deliverOnMainQueue).startStandalone(next: { globalSettings in
|
||||
let updatePeerSound: (PeerId, PeerMessageSound) -> Signal<Void, NoError> = { peerId, sound in
|
||||
return context.engine.peers.updatePeerNotificationSoundInteractive(peerId: peerId, threadId: threadId, sound: sound) |> deliverOnMainQueue
|
||||
}
|
||||
@ -758,11 +758,11 @@ func chatForumTopicMenuItems(context: AccountContext, peerId: PeerId, threadId:
|
||||
|
||||
let exceptionController = notificationPeerExceptionController(context: context, updatedPresentationData: nil, peer: .channel(channel), threadId: threadId, isStories: nil, canRemove: canRemove, defaultSound: defaultSound, defaultStoriesSound: defaultSound, edit: true, updatePeerSound: { peerId, sound in
|
||||
let _ = (updatePeerSound(peerId, sound)
|
||||
|> deliverOnMainQueue).start(next: { _ in
|
||||
|> deliverOnMainQueue).startStandalone(next: { _ in
|
||||
})
|
||||
}, updatePeerNotificationInterval: { peerId, muteInterval in
|
||||
let _ = (updatePeerNotificationInterval(peerId, muteInterval)
|
||||
|> deliverOnMainQueue).start(next: { _ in
|
||||
|> deliverOnMainQueue).startStandalone(next: { _ in
|
||||
if let muteInterval = muteInterval, muteInterval == Int32.max {
|
||||
let iconColor: UIColor = .white
|
||||
chatListController?.present(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_profilemute", scale: 0.075, colors: [
|
||||
@ -776,18 +776,18 @@ func chatForumTopicMenuItems(context: AccountContext, peerId: PeerId, threadId:
|
||||
})
|
||||
}, updatePeerDisplayPreviews: { peerId, displayPreviews in
|
||||
let _ = (updatePeerDisplayPreviews(peerId, displayPreviews)
|
||||
|> deliverOnMainQueue).start(next: { _ in
|
||||
|> deliverOnMainQueue).startStandalone(next: { _ in
|
||||
|
||||
})
|
||||
}, updatePeerStoriesMuted: { peerId, mute in
|
||||
let _ = (updatePeerStoriesMuted(peerId, mute)
|
||||
|> deliverOnMainQueue).start()
|
||||
|> deliverOnMainQueue).startStandalone()
|
||||
}, updatePeerStoriesHideSender: { peerId, hideSender in
|
||||
let _ = (updatePeerStoriesHideSender(peerId, hideSender)
|
||||
|> deliverOnMainQueue).start()
|
||||
|> deliverOnMainQueue).startStandalone()
|
||||
}, updatePeerStorySound: { peerId, sound in
|
||||
let _ = (updatePeerStorySound(peerId, sound)
|
||||
|> deliverOnMainQueue).start()
|
||||
|> deliverOnMainQueue).startStandalone()
|
||||
}, removePeerFromExceptions: {
|
||||
}, modifiedPeer: {
|
||||
})
|
||||
@ -801,7 +801,7 @@ func chatForumTopicMenuItems(context: AccountContext, peerId: PeerId, threadId:
|
||||
}, action: { _, f in
|
||||
f(.default)
|
||||
|
||||
let _ = context.engine.peers.updatePeerMuteSetting(peerId: peerId, threadId: threadId, muteInterval: Int32.max).start()
|
||||
let _ = context.engine.peers.updatePeerMuteSetting(peerId: peerId, threadId: threadId, muteInterval: Int32.max).startStandalone()
|
||||
|
||||
let iconColor: UIColor = .white
|
||||
chatListController?.present(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_profilemute", scale: 0.075, colors: [
|
||||
@ -830,7 +830,7 @@ func chatForumTopicMenuItems(context: AccountContext, peerId: PeerId, threadId:
|
||||
items.append(.action(ContextMenuActionItem(text: threadData.isClosed ? presentationData.strings.ChatList_Context_ReopenTopic : presentationData.strings.ChatList_Context_CloseTopic, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: threadData.isClosed ? "Chat/Context Menu/Play": "Chat/Context Menu/Pause"), color: theme.contextMenu.primaryColor) }, action: { _, f in
|
||||
f(.default)
|
||||
|
||||
let _ = context.engine.peers.setForumChannelTopicClosed(id: peerId, threadId: threadId, isClosed: !threadData.isClosed).start()
|
||||
let _ = context.engine.peers.setForumChannelTopicClosed(id: peerId, threadId: threadId, isClosed: !threadData.isClosed).startStandalone()
|
||||
})))
|
||||
}
|
||||
if channel.hasPermission(.deleteAllMessages) {
|
||||
@ -859,9 +859,9 @@ private func openCustomMute(context: AccountContext, peerId: EnginePeer.Id, thre
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
|
||||
if value <= 0 {
|
||||
let _ = context.engine.peers.updatePeerMuteSetting(peerId: peerId, threadId: threadId, muteInterval: nil).start()
|
||||
let _ = context.engine.peers.updatePeerMuteSetting(peerId: peerId, threadId: threadId, muteInterval: nil).startStandalone()
|
||||
} else {
|
||||
let _ = context.engine.peers.updatePeerMuteSetting(peerId: peerId, threadId: threadId, muteInterval: value).start()
|
||||
let _ = context.engine.peers.updatePeerMuteSetting(peerId: peerId, threadId: threadId, muteInterval: value).startStandalone()
|
||||
|
||||
let timeString = stringForPreciseRelativeTimestamp(strings: presentationData.strings, relativeTimestamp: Int32(Date().timeIntervalSince1970) + value, relativeTo: Int32(Date().timeIntervalSince1970), dateTimeFormat: presentationData.dateTimeFormat)
|
||||
|
||||
|
@ -198,9 +198,9 @@ final class ChatListContainerItemNode: ASDisplayNode {
|
||||
}
|
||||
|
||||
if let filter, case let .filter(id, _, _, data) = filter, data.isShared {
|
||||
self.pollFilterUpdatesDisposable = self.context.engine.peers.pollChatFolderUpdates(folderId: id).start().strict()
|
||||
self.pollFilterUpdatesDisposable = self.context.engine.peers.pollChatFolderUpdates(folderId: id).startStrict()
|
||||
self.chatFilterUpdatesDisposable = (self.context.engine.peers.subscribedChatFolderUpdates(folderId: id)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] result in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] result in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
@ -221,14 +221,14 @@ final class ChatListContainerItemNode: ASDisplayNode {
|
||||
self.updateLayout(size: size, insets: insets, visualNavigationHeight: visualNavigationHeight, originalNavigationHeight: originalNavigationHeight, inlineNavigationLocation: inlineNavigationLocation, inlineNavigationTransitionFraction: inlineNavigationTransitionFraction, storiesInset: storiesInset, transition: .animated(duration: 0.4, curve: .spring))
|
||||
}
|
||||
}
|
||||
}).strict()
|
||||
})
|
||||
}
|
||||
|
||||
if case let .forum(peerId) = location {
|
||||
self.peerDataDisposable = (context.engine.data.subscribe(
|
||||
TelegramEngine.EngineData.Item.Peer.StatusSettings(id: peerId)
|
||||
)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] statusSettings in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] statusSettings in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
@ -242,7 +242,7 @@ final class ChatListContainerItemNode: ASDisplayNode {
|
||||
self.updateLayout(size: size, insets: insets, visualNavigationHeight: visualNavigationHeight, originalNavigationHeight: originalNavigationHeight, inlineNavigationLocation: inlineNavigationLocation, inlineNavigationTransitionFraction: inlineNavigationTransitionFraction, storiesInset: storiesInset, transition: .animated(duration: 0.4, curve: .spring))
|
||||
}
|
||||
}
|
||||
}).strict()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -333,7 +333,7 @@ final class ChatListContainerItemNode: ASDisplayNode {
|
||||
guard let self, let chatFolderUpdates = self.chatFolderUpdates else {
|
||||
return
|
||||
}
|
||||
let _ = self.context.engine.peers.hideChatFolderUpdates(folderId: chatFolderUpdates.folderId).start()
|
||||
let _ = self.context.engine.peers.hideChatFolderUpdates(folderId: chatFolderUpdates.folderId).startStandalone()
|
||||
}
|
||||
)),
|
||||
environment: {},
|
||||
@ -383,7 +383,7 @@ final class ChatListContainerItemNode: ASDisplayNode {
|
||||
|
||||
if let self {
|
||||
self.controller?.setInlineChatList(location: nil)
|
||||
let _ = self.context.engine.peers.removePeerChat(peerId: peerId, reportChatSpam: true).start()
|
||||
let _ = self.context.engine.peers.removePeerChat(peerId: peerId, reportChatSpam: true).startStandalone()
|
||||
}
|
||||
})
|
||||
]),
|
||||
@ -399,7 +399,7 @@ final class ChatListContainerItemNode: ASDisplayNode {
|
||||
guard let self, case let .forum(peerId) = self.location else {
|
||||
return
|
||||
}
|
||||
let _ = self.context.engine.peers.dismissPeerStatusOptions(peerId: peerId).start()
|
||||
let _ = self.context.engine.peers.dismissPeerStatusOptions(peerId: peerId).startStandalone()
|
||||
}
|
||||
)),
|
||||
environment: {},
|
||||
|
@ -393,7 +393,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
}
|
||||
}
|
||||
|
||||
self.badgeDisposable = (combineLatest(renderedTotalUnreadCount(accountManager: context.sharedContext.accountManager, engine: context.engine), self.presentationDataValue.get()) |> deliverOnMainQueue).start(next: { [weak self] count, presentationData in
|
||||
self.badgeDisposable = (combineLatest(renderedTotalUnreadCount(accountManager: context.sharedContext.accountManager, engine: context.engine), self.presentationDataValue.get()) |> deliverOnMainQueue).startStrict(next: { [weak self] count, presentationData in
|
||||
if let strongSelf = self {
|
||||
if count.0 == 0 {
|
||||
strongSelf.tabBarItem.badgeValue = ""
|
||||
@ -404,7 +404,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
}).strict()
|
||||
|
||||
self.presentationDataDisposable = (context.sharedContext.presentationData
|
||||
|> deliverOnMainQueue).start(next: { [weak self] presentationData in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] presentationData in
|
||||
if let strongSelf = self {
|
||||
let previousTheme = strongSelf.presentationData.theme
|
||||
let previousStrings = strongSelf.presentationData.strings
|
||||
@ -500,7 +500,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
|
||||
if context.statusDisposable == nil {
|
||||
context.statusDisposable = (engine.account.postbox.mediaBox.resourceStatus(context.entry.resourceReference.resource)
|
||||
|> deliverOn(self.queue)).start(next: { [weak self, weak context] status in
|
||||
|> deliverOn(self.queue)).startStrict(next: { [weak self, weak context] status in
|
||||
guard let strongSelf = self, let context = context else {
|
||||
return
|
||||
}
|
||||
@ -603,7 +603,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
|> distinctUntilChanged
|
||||
|> deliverOnMainQueue)
|
||||
|
||||
self.activeDownloadsDisposable = stateSignal.start(next: { [weak self] state in
|
||||
self.activeDownloadsDisposable = stateSignal.startStrict(next: { [weak self] state in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -658,7 +658,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
return
|
||||
}
|
||||
strongSelf.clearUnseenDownloadsTimer = nil
|
||||
let _ = markAllRecentDownloadItemsAsSeen(postbox: strongSelf.context.account.postbox).start()
|
||||
let _ = markAllRecentDownloadItemsAsSeen(postbox: strongSelf.context.account.postbox).startStandalone()
|
||||
}, queue: .mainQueue())
|
||||
strongSelf.clearUnseenDownloadsTimer?.start()
|
||||
}
|
||||
@ -743,7 +743,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
return storiesConfiguration.posting
|
||||
}
|
||||
|> deliverOnMainQueue
|
||||
).start(next: { [weak self] postingAvailability in
|
||||
).startStrict(next: { [weak self] postingAvailability in
|
||||
if let self {
|
||||
self.storyPostingAvailability = postingAvailability
|
||||
self.storyPostingAvailabilityValue.set(postingAvailability)
|
||||
@ -1019,7 +1019,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
}
|
||||
} else {
|
||||
if case let .channel(channel) = peer, channel.flags.contains(.isForum), let threadId {
|
||||
let _ = strongSelf.context.sharedContext.navigateToForumThread(context: strongSelf.context, peerId: peer.id, threadId: threadId, messageId: nil, navigationController: navigationController, activateInput: nil, keepStack: .never).start()
|
||||
let _ = strongSelf.context.sharedContext.navigateToForumThread(context: strongSelf.context, peerId: peer.id, threadId: threadId, messageId: nil, navigationController: navigationController, activateInput: nil, keepStack: .never).startStandalone()
|
||||
strongSelf.chatListDisplayNode.clearHighlightAnimated(true)
|
||||
} else {
|
||||
var navigationAnimationOptions: NavigationAnimationOptions = []
|
||||
@ -1040,18 +1040,18 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
switch promoInfo {
|
||||
case .proxy:
|
||||
let _ = (ApplicationSpecificNotice.getProxyAdsAcknowledgment(accountManager: strongSelf.context.sharedContext.accountManager)
|
||||
|> deliverOnMainQueue).start(next: { value in
|
||||
|> deliverOnMainQueue).startStandalone(next: { value in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
if !value {
|
||||
controller.displayPromoAnnouncement(text: strongSelf.presentationData.strings.DialogList_AdNoticeAlert)
|
||||
let _ = ApplicationSpecificNotice.setProxyAdsAcknowledgment(accountManager: strongSelf.context.sharedContext.accountManager).start()
|
||||
let _ = ApplicationSpecificNotice.setProxyAdsAcknowledgment(accountManager: strongSelf.context.sharedContext.accountManager).startStandalone()
|
||||
}
|
||||
})
|
||||
case let .psa(type, _):
|
||||
let _ = (ApplicationSpecificNotice.getPsaAcknowledgment(accountManager: strongSelf.context.sharedContext.accountManager, peerId: peer.id)
|
||||
|> deliverOnMainQueue).start(next: { value in
|
||||
|> deliverOnMainQueue).startStandalone(next: { value in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -1065,7 +1065,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
}
|
||||
|
||||
controller.displayPromoAnnouncement(text: text)
|
||||
let _ = ApplicationSpecificNotice.setPsaAcknowledgment(accountManager: strongSelf.context.sharedContext.accountManager, peerId: peer.id).start()
|
||||
let _ = ApplicationSpecificNotice.setPsaAcknowledgment(accountManager: strongSelf.context.sharedContext.accountManager, peerId: peer.id).startStandalone()
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -1082,14 +1082,14 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
return
|
||||
}
|
||||
|
||||
let _ = self.context.engine.privacy.updateGlobalPrivacySettings().start()
|
||||
let _ = self.context.engine.privacy.updateGlobalPrivacySettings().startStandalone()
|
||||
let _ = (combineLatest(
|
||||
ApplicationSpecificNotice.displayChatListArchiveTooltip(accountManager: self.context.sharedContext.accountManager),
|
||||
self.context.engine.data.get(
|
||||
TelegramEngine.EngineData.Item.Configuration.GlobalPrivacy()
|
||||
)
|
||||
)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] didDisplayTip, settings in
|
||||
|> deliverOnMainQueue).startStandalone(next: { [weak self] didDisplayTip, settings in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
@ -1105,7 +1105,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
if !didDisplayTip {
|
||||
#if DEBUG
|
||||
#else
|
||||
let _ = ApplicationSpecificNotice.setDisplayChatListArchiveTooltip(accountManager: self.context.sharedContext.accountManager).start()
|
||||
let _ = ApplicationSpecificNotice.setDisplayChatListArchiveTooltip(accountManager: self.context.sharedContext.accountManager).startStandalone()
|
||||
#endif
|
||||
|
||||
self.push(ArchiveInfoScreen(context: self.context, settings: settings))
|
||||
@ -1121,7 +1121,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
strongSelf.archiveChats(peerIds: [peerId])
|
||||
} else {
|
||||
strongSelf.chatListDisplayNode.mainContainerNode.currentItemNode.setCurrentRemovingItemId(ChatListNodeState.ItemId(peerId: peerId, threadId: nil))
|
||||
let _ = strongSelf.context.engine.peers.updatePeersGroupIdInteractively(peerIds: [peerId], groupId: group ? .archive : .root).start(completed: {
|
||||
let _ = strongSelf.context.engine.peers.updatePeersGroupIdInteractively(peerIds: [peerId], groupId: group ? .archive : .root).startStandalone(completed: {
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -1133,7 +1133,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
self.chatListDisplayNode.requestOpenMessageFromSearch = { [weak self] peer, threadId, messageId, deactivateOnAction in
|
||||
if let strongSelf = self {
|
||||
strongSelf.openMessageFromSearchDisposable.set((strongSelf.context.engine.peers.ensurePeerIsLocallyAvailable(peer: peer)
|
||||
|> deliverOnMainQueue).start(next: { [weak strongSelf] actualPeer in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak strongSelf] actualPeer in
|
||||
if let strongSelf = strongSelf {
|
||||
if let navigationController = strongSelf.navigationController as? NavigationController {
|
||||
var scrollToEndIfExists = false
|
||||
@ -1145,7 +1145,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
navigationAnimationOptions = .removeOnMasterDetails
|
||||
}
|
||||
if case let .channel(channel) = actualPeer, channel.flags.contains(.isForum), let threadId {
|
||||
let _ = strongSelf.context.sharedContext.navigateToForumThread(context: strongSelf.context, peerId: peer.id, threadId: threadId, messageId: messageId, navigationController: navigationController, activateInput: nil, keepStack: .never).start()
|
||||
let _ = strongSelf.context.sharedContext.navigateToForumThread(context: strongSelf.context, peerId: peer.id, threadId: threadId, messageId: messageId, navigationController: navigationController, activateInput: nil, keepStack: .never).startStandalone()
|
||||
} else {
|
||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(actualPeer), subject: .message(id: .id(messageId), highlight: true, timecode: nil), purposefulAction: {
|
||||
if deactivateOnAction {
|
||||
@ -1163,7 +1163,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
self.chatListDisplayNode.requestOpenPeerFromSearch = { [weak self] peer, threadId, dismissSearch in
|
||||
if let strongSelf = self {
|
||||
let storedPeer = strongSelf.context.engine.peers.ensurePeerIsLocallyAvailable(peer: peer) |> map { _ -> Void in return Void() }
|
||||
strongSelf.openMessageFromSearchDisposable.set((storedPeer |> deliverOnMainQueue).start(completed: { [weak strongSelf] in
|
||||
strongSelf.openMessageFromSearchDisposable.set((storedPeer |> deliverOnMainQueue).startStrict(completed: { [weak strongSelf] in
|
||||
if let strongSelf = strongSelf {
|
||||
if dismissSearch {
|
||||
strongSelf.deactivateSearch(animated: true)
|
||||
@ -1178,7 +1178,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
navigationAnimationOptions = .removeOnMasterDetails
|
||||
}
|
||||
if case let .channel(channel) = peer, channel.flags.contains(.isForum), let threadId {
|
||||
let _ = strongSelf.context.sharedContext.navigateToForumThread(context: strongSelf.context, peerId: peer.id, threadId: threadId, messageId: nil, navigationController: navigationController, activateInput: nil, keepStack: .never).start()
|
||||
let _ = strongSelf.context.sharedContext.navigateToForumThread(context: strongSelf.context, peerId: peer.id, threadId: threadId, messageId: nil, navigationController: navigationController, activateInput: nil, keepStack: .never).startStandalone()
|
||||
} else {
|
||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(peer), purposefulAction: { [weak self] in
|
||||
self?.deactivateSearch(animated: false)
|
||||
@ -1202,7 +1202,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
actionSheet?.dismissAnimated()
|
||||
|
||||
if let strongSelf = self {
|
||||
let _ = strongSelf.context.engine.peers.removeRecentPeer(peerId: peer.id).start()
|
||||
let _ = strongSelf.context.engine.peers.removeRecentPeer(peerId: peer.id).startStandalone()
|
||||
}
|
||||
})
|
||||
]),
|
||||
@ -1255,8 +1255,8 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
controller?.isInProgress = true
|
||||
|
||||
let _ = (context.engine.peers.createForumChannelTopic(id: peerId, title: title, iconColor: iconColor, iconFileId: fileId)
|
||||
|> deliverOnMainQueue).start(next: { topicId in
|
||||
let _ = context.sharedContext.navigateToForumThread(context: context, peerId: peerId, threadId: topicId, messageId: nil, navigationController: navigationController, activateInput: .text, keepStack: .never).start()
|
||||
|> deliverOnMainQueue).startStandalone(next: { topicId in
|
||||
let _ = context.sharedContext.navigateToForumThread(context: context, peerId: peerId, threadId: topicId, messageId: nil, navigationController: navigationController, activateInput: .text, keepStack: .never).startStandalone()
|
||||
}, error: { _ in
|
||||
controller?.isInProgress = false
|
||||
})
|
||||
@ -1515,7 +1515,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
TelegramEngine.EngineData.Item.Configuration.UserLimits(isPremium: true)
|
||||
),
|
||||
filterPeersAreMuted
|
||||
).start(next: { [weak self] filters, premiumLimits, filterPeersAreMuted in
|
||||
).startStandalone(next: { [weak self] filters, premiumLimits, filterPeersAreMuted in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -1542,7 +1542,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
strongSelf.push(controller)
|
||||
} else {
|
||||
let _ = (strongSelf.context.engine.peers.currentChatListFilters()
|
||||
|> deliverOnMainQueue).start(next: { presetList in
|
||||
|> deliverOnMainQueue).startStandalone(next: { presetList in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -1593,7 +1593,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
TelegramEngine.EngineData.Item.Configuration.UserLimits(isPremium: true)
|
||||
),
|
||||
strongSelf.context.engine.peers.currentChatListFilters()
|
||||
).start(next: { result, presetList in
|
||||
).startStandalone(next: { result, presetList in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -1629,7 +1629,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
}
|
||||
|
||||
let _ = (strongSelf.context.engine.peers.currentChatListFilters()
|
||||
|> deliverOnMainQueue).start(next: { filters in
|
||||
|> deliverOnMainQueue).startStandalone(next: { filters in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -1683,7 +1683,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
}
|
||||
|
||||
let _ = (strongSelf.context.engine.peers.updateMultiplePeerMuteSettings(peerIds: filterPeersAreMuted.peerIds, muted: !filterPeersAreMuted.areMuted)
|
||||
|> deliverOnMainQueue).start(completed: {
|
||||
|> deliverOnMainQueue).startStandalone(completed: {
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -1837,7 +1837,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
self.context.sharedContext.automaticMediaDownloadSettings,
|
||||
automaticDownloadNetworkType
|
||||
)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] resources, automaticMediaDownloadSettings, automaticDownloadNetworkType in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] resources, automaticMediaDownloadSettings, automaticDownloadNetworkType in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
@ -1857,7 +1857,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
if let mediaId = info.media.id {
|
||||
validIds.append(mediaId)
|
||||
if self.preloadStoryResourceDisposables[mediaId] == nil {
|
||||
self.preloadStoryResourceDisposables[mediaId] = preloadStoryMedia(context: self.context, peer: info.peer, storyId: info.storyId, media: info.media, reactions: info.reactions).start()
|
||||
self.preloadStoryResourceDisposables[mediaId] = preloadStoryMedia(context: self.context, peer: info.peer, storyId: info.storyId, media: info.media, reactions: info.reactions).startStrict()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1878,7 +1878,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
self.storiesReady.set(.single(true))
|
||||
} else {
|
||||
self.storySubscriptionsDisposable = (self.context.engine.messages.storySubscriptions(isHidden: self.location == .chatList(groupId: .archive))
|
||||
|> deliverOnMainQueue).start(next: { [weak self] rawStorySubscriptions in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] rawStorySubscriptions in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
@ -1929,7 +1929,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
})
|
||||
})
|
||||
self.storyProgressDisposable = (self.context.engine.messages.allStoriesUploadProgress()
|
||||
|> deliverOnMainQueue).start(next: { [weak self] progress in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] progress in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
@ -1938,7 +1938,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
|
||||
if case .chatList(.root) = self.location {
|
||||
self.storyArchiveSubscriptionsDisposable = (self.context.engine.messages.storySubscriptions(isHidden: true)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] rawStoryArchiveSubscriptions in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] rawStoryArchiveSubscriptions in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
@ -2007,7 +2007,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
|
||||
if case .chatList(groupId: .root) = self.location, let orderedStorySubscriptions = self.orderedStorySubscriptions, !orderedStorySubscriptions.items.isEmpty {
|
||||
let _ = (ApplicationSpecificNotice.displayChatListStoriesTooltip(accountManager: self.context.sharedContext.accountManager)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] didDisplay in
|
||||
|> deliverOnMainQueue).startStandalone(next: { [weak self] didDisplay in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
@ -2046,7 +2046,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
self.present(tooltipScreen, in: .current)
|
||||
|
||||
#if !DEBUG
|
||||
let _ = ApplicationSpecificNotice.setDisplayChatListStoriesTooltip(accountManager: self.context.sharedContext.accountManager).start()
|
||||
let _ = ApplicationSpecificNotice.setDisplayChatListStoriesTooltip(accountManager: self.context.sharedContext.accountManager).startStandalone()
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@ -2072,7 +2072,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
|> mapToSignal { settings -> Signal<Bool, NoError> in
|
||||
return automaticEnergyUsageShouldBeOn(settings: settings)
|
||||
}
|
||||
|> distinctUntilChanged).start(next: { [weak self] isPowerSavingEnabled in
|
||||
|> distinctUntilChanged).startStrict(next: { [weak self] isPowerSavingEnabled in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
@ -2098,7 +2098,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
var settings = settings
|
||||
settings.energyUsageSettings.activationThreshold = 4
|
||||
return settings
|
||||
}).start()
|
||||
}).startStandalone()
|
||||
}
|
||||
return false
|
||||
}), in: .current)
|
||||
@ -2155,7 +2155,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
let _ = (self.chatListDisplayNode.mainContainerNode.ready
|
||||
|> filter { $0 }
|
||||
|> take(1)
|
||||
|> timeout(0.5, queue: .mainQueue(), alternate: .single(true))).start(next: { [weak self] _ in
|
||||
|> timeout(0.5, queue: .mainQueue(), alternate: .single(true))).startStandalone(next: { [weak self] _ in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
@ -2179,12 +2179,12 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
#endif
|
||||
|
||||
if let componentView = self.chatListHeaderView(), let storyPeerListView = componentView.storyPeerListView(), let _ = storyPeerListView.lockViewFrame(), !self.didShowPasscodeLockTooltipController, !"".isEmpty {
|
||||
self.passcodeLockTooltipDisposable.set(combineLatest(queue: .mainQueue(), ApplicationSpecificNotice.getPasscodeLockTips(accountManager: self.context.sharedContext.accountManager), self.context.sharedContext.accountManager.accessChallengeData() |> take(1)).start(next: { [weak self] tooltipValue, passcodeView in
|
||||
self.passcodeLockTooltipDisposable.set(combineLatest(queue: .mainQueue(), ApplicationSpecificNotice.getPasscodeLockTips(accountManager: self.context.sharedContext.accountManager), self.context.sharedContext.accountManager.accessChallengeData() |> take(1)).startStrict(next: { [weak self] tooltipValue, passcodeView in
|
||||
if let strongSelf = self {
|
||||
if !tooltipValue {
|
||||
let hasPasscode = passcodeView.data.isLockable
|
||||
if hasPasscode {
|
||||
let _ = ApplicationSpecificNotice.setPasscodeLockTips(accountManager: strongSelf.context.sharedContext.accountManager).start()
|
||||
let _ = ApplicationSpecificNotice.setPasscodeLockTips(accountManager: strongSelf.context.sharedContext.accountManager).startStandalone()
|
||||
|
||||
let tooltipController = TooltipController(content: .text(strongSelf.presentationData.strings.DialogList_PasscodeLockHelp), baseFontSize: strongSelf.presentationData.listsFontSize.baseDisplaySize, dismissByTapOutside: true)
|
||||
strongSelf.present(tooltipController, in: .window(.root), with: TooltipControllerPresentationArguments(sourceViewAndRect: { [weak self] in
|
||||
@ -2237,7 +2237,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
})
|
||||
})
|
||||
|
||||
self.suggestLocalizationDisposable.set((signal |> deliverOnMainQueue).start(next: { [weak self] suggestedLocalization in
|
||||
self.suggestLocalizationDisposable.set((signal |> deliverOnMainQueue).startStrict(next: { [weak self] suggestedLocalization in
|
||||
guard let strongSelf = self, let (currentLanguageCode, suggestedLocalization) = suggestedLocalization else {
|
||||
return
|
||||
}
|
||||
@ -2248,12 +2248,12 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
}
|
||||
}) {
|
||||
strongSelf.present(controller, in: .window(.root))
|
||||
_ = strongSelf.context.engine.localization.markSuggestedLocalizationAsSeenInteractively(languageCode: suggestedLocalization.languageCode).start()
|
||||
_ = strongSelf.context.engine.localization.markSuggestedLocalizationAsSeenInteractively(languageCode: suggestedLocalization.languageCode).startStandalone()
|
||||
}
|
||||
}))
|
||||
|
||||
self.suggestAutoarchiveDisposable.set((getServerProvidedSuggestions(account: self.context.account)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] values in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] values in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -2269,13 +2269,13 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
strongSelf.dismissAutoarchiveDisposable.set(dismissServerProvidedSuggestion(account: strongSelf.context.account, suggestion: .autoarchivePopular).start())
|
||||
strongSelf.dismissAutoarchiveDisposable.set(dismissServerProvidedSuggestion(account: strongSelf.context.account, suggestion: .autoarchivePopular).startStrict())
|
||||
}),
|
||||
TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.ChatList_AutoarchiveSuggestion_OpenSettings, action: {
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
strongSelf.dismissAutoarchiveDisposable.set(dismissServerProvidedSuggestion(account: strongSelf.context.account, suggestion: .autoarchivePopular).start())
|
||||
strongSelf.dismissAutoarchiveDisposable.set(dismissServerProvidedSuggestion(account: strongSelf.context.account, suggestion: .autoarchivePopular).startStrict())
|
||||
strongSelf.push(strongSelf.context.sharedContext.makePrivacyAndSecurityController(context: strongSelf.context))
|
||||
})
|
||||
], actionLayout: .vertical, parseMarkdown: true), in: .window(.root))
|
||||
@ -2295,7 +2295,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
return (phoneNumber, entry?.get(ApplicationSpecificCounterNotice.self)?.value)
|
||||
}
|
||||
|> deliverOnMainQueue
|
||||
).start(next: { [weak self] phoneNumber, value in
|
||||
).startStandalone(next: { [weak self] phoneNumber, value in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -2321,7 +2321,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
}),
|
||||
TextAlertAction(type: .destructiveAction, title: strongSelf.presentationData.strings.ForcedPasswordSetup_Intro_DismissActionOK, action: { [weak controller] in
|
||||
if let strongSelf = self {
|
||||
let _ = ApplicationSpecificNotice.setForcedPasswordSetup(engine: strongSelf.context.engine, reloginDaysTimeout: nil).start()
|
||||
let _ = ApplicationSpecificNotice.setForcedPasswordSetup(engine: strongSelf.context.engine, reloginDaysTimeout: nil).startStandalone()
|
||||
}
|
||||
controller?.dismiss()
|
||||
})
|
||||
@ -2415,7 +2415,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
|> take(1)
|
||||
|> delay(1.0, queue: .mainQueue())
|
||||
|> deliverOnMainQueue
|
||||
).start(next: { [weak self] hasFeatured, hasFilters in
|
||||
).startStrict(next: { [weak self] hasFeatured, hasFilters in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -2424,7 +2424,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
if hasFeatured {
|
||||
if let _ = strongSelf.validLayout, let _ = strongSelf.parent as? TabBarController {
|
||||
let _ = (ApplicationSpecificNotice.incrementChatFolderTips(accountManager: strongSelf.context.sharedContext.accountManager)
|
||||
|> deliverOnMainQueue).start(next: { count in
|
||||
|> deliverOnMainQueue).startStandalone(next: { count in
|
||||
guard let strongSelf = self, let _ = strongSelf.validLayout, let parentController = strongSelf.parent as? TabBarController, let sourceFrame = parentController.frameForControllerTab(controller: strongSelf) else {
|
||||
return
|
||||
}
|
||||
@ -2436,7 +2436,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
let text: String
|
||||
if hasFilters {
|
||||
text = strongSelf.presentationData.strings.ChatList_TabIconFoldersTooltipNonEmptyFolders
|
||||
let _ = strongSelf.context.engine.peers.markChatListFeaturedFiltersAsSeen().start()
|
||||
let _ = strongSelf.context.engine.peers.markChatListFeaturedFiltersAsSeen().startStandalone()
|
||||
return
|
||||
} else {
|
||||
text = strongSelf.presentationData.strings.ChatList_TabIconFoldersTooltipEmptyFolders
|
||||
@ -2794,7 +2794,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
TelegramEngine.EngineData.Item.NotificationSettings.Global(),
|
||||
TelegramEngine.EngineData.Item.Contacts.Top()
|
||||
)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] notificationSettings, globalSettings, topSearchPeers in
|
||||
|> deliverOnMainQueue).startStandalone(next: { [weak self] notificationSettings, globalSettings, topSearchPeers in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
@ -2853,7 +2853,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
let _ = (self.context.engine.data.get(
|
||||
TelegramEngine.EngineData.Item.Peer.Peer(id: peer.id)
|
||||
)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] peer in
|
||||
|> deliverOnMainQueue).startStandalone(next: { [weak self] peer in
|
||||
guard let self, let peer else {
|
||||
return
|
||||
}
|
||||
@ -2934,7 +2934,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
let _ = (self.context.engine.data.get(
|
||||
TelegramEngine.EngineData.Item.Peer.Peer(id: peer.id)
|
||||
)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] peer in
|
||||
|> deliverOnMainQueue).startStandalone(next: { [weak self] peer in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
@ -2955,7 +2955,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
let _ = self.context.engine.peers.togglePeerStoriesMuted(peerId: peer.id).start()
|
||||
let _ = self.context.engine.peers.togglePeerStoriesMuted(peerId: peer.id).startStandalone()
|
||||
|
||||
let iconColor = UIColor.white
|
||||
let presentationData = self.context.sharedContext.currentPresentationData.with { $0 }
|
||||
@ -3245,7 +3245,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
})
|
||||
return updatedFilters
|
||||
}
|
||||
|> deliverOnMainQueue).start(completed: { [weak self] in
|
||||
|> deliverOnMainQueue).startStandalone(completed: { [weak self] in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -3276,7 +3276,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
let _ = (pendingSecondaryContext.ready.get()
|
||||
|> filter { $0 }
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(next: { [weak self, weak pendingSecondaryContext] _ in
|
||||
|> deliverOnMainQueue).startStandalone(next: { [weak self, weak pendingSecondaryContext] _ in
|
||||
guard let self, let pendingSecondaryContext = pendingSecondaryContext, self.pendingSecondaryContext === pendingSecondaryContext else {
|
||||
return
|
||||
}
|
||||
@ -3308,7 +3308,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
|
||||
public static func openMoreMenu(context: AccountContext, peerId: EnginePeer.Id, sourceController: ViewController, isViewingAsTopics: Bool, sourceView: UIView, gesture: ContextGesture?) {
|
||||
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|
||||
|> deliverOnMainQueue).start(next: { peer in
|
||||
|> deliverOnMainQueue).startStandalone(next: { peer in
|
||||
guard case let .channel(channel) = peer else {
|
||||
return
|
||||
}
|
||||
@ -3381,7 +3381,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
let _ = (context.engine.data.get(
|
||||
TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)
|
||||
)
|
||||
|> deliverOnMainQueue).start(next: { peer in
|
||||
|> deliverOnMainQueue).startStandalone(next: { peer in
|
||||
guard let sourceController = sourceController, let peer = peer, let controller = context.sharedContext.makePeerInfoController(context: context, updatedPresentationData: nil, peer: peer._asPeer(), mode: .generic, avatarInitiallyExpanded: false, fromChat: false, requestsContext: nil) else {
|
||||
return
|
||||
}
|
||||
@ -3396,7 +3396,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
f(.default)
|
||||
|
||||
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|
||||
|> deliverOnMainQueue).start(next: { peer in
|
||||
|> deliverOnMainQueue).startStandalone(next: { peer in
|
||||
guard let sourceController = sourceController, let peer = peer else {
|
||||
return
|
||||
}
|
||||
@ -3431,9 +3431,9 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
controller?.isInProgress = true
|
||||
|
||||
let _ = (context.engine.peers.createForumChannelTopic(id: peerId, title: title, iconColor: iconColor, iconFileId: fileId)
|
||||
|> deliverOnMainQueue).start(next: { topicId in
|
||||
|> deliverOnMainQueue).startStandalone(next: { topicId in
|
||||
if let navigationController = (sourceController.navigationController as? NavigationController) {
|
||||
let _ = context.sharedContext.navigateToForumThread(context: context, peerId: peerId, threadId: topicId, messageId: nil, navigationController: navigationController, activateInput: .text, keepStack: .never).start()
|
||||
let _ = context.sharedContext.navigateToForumThread(context: context, peerId: peerId, threadId: topicId, messageId: nil, navigationController: navigationController, activateInput: .text, keepStack: .never).startStandalone()
|
||||
}
|
||||
}, error: { _ in
|
||||
controller?.isInProgress = false
|
||||
@ -3450,11 +3450,11 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
}
|
||||
|
||||
func openArchiveMoreMenu(sourceView: UIView, gesture: ContextGesture?) {
|
||||
let _ = self.context.engine.privacy.updateGlobalPrivacySettings().start()
|
||||
let _ = self.context.engine.privacy.updateGlobalPrivacySettings().startStandalone()
|
||||
|
||||
let _ = (
|
||||
self.context.engine.messages.chatList(group: .archive, count: 10) |> take(1)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] archiveChatList in
|
||||
|> deliverOnMainQueue).startStandalone(next: { [weak self] archiveChatList in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
@ -3485,7 +3485,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
let _ = (self.context.engine.data.get(
|
||||
TelegramEngine.EngineData.Item.Configuration.GlobalPrivacy()
|
||||
)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] settings in
|
||||
|> deliverOnMainQueue).startStandalone(next: { [weak self] settings in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
@ -3518,7 +3518,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
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, peerView, limits in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] countAndFilterItems, peerView, limits in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -3665,7 +3665,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
}
|
||||
|
||||
let _ = (self.context.engine.peers.currentChatListFilters()
|
||||
|> deliverOnMainQueue).start(next: { [weak self] filters in
|
||||
|> deliverOnMainQueue).startStandalone(next: { [weak self] filters in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -3710,7 +3710,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
markItems.append((EngineChatList.Group(additionalGroupId), filterPredicate))
|
||||
}
|
||||
|
||||
let _ = self.context.engine.messages.markAllChatsAsReadInteractively(items: markItems).start()
|
||||
let _ = self.context.engine.messages.markAllChatsAsReadInteractively(items: markItems).startStandalone()
|
||||
break
|
||||
}
|
||||
}
|
||||
@ -3786,7 +3786,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
return true
|
||||
}
|
||||
|> timeout(1.0, queue: .mainQueue(), alternate: .single(false))
|
||||
|> deliverOnMainQueue).start(next: { [weak self] _ in
|
||||
|> deliverOnMainQueue).startStandalone(next: { [weak self] _ in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
@ -3834,7 +3834,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
}
|
||||
}
|
||||
|
||||
self.sharedOpenStoryProgressDisposable.set((signal |> deliverOnMainQueue).start(completed: { [weak self] in
|
||||
self.sharedOpenStoryProgressDisposable.set((signal |> deliverOnMainQueue).startStrict(completed: { [weak self] in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
@ -3856,7 +3856,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
self.sharedOpenStoryProgressDisposable.set(signal.start())
|
||||
self.sharedOpenStoryProgressDisposable.set(signal.startStrict())
|
||||
}
|
||||
)
|
||||
}))
|
||||
@ -3977,7 +3977,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
let storyContent = StoryContentContextImpl(context: self.context, isHidden: self.location == .chatList(groupId: .archive), focusedPeerId: peerId, singlePeer: false, fixedOrder: self.fixedStorySubscriptionOrder)
|
||||
let _ = (storyContent.state
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] storyContentState in
|
||||
|> deliverOnMainQueue).startStandalone(next: { [weak self] storyContentState in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
@ -4058,7 +4058,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
|
||||
let _ = (strongSelf.context.engine.peers.updateChatListFiltersInteractively { filters in
|
||||
return filters.filter({ $0.id != id })
|
||||
}).start()
|
||||
}).startStandalone()
|
||||
}
|
||||
|
||||
if strongSelf.chatListDisplayNode.mainContainerNode.currentItemNode.chatListFilter?.id == id {
|
||||
@ -4072,7 +4072,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
|
||||
let _ = (self.context.engine.peers.currentChatListFilters()
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] filters in
|
||||
|> deliverOnMainQueue).startStandalone(next: { [weak self] filters in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
@ -4089,7 +4089,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
self.context.engine.peers.getExportedChatFolderLinks(id: id),
|
||||
self.context.engine.peers.requestLeaveChatFolderSuggestions(folderId: id)
|
||||
)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] peerData, links, defaultSelectedPeerIds in
|
||||
|> deliverOnMainQueue).startStandalone(next: { [weak self] peerData, links, defaultSelectedPeerIds in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
@ -4224,7 +4224,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
//TODO:scroll to top?
|
||||
|
||||
let _ = (combineLatest(self.chatListDisplayNode.mainContainerNode.currentItemNode.contentsReady |> take(1), self.context.account.postbox.tailChatListView(groupId: .root, count: 16, summaryComponents: ChatListEntrySummaryComponents(components: [:])) |> take(1))
|
||||
|> deliverOnMainQueue).start(next: { [weak self] _, chatListView in
|
||||
|> deliverOnMainQueue).startStandalone(next: { [weak self] _, chatListView in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -4477,7 +4477,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
signal = .complete()
|
||||
}
|
||||
let _ = (signal
|
||||
|> deliverOnMainQueue).start(completed: { [weak self] in
|
||||
|> deliverOnMainQueue).startStandalone(completed: { [weak self] in
|
||||
self?.donePressed()
|
||||
completion?()
|
||||
})
|
||||
@ -4663,7 +4663,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
if !peerIds.isEmpty {
|
||||
self.chatListDisplayNode.effectiveContainerNode.currentItemNode.setCurrentRemovingItemId(ChatListNodeState.ItemId(peerId: peerIds.first!, threadId: nil))
|
||||
let _ = (self.context.engine.peers.updatePeersGroupIdInteractively(peerIds: Array(peerIds), groupId: .root)
|
||||
|> deliverOnMainQueue).start(completed: { [weak self] in
|
||||
|> deliverOnMainQueue).startStandalone(completed: { [weak self] in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -4696,12 +4696,12 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
}
|
||||
|
||||
self.joinForumDisposable.set((signal
|
||||
|> deliverOnMainQueue).start(error: { [weak self] error in
|
||||
|> deliverOnMainQueue).startStrict(error: { [weak self] error in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
let _ = (strongSelf.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|
||||
|> deliverOnMainQueue).start(next: { peer in
|
||||
|> deliverOnMainQueue).startStandalone(next: { peer in
|
||||
guard let strongSelf = self, let peer = peer else {
|
||||
return
|
||||
}
|
||||
@ -4744,7 +4744,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
updatedValue = settings.isHiddenByDefault
|
||||
return settings
|
||||
})
|
||||
|> deliverOnMainQueue).start(completed: { [weak self] in
|
||||
|> deliverOnMainQueue).startStandalone(completed: { [weak self] in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -4773,7 +4773,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
var settings = settings
|
||||
settings.isHiddenByDefault = false
|
||||
return settings
|
||||
}).start()
|
||||
}).startStandalone()
|
||||
|
||||
return true
|
||||
}
|
||||
@ -4794,12 +4794,12 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
return state
|
||||
}
|
||||
|
||||
let _ = hideAccountPromoInfoChat(account: self.context.account, peerId: id).start()
|
||||
let _ = hideAccountPromoInfoChat(account: self.context.account, peerId: id).startStandalone()
|
||||
}
|
||||
|
||||
func deletePeerChat(peerId: PeerId, joined: Bool) {
|
||||
let _ = (self.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.RenderedPeer(id: peerId))
|
||||
|> deliverOnMainQueue).start(next: { [weak self] peer in
|
||||
|> deliverOnMainQueue).startStandalone(next: { [weak self] peer in
|
||||
guard let strongSelf = self, let peer = peer, let chatPeer = peer.peers[peer.peerId], let mainPeer = peer.chatMainPeer else {
|
||||
return
|
||||
}
|
||||
@ -4921,7 +4921,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
let _ = strongSelf.context.engine.privacy.requestUpdatePeerIsBlocked(peerId: peer.peerId, isBlocked: true).start()
|
||||
let _ = strongSelf.context.engine.privacy.requestUpdatePeerIsBlocked(peerId: peer.peerId, isBlocked: true).startStandalone()
|
||||
})
|
||||
}
|
||||
}))
|
||||
@ -4949,7 +4949,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
return false
|
||||
}
|
||||
if value == .commit {
|
||||
let _ = strongSelf.context.engine.messages.clearHistoryInteractively(peerId: peerId, threadId: nil, type: type).start(completed: {
|
||||
let _ = strongSelf.context.engine.messages.clearHistoryInteractively(peerId: peerId, threadId: nil, type: type).startStandalone(completed: {
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -5173,7 +5173,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
if value == .commit {
|
||||
self.chatListDisplayNode.effectiveContainerNode.currentItemNode.setCurrentRemovingItemId(ChatListNodeState.ItemId(peerId: peerId, threadId: threadId))
|
||||
|
||||
let _ = self.context.engine.peers.removeForumChannelThread(id: peerId, threadId: threadId).start(completed: { [weak self] in
|
||||
let _ = self.context.engine.peers.removeForumChannelThread(id: peerId, threadId: threadId).startStandalone(completed: { [weak self] in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
@ -5208,16 +5208,16 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
}
|
||||
|
||||
private func setPeerThreadStopped(peerId: EnginePeer.Id, threadId: Int64, isStopped: Bool) {
|
||||
self.actionDisposables.add(self.context.engine.peers.setForumChannelTopicClosed(id: peerId, threadId: threadId, isClosed: isStopped).start())
|
||||
self.actionDisposables.add(self.context.engine.peers.setForumChannelTopicClosed(id: peerId, threadId: threadId, isClosed: isStopped).startStrict())
|
||||
}
|
||||
|
||||
private func setPeerThreadPinned(peerId: EnginePeer.Id, threadId: Int64, isPinned: Bool) {
|
||||
self.actionDisposables.add(self.context.engine.peers.toggleForumChannelTopicPinned(id: peerId, threadId: threadId).start())
|
||||
self.actionDisposables.add(self.context.engine.peers.toggleForumChannelTopicPinned(id: peerId, threadId: threadId).startStrict())
|
||||
}
|
||||
|
||||
private func setPeerThreadHidden(peerId: EnginePeer.Id, threadId: Int64, isHidden: Bool) {
|
||||
self.actionDisposables.add((self.context.engine.peers.setForumChannelTopicHidden(id: peerId, threadId: threadId, isHidden: isHidden)
|
||||
|> deliverOnMainQueue).start(completed: { [weak self] in
|
||||
|> deliverOnMainQueue).startStrict(completed: { [weak self] in
|
||||
if let strongSelf = self {
|
||||
strongSelf.chatListDisplayNode.effectiveContainerNode.updateState { state in
|
||||
var state = state
|
||||
@ -5350,9 +5350,9 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
ApplicationSpecificNotice.incrementArchiveChatTips(accountManager: self.context.sharedContext.accountManager, count: 1),
|
||||
hasArchived
|
||||
)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] previousHintCount, hasArchived in
|
||||
|> deliverOnMainQueue).startStandalone(next: { [weak self] previousHintCount, hasArchived in
|
||||
let _ = (engine.peers.updatePeersGroupIdInteractively(peerIds: peerIds, groupId: .archive)
|
||||
|> deliverOnMainQueue).start(completed: {
|
||||
|> deliverOnMainQueue).startStandalone(completed: {
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -5369,7 +5369,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
if value == .undo {
|
||||
strongSelf.chatListDisplayNode.effectiveContainerNode.currentItemNode.setCurrentRemovingItemId(ChatListNodeState.ItemId(peerId: peerIds[0], threadId: nil))
|
||||
let _ = (engine.peers.updatePeersGroupIdInteractively(peerIds: peerIds, groupId: .root)
|
||||
|> deliverOnMainQueue).start(completed: {
|
||||
|> deliverOnMainQueue).startStandalone(completed: {
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -5472,7 +5472,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
if case let .channel(channel) = chatPeer {
|
||||
strongSelf.context.peerChannelMemberCategoriesContextsManager.externallyRemoved(peerId: channel.id, memberId: strongSelf.context.account.peerId)
|
||||
}
|
||||
let _ = strongSelf.context.engine.peers.removePeerChat(peerId: peerId, reportChatSpam: false, deleteGloballyIfPossible: deleteGloballyIfPossible).start(completed: {
|
||||
let _ = strongSelf.context.engine.peers.removePeerChat(peerId: peerId, reportChatSpam: false, deleteGloballyIfPossible: deleteGloballyIfPossible).startStandalone(completed: {
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -5549,7 +5549,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
TelegramEngine.EngineData.Item.Configuration.UserLimits(isPremium: true)
|
||||
)
|
||||
)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] presetList, filterItemsAndTotalCount, result in
|
||||
|> deliverOnMainQueue).startStandalone(next: { [weak self] presetList, filterItemsAndTotalCount, result in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -5557,7 +5557,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
let (accountPeer, limits, _) = result
|
||||
let isPremium = accountPeer?.isPremium ?? false
|
||||
|
||||
let _ = strongSelf.context.engine.peers.markChatListFeaturedFiltersAsSeen().start()
|
||||
let _ = strongSelf.context.engine.peers.markChatListFeaturedFiltersAsSeen().startStandalone()
|
||||
let (_, filterItems) = filterItemsAndTotalCount
|
||||
|
||||
var items: [ContextMenuItem] = []
|
||||
@ -5948,7 +5948,7 @@ private final class ChatListLocationContext {
|
||||
peerStatus,
|
||||
parentController.updatedPresentationData.1,
|
||||
storyPostingAvailable
|
||||
).start(next: { [weak self] networkState, proxy, passcode, stateAndFilterId, isReorderingTabs, peerStatus, presentationData, storyPostingAvailable in
|
||||
).startStrict(next: { [weak self] networkState, proxy, passcode, stateAndFilterId, isReorderingTabs, peerStatus, presentationData, storyPostingAvailable in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
@ -6010,7 +6010,7 @@ private final class ChatListLocationContext {
|
||||
containerNode.currentItemState,
|
||||
parentController.updatedPresentationData.1
|
||||
)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] peerView, onlineMemberCount, stateAndFilterId, presentationData in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] peerView, onlineMemberCount, stateAndFilterId, presentationData in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
@ -6078,7 +6078,7 @@ private final class ChatListLocationContext {
|
||||
parentController.updatedPresentationData.1,
|
||||
peerIdsAndOptions,
|
||||
peerView
|
||||
).start(next: { [weak self, weak containerNode] presentationData, peerIdsAndOptions, peerView in
|
||||
).startStrict(next: { [weak self, weak containerNode] presentationData, peerIdsAndOptions, peerView in
|
||||
guard let strongSelf = self, let containerNode = containerNode, let parentController = strongSelf.parentController else {
|
||||
return
|
||||
}
|
||||
@ -6433,7 +6433,7 @@ private final class ChatListLocationContext {
|
||||
let _ = (self.context.engine.data.get(
|
||||
TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)
|
||||
)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] peer in
|
||||
|> deliverOnMainQueue).startStandalone(next: { [weak self] peer in
|
||||
guard let self, let peer = peer, let controller = self.context.sharedContext.makePeerInfoController(context: self.context, updatedPresentationData: nil, peer: peer._asPeer(), mode: .generic, avatarInitiallyExpanded: false, fromChat: false, requestsContext: nil) else {
|
||||
return
|
||||
}
|
||||
|
@ -796,7 +796,7 @@ public final class ChatListContainerNode: ASDisplayNode, UIGestureRecognizerDele
|
||||
|
||||
disposable.set((itemNode.listNode.ready
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(next: { [weak self, weak itemNode] _ in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self, weak itemNode] _ in
|
||||
guard let strongSelf = self, let itemNode = itemNode, itemNode === strongSelf.pendingItemNode?.1 else {
|
||||
return
|
||||
}
|
||||
|
@ -136,12 +136,12 @@ final class ChatListEmptyNode: ASDisplayNode {
|
||||
self.animationNode.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.animationTapGesture(_:))))
|
||||
|
||||
if case .archive = subject {
|
||||
let _ = self.context.engine.privacy.updateGlobalPrivacySettings().start()
|
||||
let _ = self.context.engine.privacy.updateGlobalPrivacySettings().startStandalone()
|
||||
|
||||
self.archiveSettingsDisposable = (context.engine.data.subscribe(
|
||||
TelegramEngine.EngineData.Item.Configuration.GlobalPrivacy()
|
||||
)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] settings in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] settings in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
@ -149,7 +149,7 @@ final class ChatListEmptyNode: ASDisplayNode {
|
||||
if let (size, insets) = self.validLayout {
|
||||
self.updateLayout(size: size, insets: insets, transition: .immediate)
|
||||
}
|
||||
}).strict()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -481,7 +481,7 @@ public func chatListFilterPresetListController(context: AccountContext, mode: Ch
|
||||
}
|
||||
return filters
|
||||
}
|
||||
|> deliverOnMainQueue).start()
|
||||
|> deliverOnMainQueue).startStandalone()
|
||||
})
|
||||
]),
|
||||
ActionSheetItemGroup(items: [
|
||||
@ -541,7 +541,7 @@ public func chatListFilterPresetListController(context: AccountContext, mode: Ch
|
||||
rightNavigationButton = ItemListNavigationButton(content: .text(presentationData.strings.Common_Done), style: .bold, enabled: true, action: {
|
||||
let _ = (updatedFilterOrder.get()
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(next: { [weak updatedFilterOrder] updatedFilterOrderValue in
|
||||
|> deliverOnMainQueue).startStandalone(next: { [weak updatedFilterOrder] updatedFilterOrderValue in
|
||||
if let updatedFilterOrderValue = updatedFilterOrderValue {
|
||||
let _ = (context.engine.peers.updateChatListFiltersInteractively { filters in
|
||||
var updatedFilters: [ChatListFilter] = []
|
||||
|
@ -225,7 +225,7 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo
|
||||
return
|
||||
}
|
||||
let _ = (strongSelf.context.engine.peers.clearRecentlySearchedPeers()
|
||||
|> deliverOnMainQueue).start()
|
||||
|> deliverOnMainQueue).startStandalone()
|
||||
})
|
||||
]), ActionSheetItemGroup(items: [
|
||||
ActionSheetButtonItem(title: presentationData.strings.Common_Cancel, color: .accent, font: .bold, action: { [weak actionSheet] in
|
||||
@ -467,7 +467,8 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo
|
||||
}
|
||||
}
|
||||
return suggestedFilters
|
||||
} |> deliverOnMainQueue).start(next: { [weak self] filters in
|
||||
}
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] filters in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -492,7 +493,7 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo
|
||||
}))
|
||||
|
||||
self.presentationDataDisposable = ((updatedPresentationData?.signal ?? context.sharedContext.presentationData)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] presentationData in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] presentationData in
|
||||
if let strongSelf = self {
|
||||
let previousTheme = strongSelf.presentationData.theme
|
||||
strongSelf.presentationData = presentationData
|
||||
@ -505,7 +506,7 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo
|
||||
|
||||
if case let .forum(peerId) = location {
|
||||
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|
||||
|> deliverOnMainQueue).start(next: { [weak self] peer in
|
||||
|> deliverOnMainQueue).startStandalone(next: { [weak self] peer in
|
||||
self?.forumPeer = peer
|
||||
self?.updateSearchOptions(nil)
|
||||
})
|
||||
@ -736,7 +737,7 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo
|
||||
}
|
||||
return messages
|
||||
}
|
||||
|> deliverOnMainQueue).start(next: { messages in
|
||||
|> deliverOnMainQueue).startStandalone(next: { messages in
|
||||
if let strongSelf = self, !messages.isEmpty {
|
||||
let shareController = ShareController(context: strongSelf.context, subject: .messages(messages.sorted(by: { lhs, rhs in
|
||||
return lhs.index < rhs.index
|
||||
@ -768,7 +769,7 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo
|
||||
}
|
||||
return messages
|
||||
}
|
||||
|> deliverOnMainQueue).start(next: { messages in
|
||||
|> deliverOnMainQueue).startStandalone(next: { messages in
|
||||
if let strongSelf = self, !messages.isEmpty {
|
||||
enum PeerType {
|
||||
case group
|
||||
@ -955,7 +956,7 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo
|
||||
return
|
||||
}
|
||||
let _ = (strongSelf.context.account.postbox.mediaBox.removeCachedResources([MediaResourceId(downloadResource.id)], notify: true)
|
||||
|> deliverOnMainQueue).start(completed: {
|
||||
|> deliverOnMainQueue).startStandalone(completed: {
|
||||
f(.dismissWithoutContent)
|
||||
})
|
||||
})))
|
||||
@ -1127,7 +1128,7 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo
|
||||
private func mediaMessageContextAction(_ message: EngineMessage, node: ASDisplayNode?, rect: CGRect?, gesture anyRecognizer: UIGestureRecognizer?) {
|
||||
let gesture: ContextGesture? = anyRecognizer as? ContextGesture
|
||||
let _ = (chatMediaListPreviewControllerData(context: self.context, chatLocation: .peer(id: message.id.peerId), chatLocationContextHolder: Atomic<ChatLocationContextHolder?>(value: nil), message: message._asMessage(), standalone: true, reverseMessageGalleryOrder: false, navigationController: self.navigationController)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] previewData in
|
||||
|> deliverOnMainQueue).startStandalone(next: { [weak self] previewData in
|
||||
guard let strongSelf = self else {
|
||||
gesture?.cancel()
|
||||
return
|
||||
@ -1217,7 +1218,7 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo
|
||||
}
|
||||
return messages
|
||||
}
|
||||
|> deliverOnMainQueue).start(next: { [weak self] messages in
|
||||
|> deliverOnMainQueue).startStandalone(next: { [weak self] messages in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -1246,7 +1247,7 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo
|
||||
}
|
||||
|
||||
let _ = (strongSelf.context.account.postbox.mediaBox.removeCachedResources(Array(resourceIds), force: true, notify: true)
|
||||
|> deliverOnMainQueue).start(completed: {
|
||||
|> deliverOnMainQueue).startStandalone(completed: {
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -1267,7 +1268,7 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo
|
||||
self.context.engine.messages.ensureMessagesAreLocallyAvailable(messages: messages.values.filter { messageIds.contains($0.id) })
|
||||
|
||||
self.activeActionDisposable.set((self.context.sharedContext.chatAvailableMessageActions(engine: self.context.engine, accountPeerId: self.context.account.peerId, messageIds: messageIds, messages: messages, peers: peers)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] actions in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] actions in
|
||||
if let strongSelf = self, !actions.options.isEmpty {
|
||||
let actionSheet = ActionSheetController(presentationData: strongSelf.presentationData)
|
||||
var items: [ActionSheetItem] = []
|
||||
@ -1283,7 +1284,7 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo
|
||||
items.append(ActionSheetButtonItem(title: globalTitle, color: .destructive, action: { [weak actionSheet] in
|
||||
actionSheet?.dismissAnimated()
|
||||
if let strongSelf = self {
|
||||
let _ = strongSelf.context.engine.messages.deleteMessagesInteractively(messageIds: Array(messageIds), type: .forEveryone).start()
|
||||
let _ = strongSelf.context.engine.messages.deleteMessagesInteractively(messageIds: Array(messageIds), type: .forEveryone).startStandalone()
|
||||
|
||||
strongSelf.updateState { state in
|
||||
return state.withUpdatedSelectedMessageIds(nil)
|
||||
@ -1299,7 +1300,7 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo
|
||||
items.append(ActionSheetButtonItem(title: localOptionText, color: .destructive, action: { [weak actionSheet] in
|
||||
actionSheet?.dismissAnimated()
|
||||
if let strongSelf = self {
|
||||
let _ = strongSelf.context.engine.messages.deleteMessagesInteractively(messageIds: Array(messageIds), type: .forLocalPeer).start()
|
||||
let _ = strongSelf.context.engine.messages.deleteMessagesInteractively(messageIds: Array(messageIds), type: .forLocalPeer).startStandalone()
|
||||
|
||||
strongSelf.updateState { state in
|
||||
return state.withUpdatedSelectedMessageIds(nil)
|
||||
@ -1362,7 +1363,7 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo
|
||||
var displayPeers: [EnginePeer] = []
|
||||
for peer in peers {
|
||||
let _ = (enqueueMessages(account: strongSelf.context.account, peerId: peer.id, messages: result)
|
||||
|> deliverOnMainQueue).start(next: { messageIds in
|
||||
|> deliverOnMainQueue).startStandalone(next: { messageIds in
|
||||
if let strongSelf = self {
|
||||
let signals: [Signal<Bool, NoError>] = messageIds.compactMap({ id -> Signal<Bool, NoError>? in
|
||||
guard let id = id else {
|
||||
@ -1382,7 +1383,7 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo
|
||||
strongSelf.shareStatusDisposable = MetaDisposable()
|
||||
}
|
||||
strongSelf.shareStatusDisposable?.set((combineLatest(signals)
|
||||
|> deliverOnMainQueue).start())
|
||||
|> deliverOnMainQueue).startStrict())
|
||||
}
|
||||
})
|
||||
if case let .secretChat(secretPeer) = peer {
|
||||
@ -1436,7 +1437,7 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo
|
||||
let _ = (enqueueMessages(account: strongSelf.context.account, peerId: peerId, messages: messageIds.map { id -> EnqueueMessage in
|
||||
return .forward(source: id, threadId: threadId, grouping: .auto, attributes: [], correlationId: nil)
|
||||
})
|
||||
|> deliverOnMainQueue).start(next: { [weak self] messageIds in
|
||||
|> deliverOnMainQueue).startStandalone(next: { [weak self] messageIds in
|
||||
if let strongSelf = self {
|
||||
let signals: [Signal<Bool, NoError>] = messageIds.compactMap({ id -> Signal<Bool, NoError>? in
|
||||
guard let id = id else {
|
||||
@ -1453,7 +1454,7 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo
|
||||
|> take(1)
|
||||
})
|
||||
strongSelf.activeActionDisposable.set((combineLatest(signals)
|
||||
|> deliverOnMainQueue).start(completed: {
|
||||
|> deliverOnMainQueue).startStrict(completed: {
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -1475,7 +1476,7 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo
|
||||
let _ = (ChatInterfaceState.update(engine: strongSelf.context.engine, peerId: peerId, threadId: threadId, { currentState in
|
||||
return currentState.withUpdatedForwardMessageIds(Array(messageIds))
|
||||
})
|
||||
|> deliverOnMainQueue).start(completed: { [weak self] in
|
||||
|> deliverOnMainQueue).startStandalone(completed: { [weak self] in
|
||||
if let strongSelf = self {
|
||||
let proceed: (ChatController) -> Void = { chatController in
|
||||
chatController.purposefulAction = { [weak self] in
|
||||
@ -1493,7 +1494,7 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo
|
||||
strongSelf.activeActionDisposable.set((chatController.ready.get()
|
||||
|> filter { $0 }
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(next: { [weak navigationController] _ in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak navigationController] _ in
|
||||
viewControllers.removeAll(where: { $0 is PeerSelectionController })
|
||||
navigationController?.setViewControllers(viewControllers, animated: true)
|
||||
}))
|
||||
@ -1502,7 +1503,7 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo
|
||||
|
||||
if let threadId = threadId {
|
||||
let _ = (strongSelf.context.sharedContext.chatControllerForForumThread(context: strongSelf.context, peerId: peerId, threadId: threadId)
|
||||
|> deliverOnMainQueue).start(next: { chatController in
|
||||
|> deliverOnMainQueue).startStandalone(next: { chatController in
|
||||
proceed(chatController)
|
||||
})
|
||||
} else {
|
||||
|
@ -2154,7 +2154,7 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
|
||||
}, peerSelected: { [weak self] peer, chatPeer, threadId, _ in
|
||||
interaction.dismissInput()
|
||||
interaction.openPeer(peer, chatPeer, threadId, false)
|
||||
let _ = context.engine.peers.addRecentlySearchedPeer(peerId: peer.id).start()
|
||||
let _ = context.engine.peers.addRecentlySearchedPeer(peerId: peer.id).startStandalone()
|
||||
self?.listNode.clearHighlightAnimated(true)
|
||||
}, disabledPeerSelected: { _, _ in
|
||||
}, togglePeerSelected: { _, _ in
|
||||
@ -2205,7 +2205,7 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
|
||||
return
|
||||
}
|
||||
let _ = (self.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|
||||
|> deliverOnMainQueue).start(next: { [weak self] peer in
|
||||
|> deliverOnMainQueue).startStandalone(next: { [weak self] peer in
|
||||
guard let self, let peer else {
|
||||
return
|
||||
}
|
||||
@ -2325,14 +2325,14 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
|
||||
let previousExpandGlobalSearch = Atomic<Bool>(value: false)
|
||||
|
||||
let _ = (searchQuery
|
||||
|> deliverOnMainQueue).start(next: { [weak self, weak listInteraction, weak chatListInteraction] query in
|
||||
|> deliverOnMainQueue).startStandalone(next: { [weak self, weak listInteraction, weak chatListInteraction] query in
|
||||
self?.searchQueryValue = query
|
||||
listInteraction?.searchTextHighightState = query
|
||||
chatListInteraction?.searchTextHighightState = query
|
||||
})
|
||||
|
||||
let _ = (searchOptions
|
||||
|> deliverOnMainQueue).start(next: { [weak self] options in
|
||||
|> deliverOnMainQueue).startStandalone(next: { [weak self] options in
|
||||
self?.searchOptionsValue = options
|
||||
})
|
||||
|
||||
@ -2384,7 +2384,7 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
|
||||
return (mappedItems, isSearching)
|
||||
}
|
||||
}
|
||||
|> deliverOnMainQueue).start(next: { [weak self] foundItems in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] foundItems in
|
||||
if let strongSelf = self {
|
||||
let previousSelectedMessageIds = previousSelectedMessages.swap(strongSelf.selectedMessages)
|
||||
let previousExpandGlobalSearch = previousExpandGlobalSearch.swap(strongSelf.searchStateValue.expandGlobalSearch)
|
||||
@ -2475,7 +2475,7 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
|
||||
return
|
||||
}
|
||||
|
||||
let _ = clearRecentDownloadList(postbox: strongSelf.context.account.postbox).start()
|
||||
let _ = clearRecentDownloadList(postbox: strongSelf.context.account.postbox).startStandalone()
|
||||
}))
|
||||
|
||||
actionSheet.setItemGroups([ActionSheetItemGroup(items: items), ActionSheetItemGroup(items: [
|
||||
@ -2492,7 +2492,7 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
|
||||
|
||||
let _ = ((strongSelf.context.fetchManager as! FetchManagerImpl).entriesSummary
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(next: { entries in
|
||||
|> deliverOnMainQueue).startStandalone(next: { entries in
|
||||
guard let strongSelf = self, !entries.isEmpty else {
|
||||
return
|
||||
}
|
||||
@ -2599,14 +2599,14 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
|
||||
}
|
||||
|
||||
if case .chats = key, !peersFilter.contains(.excludeRecent) {
|
||||
self.updatedRecentPeersDisposable.set(context.engine.peers.managedUpdatedRecentPeers().start())
|
||||
self.updatedRecentPeersDisposable.set(context.engine.peers.managedUpdatedRecentPeers().startStrict())
|
||||
}
|
||||
|
||||
self.recentDisposable.set((combineLatest(queue: .mainQueue(),
|
||||
presentationDataPromise.get(),
|
||||
recentItems
|
||||
)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] presentationData, entries in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] presentationData, entries in
|
||||
if let strongSelf = self {
|
||||
let previousEntries = previousRecentItems.swap(entries)
|
||||
|
||||
@ -2614,7 +2614,7 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
|
||||
let transition = chatListSearchContainerPreparedRecentTransition(from: previousEntries ?? [], to: entries, context: context, presentationData: presentationData, filter: peersFilter, peerSelected: { peer, threadId in
|
||||
interaction.openPeer(peer, nil, threadId, true)
|
||||
if threadId == nil {
|
||||
let _ = context.engine.peers.addRecentlySearchedPeer(peerId: peer.id).start()
|
||||
let _ = context.engine.peers.addRecentlySearchedPeer(peerId: peer.id).startStandalone()
|
||||
}
|
||||
self?.recentListNode.clearHighlightAnimated(true)
|
||||
}, disabledPeerSelected: { peer, threadId in
|
||||
@ -2628,7 +2628,7 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
|
||||
}, clearRecentlySearchedPeers: {
|
||||
interaction.clearRecentSearch()
|
||||
}, deletePeer: { peerId in
|
||||
let _ = context.engine.peers.removeRecentlySearchedPeer(peerId: peerId).start()
|
||||
let _ = context.engine.peers.removeRecentlySearchedPeer(peerId: peerId).startStandalone()
|
||||
}, animationCache: strongSelf.animationCache, animationRenderer: strongSelf.animationRenderer, openStories: { peerId, avatarNode in
|
||||
interaction.openStories?(peerId, avatarNode)
|
||||
})
|
||||
@ -2637,7 +2637,7 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
|
||||
}))
|
||||
|
||||
self.presentationDataDisposable = ((updatedPresentationData?.signal ?? context.sharedContext.presentationData)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] presentationData in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] presentationData in
|
||||
if let strongSelf = self {
|
||||
strongSelf.presentationData = presentationData
|
||||
strongSelf.presentationDataPromise.set(.single(ChatListPresentationData(theme: presentationData.theme, fontSize: presentationData.listsFontSize, strings: presentationData.strings, dateTimeFormat: presentationData.dateTimeFormat, nameSortOrder: presentationData.nameSortOrder, nameDisplayOrder: presentationData.nameDisplayOrder, disableAnimations: true)))
|
||||
@ -2713,7 +2713,7 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
|
||||
return .single(nil)
|
||||
}
|
||||
}
|
||||
|> deliverOnMainQueue).start(next: { [weak self] playlistStateAndType in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] playlistStateAndType in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -2737,7 +2737,7 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
|
||||
}
|
||||
|
||||
self.deletedMessagesDisposable = (context.account.stateManager.deletedMessages
|
||||
|> deliverOnMainQueue).start(next: { [weak self] messageIds in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] messageIds in
|
||||
if let strongSelf = self {
|
||||
strongSelf.updateState { state in
|
||||
var state = state
|
||||
@ -2810,7 +2810,7 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
|
||||
return
|
||||
}
|
||||
strongSelf.scheduledMarkRecentDownloadsAsSeen = false
|
||||
let _ = markAllRecentDownloadItemsAsSeen(postbox: strongSelf.context.account.postbox).start()
|
||||
let _ = markAllRecentDownloadItemsAsSeen(postbox: strongSelf.context.account.postbox).startStandalone()
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -2907,7 +2907,7 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
|
||||
})
|
||||
return rate
|
||||
}
|
||||
|> deliverOnMainQueue).start(next: { baseRate in
|
||||
|> deliverOnMainQueue).startStandalone(next: { baseRate in
|
||||
guard let strongSelf = self, let (_, _, _, _, type, _) = strongSelf.playlistStateAndType else {
|
||||
return
|
||||
}
|
||||
@ -3035,7 +3035,7 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
|
||||
progressDisposable.dispose()
|
||||
}
|
||||
}
|
||||
|> deliverOnMainQueue).start(next: { index in
|
||||
|> deliverOnMainQueue).startStrict(next: { index in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
|
@ -166,7 +166,7 @@ private final class VisualMediaItemNode: ASDisplayNode {
|
||||
case .Local:
|
||||
self.interaction.openMessage(message)
|
||||
case .Remote, .Paused:
|
||||
self.fetchDisposable.set(messageMediaFileInteractiveFetched(context: self.context, message: message, file: file, userInitiated: true).start())
|
||||
self.fetchDisposable.set(messageMediaFileInteractiveFetched(context: self.context, message: message, file: file, userInitiated: true).startStrict())
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -220,7 +220,7 @@ private final class VisualMediaItemNode: ASDisplayNode {
|
||||
self.item = (item, media, size, mediaDimensions)
|
||||
|
||||
self.fetchStatusDisposable.set((messageMediaFileStatus(context: context, messageId: message.id, file: file)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] status in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] status in
|
||||
if let strongSelf = self, let _ = strongSelf.item {
|
||||
strongSelf.resourceStatus = status
|
||||
|
||||
@ -669,7 +669,7 @@ final class ChatListSearchMediaNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
self.addSubnode(self.scrollNode)
|
||||
self.addSubnode(self.floatingHeaderNode)
|
||||
|
||||
self.hiddenMediaDisposable = context.sharedContext.mediaManager.galleryHiddenMediaManager.hiddenIds().start(next: { [weak self] ids in
|
||||
self.hiddenMediaDisposable = context.sharedContext.mediaManager.galleryHiddenMediaManager.hiddenIds().startStrict(next: { [weak self] ids in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ final class ChatListSearchMessageSelectionPanelNode: ASDisplayNode {
|
||||
} else {
|
||||
if let chatAvailableMessageActions = self.chatAvailableMessageActions {
|
||||
self.canDeleteMessagesDisposable.set((chatAvailableMessageActions(self.selectedMessages)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] actions in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] actions in
|
||||
if let strongSelf = self {
|
||||
strongSelf.actions = actions
|
||||
if let layout = strongSelf.validLayout {
|
||||
|
@ -131,7 +131,7 @@ private final class ChatListSearchPendingPane {
|
||||
self.pane = ChatListSearchPaneWrapper(key: key, node: paneNode)
|
||||
self.disposable = (paneNode.isReady
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] _ in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] _ in
|
||||
self?.isReady = true
|
||||
hasBecomeReady(key)
|
||||
}).strict()
|
||||
|
@ -1395,7 +1395,7 @@ class ChatListItemNode: ItemListRevealOptionsItemNode {
|
||||
if peer.isPremium && peer.id != item.context.account.peerId {
|
||||
let context = item.context
|
||||
self.cachedDataDisposable.set((context.account.postbox.peerView(id: peer.id)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] peerView in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] peerView in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -1457,7 +1457,7 @@ class ChatListItemNode: ItemListRevealOptionsItemNode {
|
||||
strongSelf.updateVideoVisibility()
|
||||
} else {
|
||||
if let photo = peer.largeProfileImage, photo.hasVideo {
|
||||
let _ = context.engine.peers.fetchAndUpdateCachedPeerData(peerId: peer.id).start()
|
||||
let _ = context.engine.peers.fetchAndUpdateCachedPeerData(peerId: peer.id).startStandalone()
|
||||
}
|
||||
}
|
||||
}))
|
||||
|
@ -1417,7 +1417,7 @@ public final class ChatListNode: ListView {
|
||||
}
|
||||
}, setItemPinned: { [weak self] itemId, _ in
|
||||
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: context.account.peerId))
|
||||
|> deliverOnMainQueue).start(next: { peer in
|
||||
|> deliverOnMainQueue).startStandalone(next: { peer in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -1433,7 +1433,7 @@ public final class ChatListNode: ListView {
|
||||
location = .group(groupId._asGroup())
|
||||
}
|
||||
let _ = (context.engine.peers.toggleItemPinned(location: location, itemId: itemId)
|
||||
|> deliverOnMainQueue).start(next: { result in
|
||||
|> deliverOnMainQueue).startStandalone(next: { result in
|
||||
if let strongSelf = self {
|
||||
switch result {
|
||||
case .done:
|
||||
@ -1486,7 +1486,7 @@ public final class ChatListNode: ListView {
|
||||
}
|
||||
strongSelf.setCurrentRemovingItemId(ChatListNodeState.ItemId(peerId: peerId, threadId: nil))
|
||||
let _ = (context.engine.peers.togglePeerMuted(peerId: peerId, threadId: nil)
|
||||
|> deliverOnMainQueue).start(completed: {
|
||||
|> deliverOnMainQueue).startStandalone(completed: {
|
||||
self?.updateState { state in
|
||||
var state = state
|
||||
state.peerIdWithRevealedOptions = nil
|
||||
@ -1497,7 +1497,7 @@ public final class ChatListNode: ListView {
|
||||
}, setPeerThreadMuted: { [weak self] peerId, threadId, value in
|
||||
self?.setCurrentRemovingItemId(ChatListNodeState.ItemId(peerId: peerId, threadId: threadId))
|
||||
let _ = (context.engine.peers.updatePeerMuteSetting(peerId: peerId, threadId: threadId, muteInterval: value ? Int32.max : 0)
|
||||
|> deliverOnMainQueue).start(completed: {
|
||||
|> deliverOnMainQueue).startStandalone(completed: {
|
||||
self?.updateState { state in
|
||||
var state = state
|
||||
state.peerIdWithRevealedOptions = nil
|
||||
@ -1523,7 +1523,7 @@ public final class ChatListNode: ListView {
|
||||
}
|
||||
self?.setCurrentRemovingItemId(ChatListNodeState.ItemId(peerId: peerId, threadId: nil))
|
||||
let _ = (context.engine.messages.togglePeersUnreadMarkInteractively(peerIds: [peerId], setToValue: nil)
|
||||
|> deliverOnMainQueue).start(completed: {
|
||||
|> deliverOnMainQueue).startStandalone(completed: {
|
||||
self?.updateState { state in
|
||||
var state = state
|
||||
state.peerIdWithRevealedOptions = nil
|
||||
@ -1568,7 +1568,7 @@ public final class ChatListNode: ListView {
|
||||
return
|
||||
}
|
||||
let _ = (self.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|
||||
|> deliverOnMainQueue).start(next: { [weak self] peer in
|
||||
|> deliverOnMainQueue).startStandalone(next: { [weak self] peer in
|
||||
guard let self, let peer else {
|
||||
return
|
||||
}
|
||||
@ -1586,7 +1586,7 @@ public final class ChatListNode: ListView {
|
||||
}
|
||||
Queue.mainQueue().after(0.6) { [weak self] in
|
||||
if let self {
|
||||
let _ = dismissServerProvidedSuggestion(account: self.context.account, suggestion: .setupPassword).start()
|
||||
let _ = dismissServerProvidedSuggestion(account: self.context.account, suggestion: .setupPassword).startStandalone()
|
||||
}
|
||||
}
|
||||
let controller = self.context.sharedContext.makeSetupTwoFactorAuthController(context: self.context)
|
||||
@ -1597,9 +1597,9 @@ public final class ChatListNode: ListView {
|
||||
}
|
||||
Queue.mainQueue().after(0.6) { [weak self] in
|
||||
if let self {
|
||||
let _ = dismissServerProvidedSuggestion(account: self.context.account, suggestion: .annualPremium).start()
|
||||
let _ = dismissServerProvidedSuggestion(account: self.context.account, suggestion: .upgradePremium).start()
|
||||
let _ = dismissServerProvidedSuggestion(account: self.context.account, suggestion: .restorePremium).start()
|
||||
let _ = dismissServerProvidedSuggestion(account: self.context.account, suggestion: .annualPremium).startStandalone()
|
||||
let _ = dismissServerProvidedSuggestion(account: self.context.account, suggestion: .upgradePremium).startStandalone()
|
||||
let _ = dismissServerProvidedSuggestion(account: self.context.account, suggestion: .restorePremium).startStandalone()
|
||||
}
|
||||
}
|
||||
let controller = self.context.sharedContext.makePremiumIntroController(context: self.context, source: .ads, forceDark: false, dismissed: nil)
|
||||
@ -1615,7 +1615,7 @@ public final class ChatListNode: ListView {
|
||||
return !state.sessions.isEmpty
|
||||
}
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(completed: { [weak self] in
|
||||
|> deliverOnMainQueue).startStandalone(completed: { [weak self] in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
@ -1648,13 +1648,13 @@ public final class ChatListNode: ListView {
|
||||
return true
|
||||
}))
|
||||
|
||||
let _ = self.context.engine.privacy.confirmNewSessionReview(id: newSessionReview.id).start()
|
||||
let _ = self.context.engine.privacy.confirmNewSessionReview(id: newSessionReview.id).startStandalone()
|
||||
} else {
|
||||
self.push?(NewSessionInfoScreen(context: self.context, newSessionReview: newSessionReview))
|
||||
|
||||
//#if DEBUG
|
||||
//#else
|
||||
let _ = self.context.engine.privacy.terminateAnotherSession(id: newSessionReview.id).start()
|
||||
let _ = self.context.engine.privacy.terminateAnotherSession(id: newSessionReview.id).startStandalone()
|
||||
//#endif
|
||||
}
|
||||
}, openChatFolderUpdates: { [weak self] in
|
||||
@ -1663,7 +1663,7 @@ public final class ChatListNode: ListView {
|
||||
}
|
||||
let _ = (self.chatFolderUpdates.get()
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] result in
|
||||
|> deliverOnMainQueue).startStandalone(next: { [weak self] result in
|
||||
guard let self, let result else {
|
||||
return
|
||||
}
|
||||
@ -1676,13 +1676,13 @@ public final class ChatListNode: ListView {
|
||||
}
|
||||
let _ = (self.chatFolderUpdates.get()
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] result in
|
||||
|> deliverOnMainQueue).startStandalone(next: { [weak self] result in
|
||||
guard let self, let result else {
|
||||
return
|
||||
}
|
||||
|
||||
if let localFilterId = result.chatFolderLinkContents.localFilterId {
|
||||
let _ = self.context.engine.peers.hideChatFolderUpdates(folderId: localFilterId).start()
|
||||
let _ = self.context.engine.peers.hideChatFolderUpdates(folderId: localFilterId).startStandalone()
|
||||
}
|
||||
})
|
||||
}, openStories: { [weak self] subject, itemNode in
|
||||
@ -1743,7 +1743,7 @@ public final class ChatListNode: ListView {
|
||||
if value {
|
||||
let _ = (context.sharedContext.accountManager.transaction { transaction -> Void in
|
||||
ApplicationSpecificNotice.setArchiveIntroDismissed(transaction: transaction, value: true)
|
||||
}).start()
|
||||
}).startStandalone()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1756,7 +1756,7 @@ public final class ChatListNode: ListView {
|
||||
}
|
||||
|
||||
self.updateIsMainTabDisposable = (self.isMainTab.get()
|
||||
|> deliverOnMainQueue).start(next: { [weak self] isMainTab in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] isMainTab in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
@ -1766,7 +1766,7 @@ public final class ChatListNode: ListView {
|
||||
return
|
||||
}
|
||||
|
||||
let _ = context.engine.privacy.cleanupSessionReviews().start()
|
||||
let _ = context.engine.privacy.cleanupSessionReviews().startStandalone()
|
||||
|
||||
let twoStepData: Signal<TwoStepVerificationConfiguration?, NoError> = .single(nil) |> then(context.engine.auth.twoStepVerificationConfiguration() |> map(Optional.init))
|
||||
|
||||
@ -2558,7 +2558,7 @@ public final class ChatListNode: ListView {
|
||||
|
||||
self.interaction = nodeInteraction
|
||||
|
||||
self.chatListDisposable.set(appliedTransition.start())
|
||||
self.chatListDisposable.set(appliedTransition.startStrict())
|
||||
|
||||
let initialLocation: ChatListNodeLocation
|
||||
switch mode {
|
||||
@ -2715,7 +2715,7 @@ public final class ChatListNode: ListView {
|
||||
}
|
||||
}
|
||||
}
|
||||
|> deliverOnMainQueue).start(next: { [weak self] activities in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] activities in
|
||||
if let strongSelf = self {
|
||||
strongSelf.updateState { state in
|
||||
var state = state
|
||||
@ -2723,7 +2723,7 @@ public final class ChatListNode: ListView {
|
||||
return state
|
||||
}
|
||||
}
|
||||
}).strict()
|
||||
})
|
||||
|
||||
self.reorderItem = { [weak self] fromIndex, toIndex, transactionOpaqueState -> Signal<Bool, NoError> in
|
||||
guard let strongSelf = self, let filteredEntries = (transactionOpaqueState as? ChatListOpaqueTransactionState)?.chatListView.filteredEntries else {
|
||||
@ -3089,7 +3089,7 @@ public final class ChatListNode: ListView {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|> deliverOnMainQueue).start(next: { [weak self] updatedFilter in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] updatedFilter in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -3619,7 +3619,7 @@ public final class ChatListNode: ListView {
|
||||
return .single(nil)
|
||||
}
|
||||
}
|
||||
|> deliverOnMainQueue).start(next: { [weak self] indexAndPeer in
|
||||
|> deliverOnMainQueue).startStandalone(next: { [weak self] indexAndPeer in
|
||||
guard let strongSelf = self, let (index, peer) = indexAndPeer else {
|
||||
return
|
||||
}
|
||||
@ -3653,7 +3653,7 @@ public final class ChatListNode: ListView {
|
||||
}
|
||||
case let .peerId(peerId):
|
||||
let _ = (self.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|
||||
|> deliverOnMainQueue).start(next: { [weak self] peer in
|
||||
|> deliverOnMainQueue).startStandalone(next: { [weak self] peer in
|
||||
guard let strongSelf = self, let peer = peer else {
|
||||
return
|
||||
}
|
||||
@ -3665,7 +3665,7 @@ public final class ChatListNode: ListView {
|
||||
}
|
||||
let _ = (self.chatListFilterValue.get()
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] filter in
|
||||
|> deliverOnMainQueue).startStandalone(next: { [weak self] filter in
|
||||
guard let self = self else {
|
||||
return
|
||||
}
|
||||
@ -3674,7 +3674,7 @@ public final class ChatListNode: ListView {
|
||||
}
|
||||
let _ = (chatListViewForLocation(chatListLocation: .chatList(groupId: groupId), location: .initial(count: 10, filter: filter), account: self.context.account)
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(next: { update in
|
||||
|> deliverOnMainQueue).startStandalone(next: { update in
|
||||
let items = update.list.items
|
||||
if items.count > index {
|
||||
let item = items[9 - index - 1]
|
||||
@ -4070,5 +4070,5 @@ public class ChatHistoryListSelectionRecognizer: UIPanGestureRecognizer {
|
||||
}
|
||||
|
||||
func hideChatListContacts(context: AccountContext) {
|
||||
let _ = ApplicationSpecificNotice.setDisplayChatListContacts(accountManager: context.sharedContext.accountManager).start()
|
||||
let _ = ApplicationSpecificNotice.setDisplayChatListContacts(accountManager: context.sharedContext.accountManager).startStandalone()
|
||||
}
|
||||
|
@ -132,14 +132,14 @@ public final class MediaPlayerNode: ASDisplayNode {
|
||||
private func startPolling() {
|
||||
if !self.polling {
|
||||
self.polling = true
|
||||
self.poll(completion: { [weak self] status in
|
||||
MediaPlayerNode.poll(node: self, completion: { [weak self] status in
|
||||
self?.polling = false
|
||||
|
||||
if let strongSelf = self, let (_, requestFrames, _, _) = strongSelf.state, requestFrames {
|
||||
strongSelf.timer?.invalidate()
|
||||
switch status {
|
||||
case let .delay(delay):
|
||||
strongSelf.timer = SwiftSignalKit.Timer(timeout: delay, repeat: true, completion: {
|
||||
strongSelf.timer = SwiftSignalKit.Timer( timeout: delay, repeat: true, completion: {
|
||||
if let strongSelf = self, let videoLayer = strongSelf.videoLayer, let (_, requestFrames, _, _) = strongSelf.state, requestFrames, (strongSelf.videoInHierarchy || strongSelf.canPlaybackWithoutHierarchy) {
|
||||
if videoLayer.isReadyForMoreMediaData {
|
||||
strongSelf.timer?.invalidate()
|
||||
@ -157,197 +157,132 @@ public final class MediaPlayerNode: ASDisplayNode {
|
||||
}
|
||||
}
|
||||
|
||||
private func poll(completion: @escaping (PollStatus) -> Void) {
|
||||
if let (takeFrameQueue, takeFrame) = self.takeFrameAndQueue, let _ = self.videoLayer, let (timebase, _, _, _) = self.state {
|
||||
private struct PollState {
|
||||
var numFrames: Int
|
||||
var maxTakenTime: Double
|
||||
}
|
||||
|
||||
private static func pollInner(node: MediaPlayerNode, layerTime: Double, state: PollState, completion: @escaping (PollStatus) -> Void) {
|
||||
assert(Queue.mainQueue().isCurrent())
|
||||
|
||||
guard let (takeFrameQueue, takeFrame) = node.takeFrameAndQueue else {
|
||||
return
|
||||
}
|
||||
guard let videoLayer = node.videoLayer else {
|
||||
return
|
||||
}
|
||||
if !videoLayer.isReadyForMoreMediaData {
|
||||
completion(.delay(max(1.0 / 30.0, state.maxTakenTime - layerTime)))
|
||||
return
|
||||
}
|
||||
|
||||
var state = state
|
||||
|
||||
takeFrameQueue.async { [weak node] in
|
||||
switch takeFrame() {
|
||||
case let .restoreState(frames, atTime):
|
||||
Queue.mainQueue().async {
|
||||
guard let strongSelf = node, let videoLayer = strongSelf.videoLayer else {
|
||||
return
|
||||
}
|
||||
videoLayer.flush()
|
||||
}
|
||||
for i in 0 ..< frames.count {
|
||||
let frame = frames[i]
|
||||
let frameTime = CMTimeGetSeconds(frame.position)
|
||||
state.maxTakenTime = frameTime
|
||||
let attachments = CMSampleBufferGetSampleAttachmentsArray(frame.sampleBuffer, createIfNecessary: true)! as NSArray
|
||||
let dict = attachments[0] as! NSMutableDictionary
|
||||
if i == 0 {
|
||||
CMSetAttachment(frame.sampleBuffer, key: kCMSampleBufferAttachmentKey_ResetDecoderBeforeDecoding as NSString, value: kCFBooleanTrue as AnyObject, attachmentMode: kCMAttachmentMode_ShouldPropagate)
|
||||
CMSetAttachment(frame.sampleBuffer, key: kCMSampleBufferAttachmentKey_EndsPreviousSampleDuration as NSString, value: kCFBooleanTrue as AnyObject, attachmentMode: kCMAttachmentMode_ShouldPropagate)
|
||||
}
|
||||
if CMTimeCompare(frame.position, atTime) < 0 {
|
||||
dict.setValue(kCFBooleanTrue as AnyObject, forKey: kCMSampleAttachmentKey_DoNotDisplay as NSString as String)
|
||||
} else if CMTimeCompare(frame.position, atTime) == 0 {
|
||||
dict.setValue(kCFBooleanTrue as AnyObject, forKey: kCMSampleAttachmentKey_DisplayImmediately as NSString as String)
|
||||
dict.setValue(kCFBooleanTrue as AnyObject, forKey: kCMSampleBufferAttachmentKey_EndsPreviousSampleDuration as NSString as String)
|
||||
}
|
||||
Queue.mainQueue().async {
|
||||
guard let strongSelf = node, let videoLayer = strongSelf.videoLayer else {
|
||||
return
|
||||
}
|
||||
videoLayer.enqueue(frame.sampleBuffer)
|
||||
strongSelf.hasSentFramesToDisplay?()
|
||||
}
|
||||
}
|
||||
Queue.mainQueue().async {
|
||||
guard let node else {
|
||||
return
|
||||
}
|
||||
MediaPlayerNode.pollInner(node: node, layerTime: layerTime, state: state, completion: completion)
|
||||
}
|
||||
case let .frame(frame):
|
||||
state.numFrames += 1
|
||||
let frameTime = CMTimeGetSeconds(frame.position)
|
||||
if frame.resetDecoder {
|
||||
Queue.mainQueue().async {
|
||||
guard let strongSelf = node, let videoLayer = strongSelf.videoLayer else {
|
||||
return
|
||||
}
|
||||
videoLayer.flush()
|
||||
}
|
||||
}
|
||||
|
||||
if frame.decoded && frameTime < layerTime {
|
||||
Queue.mainQueue().async {
|
||||
guard let node else {
|
||||
return
|
||||
}
|
||||
MediaPlayerNode.pollInner(node: node, layerTime: layerTime, state: state, completion: completion)
|
||||
}
|
||||
} else {
|
||||
state.maxTakenTime = frameTime
|
||||
Queue.mainQueue().async {
|
||||
guard let strongSelf = node, let videoLayer = strongSelf.videoLayer else {
|
||||
return
|
||||
}
|
||||
videoLayer.enqueue(frame.sampleBuffer)
|
||||
strongSelf.hasSentFramesToDisplay?()
|
||||
}
|
||||
|
||||
Queue.mainQueue().async {
|
||||
guard let node else {
|
||||
return
|
||||
}
|
||||
MediaPlayerNode.pollInner(node: node, layerTime: layerTime, state: state, completion: completion)
|
||||
}
|
||||
}
|
||||
case .skipFrame:
|
||||
Queue.mainQueue().async {
|
||||
guard let node else {
|
||||
return
|
||||
}
|
||||
MediaPlayerNode.pollInner(node: node, layerTime: layerTime, state: state, completion: completion)
|
||||
}
|
||||
case .noFrames:
|
||||
DispatchQueue.main.async {
|
||||
completion(.finished)
|
||||
}
|
||||
case .finished:
|
||||
DispatchQueue.main.async {
|
||||
completion(.finished)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static func poll(node: MediaPlayerNode, completion: @escaping (PollStatus) -> Void) {
|
||||
if let _ = node.videoLayer, let (timebase, _, _, _) = node.state {
|
||||
let layerTime = CMTimeGetSeconds(CMTimebaseGetTime(timebase))
|
||||
|
||||
struct PollState {
|
||||
var numFrames: Int
|
||||
var maxTakenTime: Double
|
||||
}
|
||||
|
||||
var loop: ((PollState) -> Void)?
|
||||
let loopImpl: (PollState) -> Void = { [weak self] state in
|
||||
assert(Queue.mainQueue().isCurrent())
|
||||
|
||||
guard let strongSelf = self, let videoLayer = strongSelf.videoLayer else {
|
||||
let loopImpl: (PollState) -> Void = { [weak node] state in
|
||||
guard let node else {
|
||||
return
|
||||
}
|
||||
if !videoLayer.isReadyForMoreMediaData {
|
||||
completion(.delay(max(1.0 / 30.0, state.maxTakenTime - layerTime)))
|
||||
return
|
||||
}
|
||||
|
||||
var state = state
|
||||
|
||||
takeFrameQueue.async {
|
||||
switch takeFrame() {
|
||||
case let .restoreState(frames, atTime):
|
||||
Queue.mainQueue().async {
|
||||
guard let strongSelf = self, let videoLayer = strongSelf.videoLayer else {
|
||||
return
|
||||
}
|
||||
videoLayer.flush()
|
||||
}
|
||||
for i in 0 ..< frames.count {
|
||||
let frame = frames[i]
|
||||
let frameTime = CMTimeGetSeconds(frame.position)
|
||||
state.maxTakenTime = frameTime
|
||||
let attachments = CMSampleBufferGetSampleAttachmentsArray(frame.sampleBuffer, createIfNecessary: true)! as NSArray
|
||||
let dict = attachments[0] as! NSMutableDictionary
|
||||
if i == 0 {
|
||||
CMSetAttachment(frame.sampleBuffer, key: kCMSampleBufferAttachmentKey_ResetDecoderBeforeDecoding as NSString, value: kCFBooleanTrue as AnyObject, attachmentMode: kCMAttachmentMode_ShouldPropagate)
|
||||
CMSetAttachment(frame.sampleBuffer, key: kCMSampleBufferAttachmentKey_EndsPreviousSampleDuration as NSString, value: kCFBooleanTrue as AnyObject, attachmentMode: kCMAttachmentMode_ShouldPropagate)
|
||||
}
|
||||
if CMTimeCompare(frame.position, atTime) < 0 {
|
||||
dict.setValue(kCFBooleanTrue as AnyObject, forKey: kCMSampleAttachmentKey_DoNotDisplay as NSString as String)
|
||||
} else if CMTimeCompare(frame.position, atTime) == 0 {
|
||||
dict.setValue(kCFBooleanTrue as AnyObject, forKey: kCMSampleAttachmentKey_DisplayImmediately as NSString as String)
|
||||
dict.setValue(kCFBooleanTrue as AnyObject, forKey: kCMSampleBufferAttachmentKey_EndsPreviousSampleDuration as NSString as String)
|
||||
}
|
||||
Queue.mainQueue().async {
|
||||
guard let strongSelf = self, let videoLayer = strongSelf.videoLayer else {
|
||||
return
|
||||
}
|
||||
videoLayer.enqueue(frame.sampleBuffer)
|
||||
strongSelf.hasSentFramesToDisplay?()
|
||||
}
|
||||
}
|
||||
Queue.mainQueue().async {
|
||||
loop?(state)
|
||||
}
|
||||
case let .frame(frame):
|
||||
state.numFrames += 1
|
||||
let frameTime = CMTimeGetSeconds(frame.position)
|
||||
if frame.resetDecoder {
|
||||
Queue.mainQueue().async {
|
||||
guard let strongSelf = self, let videoLayer = strongSelf.videoLayer else {
|
||||
return
|
||||
}
|
||||
videoLayer.flush()
|
||||
}
|
||||
}
|
||||
|
||||
if frame.decoded && frameTime < layerTime {
|
||||
Queue.mainQueue().async {
|
||||
loop?(state)
|
||||
}
|
||||
} else {
|
||||
state.maxTakenTime = frameTime
|
||||
Queue.mainQueue().async {
|
||||
guard let strongSelf = self, let videoLayer = strongSelf.videoLayer else {
|
||||
return
|
||||
}
|
||||
videoLayer.enqueue(frame.sampleBuffer)
|
||||
strongSelf.hasSentFramesToDisplay?()
|
||||
}
|
||||
|
||||
Queue.mainQueue().async {
|
||||
loop?(state)
|
||||
}
|
||||
}
|
||||
case .skipFrame:
|
||||
Queue.mainQueue().async {
|
||||
loop?(state)
|
||||
}
|
||||
case .noFrames:
|
||||
DispatchQueue.main.async {
|
||||
completion(.finished)
|
||||
}
|
||||
case .finished:
|
||||
DispatchQueue.main.async {
|
||||
completion(.finished)
|
||||
}
|
||||
}
|
||||
}
|
||||
MediaPlayerNode.pollInner(node: node, layerTime: layerTime, state: state, completion: completion)
|
||||
}
|
||||
loop = loopImpl
|
||||
loop?(PollState(numFrames: 0, maxTakenTime: layerTime + 0.1))
|
||||
|
||||
/*let layerRef = Unmanaged.passRetained(videoLayer)
|
||||
takeFrameQueue.async {
|
||||
let status: PollStatus
|
||||
do {
|
||||
var numFrames = 0
|
||||
let layer = layerRef.takeUnretainedValue()
|
||||
|
||||
var maxTakenTime = layerTime + 0.1
|
||||
var finised = false
|
||||
loop: while true {
|
||||
let isReady = layer.isReadyForMoreMediaData
|
||||
#if DEBUG
|
||||
if let error = layer.error {
|
||||
print("MediaPlayerNode error: \(error)")
|
||||
}
|
||||
#endif
|
||||
|
||||
if isReady {
|
||||
switch takeFrame() {
|
||||
case let .restoreState(frames, atTime):
|
||||
layer.flush()
|
||||
for i in 0 ..< frames.count {
|
||||
let frame = frames[i]
|
||||
let frameTime = CMTimeGetSeconds(frame.position)
|
||||
maxTakenTime = frameTime
|
||||
let attachments = CMSampleBufferGetSampleAttachmentsArray(frame.sampleBuffer, createIfNecessary: true)! as NSArray
|
||||
let dict = attachments[0] as! NSMutableDictionary
|
||||
if i == 0 {
|
||||
CMSetAttachment(frame.sampleBuffer, key: kCMSampleBufferAttachmentKey_ResetDecoderBeforeDecoding as NSString, value: kCFBooleanTrue as AnyObject, attachmentMode: kCMAttachmentMode_ShouldPropagate)
|
||||
CMSetAttachment(frame.sampleBuffer, key: kCMSampleBufferAttachmentKey_EndsPreviousSampleDuration as NSString, value: kCFBooleanTrue as AnyObject, attachmentMode: kCMAttachmentMode_ShouldPropagate)
|
||||
}
|
||||
if CMTimeCompare(frame.position, atTime) < 0 {
|
||||
dict.setValue(kCFBooleanTrue as AnyObject, forKey: kCMSampleAttachmentKey_DoNotDisplay as NSString as String)
|
||||
} else if CMTimeCompare(frame.position, atTime) == 0 {
|
||||
dict.setValue(kCFBooleanTrue as AnyObject, forKey: kCMSampleAttachmentKey_DisplayImmediately as NSString as String)
|
||||
dict.setValue(kCFBooleanTrue as AnyObject, forKey: kCMSampleBufferAttachmentKey_EndsPreviousSampleDuration as NSString as String)
|
||||
//print("restore state to \(frame.position) -> \(frameTime) at \(layerTime) (\(i + 1) of \(frames.count))")
|
||||
}
|
||||
layer.enqueue(frame.sampleBuffer)
|
||||
}
|
||||
case let .frame(frame):
|
||||
numFrames += 1
|
||||
let frameTime = CMTimeGetSeconds(frame.position)
|
||||
if rate.isZero {
|
||||
//print("enqueue \(frameTime) at \(layerTime)")
|
||||
}
|
||||
if frame.resetDecoder {
|
||||
layer.flush()
|
||||
}
|
||||
|
||||
if frame.decoded && frameTime < layerTime {
|
||||
//print("drop frame at \(frameTime) current \(layerTime)")
|
||||
continue loop
|
||||
}
|
||||
|
||||
//print("took frame at \(frameTime) current \(layerTime)")
|
||||
maxTakenTime = frameTime
|
||||
layer.enqueue(frame.sampleBuffer)
|
||||
case .skipFrame:
|
||||
break
|
||||
case .noFrames:
|
||||
finised = true
|
||||
break loop
|
||||
case .finished:
|
||||
finised = true
|
||||
break loop
|
||||
}
|
||||
} else {
|
||||
break loop
|
||||
}
|
||||
}
|
||||
if finised {
|
||||
status = .finished
|
||||
} else {
|
||||
status = .delay(max(1.0 / 30.0, maxTakenTime - layerTime))
|
||||
}
|
||||
//print("took \(numFrames) frames, status \(status)")
|
||||
}
|
||||
DispatchQueue.main.async {
|
||||
layerRef.release()
|
||||
|
||||
completion(status)
|
||||
}
|
||||
}*/
|
||||
loopImpl(PollState(numFrames: 0, maxTakenTime: layerTime + 0.1))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -261,7 +261,7 @@ public final class PeerInfoAvatarListItemNode: ASDisplayNode {
|
||||
}
|
||||
if let videoContent = self.videoContent {
|
||||
let duration: Double = (self.videoStartTimestamp ?? 0.0) + 4.0
|
||||
self.preloadDisposable.set(preloadVideoResource(postbox: self.context.account.postbox, userLocation: .other, userContentType: .video, resourceReference: videoContent.fileReference.resourceReference(videoContent.fileReference.media.resource), duration: duration).start())
|
||||
self.preloadDisposable.set(preloadVideoResource(postbox: self.context.account.postbox, userLocation: .other, userContentType: .video, resourceReference: videoContent.fileReference.resourceReference(videoContent.fileReference.media.resource), duration: duration).startStrict())
|
||||
}
|
||||
}
|
||||
self.markupNode?.updateVisibility(isCentral)
|
||||
@ -291,7 +291,7 @@ public final class PeerInfoAvatarListItemNode: ASDisplayNode {
|
||||
} else {
|
||||
return .single(value)
|
||||
}
|
||||
} |> distinctUntilChanged, self.loadingProgress.get() |> distinctUntilChanged)).start(next: { [weak self] isLoading, progress in
|
||||
} |> distinctUntilChanged, self.loadingProgress.get() |> distinctUntilChanged)).startStrict(next: { [weak self] isLoading, progress in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -318,6 +318,7 @@ public final class PeerInfoAvatarListItemNode: ASDisplayNode {
|
||||
self.statusDisposable.dispose()
|
||||
self.playbackStartDisposable.dispose()
|
||||
self.preloadDisposable.dispose()
|
||||
self.loadingProgressDisposable.dispose()
|
||||
}
|
||||
|
||||
private func updateStatus() {
|
||||
@ -387,7 +388,7 @@ public final class PeerInfoAvatarListItemNode: ASDisplayNode {
|
||||
return playing
|
||||
}
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(error: { [weak self] _ in
|
||||
|> deliverOnMainQueue).startStrict(error: { [weak self] _ in
|
||||
if let strongSelf = self {
|
||||
if let _ = strongSelf.videoNode {
|
||||
videoNode.seek(0.0)
|
||||
@ -419,7 +420,7 @@ public final class PeerInfoAvatarListItemNode: ASDisplayNode {
|
||||
self.statusPromise.set(videoNode.status |> map { ($0, videoStartTimestamp) })
|
||||
|
||||
self.statusDisposable.set((self.mediaStatus
|
||||
|> deliverOnMainQueue).start(next: { [weak self] mediaStatus in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] mediaStatus in
|
||||
if let strongSelf = self {
|
||||
if let mediaStatusAndStartTimestamp = mediaStatus {
|
||||
strongSelf.playerStatus = mediaStatusAndStartTimestamp.0
|
||||
@ -1188,7 +1189,7 @@ public final class PeerInfoAvatarListContainerNode: ASDisplayNode {
|
||||
return representation.flatMap { AvatarGalleryEntry(representation: $0.0, peer: peer) }
|
||||
}
|
||||
|
||||
self.disposable.set(combineLatest(queue: Queue.mainQueue(), peerInfoProfilePhotosWithCache(context: self.context, peerId: peer.id), entry).start(next: { [weak self] completeAndEntries, entry in
|
||||
self.disposable.set(combineLatest(queue: Queue.mainQueue(), peerInfoProfilePhotosWithCache(context: self.context, peerId: peer.id), entry).startStrict(next: { [weak self] completeAndEntries, entry in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -1321,7 +1322,7 @@ public final class PeerInfoAvatarListContainerNode: ASDisplayNode {
|
||||
|
||||
if let currentItemNode = self.currentItemNode {
|
||||
self.positionDisposable.set((currentItemNode.mediaStatus
|
||||
|> deliverOnMainQueue).start(next: { [weak self] statusAndVideoStartTimestamp in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] statusAndVideoStartTimestamp in
|
||||
if let strongSelf = self {
|
||||
strongSelf.playerStatus = statusAndVideoStartTimestamp
|
||||
}
|
||||
|
@ -6,15 +6,21 @@ public protocol Disposable: AnyObject {
|
||||
|
||||
public final class StrictDisposable: Disposable {
|
||||
private let disposable: Disposable
|
||||
private let file: String
|
||||
private let line: Int
|
||||
private let isDisposed = Atomic<Bool>(value: false)
|
||||
|
||||
public init(_ disposable: Disposable) {
|
||||
public init(_ disposable: Disposable, file: String, line: Int) {
|
||||
self.disposable = disposable
|
||||
self.file = file
|
||||
self.line = line
|
||||
}
|
||||
|
||||
deinit {
|
||||
#if DEBUG
|
||||
assert(self.isDisposed.with({ $0 }))
|
||||
if !self.isDisposed.with({ $0 }) {
|
||||
assertionFailure("Leaked disposable \(self.disposable) from \(self.file):\(self.line)")
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -25,8 +31,8 @@ public final class StrictDisposable: Disposable {
|
||||
}
|
||||
|
||||
public extension Disposable {
|
||||
func strict() -> Disposable {
|
||||
return StrictDisposable(self)
|
||||
func strict(file: String = #file, line: Int = #line) -> Disposable {
|
||||
return StrictDisposable(self, file: file, line: line)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,11 +24,7 @@ public func |> <T, U>(value: T, function: ((T) -> U)) -> U {
|
||||
}
|
||||
|
||||
private final class SubscriberDisposable<T, E>: Disposable, CustomStringConvertible {
|
||||
#if DEBUG
|
||||
private weak var subscriber: Subscriber<T, E>?
|
||||
#else
|
||||
private var subscriber: Subscriber<T, E>?
|
||||
#endif
|
||||
|
||||
private var lock = pthread_mutex_t()
|
||||
private var disposable: Disposable?
|
||||
@ -78,6 +74,20 @@ public final class Signal<T, E> {
|
||||
return SubscriberDisposable(subscriber: subscriber, disposable: disposable)
|
||||
}
|
||||
|
||||
public func startStandalone(next: ((T) -> Void)! = nil, error: ((E) -> Void)! = nil, completed: (() -> Void)! = nil) -> Disposable {
|
||||
let subscriber = Subscriber<T, E>(next: next, error: error, completed: completed)
|
||||
let disposable = self.generator(subscriber)
|
||||
subscriber.assignDisposable(disposable)
|
||||
return SubscriberDisposable(subscriber: subscriber, disposable: disposable)
|
||||
}
|
||||
|
||||
public func startStrict(next: ((T) -> Void)! = nil, error: ((E) -> Void)! = nil, completed: (() -> Void)! = nil, file: String = #file, line: Int = #line) -> Disposable {
|
||||
let subscriber = Subscriber<T, E>(next: next, error: error, completed: completed)
|
||||
let disposable = self.generator(subscriber)
|
||||
subscriber.assignDisposable(disposable)
|
||||
return SubscriberDisposable(subscriber: subscriber, disposable: disposable).strict(file: file, line: line)
|
||||
}
|
||||
|
||||
public static func single(_ value: T) -> Signal<T, E> {
|
||||
return Signal<T, E> { subscriber in
|
||||
subscriber.putNext(value)
|
||||
|
@ -72,7 +72,7 @@ private func combineLatestAny<E, R>(_ signals: [Signal<Any, E>], combine: @escap
|
||||
disposable.add(signalDisposable)
|
||||
}
|
||||
|
||||
return disposable;
|
||||
return disposable
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -64,10 +64,10 @@ public func suspendAwareDelay<T, E>(_ timeout: Double, granularity: Double = 4.0
|
||||
startFinalTimer()
|
||||
} else {
|
||||
var invalidateImpl: (() -> Void)?
|
||||
let timer = Timer(timeout: granularity, repeat: true, completion: {
|
||||
let timer = Timer(timeout: granularity, repeat: true, completion: { timer in
|
||||
let currentTimestamp = CFAbsoluteTimeGetCurrent()
|
||||
if beginTimestamp + timeout - granularity * 1.1 <= currentTimestamp {
|
||||
invalidateImpl?()
|
||||
timer.invalidate()
|
||||
startFinalTimer()
|
||||
}
|
||||
}, queue: queue)
|
||||
|
@ -4,10 +4,19 @@ public final class Timer {
|
||||
private let timer = Atomic<DispatchSourceTimer?>(value: nil)
|
||||
private let timeout: Double
|
||||
private let `repeat`: Bool
|
||||
private let completion: () -> Void
|
||||
private let completion: (Timer) -> Void
|
||||
private let queue: Queue
|
||||
|
||||
public init(timeout: Double, `repeat`: Bool, completion: @escaping() -> Void, queue: Queue) {
|
||||
public init(timeout: Double, `repeat`: Bool, completion: @escaping () -> Void, queue: Queue) {
|
||||
self.timeout = timeout
|
||||
self.`repeat` = `repeat`
|
||||
self.completion = { _ in
|
||||
completion()
|
||||
}
|
||||
self.queue = queue
|
||||
}
|
||||
|
||||
public init(timeout: Double, `repeat`: Bool, completion: @escaping (Timer) -> Void, queue: Queue) {
|
||||
self.timeout = timeout
|
||||
self.`repeat` = `repeat`
|
||||
self.completion = completion
|
||||
@ -22,7 +31,7 @@ public final class Timer {
|
||||
let timer = DispatchSource.makeTimerSource(queue: self.queue.queue)
|
||||
timer.setEventHandler(handler: { [weak self] in
|
||||
if let strongSelf = self {
|
||||
strongSelf.completion()
|
||||
strongSelf.completion(strongSelf)
|
||||
if !strongSelf.`repeat` {
|
||||
strongSelf.invalidate()
|
||||
}
|
||||
|
@ -246,7 +246,7 @@ func makeAttachmentFileControllerImpl(context: AccountContext, updatedPresentati
|
||||
},
|
||||
send: { message in
|
||||
let _ = (context.engine.messages.getMessagesLoadIfNecessary([message.id], strategy: .cloud(skipLocal: true))
|
||||
|> deliverOnMainQueue).start(next: { messages in
|
||||
|> deliverOnMainQueue).startStandalone(next: { messages in
|
||||
if let message = messages.first, let file = message.media.first(where: { $0 is TelegramMediaFile }) as? TelegramMediaFile {
|
||||
send(.message(message: MessageReference(message), media: file))
|
||||
}
|
||||
|
@ -129,7 +129,7 @@ final class AttachmentFileSearchItem: ItemListControllerSearch {
|
||||
} else {
|
||||
return .single(value)
|
||||
}
|
||||
}).start(next: { [weak self] value in
|
||||
}).startStrict(next: { [weak self] value in
|
||||
self?.updateActivity?(value)
|
||||
}))
|
||||
}
|
||||
@ -421,7 +421,7 @@ public final class AttachmentFileSearchContainerNode: SearchDisplayControllerCon
|
||||
|
||||
let previousSearchItems = Atomic<[AttachmentFileSearchEntry]?>(value: nil)
|
||||
self.searchDisposable.set((combineLatest(searchQuery, foundItems, self.presentationDataPromise.get())
|
||||
|> deliverOnMainQueue).start(next: { [weak self] query, entries, presentationData in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] query, entries, presentationData in
|
||||
if let strongSelf = self {
|
||||
let previousEntries = previousSearchItems.swap(entries)
|
||||
updateActivity(false)
|
||||
@ -432,7 +432,7 @@ public final class AttachmentFileSearchContainerNode: SearchDisplayControllerCon
|
||||
}))
|
||||
|
||||
self.presentationDataDisposable = (context.sharedContext.presentationData
|
||||
|> deliverOnMainQueue).start(next: { [weak self] presentationData in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] presentationData in
|
||||
if let strongSelf = self {
|
||||
var presentationData = presentationData
|
||||
|
||||
|
@ -298,7 +298,7 @@ final class ChatBotInfoItemNode: ListViewItemNode {
|
||||
if let updatedImageSignal = updatedImageSignal {
|
||||
strongSelf.imageNode.setSignal(updatedImageSignal)
|
||||
if let image = item.photo {
|
||||
strongSelf.fetchDisposable.set(chatMessagePhotoInteractiveFetched(context: item.context, userLocation: .other, photoReference: .standalone(media: image), displayAtSize: nil, storeToDownloadsPeerId: nil).start())
|
||||
strongSelf.fetchDisposable.set(chatMessagePhotoInteractiveFetched(context: item.context, userLocation: .other, photoReference: .standalone(media: image), displayAtSize: nil, storeToDownloadsPeerId: nil).startStrict())
|
||||
}
|
||||
}
|
||||
strongSelf.imageNode.isHidden = false
|
||||
@ -458,7 +458,7 @@ final class ChatBotInfoItemNode: ListViewItemNode {
|
||||
case let .peerMention(peerId, _, _):
|
||||
if let item = self.item {
|
||||
let _ = (item.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|
||||
|> deliverOnMainQueue).start(next: { [weak self] peer in
|
||||
|> deliverOnMainQueue).startStandalone(next: { [weak self] peer in
|
||||
if let peer = peer {
|
||||
self?.item?.controllerInteraction.openPeer(peer, .chat(textInputState: nil, subject: nil, peekData: nil), nil, .default)
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ final class ChatBotStartInputPanelNode: ChatInputPanelNode {
|
||||
if let _ = self.interfaceInteraction {
|
||||
if self.statusDisposable == nil {
|
||||
if let startingBot = self.interfaceInteraction?.statuses?.startingBot {
|
||||
self.statusDisposable = (startingBot |> deliverOnMainQueue).start(next: { [weak self] value in
|
||||
self.statusDisposable = (startingBot |> deliverOnMainQueue).startStrict(next: { [weak self] value in
|
||||
if let strongSelf = self {
|
||||
strongSelf.inProgress = value
|
||||
}
|
||||
|
@ -426,7 +426,7 @@ final class ChatButtonKeyboardInputNode: ChatInputNode {
|
||||
self.controllerInteraction.openPollCreation(isQuiz)
|
||||
case let .openUserProfile(peerId):
|
||||
let _ = (self.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|
||||
|> deliverOnMainQueue).start(next: { [weak self] peer in
|
||||
|> deliverOnMainQueue).startStandalone(next: { [weak self] peer in
|
||||
guard let self, let peer else {
|
||||
return
|
||||
}
|
||||
|
@ -224,7 +224,7 @@ final class ChatChannelSubscriberInputPanelNode: ChatInputPanelNode {
|
||||
strongSelf.isJoining = false
|
||||
}
|
||||
}
|
||||
}).start(error: { [weak self] error in
|
||||
}).startStrict(error: { [weak self] error in
|
||||
guard let strongSelf = self, let presentationInterfaceState = strongSelf.presentationInterfaceState, let peer = presentationInterfaceState.renderedPeer?.peer else {
|
||||
return
|
||||
}
|
||||
@ -256,7 +256,7 @@ final class ChatChannelSubscriberInputPanelNode: ChatInputPanelNode {
|
||||
break
|
||||
case .muteNotifications, .unmuteNotifications:
|
||||
if let context = self.context, let presentationInterfaceState = self.presentationInterfaceState, let peer = presentationInterfaceState.renderedPeer?.peer {
|
||||
self.actionDisposable.set(context.engine.peers.togglePeerMuted(peerId: peer.id, threadId: nil).start())
|
||||
self.actionDisposable.set(context.engine.peers.togglePeerMuted(peerId: peer.id, threadId: nil).startStrict())
|
||||
}
|
||||
case .hidePinnedMessages, .unpinMessages:
|
||||
self.interfaceInteraction?.unpinAllMessages()
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -612,7 +612,7 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
let appConfiguration: AppConfiguration = preferencesView.values[PreferencesKeys.appConfiguration]?.get(AppConfiguration.self) ?? .defaultValue
|
||||
return InteractiveEmojiConfiguration.with(appConfiguration: appConfiguration)
|
||||
}
|
||||
|> deliverOnMainQueue).start(next: { [weak self] emojis in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] emojis in
|
||||
if let strongSelf = self {
|
||||
strongSelf.interactiveEmojis = emojis
|
||||
}
|
||||
@ -748,7 +748,7 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
}
|
||||
|
||||
self.inputMediaNodeDataDisposable = (self.inputMediaNodeDataPromise.get()
|
||||
|> deliverOnMainQueue).start(next: { [weak self] value in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] value in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -823,7 +823,7 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
} else {
|
||||
return .single(display)
|
||||
}
|
||||
}).start(next: { [weak self] display in
|
||||
}).startStrict(next: { [weak self] display in
|
||||
if let strongSelf = self, let interfaceInteraction = strongSelf.interfaceInteraction {
|
||||
if display {
|
||||
var nodes: [(CGFloat, ChatMessageItemView, ASDisplayNode)] = []
|
||||
@ -3154,7 +3154,7 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
if self.openStickersDisposable == nil {
|
||||
self.openStickersDisposable = (self.inputMediaNodeDataPromise.get()
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] _ in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] _ in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
|
@ -180,7 +180,7 @@ final class ChatEmptyNodeGreetingChatContent: ASDisplayNode, ChatEmptyNodeSticke
|
||||
|
||||
self.didSetupSticker = true
|
||||
self.disposable.set((sticker
|
||||
|> deliverOnMainQueue).start(next: { [weak self] sticker in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] sticker in
|
||||
if let strongSelf = self, let sticker = sticker {
|
||||
let inputNodeInteraction = ChatMediaInputNodeInteraction(
|
||||
navigateToCollectionId: { _ in
|
||||
@ -351,7 +351,7 @@ final class ChatEmptyNodeNearbyChatContent: ASDisplayNode, ChatEmptyNodeStickerC
|
||||
|
||||
self.didSetupSticker = true
|
||||
self.disposable.set((sticker
|
||||
|> deliverOnMainQueue).start(next: { [weak self] sticker in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] sticker in
|
||||
if let strongSelf = self, let sticker = sticker {
|
||||
let inputNodeInteraction = ChatMediaInputNodeInteraction(
|
||||
navigateToCollectionId: { _ in
|
||||
|
@ -434,8 +434,6 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
||||
private let historyDisposable = MetaDisposable()
|
||||
private let readHistoryDisposable = MetaDisposable()
|
||||
|
||||
//private let messageViewQueue = Queue(name: "ChatHistoryListNode processing")
|
||||
|
||||
private var dequeuedInitialTransitionOnLayout = false
|
||||
private var enqueuedHistoryViewTransitions: [ChatHistoryListViewTransition] = []
|
||||
private var hasActiveTransition = false
|
||||
@ -667,10 +665,8 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
||||
|
||||
public init(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>), chatLocation: ChatLocation, chatLocationContextHolder: Atomic<ChatLocationContextHolder?>, tagMask: MessageTags?, source: ChatHistoryListSource = .default, subject: ChatControllerSubject?, controllerInteraction: ChatControllerInteraction, selectedMessages: Signal<Set<MessageId>?, NoError>, mode: ChatHistoryListMode = .bubbles, messageTransitionNode: @escaping () -> ChatMessageTransitionNode? = { nil }) {
|
||||
var tagMask = tagMask
|
||||
var appendMessagesFromTheSameGroup = false
|
||||
if case .pinnedMessages = subject {
|
||||
tagMask = .pinned
|
||||
appendMessagesFromTheSameGroup = true
|
||||
}
|
||||
|
||||
self.context = context
|
||||
@ -692,14 +688,12 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
||||
self.chatPresentationDataPromise = Promise()
|
||||
|
||||
self.prefetchManager = InChatPrefetchManager(context: context)
|
||||
|
||||
|
||||
var displayAdPeer: PeerId?
|
||||
//var sparseScrollPeerId: PeerId?
|
||||
switch subject {
|
||||
case .none, .message:
|
||||
if case let .peer(peerId) = chatLocation {
|
||||
displayAdPeer = peerId
|
||||
//sparseScrollPeerId = peerId
|
||||
}
|
||||
default:
|
||||
break
|
||||
@ -713,12 +707,6 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
||||
self.adMessagesContext = nil
|
||||
adMessages = .single((nil, []))
|
||||
}
|
||||
|
||||
/*if case .bubbles = mode, let peerId = sparseScrollPeerId {
|
||||
self.sparseScrollingContext = context.engine.messages.sparseMessageScrollingContext(peerId: peerId)
|
||||
} else {
|
||||
self.sparseScrollingContext = nil
|
||||
}*/
|
||||
|
||||
let clientId = Atomic<Int32>(value: nextClientId)
|
||||
self.clientId = clientId
|
||||
@ -726,46 +714,10 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
||||
|
||||
super.init()
|
||||
|
||||
self.adMessagesDisposable = (adMessages
|
||||
|> deliverOnMainQueue).start(next: { [weak self] interPostInterval, messages in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
|
||||
if let interPostInterval = interPostInterval {
|
||||
self.pendingDynamicAdMessages = messages
|
||||
self.pendingDynamicAdMessageInterval = Int(interPostInterval)
|
||||
|
||||
if self.remainingDynamicAdMessageInterval == nil {
|
||||
self.remainingDynamicAdMessageInterval = Int(interPostInterval)
|
||||
}
|
||||
if self.remainingDynamicAdMessageDistance == nil {
|
||||
self.remainingDynamicAdMessageDistance = self.bounds.height
|
||||
}
|
||||
|
||||
self.allAdMessages = (messages.first, [], 0)
|
||||
} else {
|
||||
var adPeerId: PeerId?
|
||||
adPeerId = messages.first?.author?.id
|
||||
|
||||
if self.preloadAdPeerId != adPeerId {
|
||||
self.preloadAdPeerId = adPeerId
|
||||
if let adPeerId = adPeerId {
|
||||
let combinedDisposable = DisposableSet()
|
||||
self.preloadAdPeerDisposable.set(combinedDisposable)
|
||||
combinedDisposable.add(self.context.account.viewTracker.polledChannel(peerId: adPeerId).start())
|
||||
combinedDisposable.add(self.context.account.addAdditionalPreloadHistoryPeerId(peerId: adPeerId))
|
||||
} else {
|
||||
self.preloadAdPeerDisposable.set(nil)
|
||||
}
|
||||
}
|
||||
|
||||
self.allAdMessages = (messages.first, [], 0)
|
||||
}
|
||||
})
|
||||
|
||||
self.clipsToBounds = false
|
||||
|
||||
self.beginAdMessageManagement(adMessages: adMessages)
|
||||
|
||||
self.accessibilityPageScrolledString = { [weak self] row, count in
|
||||
if let strongSelf = self {
|
||||
return strongSelf.currentPresentationData.strings.VoiceOver_ScrollStatus(row, count).string
|
||||
@ -799,7 +751,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
||||
}
|
||||
self.translationProcessingManager.process = { [weak self, weak context] messageIds in
|
||||
if let context = context, let toLang = self?.toLang {
|
||||
let _ = translateMessageIds(context: context, messageIds: Array(messageIds), toLang: toLang).start()
|
||||
let _ = translateMessageIds(context: context, messageIds: Array(messageIds), toLang: toLang).startStandalone()
|
||||
}
|
||||
}
|
||||
|
||||
@ -838,23 +790,261 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
||||
case .list:
|
||||
break
|
||||
}
|
||||
//self.snapToBottomInsetUntilFirstInteraction = true
|
||||
|
||||
let messageViewQueue = Queue.mainQueue() //self.messageViewQueue
|
||||
self.beginChatHistoryTransitions(
|
||||
selectedMessages: selectedMessages,
|
||||
messageTransitionNode: messageTransitionNode
|
||||
)
|
||||
|
||||
self.beginReadHistoryManagement()
|
||||
|
||||
if let subject = subject, case let .message(messageSubject, highlight, _) = subject {
|
||||
let initialSearchLocation: ChatHistoryInitialSearchLocation
|
||||
switch messageSubject {
|
||||
case let .id(id):
|
||||
initialSearchLocation = .id(id)
|
||||
case let .timestamp(timestamp):
|
||||
if let peerId = self.chatLocation.peerId {
|
||||
initialSearchLocation = .index(MessageIndex(id: MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: 1), timestamp: timestamp))
|
||||
} else {
|
||||
//TODO:implement
|
||||
initialSearchLocation = .index(MessageIndex.absoluteUpperBound())
|
||||
}
|
||||
}
|
||||
self.chatHistoryLocationValue = ChatHistoryLocationInput(content: .InitialSearch(location: initialSearchLocation, count: historyMessageCount, highlight: highlight), id: 0)
|
||||
} else if let subject = subject, case let .pinnedMessages(maybeMessageId) = subject, let messageId = maybeMessageId {
|
||||
self.chatHistoryLocationValue = ChatHistoryLocationInput(content: .InitialSearch(location: .id(messageId), count: historyMessageCount, highlight: true), id: 0)
|
||||
} else {
|
||||
self.chatHistoryLocationValue = ChatHistoryLocationInput(content: .Initial(count: historyMessageCount), id: 0)
|
||||
}
|
||||
self.chatHistoryLocationPromise.set(self.chatHistoryLocationValue!)
|
||||
|
||||
self.generalScrollDirectionUpdated = { [weak self] direction in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
let prefetchDirectionIsToLater = direction == .up
|
||||
if strongSelf.currentPrefetchDirectionIsToLater != prefetchDirectionIsToLater {
|
||||
strongSelf.currentPrefetchDirectionIsToLater = prefetchDirectionIsToLater
|
||||
if strongSelf.currentPrefetchDirectionIsToLater {
|
||||
strongSelf.prefetchManager.updateMessages(strongSelf.currentLaterPrefetchMessages, directionIsToLater: strongSelf.currentPrefetchDirectionIsToLater)
|
||||
} else {
|
||||
strongSelf.prefetchManager.updateMessages(strongSelf.currentEarlierPrefetchMessages, directionIsToLater: strongSelf.currentPrefetchDirectionIsToLater)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.displayedItemRangeChanged = { [weak self] displayedRange, opaqueTransactionState in
|
||||
if let strongSelf = self, let transactionState = opaqueTransactionState as? ChatHistoryTransactionOpaqueState {
|
||||
strongSelf.processDisplayedItemRangeChanged(displayedRange: displayedRange, transactionState: transactionState)
|
||||
}
|
||||
}
|
||||
|
||||
self.refreshDisplayedItemRangeTimer = SwiftSignalKit.Timer(timeout: 10.0, repeat: true, completion: { [weak self] in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
strongSelf.updateVisibleItemRange(force: true)
|
||||
}, queue: .mainQueue())
|
||||
self.refreshDisplayedItemRangeTimer?.start()
|
||||
|
||||
self.beginPresentationDataManagement(updated: updatedPresentationData.signal)
|
||||
|
||||
self.visibleContentOffsetChanged = { [weak self] offset in
|
||||
if let strongSelf = self {
|
||||
strongSelf.contentPositionChanged(offset)
|
||||
|
||||
if strongSelf.tagMask == nil {
|
||||
var atBottom = false
|
||||
var offsetFromBottom: CGFloat?
|
||||
switch offset {
|
||||
case let .known(offsetValue):
|
||||
if offsetValue.isLessThanOrEqualTo(0.0) {
|
||||
atBottom = true
|
||||
offsetFromBottom = offsetValue
|
||||
}
|
||||
//print("offsetValue: \(offsetValue)")
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
if atBottom != strongSelf.isScrollAtBottomPosition {
|
||||
strongSelf.isScrollAtBottomPosition = atBottom
|
||||
strongSelf.updateReadHistoryActions()
|
||||
|
||||
strongSelf.isScrollAtBottomPositionUpdated?()
|
||||
}
|
||||
|
||||
strongSelf.maybeUpdateOverscrollAction(offset: offsetFromBottom)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.loadedMessagesFromCachedDataDisposable = (self._cachedPeerDataAndMessages.get() |> map { dataAndMessages -> MessageId? in
|
||||
return dataAndMessages.0?.messageIds.first
|
||||
} |> distinctUntilChanged(isEqual: { $0 == $1 })
|
||||
|> mapToSignal { messageId -> Signal<Void, NoError> in
|
||||
if let messageId = messageId {
|
||||
return context.engine.messages.getMessagesLoadIfNecessary([messageId]) |> map { _ -> Void in return Void() }
|
||||
} else {
|
||||
return .complete()
|
||||
}
|
||||
}).startStrict()
|
||||
|
||||
self.beganInteractiveDragging = { [weak self] _ in
|
||||
self?.isInteractivelyScrollingValue = true
|
||||
self?.isInteractivelyScrollingPromise.set(true)
|
||||
self?.beganDragging?()
|
||||
//self?.updateHistoryScrollingArea(transition: .immediate)
|
||||
}
|
||||
|
||||
self.endedInteractiveDragging = { [weak self] _ in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
if strongSelf.offerNextChannelToRead, strongSelf.currentOverscrollExpandProgress >= 0.99 {
|
||||
if let nextChannelToRead = strongSelf.nextChannelToRead {
|
||||
strongSelf.freezeOverscrollControl = true
|
||||
strongSelf.openNextChannelToRead?(nextChannelToRead.peer, nextChannelToRead.location)
|
||||
} else {
|
||||
strongSelf.freezeOverscrollControlProgress = true
|
||||
strongSelf.scroller.contentInset = UIEdgeInsets(top: 94.0 + 12.0, left: 0.0, bottom: 0.0, right: 0.0)
|
||||
Queue.mainQueue().after(0.3, {
|
||||
let animator = DisplayLinkAnimator(duration: 0.2, from: 1.0, to: 0.0, update: { rawT in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
let t = listViewAnimationCurveEaseInOut(rawT)
|
||||
let value = (94.0 + 12.0) * t
|
||||
strongSelf.scroller.contentInset = UIEdgeInsets(top: value, left: 0.0, bottom: 0.0, right: 0.0)
|
||||
}, completion: {
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
strongSelf.contentInsetAnimator = nil
|
||||
strongSelf.scroller.contentInset = UIEdgeInsets()
|
||||
strongSelf.freezeOverscrollControlProgress = false
|
||||
})
|
||||
strongSelf.contentInsetAnimator = animator
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.didEndScrolling = { [weak self] _ in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
strongSelf.isInteractivelyScrollingValue = false
|
||||
strongSelf.isInteractivelyScrollingPromise.set(false)
|
||||
//strongSelf.updateHistoryScrollingArea(transition: .immediate)
|
||||
}
|
||||
|
||||
/*self.updateScrollingIndicator = { [weak self] scrollingState, transition in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
strongSelf.scrollingState = scrollingState
|
||||
strongSelf.updateHistoryScrollingArea(transition: transition)
|
||||
}*/
|
||||
|
||||
let selectionRecognizer = ChatHistoryListSelectionRecognizer(target: self, action: #selector(self.selectionPanGesture(_:)))
|
||||
selectionRecognizer.shouldBegin = { [weak self] in
|
||||
guard let strongSelf = self else {
|
||||
return false
|
||||
}
|
||||
return strongSelf.isSelectionGestureEnabled
|
||||
}
|
||||
self.view.addGestureRecognizer(selectionRecognizer)
|
||||
|
||||
self.loadNextGenericReactionEffect(context: context)
|
||||
}
|
||||
|
||||
deinit {
|
||||
self.historyDisposable.dispose()
|
||||
self.readHistoryDisposable.dispose()
|
||||
self.interactiveReadActionDisposable?.dispose()
|
||||
self.interactiveReadReactionsDisposable?.dispose()
|
||||
self.canReadHistoryDisposable?.dispose()
|
||||
self.loadedMessagesFromCachedDataDisposable?.dispose()
|
||||
self.preloadAdPeerDisposable.dispose()
|
||||
self.refreshDisplayedItemRangeTimer?.invalidate()
|
||||
self.genericReactionEffectDisposable?.dispose()
|
||||
self.adMessagesDisposable?.dispose()
|
||||
self.presentationDataDisposable?.dispose()
|
||||
}
|
||||
|
||||
private func beginAdMessageManagement(adMessages: Signal<(interPostInterval: Int32?, messages: [Message]), NoError>) {
|
||||
self.adMessagesDisposable = (adMessages
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] interPostInterval, messages in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
|
||||
if let interPostInterval = interPostInterval {
|
||||
self.pendingDynamicAdMessages = messages
|
||||
self.pendingDynamicAdMessageInterval = Int(interPostInterval)
|
||||
|
||||
if self.remainingDynamicAdMessageInterval == nil {
|
||||
self.remainingDynamicAdMessageInterval = Int(interPostInterval)
|
||||
}
|
||||
if self.remainingDynamicAdMessageDistance == nil {
|
||||
self.remainingDynamicAdMessageDistance = self.bounds.height
|
||||
}
|
||||
|
||||
self.allAdMessages = (messages.first, [], 0)
|
||||
} else {
|
||||
var adPeerId: PeerId?
|
||||
adPeerId = messages.first?.author?.id
|
||||
|
||||
if self.preloadAdPeerId != adPeerId {
|
||||
self.preloadAdPeerId = adPeerId
|
||||
if let adPeerId = adPeerId {
|
||||
let combinedDisposable = DisposableSet()
|
||||
self.preloadAdPeerDisposable.set(combinedDisposable)
|
||||
combinedDisposable.add(self.context.account.viewTracker.polledChannel(peerId: adPeerId).startStrict())
|
||||
combinedDisposable.add(self.context.account.addAdditionalPreloadHistoryPeerId(peerId: adPeerId))
|
||||
} else {
|
||||
self.preloadAdPeerDisposable.set(nil)
|
||||
}
|
||||
}
|
||||
|
||||
self.allAdMessages = (messages.first, [], 0)
|
||||
}
|
||||
}).strict()
|
||||
}
|
||||
|
||||
private func beginChatHistoryTransitions(
|
||||
selectedMessages: Signal<Set<MessageId>?, NoError>,
|
||||
messageTransitionNode: @escaping () -> ChatMessageTransitionNode?
|
||||
) {
|
||||
let context = self.context
|
||||
let chatLocation = self.chatLocation
|
||||
let subject = self.subject
|
||||
let source = self.source
|
||||
let tagMask = self.tagMask
|
||||
let chatLocationContextHolder = self.chatLocationContextHolder
|
||||
let controllerInteraction = self.controllerInteraction
|
||||
let mode = self.mode
|
||||
|
||||
var appendMessagesFromTheSameGroup = false
|
||||
if case .pinnedMessages = subject {
|
||||
appendMessagesFromTheSameGroup = true
|
||||
}
|
||||
|
||||
let fixedCombinedReadStates = Atomic<MessageHistoryViewReadState?>(value: nil)
|
||||
|
||||
var isScheduledMessages = false
|
||||
if let subject = subject, case .scheduledMessages = subject {
|
||||
if let subject = self.subject, case .scheduledMessages = subject {
|
||||
isScheduledMessages = true
|
||||
}
|
||||
var isAuxiliaryChat = isScheduledMessages
|
||||
if case .replyThread = chatLocation {
|
||||
if case .replyThread = self.chatLocation {
|
||||
isAuxiliaryChat = true
|
||||
}
|
||||
|
||||
var additionalData: [AdditionalMessageHistoryViewData] = []
|
||||
if case let .peer(peerId) = chatLocation {
|
||||
if case let .peer(peerId) = self.chatLocation {
|
||||
additionalData.append(.cachedPeerData(peerId))
|
||||
additionalData.append(.cachedPeerDataMessages(peerId))
|
||||
additionalData.append(.peerNotificationSettings(peerId))
|
||||
@ -871,7 +1061,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
||||
if !isAuxiliaryChat {
|
||||
additionalData.append(.totalUnreadState)
|
||||
}
|
||||
if case let .replyThread(replyThreadMessage) = chatLocation {
|
||||
if case let .replyThread(replyThreadMessage) = self.chatLocation {
|
||||
additionalData.append(.cachedPeerData(replyThreadMessage.messageId.peerId))
|
||||
additionalData.append(.peerNotificationSettings(replyThreadMessage.messageId.peerId))
|
||||
if replyThreadMessage.messageId.peerId.namespace == Namespaces.Peer.CloudChannel {
|
||||
@ -887,7 +1077,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
||||
let historyViewUpdate: Signal<(ChatHistoryViewUpdate, Int, ChatHistoryLocationInput?, ClosedRange<Int32>?), NoError>
|
||||
var isFirstTime = true
|
||||
var updateAllOnEachVersion = false
|
||||
if case let .custom(messages, at, _) = source {
|
||||
if case let .custom(messages, at, _) = self.source {
|
||||
updateAllOnEachVersion = true
|
||||
historyViewUpdate = messages
|
||||
|> map { messages, _, hasMore in
|
||||
@ -1030,8 +1220,8 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
||||
let availableReactions: Signal<AvailableReactions?, NoError> = (context as! AccountContextImpl).availableReactions
|
||||
|
||||
let defaultReaction = combineLatest(
|
||||
context.engine.data.subscribe(TelegramEngine.EngineData.Item.Peer.Peer(id: context.account.peerId)),
|
||||
context.account.postbox.preferencesView(keys: [PreferencesKeys.reactionSettings])
|
||||
self.context.engine.data.subscribe(TelegramEngine.EngineData.Item.Peer.Peer(id: context.account.peerId)),
|
||||
self.context.account.postbox.preferencesView(keys: [PreferencesKeys.reactionSettings])
|
||||
)
|
||||
|> map { peer, preferencesView -> MessageReaction.Reaction? in
|
||||
let reactionSettings: ReactionSettings
|
||||
@ -1087,8 +1277,8 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
||||
)
|
||||
|
||||
let maxReadStoryId: Signal<Int32?, NoError>
|
||||
if let peerId = chatLocation.peerId, peerId.namespace == Namespaces.Peer.CloudUser {
|
||||
maxReadStoryId = context.account.postbox.combinedView(keys: [PostboxViewKey.storiesState(key: .peer(peerId))])
|
||||
if let peerId = self.chatLocation.peerId, peerId.namespace == Namespaces.Peer.CloudUser {
|
||||
maxReadStoryId = self.context.account.postbox.combinedView(keys: [PostboxViewKey.storiesState(key: .peer(peerId))])
|
||||
|> map { views -> Int32? in
|
||||
guard let view = views.views[PostboxViewKey.storiesState(key: .peer(peerId))] as? StoryStatesView else {
|
||||
return nil
|
||||
@ -1104,6 +1294,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
||||
maxReadStoryId = .single(nil)
|
||||
}
|
||||
|
||||
let messageViewQueue = Queue.mainQueue()
|
||||
let historyViewTransitionDisposable = combineLatest(queue: messageViewQueue,
|
||||
historyViewUpdate,
|
||||
self.chatPresentationDataPromise.get(),
|
||||
@ -1123,7 +1314,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
||||
self.allAdMessagesPromise.get(),
|
||||
translationState,
|
||||
maxReadStoryId
|
||||
).start(next: { [weak self] update, chatPresentationData, selectedMessages, updatingMedia, networkType, animatedEmojiStickers, additionalAnimatedEmojiStickers, customChannelDiscussionReadState, customThreadOutgoingReadState, availableReactions, defaultReaction, accountPeer, suggestAudioTranscription, promises, topicAuthorId, allAdMessages, translationState, maxReadStoryId in
|
||||
).startStrict(next: { [weak self] update, chatPresentationData, selectedMessages, updatingMedia, networkType, animatedEmojiStickers, additionalAnimatedEmojiStickers, customChannelDiscussionReadState, customThreadOutgoingReadState, availableReactions, defaultReaction, accountPeer, suggestAudioTranscription, promises, topicAuthorId, allAdMessages, translationState, maxReadStoryId in
|
||||
let (historyAppearsCleared, pendingUnpinnedAllMessages, pendingRemovedMessages, currentlyPlayingMessageIdAndType, scrollToMessageId, chatHasBots) = promises
|
||||
|
||||
func applyHole() {
|
||||
@ -1266,7 +1457,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
||||
|
||||
var translateToLanguage: String?
|
||||
if let translationState, isPremium && translationState.isEnabled {
|
||||
var languageCode = translationState.toLang ?? presentationData.strings.baseLanguageCode
|
||||
var languageCode = translationState.toLang ?? chatPresentationData.strings.baseLanguageCode
|
||||
let rawSuffix = "-raw"
|
||||
if languageCode.hasSuffix(rawSuffix) {
|
||||
languageCode = String(languageCode.dropLast(rawSuffix.count))
|
||||
@ -1487,12 +1678,14 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
||||
}
|
||||
})
|
||||
|
||||
self.historyDisposable.set(historyViewTransitionDisposable)
|
||||
|
||||
self.historyDisposable.set(historyViewTransitionDisposable.strict())
|
||||
}
|
||||
|
||||
private func beginReadHistoryManagement() {
|
||||
let previousMaxIncomingMessageIndexByNamespace = Atomic<[MessageId.Namespace: MessageIndex]>(value: [:])
|
||||
let readHistory = combineLatest(self.maxVisibleIncomingMessageIndex.get(), self.canReadHistory.get())
|
||||
|
||||
self.readHistoryDisposable.set((readHistory |> deliverOnMainQueue).start(next: { [weak self] messageIndex, canRead in
|
||||
self.readHistoryDisposable.set((readHistory |> deliverOnMainQueue).startStrict(next: { [weak self] messageIndex, canRead in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -1512,16 +1705,16 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
||||
return dict
|
||||
}
|
||||
if apply {
|
||||
switch chatLocation {
|
||||
switch strongSelf.chatLocation {
|
||||
case .peer, .replyThread, .feed:
|
||||
if !strongSelf.context.sharedContext.immediateExperimentalUISettings.skipReadHistory {
|
||||
strongSelf.context.applyMaxReadIndex(for: chatLocation, contextHolder: chatLocationContextHolder, messageIndex: messageIndex)
|
||||
strongSelf.context.applyMaxReadIndex(for: strongSelf.chatLocation, contextHolder: strongSelf.chatLocationContextHolder, messageIndex: messageIndex)
|
||||
}
|
||||
}
|
||||
}
|
||||
}))
|
||||
}).strict())
|
||||
|
||||
self.canReadHistoryDisposable = (self.canReadHistory.get() |> deliverOnMainQueue).start(next: { [weak self, weak context] value in
|
||||
self.canReadHistoryDisposable = (self.canReadHistory.get() |> deliverOnMainQueue).startStrict(next: { [weak self, weak context] value in
|
||||
if let strongSelf = self {
|
||||
if strongSelf.canReadHistoryValue != value {
|
||||
strongSelf.canReadHistoryValue = value
|
||||
@ -1536,70 +1729,22 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
||||
strongSelf.attemptReadingReactions()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
if let subject = subject, case let .message(messageSubject, highlight, _) = subject {
|
||||
let initialSearchLocation: ChatHistoryInitialSearchLocation
|
||||
switch messageSubject {
|
||||
case let .id(id):
|
||||
initialSearchLocation = .id(id)
|
||||
case let .timestamp(timestamp):
|
||||
if let peerId = self.chatLocation.peerId {
|
||||
initialSearchLocation = .index(MessageIndex(id: MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: 1), timestamp: timestamp))
|
||||
} else {
|
||||
//TODO:implement
|
||||
initialSearchLocation = .index(MessageIndex.absoluteUpperBound())
|
||||
}
|
||||
}
|
||||
self.chatHistoryLocationValue = ChatHistoryLocationInput(content: .InitialSearch(location: initialSearchLocation, count: historyMessageCount, highlight: highlight), id: 0)
|
||||
} else if let subject = subject, case let .pinnedMessages(maybeMessageId) = subject, let messageId = maybeMessageId {
|
||||
self.chatHistoryLocationValue = ChatHistoryLocationInput(content: .InitialSearch(location: .id(messageId), count: historyMessageCount, highlight: true), id: 0)
|
||||
} else {
|
||||
self.chatHistoryLocationValue = ChatHistoryLocationInput(content: .Initial(count: historyMessageCount), id: 0)
|
||||
}
|
||||
self.chatHistoryLocationPromise.set(self.chatHistoryLocationValue!)
|
||||
|
||||
self.generalScrollDirectionUpdated = { [weak self] direction in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
let prefetchDirectionIsToLater = direction == .up
|
||||
if strongSelf.currentPrefetchDirectionIsToLater != prefetchDirectionIsToLater {
|
||||
strongSelf.currentPrefetchDirectionIsToLater = prefetchDirectionIsToLater
|
||||
if strongSelf.currentPrefetchDirectionIsToLater {
|
||||
strongSelf.prefetchManager.updateMessages(strongSelf.currentLaterPrefetchMessages, directionIsToLater: strongSelf.currentPrefetchDirectionIsToLater)
|
||||
} else {
|
||||
strongSelf.prefetchManager.updateMessages(strongSelf.currentEarlierPrefetchMessages, directionIsToLater: strongSelf.currentPrefetchDirectionIsToLater)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.displayedItemRangeChanged = { [weak self] displayedRange, opaqueTransactionState in
|
||||
if let strongSelf = self, let transactionState = opaqueTransactionState as? ChatHistoryTransactionOpaqueState {
|
||||
strongSelf.processDisplayedItemRangeChanged(displayedRange: displayedRange, transactionState: transactionState)
|
||||
}
|
||||
}
|
||||
|
||||
self.refreshDisplayedItemRangeTimer = SwiftSignalKit.Timer(timeout: 10.0, repeat: true, completion: { [weak self] in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
strongSelf.updateVisibleItemRange(force: true)
|
||||
}, queue: .mainQueue())
|
||||
self.refreshDisplayedItemRangeTimer?.start()
|
||||
|
||||
let appConfiguration = context.account.postbox.preferencesView(keys: [PreferencesKeys.appConfiguration])
|
||||
}).strict()
|
||||
}
|
||||
|
||||
private func beginPresentationDataManagement(updated: Signal<PresentationData, NoError>) {
|
||||
let appConfiguration = self.context.account.postbox.preferencesView(keys: [PreferencesKeys.appConfiguration])
|
||||
|> take(1)
|
||||
|> map { view in
|
||||
return view.values[PreferencesKeys.appConfiguration]?.get(AppConfiguration.self) ?? .defaultValue
|
||||
}
|
||||
|
||||
var didSetPresentationData = false
|
||||
self.presentationDataDisposable = (
|
||||
combineLatest(queue: .mainQueue(),
|
||||
updatedPresentationData.signal,
|
||||
appConfiguration)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] presentationData, appConfiguration in
|
||||
self.presentationDataDisposable = (combineLatest(queue: .mainQueue(),
|
||||
updated,
|
||||
appConfiguration
|
||||
)
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] presentationData, appConfiguration in
|
||||
if let strongSelf = self {
|
||||
let previousTheme = strongSelf.currentPresentationData.theme
|
||||
let previousStrings = strongSelf.currentPresentationData.strings
|
||||
@ -1619,9 +1764,9 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
||||
|
||||
strongSelf.forEachItemHeaderNode { itemHeaderNode in
|
||||
if let dateNode = itemHeaderNode as? ChatMessageDateHeaderNode {
|
||||
dateNode.updatePresentationData(chatPresentationData, context: context)
|
||||
dateNode.updatePresentationData(chatPresentationData, context: strongSelf.context)
|
||||
} else if let avatarNode = itemHeaderNode as? ChatMessageAvatarHeaderNode {
|
||||
avatarNode.updatePresentationData(chatPresentationData, context: context)
|
||||
avatarNode.updatePresentationData(chatPresentationData, context: strongSelf.context)
|
||||
} else if let dateNode = itemHeaderNode as? ListMessageDateHeaderNode {
|
||||
dateNode.updateThemeAndStrings(theme: presentationData.theme, strings: presentationData.strings)
|
||||
}
|
||||
@ -1629,129 +1774,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
||||
strongSelf.chatPresentationDataPromise.set(.single(chatPresentationData))
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
self.visibleContentOffsetChanged = { [weak self] offset in
|
||||
if let strongSelf = self {
|
||||
strongSelf.contentPositionChanged(offset)
|
||||
|
||||
if strongSelf.tagMask == nil {
|
||||
var atBottom = false
|
||||
var offsetFromBottom: CGFloat?
|
||||
switch offset {
|
||||
case let .known(offsetValue):
|
||||
if offsetValue.isLessThanOrEqualTo(0.0) {
|
||||
atBottom = true
|
||||
offsetFromBottom = offsetValue
|
||||
}
|
||||
//print("offsetValue: \(offsetValue)")
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
if atBottom != strongSelf.isScrollAtBottomPosition {
|
||||
strongSelf.isScrollAtBottomPosition = atBottom
|
||||
strongSelf.updateReadHistoryActions()
|
||||
|
||||
strongSelf.isScrollAtBottomPositionUpdated?()
|
||||
}
|
||||
|
||||
strongSelf.maybeUpdateOverscrollAction(offset: offsetFromBottom)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.loadedMessagesFromCachedDataDisposable = (self._cachedPeerDataAndMessages.get() |> map { dataAndMessages -> MessageId? in
|
||||
return dataAndMessages.0?.messageIds.first
|
||||
} |> distinctUntilChanged(isEqual: { $0 == $1 })
|
||||
|> mapToSignal { messageId -> Signal<Void, NoError> in
|
||||
if let messageId = messageId {
|
||||
return context.engine.messages.getMessagesLoadIfNecessary([messageId]) |> map { _ -> Void in return Void() }
|
||||
} else {
|
||||
return .complete()
|
||||
}
|
||||
}).start()
|
||||
|
||||
self.beganInteractiveDragging = { [weak self] _ in
|
||||
self?.isInteractivelyScrollingValue = true
|
||||
self?.isInteractivelyScrollingPromise.set(true)
|
||||
self?.beganDragging?()
|
||||
//self?.updateHistoryScrollingArea(transition: .immediate)
|
||||
}
|
||||
|
||||
self.endedInteractiveDragging = { [weak self] _ in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
if strongSelf.offerNextChannelToRead, strongSelf.currentOverscrollExpandProgress >= 0.99 {
|
||||
if let nextChannelToRead = strongSelf.nextChannelToRead {
|
||||
strongSelf.freezeOverscrollControl = true
|
||||
strongSelf.openNextChannelToRead?(nextChannelToRead.peer, nextChannelToRead.location)
|
||||
} else {
|
||||
strongSelf.freezeOverscrollControlProgress = true
|
||||
strongSelf.scroller.contentInset = UIEdgeInsets(top: 94.0 + 12.0, left: 0.0, bottom: 0.0, right: 0.0)
|
||||
Queue.mainQueue().after(0.3, {
|
||||
let animator = DisplayLinkAnimator(duration: 0.2, from: 1.0, to: 0.0, update: { rawT in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
let t = listViewAnimationCurveEaseInOut(rawT)
|
||||
let value = (94.0 + 12.0) * t
|
||||
strongSelf.scroller.contentInset = UIEdgeInsets(top: value, left: 0.0, bottom: 0.0, right: 0.0)
|
||||
}, completion: {
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
strongSelf.contentInsetAnimator = nil
|
||||
strongSelf.scroller.contentInset = UIEdgeInsets()
|
||||
strongSelf.freezeOverscrollControlProgress = false
|
||||
})
|
||||
strongSelf.contentInsetAnimator = animator
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.didEndScrolling = { [weak self] _ in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
strongSelf.isInteractivelyScrollingValue = false
|
||||
strongSelf.isInteractivelyScrollingPromise.set(false)
|
||||
//strongSelf.updateHistoryScrollingArea(transition: .immediate)
|
||||
}
|
||||
|
||||
/*self.updateScrollingIndicator = { [weak self] scrollingState, transition in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
strongSelf.scrollingState = scrollingState
|
||||
strongSelf.updateHistoryScrollingArea(transition: transition)
|
||||
}*/
|
||||
|
||||
let selectionRecognizer = ChatHistoryListSelectionRecognizer(target: self, action: #selector(self.selectionPanGesture(_:)))
|
||||
selectionRecognizer.shouldBegin = { [weak self] in
|
||||
guard let strongSelf = self else {
|
||||
return false
|
||||
}
|
||||
return strongSelf.isSelectionGestureEnabled
|
||||
}
|
||||
self.view.addGestureRecognizer(selectionRecognizer)
|
||||
|
||||
self.loadNextGenericReactionEffect(context: context)
|
||||
}
|
||||
|
||||
deinit {
|
||||
self.historyDisposable.dispose()
|
||||
self.readHistoryDisposable.dispose()
|
||||
self.interactiveReadActionDisposable?.dispose()
|
||||
self.interactiveReadReactionsDisposable?.dispose()
|
||||
self.canReadHistoryDisposable?.dispose()
|
||||
self.loadedMessagesFromCachedDataDisposable?.dispose()
|
||||
self.preloadAdPeerDisposable.dispose()
|
||||
self.refreshDisplayedItemRangeTimer?.invalidate()
|
||||
self.genericReactionEffectDisposable?.dispose()
|
||||
self.adMessagesDisposable?.dispose()
|
||||
}).strict()
|
||||
}
|
||||
|
||||
private func attemptReadingReactions() {
|
||||
@ -1774,7 +1797,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
||||
|
||||
private func loadNextGenericReactionEffect(context: AccountContext) {
|
||||
self.genericReactionEffectDisposable?.dispose()
|
||||
self.genericReactionEffectDisposable = (ReactionContextNode.randomGenericReactionEffect(context: context) |> deliverOnMainQueue).start(next: { [weak self] path in
|
||||
self.genericReactionEffectDisposable = (ReactionContextNode.randomGenericReactionEffect(context: context) |> deliverOnMainQueue).startStrict(next: { [weak self] path in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -2389,7 +2412,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
||||
self.messageWithReactionsProcessingManager.add(messageIdsWithPossibleReactions)
|
||||
}
|
||||
if !downloadableResourceIds.isEmpty {
|
||||
let _ = markRecentDownloadItemsAsSeen(postbox: self.context.account.postbox, items: downloadableResourceIds).start()
|
||||
let _ = markRecentDownloadItemsAsSeen(postbox: self.context.account.postbox, items: downloadableResourceIds).startStandalone()
|
||||
}
|
||||
if !messageIdsWithInactiveExtendedMedia.isEmpty {
|
||||
self.extendedMediaProcessingManager.update(messageIdsWithInactiveExtendedMedia)
|
||||
|
@ -1,5 +0,0 @@
|
||||
import Postbox
|
||||
import UIKit
|
||||
import Display
|
||||
|
||||
|
@ -171,7 +171,7 @@ final class ChatHistorySearchContainerNode: SearchDisplayControllerContentNode {
|
||||
let previousEntriesValue = Atomic<[ChatHistorySearchEntry]?>(value: nil)
|
||||
|
||||
self.searchQueryDisposable.set((self.searchQuery.get()
|
||||
|> deliverOnMainQueue).start(next: { [weak self] query in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] query in
|
||||
if let strongSelf = self {
|
||||
let signal: Signal<([ChatHistorySearchEntry], [MessageId: Message])?, NoError>
|
||||
if let query = query, !query.isEmpty {
|
||||
@ -197,7 +197,7 @@ final class ChatHistorySearchContainerNode: SearchDisplayControllerContentNode {
|
||||
}
|
||||
|
||||
strongSelf.searchDisposable.set((signal
|
||||
|> deliverOnMainQueue).start(next: { entriesAndMessages in
|
||||
|> deliverOnMainQueue).startStrict(next: { entriesAndMessages in
|
||||
if let strongSelf = self {
|
||||
let previousEntries = previousEntriesValue.swap(entriesAndMessages?.0)
|
||||
|
||||
@ -216,7 +216,7 @@ final class ChatHistorySearchContainerNode: SearchDisplayControllerContentNode {
|
||||
self?.dismissInput?()
|
||||
}
|
||||
|
||||
self.presentationDataDisposable = context.sharedContext.presentationData.start(next: { [weak self] presentationData in
|
||||
self.presentationDataDisposable = context.sharedContext.presentationData.startStrict(next: { [weak self] presentationData in
|
||||
if let strongSelf = self {
|
||||
strongSelf.themeAndStringsPromise.set(.single((presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, presentationData.listsFontSize)))
|
||||
|
||||
|
@ -1,6 +0,0 @@
|
||||
import Foundation
|
||||
import Postbox
|
||||
import TelegramCore
|
||||
import Display
|
||||
import AccountContext
|
||||
|
@ -115,7 +115,7 @@ final class ChatInstantVideoMessageDurationNode: ASImageNode {
|
||||
self.contentMode = .topRight
|
||||
|
||||
self.statusDisposable = (self.statusValuePromise.get()
|
||||
|> deliverOnMainQueue).start(next: { [weak self] status in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] status in
|
||||
if let strongSelf = self {
|
||||
strongSelf.statusValue = status
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ func serviceTasksForChatPresentationIntefaceState(context: AccountContext, chatP
|
||||
for id in missingEmoji {
|
||||
result["emoji-\(id)"] = {
|
||||
return (context.engine.stickers.resolveInlineStickers(fileIds: [id])
|
||||
|> deliverOnMainQueue).start(next: { result in
|
||||
|> deliverOnMainQueue).startStrict(next: { result in
|
||||
if let file = result[id] {
|
||||
updateState({ state -> ChatPresentationInterfaceState in
|
||||
return state.updatedInterfaceState { interfaceState -> ChatInterfaceState in
|
||||
|
@ -800,7 +800,7 @@ func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState
|
||||
let file = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: id), partialReference: nil, resource: LocalFileReferenceMediaResource(localFilePath: logPath, randomId: id), previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "application/text", size: nil, attributes: [.FileName(fileName: "CallStats.log")])
|
||||
let message: EnqueueMessage = .message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: file), replyToMessageId: nil, replyToStoryId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])
|
||||
|
||||
let _ = enqueueMessages(account: context.account, peerId: peerId, messages: [message]).start()
|
||||
let _ = enqueueMessages(account: context.account, peerId: peerId, messages: [message]).startStandalone()
|
||||
}
|
||||
}
|
||||
controllerInteraction.navigationController()?.pushViewController(controller)
|
||||
@ -838,7 +838,7 @@ func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState
|
||||
return
|
||||
}
|
||||
|
||||
let _ = context.engine.messages.rateAudioTranscription(messageId: message.id, id: audioTranscription.id, isGood: value).start()
|
||||
let _ = context.engine.messages.rateAudioTranscription(messageId: message.id, id: audioTranscription.id, isGood: value).startStandalone()
|
||||
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
let content: UndoOverlayContent = .info(title: nil, text: presentationData.strings.Chat_AudioTranscriptionFeedbackTip, timeout: nil)
|
||||
@ -873,7 +873,7 @@ func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState
|
||||
controllerInteraction.displayUndo(.info(title: presentationData.strings.Notifications_UploadError_TooLong_Title(fileName).string, text: presentationData.strings.Notifications_UploadError_TooLong_Text(stringForDuration(Int32(settings.maxDuration))).string, timeout: nil))
|
||||
} else {
|
||||
let _ = (context.engine.peers.saveNotificationSound(file: .message(message: MessageReference(message), media: file))
|
||||
|> deliverOnMainQueue).start(completed: {
|
||||
|> deliverOnMainQueue).startStandalone(completed: {
|
||||
controllerInteraction.displayUndo(.notificationSoundAdded(title: presentationData.strings.Notifications_UploadSuccess_Title, text: presentationData.strings.Notifications_SaveSuccess_Text, action: {
|
||||
controllerInteraction.navigationController()?.pushViewController(notificationsAndSoundsController(context: context, exceptionsList: nil))
|
||||
}))
|
||||
@ -1061,7 +1061,7 @@ func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState
|
||||
if let image = media as? TelegramMediaImage, let largest = largestImageRepresentation(image.representations) {
|
||||
let _ = (context.account.postbox.mediaBox.resourceData(largest.resource, option: .incremental(waitUntilFetchStatus: false))
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(next: { data in
|
||||
|> deliverOnMainQueue).startStandalone(next: { data in
|
||||
if data.complete, let imageData = try? Data(contentsOf: URL(fileURLWithPath: data.path)) {
|
||||
if let image = UIImage(data: imageData) {
|
||||
if !messageText.isEmpty {
|
||||
@ -1145,7 +1145,7 @@ func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Save"), color: theme.actionSheet.primaryTextColor)
|
||||
}, action: { _, f in
|
||||
let _ = (saveToCameraRoll(context: context, postbox: context.account.postbox, userLocation: .peer(message.id.peerId), mediaReference: mediaReference)
|
||||
|> deliverOnMainQueue).start(completed: {
|
||||
|> deliverOnMainQueue).startStandalone(completed: {
|
||||
Queue.mainQueue().after(0.2) {
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
controllerInteraction.presentControllerInCurrent(UndoOverlayController(presentationData: presentationData, content: .mediaSaved(text: isVideo ? presentationData.strings.Gallery_VideoSaved : presentationData.strings.Gallery_ImageSaved), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return true }), nil)
|
||||
@ -1367,7 +1367,7 @@ func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState
|
||||
|> map { result -> String? in
|
||||
return result
|
||||
}
|
||||
|> deliverOnMainQueue).start(next: { link in
|
||||
|> deliverOnMainQueue).startStandalone(next: { link in
|
||||
if let link = link {
|
||||
UIPasteboard.general.string = link
|
||||
|
||||
@ -1434,7 +1434,7 @@ func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState
|
||||
}, action: { _, f in
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
let _ = (toggleGifSaved(account: context.account, fileReference: .message(message: MessageReference(message), media: file), saved: true)
|
||||
|> deliverOnMainQueue).start(next: { result in
|
||||
|> deliverOnMainQueue).startStandalone(next: { result in
|
||||
Queue.mainQueue().after(0.2) {
|
||||
switch result {
|
||||
case .generic:
|
||||
@ -2442,7 +2442,7 @@ private final class ChatReadReportContextItemNode: ASDisplayNode, ContextMenuCus
|
||||
return (stickerPacks.compactMap { $0 }, firstCustomEmojiReaction)
|
||||
}
|
||||
}
|
||||
|> deliverOnMainQueue).start(next: { [weak self] customEmojiPacks, firstCustomEmojiReaction in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] customEmojiPacks, firstCustomEmojiReaction in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -2457,7 +2457,7 @@ private final class ChatReadReportContextItemNode: ASDisplayNode, ContextMenuCus
|
||||
self.buttonNode.isUserInteractionEnabled = reactionCount != 0
|
||||
|
||||
self.disposable = (item.context.engine.messages.messageReadStats(id: item.message.id)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] value in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] value in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
|
@ -221,7 +221,7 @@ final class ChatInviteRequestsTitlePanelNode: ChatTitleAccessoryPanelNode {
|
||||
}
|
||||
|
||||
let ids = peers.map { $0.id.toInt64() }
|
||||
let _ = ApplicationSpecificNotice.setDismissedInvitationRequests(accountManager: context.sharedContext.accountManager, peerId: peerId, values: ids).start()
|
||||
let _ = ApplicationSpecificNotice.setDismissedInvitationRequests(accountManager: context.sharedContext.accountManager, peerId: peerId, values: ids).startStandalone()
|
||||
}
|
||||
|
||||
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
|
||||
|
@ -21,7 +21,7 @@ func interactiveChatLinkPreviewsEnabled(accountManager: AccountManager<TelegramA
|
||||
return Signal { subscriber in
|
||||
Queue.mainQueue().async {
|
||||
displayAlert(InteractiveChatLinkPreviewsResult({ result in
|
||||
let _ = ApplicationSpecificNotice.setSecretChatLinkPreviews(accountManager: accountManager, value: result).start()
|
||||
let _ = ApplicationSpecificNotice.setSecretChatLinkPreviews(accountManager: accountManager, value: result).startStandalone()
|
||||
subscriber.putNext(result)
|
||||
subscriber.putCompletion()
|
||||
}))
|
||||
|
@ -288,7 +288,7 @@ final class ChatMediaInputStickerGridItemNode: GridItemNode {
|
||||
self.imageNode.setSignal(chatMessageAnimatedSticker(postbox: item.context.account.postbox, userLocation: .other, file: item.stickerItem.file, small: false, size: dimensions.cgSize.aspectFitted(fittedSize)))
|
||||
}
|
||||
self.updateVisibility()
|
||||
self.stickerFetchedDisposable.set(freeMediaFileResourceInteractiveFetched(account: item.context.account, userLocation: .other, fileReference: stickerPackFileReference(item.stickerItem.file), resource: item.stickerItem.file.resource).start())
|
||||
self.stickerFetchedDisposable.set(freeMediaFileResourceInteractiveFetched(account: item.context.account, userLocation: .other, fileReference: stickerPackFileReference(item.stickerItem.file), resource: item.stickerItem.file.resource).startStrict())
|
||||
} else {
|
||||
if let animationNode = self.animationNode {
|
||||
animationNode.visibility = false
|
||||
@ -298,7 +298,7 @@ final class ChatMediaInputStickerGridItemNode: GridItemNode {
|
||||
self.didSetUpAnimationNode = false
|
||||
}
|
||||
self.imageNode.setSignal(chatMessageSticker(account: item.context.account, userLocation: .other, file: item.stickerItem.file, small: !item.large, synchronousLoad: synchronousLoads && isVisible))
|
||||
self.stickerFetchedDisposable.set(freeMediaFileResourceInteractiveFetched(account: item.context.account, userLocation: .other, fileReference: stickerPackFileReference(item.stickerItem.file), resource: chatMessageStickerResource(file: item.stickerItem.file, small: !item.large)).start())
|
||||
self.stickerFetchedDisposable.set(freeMediaFileResourceInteractiveFetched(account: item.context.account, userLocation: .other, fileReference: stickerPackFileReference(item.stickerItem.file), resource: chatMessageStickerResource(file: item.stickerItem.file, small: !item.large)).startStrict())
|
||||
}
|
||||
|
||||
self.currentState = (item.context, item.stickerItem, dimensions.cgSize)
|
||||
|
@ -251,7 +251,7 @@ class ChatMessageActionBubbleContentNode: ChatMessageBubbleContentNode {
|
||||
strongSelf.insertSubnode(imageNode, at: 0)
|
||||
strongSelf.insertSubnode(strongSelf.mediaBackgroundNode, at: 0)
|
||||
}
|
||||
strongSelf.fetchDisposable.set(chatMessagePhotoInteractiveFetched(context: item.context, userLocation: .peer(item.message.id.peerId), photoReference: .message(message: MessageReference(item.message), media: image), displayAtSize: nil, storeToDownloadsPeerId: nil).start())
|
||||
strongSelf.fetchDisposable.set(chatMessagePhotoInteractiveFetched(context: item.context, userLocation: .peer(item.message.id.peerId), photoReference: .message(message: MessageReference(item.message), media: image), displayAtSize: nil, storeToDownloadsPeerId: nil).startStrict())
|
||||
let updateImageSignal = chatMessagePhoto(postbox: item.context.account.postbox, userLocation: .peer(item.message.id.peerId), photoReference: .message(message: MessageReference(item.message), media: image), synchronousLoad: synchronousLoads)
|
||||
|
||||
imageNode.setSignal(updateImageSignal, attemptSynchronously: synchronousLoads)
|
||||
|
@ -585,11 +585,11 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
||||
let dimensions = telegramFile.dimensions ?? PixelDimensions(width: 512, height: 512)
|
||||
self.imageNode.setSignal(chatMessageAnimatedSticker(postbox: item.context.account.postbox, userLocation: .peer(item.message.id.peerId), file: telegramFile, small: false, size: dimensions.cgSize.aspectFitted(CGSize(width: 384.0, height: 384.0)), thumbnail: false, synchronousLoad: synchronousLoad), attemptSynchronously: synchronousLoad)
|
||||
self.updateVisibility()
|
||||
self.disposable.set(freeMediaFileInteractiveFetched(account: item.context.account, userLocation: .peer(item.message.id.peerId), fileReference: .message(message: MessageReference(item.message), media: telegramFile)).start())
|
||||
self.disposable.set(freeMediaFileInteractiveFetched(account: item.context.account, userLocation: .peer(item.message.id.peerId), fileReference: .message(message: MessageReference(item.message), media: telegramFile)).startStrict())
|
||||
|
||||
if telegramFile.isPremiumSticker {
|
||||
if let effect = telegramFile.videoThumbnails.first {
|
||||
self.disposables.add(freeMediaFileResourceInteractiveFetched(account: item.context.account, userLocation: .peer(item.message.id.peerId), fileReference: .message(message: MessageReference(item.message), media: telegramFile), resource: effect.resource) .start())
|
||||
self.disposables.add(freeMediaFileResourceInteractiveFetched(account: item.context.account, userLocation: .peer(item.message.id.peerId), fileReference: .message(message: MessageReference(item.message), media: telegramFile), resource: effect.resource).startStrict())
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -663,7 +663,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
||||
let fillSize = emojiFile.isCustomEmoji ? CGSize(width: 512.0, height: 512.0) : CGSize(width: 384.0, height: 384.0)
|
||||
|
||||
self.imageNode.setSignal(chatMessageAnimatedSticker(postbox: item.context.account.postbox, userLocation: .peer(item.message.id.peerId), file: emojiFile, small: false, size: dimensions.cgSize.aspectFilled(fillSize), fitzModifier: fitzModifier, thumbnail: false, synchronousLoad: synchronousLoad), attemptSynchronously: synchronousLoad)
|
||||
self.disposable.set(freeMediaFileInteractiveFetched(account: item.context.account, userLocation: .peer(item.message.id.peerId), fileReference: .standalone(media: emojiFile)).start())
|
||||
self.disposable.set(freeMediaFileInteractiveFetched(account: item.context.account, userLocation: .peer(item.message.id.peerId), fileReference: .standalone(media: emojiFile)).startStrict())
|
||||
}
|
||||
|
||||
let textEmoji = item.message.text.strippedEmoji
|
||||
@ -687,7 +687,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
||||
|
||||
if let animationItems = animationItems {
|
||||
for (_, animationItem) in animationItems {
|
||||
self.disposables.add(freeMediaFileInteractiveFetched(account: item.context.account, userLocation: .peer(item.message.id.peerId), fileReference: .standalone(media: animationItem.file)).start())
|
||||
self.disposables.add(freeMediaFileInteractiveFetched(account: item.context.account, userLocation: .peer(item.message.id.peerId), fileReference: .standalone(media: animationItem.file)).startStrict())
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2279,7 +2279,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
||||
|
||||
if shouldPlay {
|
||||
let _ = (appConfiguration
|
||||
|> deliverOnMainQueue).start(next: { [weak self] appConfiguration in
|
||||
|> deliverOnMainQueue).startStandalone(next: { [weak self] appConfiguration in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -2297,7 +2297,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
||||
strongSelf.mediaPlayer = mediaPlayer
|
||||
|
||||
strongSelf.mediaStatusDisposable.set((mediaPlayer.status
|
||||
|> deliverOnMainQueue).start(next: { [weak self] status in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] status in
|
||||
if let strongSelf = self {
|
||||
if let haptic = haptic, !haptic.active {
|
||||
haptic.start(time: 0.0)
|
||||
|
@ -3826,7 +3826,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
|
||||
return .action({ [weak self] in
|
||||
if let item = self?.item {
|
||||
let _ = (item.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|
||||
|> deliverOnMainQueue).start(next: { peer in
|
||||
|> deliverOnMainQueue).startStandalone(next: { peer in
|
||||
if let self = self, let item = self.item, let peer = peer {
|
||||
item.controllerInteraction.openPeer(peer, openProfile ? .info : .chat(textInputState: nil, subject: nil, peekData: nil), nil, .default)
|
||||
}
|
||||
|
@ -529,7 +529,7 @@ final class ChatMessageAvatarHeaderNode: ListViewItemHeaderNode {
|
||||
|
||||
if peer.isPremium && context.sharedContext.energyUsageSettings.autoplayVideo {
|
||||
self.cachedDataDisposable.set((context.account.postbox.peerView(id: peer.id)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] peerView in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] peerView in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -592,7 +592,7 @@ final class ChatMessageAvatarHeaderNode: ListViewItemHeaderNode {
|
||||
strongSelf.updateVideoVisibility()
|
||||
} else {
|
||||
if let photo = peer.largeProfileImage, photo.hasVideo {
|
||||
let _ = context.engine.peers.fetchAndUpdateCachedPeerData(peerId: peer.id).start()
|
||||
let _ = context.engine.peers.fetchAndUpdateCachedPeerData(peerId: peer.id).startStandalone()
|
||||
}
|
||||
}
|
||||
}))
|
||||
|
@ -319,7 +319,7 @@ final class ChatMessageInteractiveFileNode: ASDisplayNode {
|
||||
switch resourceStatus.mediaStatus {
|
||||
case let .fetchStatus(fetchStatus):
|
||||
if let context = self.context, let message = self.message, message.flags.isSending {
|
||||
let _ = context.engine.messages.deleteMessagesInteractively(messageIds: [message.id], type: .forEveryone).start()
|
||||
let _ = context.engine.messages.deleteMessagesInteractively(messageIds: [message.id], type: .forEveryone).startStandalone()
|
||||
} else {
|
||||
switch fetchStatus {
|
||||
case .Fetching:
|
||||
@ -376,7 +376,7 @@ final class ChatMessageInteractiveFileNode: ASDisplayNode {
|
||||
}
|
||||
arguments.controllerInteraction.navigationController()?.pushViewController(controller, animated: true)
|
||||
|
||||
let _ = ApplicationSpecificNotice.incrementAudioTranscriptionSuggestion(accountManager: context.sharedContext.accountManager).start()
|
||||
let _ = ApplicationSpecificNotice.incrementAudioTranscriptionSuggestion(accountManager: context.sharedContext.accountManager).startStandalone()
|
||||
}
|
||||
return false })
|
||||
arguments.controllerInteraction.presentControllerInCurrent(tipController, nil)
|
||||
@ -443,13 +443,13 @@ final class ChatMessageInteractiveFileNode: ASDisplayNode {
|
||||
}
|
||||
|
||||
self.transcribeDisposable = (signal
|
||||
|> deliverOnMainQueue).start(next: { [weak self] result in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] result in
|
||||
guard let strongSelf = self, let arguments = strongSelf.arguments else {
|
||||
return
|
||||
}
|
||||
|
||||
if let result = result {
|
||||
let _ = arguments.context.engine.messages.storeLocallyTranscribedAudio(messageId: arguments.message.id, text: result.text, isFinal: result.isFinal, error: nil).start()
|
||||
let _ = arguments.context.engine.messages.storeLocallyTranscribedAudio(messageId: arguments.message.id, text: result.text, isFinal: result.isFinal, error: nil).startStandalone()
|
||||
} else {
|
||||
strongSelf.audioTranscriptionState = .collapsed
|
||||
strongSelf.requestUpdateLayout(true)
|
||||
@ -462,7 +462,7 @@ final class ChatMessageInteractiveFileNode: ASDisplayNode {
|
||||
})
|
||||
} else {
|
||||
self.transcribeDisposable = (context.engine.messages.transcribeAudio(messageId: message.id)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] result in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] result in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -534,7 +534,7 @@ final class ChatMessageInteractiveFileNode: ASDisplayNode {
|
||||
|
||||
updatedFetchControls = FetchControls(fetch: { [weak self] userInitiated in
|
||||
if let strongSelf = self {
|
||||
strongSelf.fetchDisposable.set(messageMediaFileInteractiveFetched(context: arguments.context, message: arguments.message, file: arguments.file, userInitiated: userInitiated).start())
|
||||
strongSelf.fetchDisposable.set(messageMediaFileInteractiveFetched(context: arguments.context, message: arguments.message, file: arguments.file, userInitiated: userInitiated).startStrict())
|
||||
}
|
||||
}, cancel: {
|
||||
messageMediaFileCancelInteractiveFetch(context: arguments.context, messageId: arguments.message.id, file: arguments.file)
|
||||
@ -1293,7 +1293,7 @@ final class ChatMessageInteractiveFileNode: ASDisplayNode {
|
||||
return .single(next) |> then(.complete() |> delay(0.1, queue: Queue.concurrentDefaultQueue()))
|
||||
}
|
||||
}
|
||||
strongSelf.statusDisposable.set((updatedStatusSignal |> deliverOnMainQueue).start(next: { [weak strongSelf] status, actualFetchStatus in
|
||||
strongSelf.statusDisposable.set((updatedStatusSignal |> deliverOnMainQueue).startStrict(next: { [weak strongSelf] status, actualFetchStatus in
|
||||
displayLinkDispatcher.dispatch {
|
||||
if let strongSelf = strongSelf {
|
||||
let firstTime = strongSelf.resourceStatus == nil
|
||||
@ -1307,7 +1307,7 @@ final class ChatMessageInteractiveFileNode: ASDisplayNode {
|
||||
|
||||
if let updatedAudioLevelEventsSignal = updatedAudioLevelEventsSignal {
|
||||
strongSelf.audioLevelEventsDisposable.set((updatedAudioLevelEventsSignal
|
||||
|> deliverOnMainQueue).start(next: { value in
|
||||
|> deliverOnMainQueue).startStrict(next: { value in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -1318,7 +1318,7 @@ final class ChatMessageInteractiveFileNode: ASDisplayNode {
|
||||
|
||||
if let updatedPlaybackStatusSignal = updatedPlaybackStatusSignal {
|
||||
strongSelf.playbackStatus.set(updatedPlaybackStatusSignal)
|
||||
strongSelf.playbackStatusDisposable.set((updatedPlaybackStatusSignal |> deliverOnMainQueue).start(next: { [weak strongSelf] status in
|
||||
strongSelf.playbackStatusDisposable.set((updatedPlaybackStatusSignal |> deliverOnMainQueue).startStrict(next: { [weak strongSelf] status in
|
||||
displayLinkDispatcher.dispatch {
|
||||
if let strongSelf = strongSelf {
|
||||
strongSelf.playerStatus = status
|
||||
|
@ -623,7 +623,7 @@ class ChatMessageInteractiveInstantVideoNode: ASDisplayNode {
|
||||
|
||||
if let updatedFile = updatedFile, updatedMedia {
|
||||
if let resource = updatedFile.previewRepresentations.first?.resource {
|
||||
strongSelf.fetchedThumbnailDisposable.set(fetchedMediaResource(mediaBox: item.context.account.postbox.mediaBox, userLocation: .peer(item.message.id.peerId), userContentType: .video, reference: FileMediaReference.message(message: MessageReference(item.message), media: updatedFile).resourceReference(resource)).start())
|
||||
strongSelf.fetchedThumbnailDisposable.set(fetchedMediaResource(mediaBox: item.context.account.postbox.mediaBox, userLocation: .peer(item.message.id.peerId), userContentType: .video, reference: FileMediaReference.message(message: MessageReference(item.message), media: updatedFile).resourceReference(resource)).startStrict())
|
||||
} else {
|
||||
strongSelf.fetchedThumbnailDisposable.set(nil)
|
||||
}
|
||||
@ -731,7 +731,7 @@ class ChatMessageInteractiveInstantVideoNode: ASDisplayNode {
|
||||
|
||||
if let updatedPlaybackStatus = updatedPlaybackStatus {
|
||||
strongSelf.playbackStatusDisposable.set((updatedPlaybackStatus
|
||||
|> deliverOnMainQueue).start(next: { status in
|
||||
|> deliverOnMainQueue).startStrict(next: { status in
|
||||
if let strongSelf = self {
|
||||
strongSelf.status = status
|
||||
strongSelf.updateStatus(animator: nil)
|
||||
@ -741,7 +741,7 @@ class ChatMessageInteractiveInstantVideoNode: ASDisplayNode {
|
||||
|
||||
if let updatedPlayerStatusSignal = updatedPlayerStatusSignal {
|
||||
strongSelf.playerStatusDisposable.set((updatedPlayerStatusSignal
|
||||
|> deliverOnMainQueue).start(next: { [weak self] status in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] status in
|
||||
displayLinkDispatcher.dispatch {
|
||||
if let strongSelf = self {
|
||||
strongSelf.playerStatus = status
|
||||
@ -892,7 +892,7 @@ class ChatMessageInteractiveInstantVideoNode: ASDisplayNode {
|
||||
strongSelf.updateStatus(animator: animation.animator)
|
||||
|
||||
if let telegramFile = updatedFile, previousAutomaticDownload != automaticDownload, automaticDownload {
|
||||
strongSelf.fetchDisposable.set(messageMediaFileInteractiveFetched(context: item.context, message: item.message, file: telegramFile, userInitiated: false).start())
|
||||
strongSelf.fetchDisposable.set(messageMediaFileInteractiveFetched(context: item.context, message: item.message, file: telegramFile, userInitiated: false).startStrict())
|
||||
}
|
||||
|
||||
if let forwardInfo = item.message.forwardInfo, forwardInfo.flags.contains(.isImported) {
|
||||
@ -1384,13 +1384,13 @@ class ChatMessageInteractiveInstantVideoNode: ASDisplayNode {
|
||||
switch fetchStatus {
|
||||
case .Fetching:
|
||||
if item.message.flags.isSending {
|
||||
let _ = item.context.engine.messages.deleteMessagesInteractively(messageIds: [item.message.id], type: .forEveryone).start()
|
||||
let _ = item.context.engine.messages.deleteMessagesInteractively(messageIds: [item.message.id], type: .forEveryone).startStandalone()
|
||||
} else {
|
||||
messageMediaFileCancelInteractiveFetch(context: item.context, messageId: item.message.id, file: file)
|
||||
}
|
||||
case .Remote, .Paused:
|
||||
if let file = self.media {
|
||||
self.fetchDisposable.set(messageMediaFileInteractiveFetched(context: item.context, message: item.message, file: file, userInitiated: true).start())
|
||||
self.fetchDisposable.set(messageMediaFileInteractiveFetched(context: item.context, message: item.message, file: file, userInitiated: true).startStrict())
|
||||
}
|
||||
case .Local:
|
||||
self.activateVideoPlayback()
|
||||
@ -1476,7 +1476,7 @@ class ChatMessageInteractiveInstantVideoNode: ASDisplayNode {
|
||||
if !self.infoBackgroundNode.alpha.isZero {
|
||||
let _ = (item.context.sharedContext.mediaManager.globalMediaPlayerState
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(next: { playlistStateAndType in
|
||||
|> deliverOnMainQueue).startStandalone(next: { playlistStateAndType in
|
||||
var canPlay = true
|
||||
if let (_, state, _) = playlistStateAndType {
|
||||
switch state {
|
||||
@ -1551,7 +1551,7 @@ class ChatMessageInteractiveInstantVideoNode: ASDisplayNode {
|
||||
}
|
||||
item.controllerInteraction.navigationController()?.pushViewController(controller, animated: true)
|
||||
|
||||
let _ = ApplicationSpecificNotice.incrementAudioTranscriptionSuggestion(accountManager: item.context.sharedContext.accountManager).start()
|
||||
let _ = ApplicationSpecificNotice.incrementAudioTranscriptionSuggestion(accountManager: item.context.sharedContext.accountManager).startStandalone()
|
||||
}
|
||||
return false })
|
||||
item.controllerInteraction.presentControllerInCurrent(tipController, nil)
|
||||
@ -1583,7 +1583,7 @@ class ChatMessageInteractiveInstantVideoNode: ASDisplayNode {
|
||||
self.requestUpdateLayout(true)
|
||||
|
||||
self.transcribeDisposable = (item.context.engine.messages.transcribeAudio(messageId: item.message.id)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] result in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] result in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
|
@ -577,7 +577,7 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
|
||||
switch fetchStatus {
|
||||
case .Fetching:
|
||||
if let context = self.context, let message = self.message, message.flags.isSending {
|
||||
let _ = context.engine.messages.deleteMessagesInteractively(messageIds: [message.id], type: .forEveryone).start()
|
||||
let _ = context.engine.messages.deleteMessagesInteractively(messageIds: [message.id], type: .forEveryone).startStandalone()
|
||||
} else if let media = self.media, let context = self.context, let message = self.message {
|
||||
if let media = media as? TelegramMediaFile {
|
||||
messageMediaFileCancelInteractiveFetch(context: context, messageId: message.id, file: media)
|
||||
@ -1054,7 +1054,7 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
|
||||
updatedFetchControls = FetchControls(fetch: { manual in
|
||||
if let strongSelf = self {
|
||||
if let representation = largestRepresentationForPhoto(image) {
|
||||
strongSelf.fetchDisposable.set(messageMediaImageInteractiveFetched(context: context, message: message, image: image, resource: representation.resource, range: representationFetchRangeForDisplayAtSize(representation: representation, dimension: nil/*isSecretMedia ? nil : 600*/), userInitiated: manual, storeToDownloadsPeerId: storeToDownloadsPeerId).start())
|
||||
strongSelf.fetchDisposable.set(messageMediaImageInteractiveFetched(context: context, message: message, image: image, resource: representation.resource, range: representationFetchRangeForDisplayAtSize(representation: representation, dimension: nil/*isSecretMedia ? nil : 600*/), userInitiated: manual, storeToDownloadsPeerId: storeToDownloadsPeerId).startStrict())
|
||||
}
|
||||
}
|
||||
}, cancel: {
|
||||
@ -1135,9 +1135,9 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
|
||||
updatedFetchControls = FetchControls(fetch: { manual in
|
||||
if let strongSelf = self {
|
||||
if file.isAnimated {
|
||||
strongSelf.fetchDisposable.set(fetchedMediaResource(mediaBox: context.account.postbox.mediaBox, userLocation: .peer(message.id.peerId), userContentType: MediaResourceUserContentType(file: file), reference: AnyMediaReference.message(message: MessageReference(message), media: file).resourceReference(file.resource), statsCategory: statsCategoryForFileWithAttributes(file.attributes)).start())
|
||||
strongSelf.fetchDisposable.set(fetchedMediaResource(mediaBox: context.account.postbox.mediaBox, userLocation: .peer(message.id.peerId), userContentType: MediaResourceUserContentType(file: file), reference: AnyMediaReference.message(message: MessageReference(message), media: file).resourceReference(file.resource), statsCategory: statsCategoryForFileWithAttributes(file.attributes)).startStrict())
|
||||
} else {
|
||||
strongSelf.fetchDisposable.set(messageMediaFileInteractiveFetched(context: context, message: message, file: file, userInitiated: manual, storeToDownloadsPeerId: storeToDownloadsPeerId).start())
|
||||
strongSelf.fetchDisposable.set(messageMediaFileInteractiveFetched(context: context, message: message, file: file, userInitiated: manual, storeToDownloadsPeerId: storeToDownloadsPeerId).startStrict())
|
||||
}
|
||||
}
|
||||
}, cancel: {
|
||||
@ -1172,7 +1172,7 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
|
||||
updatedFetchControls = FetchControls(fetch: { manual in
|
||||
if let strongSelf = self {
|
||||
if let representation = largestRepresentationForPhoto(image) {
|
||||
strongSelf.fetchDisposable.set(messageMediaImageInteractiveFetched(context: context, message: message, image: image, resource: representation.resource, range: representationFetchRangeForDisplayAtSize(representation: representation, dimension: nil/*isSecretMedia ? nil : 600*/), userInitiated: manual, storeToDownloadsPeerId: storeToDownloadsPeerId).start())
|
||||
strongSelf.fetchDisposable.set(messageMediaImageInteractiveFetched(context: context, message: message, image: image, resource: representation.resource, range: representationFetchRangeForDisplayAtSize(representation: representation, dimension: nil/*isSecretMedia ? nil : 600*/), userInitiated: manual, storeToDownloadsPeerId: storeToDownloadsPeerId).startStrict())
|
||||
}
|
||||
}
|
||||
}, cancel: {
|
||||
@ -1194,7 +1194,7 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
|
||||
|
||||
updatedFetchControls = FetchControls(fetch: { _ in
|
||||
if let strongSelf = self {
|
||||
strongSelf.fetchDisposable.set(chatMessageWebFileInteractiveFetched(account: context.account, userLocation: .peer(message.id.peerId), image: image).start())
|
||||
strongSelf.fetchDisposable.set(chatMessageWebFileInteractiveFetched(account: context.account, userLocation: .peer(message.id.peerId), image: image).startStrict())
|
||||
}
|
||||
}, cancel: {
|
||||
chatMessageWebFileCancelInteractiveFetch(account: context.account, image: image)
|
||||
@ -1271,9 +1271,9 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
|
||||
updatedFetchControls = FetchControls(fetch: { manual in
|
||||
if let strongSelf = self {
|
||||
if file.isAnimated {
|
||||
strongSelf.fetchDisposable.set(fetchedMediaResource(mediaBox: context.account.postbox.mediaBox, userLocation: .peer(message.id.peerId), userContentType: MediaResourceUserContentType(file: file), reference: AnyMediaReference.message(message: MessageReference(message), media: file).resourceReference(file.resource), statsCategory: statsCategoryForFileWithAttributes(file.attributes)).start())
|
||||
strongSelf.fetchDisposable.set(fetchedMediaResource(mediaBox: context.account.postbox.mediaBox, userLocation: .peer(message.id.peerId), userContentType: MediaResourceUserContentType(file: file), reference: AnyMediaReference.message(message: MessageReference(message), media: file).resourceReference(file.resource), statsCategory: statsCategoryForFileWithAttributes(file.attributes)).startStrict())
|
||||
} else {
|
||||
strongSelf.fetchDisposable.set(messageMediaFileInteractiveFetched(context: context, message: message, file: file, userInitiated: manual, storeToDownloadsPeerId: storeToDownloadsPeerId).start())
|
||||
strongSelf.fetchDisposable.set(messageMediaFileInteractiveFetched(context: context, message: message, file: file, userInitiated: manual, storeToDownloadsPeerId: storeToDownloadsPeerId).startStrict())
|
||||
}
|
||||
}
|
||||
}, cancel: {
|
||||
@ -1321,7 +1321,7 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
|
||||
if case let .file(file, _, _, _, _, _) = wallpaper.content {
|
||||
updatedFetchControls = FetchControls(fetch: { manual in
|
||||
if let strongSelf = self {
|
||||
strongSelf.fetchDisposable.set(messageMediaFileInteractiveFetched(context: context, message: message, file: file, userInitiated: manual).start())
|
||||
strongSelf.fetchDisposable.set(messageMediaFileInteractiveFetched(context: context, message: message, file: file, userInitiated: manual).startStrict())
|
||||
}
|
||||
}, cancel: {
|
||||
messageMediaFileCancelInteractiveFetch(context: context, messageId: message.id, file: file)
|
||||
@ -1466,7 +1466,7 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
|
||||
guard let context, let peerId else {
|
||||
return
|
||||
}
|
||||
let _ = storeDownloadedMedia(storeManager: context.downloadedMediaStoreManager, media: .message(message: MessageReference(message), media: updatedVideoFile), peerId: peerId).start()
|
||||
let _ = storeDownloadedMedia(storeManager: context.downloadedMediaStoreManager, media: .message(message: MessageReference(message), media: updatedVideoFile), peerId: peerId).startStandalone()
|
||||
})
|
||||
let videoNode = UniversalVideoNode(postbox: context.account.postbox, audioSession: mediaManager.audioSession, manager: mediaManager.universalVideoManager, decoration: decoration, content: videoContent, priority: .embedded)
|
||||
videoNode.isUserInteractionEnabled = false
|
||||
@ -1582,7 +1582,7 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
|
||||
|
||||
if let updatedStatusSignal = updatedStatusSignal {
|
||||
strongSelf.statusDisposable.set((updatedStatusSignal
|
||||
|> deliverOnMainQueue).start(next: { [weak strongSelf] status, actualFetchStatus in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak strongSelf] status, actualFetchStatus in
|
||||
displayLinkDispatcher.dispatch {
|
||||
if let strongSelf = strongSelf {
|
||||
strongSelf.fetchStatus = status
|
||||
@ -1595,7 +1595,7 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
|
||||
|
||||
if let updatedVideoNodeReadySignal = updatedVideoNodeReadySignal {
|
||||
strongSelf.videoNodeReadyDisposable.set((updatedVideoNodeReadySignal
|
||||
|> deliverOnMainQueue).start(next: { [weak strongSelf] status in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak strongSelf] status in
|
||||
displayLinkDispatcher.dispatch {
|
||||
if let strongSelf = strongSelf, let videoNode = strongSelf.videoNode {
|
||||
strongSelf.pinchContainerNode.contentNode.insertSubnode(videoNode, aboveSubnode: strongSelf.imageNode)
|
||||
@ -1606,7 +1606,7 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
|
||||
|
||||
if let updatedPlayerStatusSignal = updatedPlayerStatusSignal {
|
||||
strongSelf.playerStatusDisposable.set((updatedPlayerStatusSignal
|
||||
|> deliverOnMainQueue).start(next: { [weak strongSelf] status in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak strongSelf] status in
|
||||
displayLinkDispatcher.dispatch {
|
||||
if let strongSelf = strongSelf {
|
||||
strongSelf.playerStatus = status
|
||||
@ -1632,7 +1632,7 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
|
||||
if let _ = media as? TelegramMediaImage {
|
||||
updatedFetchControls.fetch(false)
|
||||
} else if let image = media as? TelegramMediaWebFile {
|
||||
strongSelf.fetchDisposable.set(chatMessageWebFileInteractiveFetched(account: context.account, userLocation: .peer(message.id.peerId), image: image).start())
|
||||
strongSelf.fetchDisposable.set(chatMessageWebFileInteractiveFetched(account: context.account, userLocation: .peer(message.id.peerId), image: image).startStrict())
|
||||
} else if let file = media as? TelegramMediaFile {
|
||||
let fetchSignal = messageMediaFileInteractiveFetched(context: context, message: message, file: file, userInitiated: false, storeToDownloadsPeerId: peerId)
|
||||
let visibilityAwareFetchSignal = strongSelf.visibilityPromise.get()
|
||||
@ -1646,7 +1646,7 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
|
||||
return .complete()
|
||||
}
|
||||
}
|
||||
strongSelf.fetchDisposable.set(visibilityAwareFetchSignal.start())
|
||||
strongSelf.fetchDisposable.set(visibilityAwareFetchSignal.startStrict())
|
||||
}
|
||||
} else if case .prefetch = automaticDownload, message.id.namespace != Namespaces.Message.SecretIncoming /*&& message.id.namespace != Namespaces.Message.Local*/ {
|
||||
if let file = media as? TelegramMediaFile {
|
||||
@ -1661,7 +1661,7 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
|
||||
return .complete()
|
||||
}
|
||||
}
|
||||
strongSelf.fetchDisposable.set(visibilityAwareFetchSignal.start())
|
||||
strongSelf.fetchDisposable.set(visibilityAwareFetchSignal.startStrict())
|
||||
}
|
||||
}
|
||||
} else if currentAutomaticDownload != automaticDownload, case .full = automaticDownload {
|
||||
@ -2354,7 +2354,7 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
|
||||
} else {
|
||||
let _ = (context.sharedContext.mediaManager.globalMediaPlayerState
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(next: { playlistStateAndType in
|
||||
|> deliverOnMainQueue).startStandalone(next: { playlistStateAndType in
|
||||
var canPlay = true
|
||||
if let (_, state, _) = playlistStateAndType {
|
||||
switch state {
|
||||
|
@ -891,7 +891,7 @@ public class ChatMessageItemView: ListViewItemNode, ChatMessageItemNodeProtocol
|
||||
break
|
||||
case let .openUserProfile(peerId):
|
||||
let _ = (item.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|
||||
|> deliverOnMainQueue).start(next: { peer in
|
||||
|> deliverOnMainQueue).startStandalone(next: { peer in
|
||||
if let peer = peer {
|
||||
item.controllerInteraction.openPeer(peer, .info, nil, .default)
|
||||
}
|
||||
|
@ -1925,7 +1925,7 @@ final class MergedAvatarsNode: ASDisplayNode {
|
||||
if self.disposables[peer.peerId] == nil {
|
||||
if let signal = peerAvatarImage(account: context.account, peerReference: peerReference, authorOfMessage: nil, representation: representation, displayDimensions: CGSize(width: imageSize, height: imageSize), synchronousLoad: synchronousLoad) {
|
||||
let disposable = (signal
|
||||
|> deliverOnMainQueue).start(next: { [weak self] imageVersions in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] imageVersions in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
|
@ -201,7 +201,7 @@ class ChatMessageProfilePhotoSuggestionContentNode: ChatMessageBubbleContentNode
|
||||
let imageFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((backgroundSize.width - imageSize.width) / 2.0), y: 13.0), size: imageSize)
|
||||
if let photo = photo {
|
||||
if mediaUpdated {
|
||||
strongSelf.fetchDisposable.set(chatMessagePhotoInteractiveFetched(context: item.context, userLocation: .peer(item.message.id.peerId), photoReference: .message(message: MessageReference(item.message), media: photo), displayAtSize: nil, storeToDownloadsPeerId: nil).start())
|
||||
strongSelf.fetchDisposable.set(chatMessagePhotoInteractiveFetched(context: item.context, userLocation: .peer(item.message.id.peerId), photoReference: .message(message: MessageReference(item.message), media: photo), displayAtSize: nil, storeToDownloadsPeerId: nil).startStrict())
|
||||
}
|
||||
|
||||
let updateImageSignal = chatMessagePhoto(postbox: item.context.account.postbox, userLocation: .peer(item.message.id.peerId), photoReference: .message(message: MessageReference(item.message), media: photo), synchronousLoad: synchronousLoads)
|
||||
|
@ -39,7 +39,7 @@ final class ChatMessageSelectionInputPanelNode: ChatInputPanelNode {
|
||||
self.canDeleteMessagesDisposable.set(nil)
|
||||
} else if let context = self.context {
|
||||
self.canDeleteMessagesDisposable.set((context.sharedContext.chatAvailableMessageActions(engine: context.engine, accountPeerId: context.account.peerId, messageIds: self.selectedMessages)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] actions in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] actions in
|
||||
if let strongSelf = self {
|
||||
strongSelf.actions = actions
|
||||
if let (width, leftInset, rightInset, bottomInset, additionalSideInsets, maxHeight, metrics, isSecondary, isMediaInputExpanded) = strongSelf.validLayout, let interfaceState = strongSelf.presentationInterfaceState {
|
||||
|
@ -266,7 +266,7 @@ class ChatMessageStickerItemNode: ChatMessageItemView {
|
||||
let signal = chatMessageSticker(account: item.context.account, userLocation: .peer(item.message.id.peerId), file: telegramFile, small: false, onlyFullSize: self.telegramFile != nil, synchronousLoad: synchronousLoad)
|
||||
self.telegramFile = telegramFile
|
||||
self.imageNode.setSignal(signal, attemptSynchronously: synchronousLoad)
|
||||
self.fetchDisposable.set(freeMediaFileInteractiveFetched(account: item.context.account, userLocation: .peer(item.message.id.peerId), fileReference: .message(message: MessageReference(item.message), media: telegramFile)).start())
|
||||
self.fetchDisposable.set(freeMediaFileInteractiveFetched(account: item.context.account, userLocation: .peer(item.message.id.peerId), fileReference: .message(message: MessageReference(item.message), media: telegramFile)).startStrict())
|
||||
}
|
||||
|
||||
break
|
||||
|
@ -242,7 +242,7 @@ class ChatMessageStoryMentionContentNode: ChatMessageBubbleContentNode {
|
||||
let maxImageSize = photo.representations.last?.dimensions.cgSize ?? imageFrame.size
|
||||
let boundingImageSize = maxImageSize.aspectFilled(imageFrame.size)
|
||||
|
||||
strongSelf.fetchDisposable.set(chatMessagePhotoInteractiveFetched(context: item.context, userLocation: .peer(item.message.id.peerId), photoReference: .message(message: MessageReference(item.message), media: photo), displayAtSize: nil, storeToDownloadsPeerId: nil).start())
|
||||
strongSelf.fetchDisposable.set(chatMessagePhotoInteractiveFetched(context: item.context, userLocation: .peer(item.message.id.peerId), photoReference: .message(message: MessageReference(item.message), media: photo), displayAtSize: nil, storeToDownloadsPeerId: nil).startStrict())
|
||||
|
||||
let updateImageSignal = chatMessagePhoto(postbox: item.context.account.postbox, userLocation: .peer(item.message.id.peerId), photoReference: .message(message: MessageReference(item.message), media: photo), synchronousLoad: synchronousLoads)
|
||||
strongSelf.imageNode.setSignal(updateImageSignal, attemptSynchronously: synchronousLoads)
|
||||
|
@ -359,7 +359,7 @@ class ChatMessageWallpaperBubbleContentNode: ChatMessageBubbleContentNode {
|
||||
if mediaUpdated {
|
||||
if item.message.id.namespace == Namespaces.Message.Local {
|
||||
strongSelf.statusDisposable.set((item.context.account.pendingPeerMediaUploadManager.uploadProgress(messageId: item.message.id)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] progress in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] progress in
|
||||
if let strongSelf = self {
|
||||
strongSelf.updateProgress(progress)
|
||||
}
|
||||
|
@ -258,7 +258,7 @@ final class ChatPinnedMessageTitlePanelNode: ChatTitleAccessoryPanelNode {
|
||||
|> map { status -> Bool in
|
||||
return status == .pinnedMessage
|
||||
}
|
||||
|> deliverOnMainQueue).start(next: { [weak self] isLoading in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] isLoading in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -496,7 +496,7 @@ final class ChatPinnedMessageTitlePanelNode: ChatTitleAccessoryPanelNode {
|
||||
if currentTranslateToLanguageUpdated || messageUpdated, let message = interfaceState.pinnedMessage?.message {
|
||||
if let translation = message.attributes.first(where: { $0 is TranslationMessageAttribute }) as? TranslationMessageAttribute, translation.toLang == translateToLanguage {
|
||||
} else if let translateToLanguage {
|
||||
self.translationDisposable.set(translateMessageIds(context: self.context, messageIds: [message.id], toLang: translateToLanguage).start())
|
||||
self.translationDisposable.set(translateMessageIds(context: self.context, messageIds: [message.id], toLang: translateToLanguage).startStrict())
|
||||
}
|
||||
}
|
||||
|
||||
@ -816,7 +816,7 @@ final class ChatPinnedMessageTitlePanelNode: ChatTitleAccessoryPanelNode {
|
||||
strongSelf.imageNode.setSignal(updateImageSignal)
|
||||
}
|
||||
if let updatedFetchMediaSignal = updatedFetchMediaSignal {
|
||||
strongSelf.fetchDisposable.set(updatedFetchMediaSignal.start())
|
||||
strongSelf.fetchDisposable.set(updatedFetchMediaSignal.startStrict())
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -898,7 +898,7 @@ final class ChatPinnedMessageTitlePanelNode: ChatTitleAccessoryPanelNode {
|
||||
break
|
||||
case let .openUserProfile(peerId):
|
||||
let _ = (self.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|
||||
|> deliverOnMainQueue).start(next: { peer in
|
||||
|> deliverOnMainQueue).startStandalone(next: { peer in
|
||||
if let peer = peer {
|
||||
controllerInteraction.openPeer(peer, .info, nil, .default)
|
||||
}
|
||||
|
@ -513,7 +513,7 @@ private final class ThemeSettingsThemeItemIconNode : ListViewItemNode {
|
||||
animatedStickerNode.autoplay = true
|
||||
animatedStickerNode.visibility = strongSelf.visibilityStatus
|
||||
|
||||
strongSelf.stickerFetchedDisposable.set(fetchedMediaResource(mediaBox: item.context.account.postbox.mediaBox, userLocation: .other, userContentType: .sticker, reference: MediaResourceReference.media(media: .standalone(media: file), resource: file.resource)).start())
|
||||
strongSelf.stickerFetchedDisposable.set(fetchedMediaResource(mediaBox: item.context.account.postbox.mediaBox, userLocation: .other, userContentType: .sticker, reference: MediaResourceReference.media(media: .standalone(media: file), resource: file.resource)).startStrict())
|
||||
|
||||
let thumbnailDimensions = PixelDimensions(width: 512, height: 512)
|
||||
strongSelf.placeholderNode.update(backgroundColor: nil, foregroundColor: UIColor(rgb: 0xffffff, alpha: 0.2), shimmeringColor: UIColor(rgb: 0xffffff, alpha: 0.3), data: file.immediateThumbnailData, size: emojiFrame.size, enableEffect: item.context.sharedContext.energyUsageSettings.fullTranslucency, imageSize: thumbnailDimensions.cgSize)
|
||||
@ -625,7 +625,7 @@ final class ChatQrCodeScreen: ViewController {
|
||||
self.presentationThemePromise.set(.single(nil))
|
||||
|
||||
self.presentationDataDisposable = (combineLatest(context.sharedContext.presentationData, self.presentationThemePromise.get())
|
||||
|> deliverOnMainQueue).start(next: { [weak self] presentationData, theme in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] presentationData, theme in
|
||||
if let strongSelf = self {
|
||||
var presentationData = presentationData
|
||||
if let theme = theme {
|
||||
@ -1045,7 +1045,7 @@ private class ChatQrCodeScreenNode: ViewControllerTracingNode, UIScrollViewDeleg
|
||||
if case .messages = controller.subject {
|
||||
isMessage = true
|
||||
}
|
||||
self.disposable.set(combineLatest(queue: Queue.mainQueue(), animatedEmojiStickers, initiallySelectedEmoticon, self.context.engine.themes.getChatThemes(accountManager: self.context.sharedContext.accountManager), self.selectedEmoticonPromise.get(), self.isDarkAppearancePromise.get()).start(next: { [weak self] animatedEmojiStickers, initiallySelectedEmoticon, themes, selectedEmoticon, isDarkAppearance in
|
||||
self.disposable.set(combineLatest(queue: Queue.mainQueue(), animatedEmojiStickers, initiallySelectedEmoticon, self.context.engine.themes.getChatThemes(accountManager: self.context.sharedContext.accountManager), self.selectedEmoticonPromise.get(), self.isDarkAppearancePromise.get()).startStrict(next: { [weak self] animatedEmojiStickers, initiallySelectedEmoticon, themes, selectedEmoticon, isDarkAppearance in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -1173,7 +1173,7 @@ private class ChatQrCodeScreenNode: ViewControllerTracingNode, UIScrollViewDeleg
|
||||
if case let .peer(_, _, temporary) = controller.subject, temporary {
|
||||
self.contactDisposable.set(
|
||||
(context.engine.peers.exportContactToken()
|
||||
|> deliverOnMainQueue).start(next: { [weak self] token in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] token in
|
||||
if let strongSelf = self {
|
||||
strongSelf.currentContactToken = token
|
||||
if let contentNode = strongSelf.contentNode as? QrContentNode, let token = token {
|
||||
@ -1188,7 +1188,7 @@ private class ChatQrCodeScreenNode: ViewControllerTracingNode, UIScrollViewDeleg
|
||||
if let strongSelf = self {
|
||||
strongSelf.contactDisposable.set(
|
||||
(context.engine.peers.exportContactToken()
|
||||
|> deliverOnMainQueue).start(next: { [weak self] token in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] token in
|
||||
if let strongSelf = self {
|
||||
strongSelf.currentContactToken = token
|
||||
if let contentNode = strongSelf.contentNode as? QrContentNode, let token = token {
|
||||
@ -1322,9 +1322,9 @@ private class ChatQrCodeScreenNode: ViewControllerTracingNode, UIScrollViewDeleg
|
||||
self.isDarkAppearance = isDarkAppearance
|
||||
|
||||
if isDarkAppearance {
|
||||
let _ = ApplicationSpecificNotice.incrementChatSpecificThemeDarkPreviewTip(accountManager: self.context.sharedContext.accountManager, count: 3, timestamp: Int32(Date().timeIntervalSince1970)).start()
|
||||
let _ = ApplicationSpecificNotice.incrementChatSpecificThemeDarkPreviewTip(accountManager: self.context.sharedContext.accountManager, count: 3, timestamp: Int32(Date().timeIntervalSince1970)).startStandalone()
|
||||
} else {
|
||||
let _ = ApplicationSpecificNotice.incrementChatSpecificThemeLightPreviewTip(accountManager: self.context.sharedContext.accountManager, count: 3, timestamp: Int32(Date().timeIntervalSince1970)).start()
|
||||
let _ = ApplicationSpecificNotice.incrementChatSpecificThemeLightPreviewTip(accountManager: self.context.sharedContext.accountManager, count: 3, timestamp: Int32(Date().timeIntervalSince1970)).startStandalone()
|
||||
}
|
||||
}
|
||||
|
||||
@ -1818,7 +1818,7 @@ private class QrContentNode: ASDisplayNode, ContentNode {
|
||||
|
||||
let _ = (copyNode.isReady
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(next: { [weak copyNode] _ in
|
||||
|> deliverOnMainQueue).startStandalone(next: { [weak copyNode] _ in
|
||||
Queue.mainQueue().after(0.1) {
|
||||
if #available(iOS 10.0, *) {
|
||||
let format = UIGraphicsImageRendererFormat()
|
||||
@ -2138,7 +2138,7 @@ private class MessageContentNode: ASDisplayNode, ContentNode {
|
||||
|
||||
let _ = (copyNode.isReady
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(next: { [weak copyNode] _ in
|
||||
|> deliverOnMainQueue).startStandalone(next: { [weak copyNode] _ in
|
||||
Queue.mainQueue().after(0.1) {
|
||||
let image: UIImage?
|
||||
if #available(iOS 10.0, *) {
|
||||
@ -2285,7 +2285,7 @@ private class MessageContentNode: ASDisplayNode, ContentNode {
|
||||
let videoNode = UniversalVideoNode(postbox: self.context.account.postbox, audioSession: self.context.sharedContext.mediaManager.audioSession, manager: self.context.sharedContext.mediaManager.universalVideoManager, decoration: GalleryVideoDecoration(), content: videoContent, priority: .overlay, autoplay: !self.isStatic)
|
||||
|
||||
self.videoStatusDisposable.set((videoNode.status
|
||||
|> deliverOnMainQueue).start(next: { [weak self] status in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] status in
|
||||
if let strongSelf = self {
|
||||
strongSelf.videoStatus = status
|
||||
if let (size, topInset, bottomInset) = strongSelf.validLayout {
|
||||
@ -2416,7 +2416,7 @@ private enum RenderVideoResult {
|
||||
|
||||
private func renderVideo(context: AccountContext, backgroundImage: UIImage, userLocation: MediaResourceUserLocation, media: TelegramMediaFile, videoFrame: CGRect, completion: @escaping (URL?) -> Void) {
|
||||
let _ = (fetchMediaData(context: context, postbox: context.account.postbox, userLocation: userLocation, mediaReference: AnyMediaReference.standalone(media: media))
|
||||
|> deliverOnMainQueue).start(next: { value, isImage in
|
||||
|> deliverOnMainQueue).startStandalone(next: { value, isImage in
|
||||
guard case let .data(data) = value, data.complete else {
|
||||
return
|
||||
}
|
||||
|
@ -192,7 +192,7 @@ final class ChatRecentActionsController: TelegramBaseController {
|
||||
}
|
||||
|> distinctUntilChanged
|
||||
|
||||
self.presentationDataDisposable = combineLatest(queue: Queue.mainQueue(), context.sharedContext.presentationData, context.engine.themes.getChatThemes(accountManager: context.sharedContext.accountManager, onlyCached: true), themeEmoticon).start(next: { [weak self] presentationData, chatThemes, themeEmoticon in
|
||||
self.presentationDataDisposable = combineLatest(queue: Queue.mainQueue(), context.sharedContext.presentationData, context.engine.themes.getChatThemes(accountManager: context.sharedContext.accountManager, onlyCached: true), themeEmoticon).startStrict(next: { [weak self] presentationData, chatThemes, themeEmoticon in
|
||||
if let strongSelf = self {
|
||||
let previousTheme = strongSelf.presentationData.theme
|
||||
let previousStrings = strongSelf.presentationData.strings
|
||||
|
@ -175,7 +175,7 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
|
||||
actionSheet?.dismissAnimated()
|
||||
if let strongSelf = self {
|
||||
let _ = (strongSelf.context.engine.peers.revokePeerExportedInvitation(peerId: peer.id, link: inviteLink)
|
||||
|> deliverOnMainQueue).start(completed: { [weak self] in
|
||||
|> deliverOnMainQueue).startStandalone(completed: { [weak self] in
|
||||
self?.eventLogContext.reload()
|
||||
})
|
||||
}
|
||||
@ -237,7 +237,7 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
|
||||
}, enqueueMessage: { _ in
|
||||
}, sendSticker: nil, sendEmoji: nil, setupTemporaryHiddenMedia: { _, _, _ in }, chatAvatarHiddenMedia: { signal, media in
|
||||
if let strongSelf = self {
|
||||
strongSelf.temporaryHiddenGalleryMediaDisposable.set((signal |> deliverOnMainQueue).start(next: { messageId in
|
||||
strongSelf.temporaryHiddenGalleryMediaDisposable.set((signal |> deliverOnMainQueue).startStrict(next: { messageId in
|
||||
if let strongSelf = self, let controllerInteraction = strongSelf.controllerInteraction {
|
||||
var messageIdAndMedia: [MessageId: [Media]] = [:]
|
||||
|
||||
@ -302,7 +302,7 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
|
||||
|> map(Optional.init)
|
||||
}
|
||||
strongSelf.resolvePeerByNameDisposable.set((resolveSignal
|
||||
|> deliverOnMainQueue).start(next: { peer in
|
||||
|> deliverOnMainQueue).startStrict(next: { peer in
|
||||
if let strongSelf = self, !hashtag.isEmpty {
|
||||
let searchController = HashtagSearchController(context: strongSelf.context, peer: peer.flatMap(EnginePeer.init), query: hashtag)
|
||||
strongSelf.pushController(searchController)
|
||||
@ -390,7 +390,7 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
|
||||
actionSheet?.dismissAnimated()
|
||||
if let strongSelf = self {
|
||||
let _ = (strongSelf.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|
||||
|> deliverOnMainQueue).start(next: { peer in
|
||||
|> deliverOnMainQueue).startStandalone(next: { peer in
|
||||
if let strongSelf = self, let peer = peer {
|
||||
strongSelf.openPeer(peer: peer)
|
||||
}
|
||||
@ -608,10 +608,10 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
|
||||
return .complete()
|
||||
}
|
||||
|
||||
self.historyDisposable = appliedTransition.start()
|
||||
self.historyDisposable = appliedTransition.startStrict()
|
||||
|
||||
let mediaManager = self.context.sharedContext.mediaManager
|
||||
self.galleryHiddenMesageAndMediaDisposable.set(mediaManager.galleryHiddenMediaManager.hiddenIds().start(next: { [weak self] ids in
|
||||
self.galleryHiddenMesageAndMediaDisposable.set(mediaManager.galleryHiddenMediaManager.hiddenIds().startStrict(next: { [weak self] ids in
|
||||
if let strongSelf = self, let controllerInteraction = strongSelf.controllerInteraction {
|
||||
var messageIdAndMedia: [MessageId: [Media]] = [:]
|
||||
|
||||
@ -806,7 +806,7 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
|
||||
}), .window(.root), nil)
|
||||
} else {
|
||||
let peerSignal: Signal<Peer?, NoError> = .single(peer._asPeer())
|
||||
self.navigationActionDisposable.set((peerSignal |> take(1) |> deliverOnMainQueue).start(next: { [weak self] peer in
|
||||
self.navigationActionDisposable.set((peerSignal |> take(1) |> deliverOnMainQueue).startStrict(next: { [weak self] peer in
|
||||
if let strongSelf = self, let peer = peer {
|
||||
if peer is TelegramChannel, let navigationController = strongSelf.getNavigationController() {
|
||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(EnginePeer(peer)), peekData: peekData, animated: true))
|
||||
@ -823,7 +823,7 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
|
||||
private func openPeerMention(_ name: String) {
|
||||
self.navigationActionDisposable.set((self.context.engine.peers.resolvePeerByName(name: name, ageLimit: 10)
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] peer in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] peer in
|
||||
if let strongSelf = self {
|
||||
if let peer = peer {
|
||||
if let infoController = strongSelf.context.sharedContext.makePeerInfoController(context: strongSelf.context, updatedPresentationData: nil, peer: peer._asPeer(), mode: .generic, avatarInitiallyExpanded: false, fromChat: false, requestsContext: nil) {
|
||||
@ -903,7 +903,7 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
|
||||
if let strongSelf = self {
|
||||
f(.default)
|
||||
strongSelf.banDisposables.set((strongSelf.context.engine.peers.fetchChannelParticipant(peerId: strongSelf.peer.id, participantId: author.id)
|
||||
|> deliverOnMainQueue).start(next: { participant in
|
||||
|> deliverOnMainQueue).startStrict(next: { participant in
|
||||
if let strongSelf = self {
|
||||
strongSelf.presentController(channelBannedMemberController(context: strongSelf.context, peerId: strongSelf.peer.id, memberId: author.id, initialParticipant: participant, updated: { _ in }, upgradedToSupergroup: { _, f in f() }), .window(.root), ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
|
||||
}
|
||||
@ -926,7 +926,7 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
|
||||
|
||||
if let strongSelf = self {
|
||||
strongSelf.reportFalsePositiveDisposables.set((strongSelf.context.engine.peers.reportAntiSpamFalsePositive(peerId: message.id.peerId, messageId: message.id)
|
||||
|> deliverOnMainQueue).start(), forKey: message.id)
|
||||
|> deliverOnMainQueue).startStrict(), forKey: message.id)
|
||||
|
||||
Queue.mainQueue().after(0.2, {
|
||||
strongSelf.presentController(UndoOverlayController(presentationData: strongSelf.presentationData, content: .universal(animation: "anim_antispam", scale: 0.066, colors: [:], title: nil, text: strongSelf.presentationData.strings.Group_AdminLog_AntiSpamFalsePositiveReportedText, customUndoText: nil, timeout: nil), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), .current, nil)
|
||||
@ -956,7 +956,7 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
|
||||
}
|
||||
|
||||
private func openUrl(_ url: String) {
|
||||
self.navigationActionDisposable.set((self.context.sharedContext.resolveUrl(context: self.context, peerId: nil, url: url, skipUrlAuth: true) |> deliverOnMainQueue).start(next: { [weak self] result in
|
||||
self.navigationActionDisposable.set((self.context.sharedContext.resolveUrl(context: self.context, peerId: nil, url: url, skipUrlAuth: true) |> deliverOnMainQueue).startStrict(next: { [weak self] result in
|
||||
if let strongSelf = self {
|
||||
switch result {
|
||||
case let .externalUrl(url):
|
||||
@ -991,7 +991,7 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
|
||||
}
|
||||
case let .replyThread(messageId):
|
||||
if let navigationController = strongSelf.getNavigationController() {
|
||||
let _ = strongSelf.context.sharedContext.navigateToForumThread(context: strongSelf.context, peerId: messageId.peerId, threadId: Int64(messageId.id), messageId: nil, navigationController: navigationController, activateInput: nil, keepStack: .always).start()
|
||||
let _ = strongSelf.context.sharedContext.navigateToForumThread(context: strongSelf.context, peerId: messageId.peerId, threadId: Int64(messageId.id), messageId: nil, navigationController: navigationController, activateInput: nil, keepStack: .always).startStandalone()
|
||||
}
|
||||
case let .stickerPack(name, type):
|
||||
let _ = type
|
||||
|
@ -390,7 +390,7 @@ public func channelRecentActionsFilterController(context: AccountContext, update
|
||||
}, toggleAllAdmins: { value in
|
||||
let _ = (adminsPromise.get()
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(next: { admins in
|
||||
|> deliverOnMainQueue).startStandalone(next: { admins in
|
||||
if let _ = admins {
|
||||
updateState { current in
|
||||
if value {
|
||||
@ -404,7 +404,7 @@ public func channelRecentActionsFilterController(context: AccountContext, update
|
||||
}, toggleAdmin: { adminId in
|
||||
let _ = (adminsPromise.get()
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(next: { admins in
|
||||
|> deliverOnMainQueue).startStandalone(next: { admins in
|
||||
if let admins = admins {
|
||||
updateState { current in
|
||||
if let adminPeerIds = current.adminPeerIds, let index = adminPeerIds.firstIndex(of: adminId) {
|
||||
|
@ -167,7 +167,7 @@ final class ChatRecordingPreviewInputPanelNode: ChatInputPanelNode {
|
||||
self.durationLabel.status = mediaPlayer.status
|
||||
self.waveformScubberNode.status = mediaPlayer.status
|
||||
self.statusDisposable.set((mediaPlayer.status
|
||||
|> deliverOnMainQueue).start(next: { [weak self] status in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] status in
|
||||
if let strongSelf = self {
|
||||
switch status.status {
|
||||
case .playing, .buffering(_, true, _, _):
|
||||
|
@ -33,7 +33,7 @@ final class ChatSearchInputPanelNode: ChatInputPanelNode {
|
||||
override var interfaceInteraction: ChatPanelInterfaceInteraction? {
|
||||
didSet {
|
||||
if let statuses = self.interfaceInteraction?.statuses {
|
||||
self.activityDisposable.set((combineLatest((statuses.searching |> deliverOnMainQueue), (statuses.loadingMessage |> deliverOnMainQueue))).start(next: { [weak self] searching, loadingMessage in
|
||||
self.activityDisposable.set((combineLatest((statuses.searching |> deliverOnMainQueue), (statuses.loadingMessage |> deliverOnMainQueue))).startStrict(next: { [weak self] searching, loadingMessage in
|
||||
let value = searching || loadingMessage == .generic
|
||||
if let strongSelf = self, strongSelf.displayActivity != value {
|
||||
strongSelf.displayActivity = value
|
||||
@ -91,7 +91,7 @@ final class ChatSearchInputPanelNode: ChatInputPanelNode {
|
||||
}
|
||||
|
||||
let _ = (ApplicationSpecificNotice.getChatMessageSearchResultsTip(accountManager: context.sharedContext.accountManager)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] counter in
|
||||
|> deliverOnMainQueue).startStandalone(next: { [weak self] counter in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -101,7 +101,7 @@ final class ChatSearchInputPanelNode: ChatInputPanelNode {
|
||||
} else if arc4random_uniform(4) == 1 {
|
||||
strongSelf.needsSearchResultsTooltip = false
|
||||
|
||||
let _ = ApplicationSpecificNotice.incrementChatMessageSearchResultsTip(accountManager: context.sharedContext.accountManager).start()
|
||||
let _ = ApplicationSpecificNotice.incrementChatMessageSearchResultsTip(accountManager: context.sharedContext.accountManager).startStandalone()
|
||||
strongSelf.interfaceInteraction?.displaySearchResultsTooltip(strongSelf.resultsButton, strongSelf.resultsButton.bounds)
|
||||
}
|
||||
})
|
||||
@ -123,7 +123,7 @@ final class ChatSearchInputPanelNode: ChatInputPanelNode {
|
||||
self.interfaceInteraction?.openSearchResults()
|
||||
|
||||
if let context = self.context {
|
||||
let _ = ApplicationSpecificNotice.incrementChatMessageSearchResultsTip(accountManager: context.sharedContext.accountManager, count: 4).start()
|
||||
let _ = ApplicationSpecificNotice.incrementChatMessageSearchResultsTip(accountManager: context.sharedContext.accountManager, count: 4).startStandalone()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -66,7 +66,7 @@ final class ChatSearchNavigationContentNode: NavigationBarContentNode {
|
||||
|
||||
if let statuses = interaction.statuses {
|
||||
self.searchingActivityDisposable = (statuses.searching
|
||||
|> deliverOnMainQueue).start(next: { [weak self] value in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] value in
|
||||
self?.searchBar.activity = value
|
||||
})
|
||||
}
|
||||
|
@ -276,7 +276,7 @@ class ChatSearchResultsControllerNode: ViewControllerTracingNode, UIScrollViewDe
|
||||
self.interaction = interaction
|
||||
|
||||
self.disposable.set((signal
|
||||
|> deliverOnMainQueue).start(next: { [weak self] entries in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] entries in
|
||||
if let strongSelf = self {
|
||||
let previousEntries = strongSelf.previousEntries.swap(entries)
|
||||
|
||||
@ -312,7 +312,7 @@ class ChatSearchResultsControllerNode: ViewControllerTracingNode, UIScrollViewDe
|
||||
self.isLoadingMore = true
|
||||
|
||||
self.loadMoreDisposable.set((self.context.engine.messages.searchMessages(location: self.location, query: self.searchQuery, state: self.searchState)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] (updatedResult, updatedState) in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] (updatedResult, updatedState) in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -345,7 +345,7 @@ class ChatSearchResultsControllerNode: ViewControllerTracingNode, UIScrollViewDe
|
||||
}
|
||||
|
||||
strongSelf.disposable.set((signal
|
||||
|> deliverOnMainQueue).start(next: { entries in
|
||||
|> deliverOnMainQueue).startStrict(next: { entries in
|
||||
if let strongSelf = self {
|
||||
let previousEntries = strongSelf.previousEntries.swap(entries)
|
||||
|
||||
|
@ -40,7 +40,7 @@ final class ChatSearchResultsController: ViewController {
|
||||
self.navigationPresentation = .modal
|
||||
|
||||
self.presentationDataDisposable = ((updatedPresentationData?.signal ?? context.sharedContext.presentationData)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] presentationData in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] presentationData in
|
||||
if let strongSelf = self {
|
||||
strongSelf.presentationData = presentationData
|
||||
strongSelf.navigationBar?.updatePresentationData(NavigationBarPresentationData(presentationTheme: presentationData.theme, presentationStrings: presentationData.strings))
|
||||
|
@ -23,7 +23,7 @@ final class ChatSecretAutoremoveTimerActionSheetController: ActionSheetControlle
|
||||
|
||||
super.init(theme: ActionSheetControllerTheme(presentationData: presentationData))
|
||||
|
||||
self.presentationDisposable = context.sharedContext.presentationData.start(next: { [weak self] presentationData in
|
||||
self.presentationDisposable = context.sharedContext.presentationData.startStrict(next: { [weak self] presentationData in
|
||||
if let strongSelf = self {
|
||||
strongSelf.theme = ActionSheetControllerTheme(presentationData: presentationData)
|
||||
}
|
||||
|
@ -115,7 +115,7 @@ private final class ChatSendAsPeerListContextItemNode: ASDisplayNode, ContextMen
|
||||
}
|
||||
|
||||
if peer.peer.id != item.selectedPeerId {
|
||||
let _ = item.context.engine.peers.updatePeerSendAsPeer(peerId: item.chatPeerId, sendAs: peer.peer.id).start()
|
||||
let _ = item.context.engine.peers.updatePeerSendAsPeer(peerId: item.chatPeerId, sendAs: peer.peer.id).startStandalone()
|
||||
}
|
||||
})
|
||||
let actionNode = ContextActionNode(presentationData: presentationData, action: action, getController: getController, actionSelected: actionSelected, requestLayout: {}, requestUpdateAction: { _, _ in
|
||||
|
@ -38,7 +38,7 @@ final class ChatTextInputAudioRecordingTimeNode: ASDisplayNode {
|
||||
didSet {
|
||||
if self.audioRecorder !== oldValue {
|
||||
if let audioRecorder = self.audioRecorder {
|
||||
self.stateDisposable.set(audioRecorder.recordingState.start(next: { [weak self] state in
|
||||
self.stateDisposable.set(audioRecorder.recordingState.startStrict(next: { [weak self] state in
|
||||
if let strongSelf = self {
|
||||
switch state {
|
||||
case let .paused(duration):
|
||||
@ -69,11 +69,11 @@ final class ChatTextInputAudioRecordingTimeNode: ASDisplayNode {
|
||||
didSet {
|
||||
if self.videoRecordingStatus !== oldValue {
|
||||
if self.durationDisposable == nil {
|
||||
durationDisposable = MetaDisposable()
|
||||
self.durationDisposable = MetaDisposable()
|
||||
}
|
||||
|
||||
if let videoRecordingStatus = self.videoRecordingStatus {
|
||||
self.durationDisposable?.set(videoRecordingStatus.duration.start(next: { [weak self] duration in
|
||||
self.durationDisposable?.set(videoRecordingStatus.duration.startStrict(next: { [weak self] duration in
|
||||
Queue.mainQueue().async { [weak self] in
|
||||
if let strongSelf = self {
|
||||
strongSelf.timestamp = duration
|
||||
|
@ -588,16 +588,16 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
if let statuses = self.interfaceInteraction?.statuses {
|
||||
self.statusDisposable.set((statuses.inlineSearch
|
||||
|> distinctUntilChanged
|
||||
|> deliverOnMainQueue).start(next: { [weak self] value in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] value in
|
||||
self?.updateIsProcessingInlineRequest(value)
|
||||
}))
|
||||
}).strict())
|
||||
}
|
||||
if let startingBot = self.interfaceInteraction?.statuses?.startingBot {
|
||||
self.startingBotDisposable.set((startingBot |> deliverOnMainQueue).start(next: { [weak self] value in
|
||||
self.startingBotDisposable.set((startingBot |> deliverOnMainQueue).startStrict(next: { [weak self] value in
|
||||
if let strongSelf = self {
|
||||
strongSelf.startingBotProgress = value
|
||||
}
|
||||
}))
|
||||
}).strict())
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1022,6 +1022,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
|
||||
deinit {
|
||||
self.statusDisposable.dispose()
|
||||
self.startingBotDisposable.dispose()
|
||||
self.tooltipController?.dismiss()
|
||||
}
|
||||
|
||||
@ -2790,7 +2791,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
|
||||
if beginRequest {
|
||||
suggestionContext.disposable.set((EmojiSuggestionsComponent.suggestionData(context: context, isSavedMessages: self.presentationInterfaceState?.chatLocation.peerId == self.context?.account.peerId, query: String(lastCharacter))
|
||||
|> deliverOnMainQueue).start(next: { [weak self, weak suggestionContext] result in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self, weak suggestionContext] result in
|
||||
guard let strongSelf = self, let suggestionContext = suggestionContext, strongSelf.currentEmojiSuggestion === suggestionContext else {
|
||||
return
|
||||
}
|
||||
@ -2800,7 +2801,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
if let textInputNode = strongSelf.textInputNode {
|
||||
strongSelf.updateInputField(textInputFrame: textInputNode.frame, transition: .immediate)
|
||||
}
|
||||
}))
|
||||
}).strict())
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3125,7 +3126,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
return
|
||||
}
|
||||
|
||||
let _ = context.engine.accountData.setEmojiStatus(file: file, expirationDate: nil).start()
|
||||
let _ = context.engine.accountData.setEmojiStatus(file: file, expirationDate: nil).startStandalone()
|
||||
|
||||
var animateInAsReplacement = false
|
||||
animateInAsReplacement = false
|
||||
|
@ -474,7 +474,7 @@ private final class ThemeSettingsThemeItemIconNode : ListViewItemNode {
|
||||
animatedStickerNode.autoplay = true
|
||||
animatedStickerNode.visibility = strongSelf.visibilityStatus
|
||||
|
||||
strongSelf.stickerFetchedDisposable.set(fetchedMediaResource(mediaBox: item.context.account.postbox.mediaBox, userLocation: .other, userContentType: .sticker, reference: MediaResourceReference.media(media: .standalone(media: file), resource: file.resource)).start())
|
||||
strongSelf.stickerFetchedDisposable.set(fetchedMediaResource(mediaBox: item.context.account.postbox.mediaBox, userLocation: .other, userContentType: .sticker, reference: MediaResourceReference.media(media: .standalone(media: file), resource: file.resource)).startStrict())
|
||||
|
||||
let thumbnailDimensions = PixelDimensions(width: 512, height: 512)
|
||||
strongSelf.placeholderNode.update(backgroundColor: nil, foregroundColor: UIColor(rgb: 0xffffff, alpha: 0.2), shimmeringColor: UIColor(rgb: 0xffffff, alpha: 0.3), data: file.immediateThumbnailData, size: emojiFrame.size, enableEffect: item.context.sharedContext.energyUsageSettings.fullTranslucency, imageSize: thumbnailDimensions.cgSize)
|
||||
@ -586,7 +586,7 @@ final class ChatThemeScreen: ViewController {
|
||||
self.blocksBackgroundWhenInOverlay = true
|
||||
|
||||
self.presentationDataDisposable = (updatedPresentationData.signal
|
||||
|> deliverOnMainQueue).start(next: { [weak self] presentationData in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] presentationData in
|
||||
if let strongSelf = self {
|
||||
strongSelf.presentationData = presentationData
|
||||
strongSelf.controllerNode.updatePresentationData(presentationData)
|
||||
@ -877,7 +877,7 @@ private class ChatThemeScreenNode: ViewControllerTracingNode, UIScrollViewDelega
|
||||
}
|
||||
self.otherButton.addTarget(self, action: #selector(self.otherButtonPressed), forControlEvents: .touchUpInside)
|
||||
|
||||
self.disposable.set(combineLatest(queue: Queue.mainQueue(), self.context.engine.themes.getChatThemes(accountManager: self.context.sharedContext.accountManager), self.selectedEmoticonPromise.get(), self.isDarkAppearancePromise.get()).start(next: { [weak self] themes, selectedEmoticon, isDarkAppearance in
|
||||
self.disposable.set(combineLatest(queue: Queue.mainQueue(), self.context.engine.themes.getChatThemes(accountManager: self.context.sharedContext.accountManager), self.selectedEmoticonPromise.get(), self.isDarkAppearancePromise.get()).startStrict(next: { [weak self] themes, selectedEmoticon, isDarkAppearance in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -1165,9 +1165,9 @@ private class ChatThemeScreenNode: ViewControllerTracingNode, UIScrollViewDelega
|
||||
self.isDarkAppearance = isDarkAppearance
|
||||
|
||||
if isDarkAppearance {
|
||||
let _ = ApplicationSpecificNotice.incrementChatSpecificThemeDarkPreviewTip(accountManager: self.context.sharedContext.accountManager, count: 3, timestamp: Int32(Date().timeIntervalSince1970)).start()
|
||||
let _ = ApplicationSpecificNotice.incrementChatSpecificThemeDarkPreviewTip(accountManager: self.context.sharedContext.accountManager, count: 3, timestamp: Int32(Date().timeIntervalSince1970)).startStandalone()
|
||||
} else {
|
||||
let _ = ApplicationSpecificNotice.incrementChatSpecificThemeLightPreviewTip(accountManager: self.context.sharedContext.accountManager, count: 3, timestamp: Int32(Date().timeIntervalSince1970)).start()
|
||||
let _ = ApplicationSpecificNotice.incrementChatSpecificThemeLightPreviewTip(accountManager: self.context.sharedContext.accountManager, count: 3, timestamp: Int32(Date().timeIntervalSince1970)).startStandalone()
|
||||
}
|
||||
}
|
||||
|
||||
@ -1258,7 +1258,7 @@ private class ChatThemeScreenNode: ViewControllerTracingNode, UIScrollViewDelega
|
||||
}
|
||||
|
||||
let _ = (signal
|
||||
|> deliverOnMainQueue).start(next: { [weak self] count, timestamp in
|
||||
|> deliverOnMainQueue).startStandalone(next: { [weak self] count, timestamp in
|
||||
if let strongSelf = self, count < 2 && currentTimestamp > timestamp + 24 * 60 * 60 {
|
||||
strongSelf.displayedPreviewTooltip = true
|
||||
|
||||
@ -1267,9 +1267,9 @@ private class ChatThemeScreenNode: ViewControllerTracingNode, UIScrollViewDelega
|
||||
}))
|
||||
|
||||
if isDark {
|
||||
let _ = ApplicationSpecificNotice.incrementChatSpecificThemeLightPreviewTip(accountManager: strongSelf.context.sharedContext.accountManager, timestamp: currentTimestamp).start()
|
||||
let _ = ApplicationSpecificNotice.incrementChatSpecificThemeLightPreviewTip(accountManager: strongSelf.context.sharedContext.accountManager, timestamp: currentTimestamp).startStandalone()
|
||||
} else {
|
||||
let _ = ApplicationSpecificNotice.incrementChatSpecificThemeDarkPreviewTip(accountManager: strongSelf.context.sharedContext.accountManager, timestamp: currentTimestamp).start()
|
||||
let _ = ApplicationSpecificNotice.incrementChatSpecificThemeDarkPreviewTip(accountManager: strongSelf.context.sharedContext.accountManager, timestamp: currentTimestamp).startStandalone()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -178,7 +178,7 @@ final class ChatTranslationPanelNode: ASDisplayNode {
|
||||
}
|
||||
|
||||
@objc private func closePressed() {
|
||||
let _ = ApplicationSpecificNotice.incrementTranslationSuggestion(accountManager: self.context.sharedContext.accountManager, count: -100, timestamp: Int32(Date().timeIntervalSince1970) + 60 * 60 * 24 * 7).start()
|
||||
let _ = ApplicationSpecificNotice.incrementTranslationSuggestion(accountManager: self.context.sharedContext.accountManager, count: -100, timestamp: Int32(Date().timeIntervalSince1970) + 60 * 60 * 24 * 7).startStandalone()
|
||||
}
|
||||
|
||||
@objc private func buttonPressed() {
|
||||
|
@ -20,7 +20,7 @@ final class ChatUnblockInputPanelNode: ChatInputPanelNode {
|
||||
didSet {
|
||||
if self.statusDisposable == nil {
|
||||
if let startingBot = self.interfaceInteraction?.statuses?.unblockingPeer {
|
||||
self.statusDisposable = (startingBot |> deliverOnMainQueue).start(next: { [weak self] value in
|
||||
self.statusDisposable = (startingBot |> deliverOnMainQueue).startStrict(next: { [weak self] value in
|
||||
if let strongSelf = self {
|
||||
if value != !strongSelf.activityIndicator.isHidden {
|
||||
if value {
|
||||
|
@ -88,7 +88,7 @@ final class CommandMenuChatInputContextPanelNode: ChatInputContextPanelNode {
|
||||
self.addSubnode(self.listView)
|
||||
|
||||
self.disposable.set((context.engine.peers.peerCommands(id: peerId)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] results in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] results in
|
||||
if let strongSelf = self {
|
||||
strongSelf.updateResults(results.commands)
|
||||
}
|
||||
|
@ -62,7 +62,7 @@ public class ComposeControllerImpl: ViewController, ComposeController {
|
||||
}
|
||||
|
||||
self.presentationDataDisposable = (context.sharedContext.presentationData
|
||||
|> deliverOnMainQueue).start(next: { [weak self] presentationData in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] presentationData in
|
||||
if let strongSelf = self {
|
||||
let previousTheme = strongSelf.presentationData.theme
|
||||
let previousStrings = strongSelf.presentationData.strings
|
||||
@ -131,7 +131,7 @@ public class ComposeControllerImpl: ViewController, ComposeController {
|
||||
}
|
||||
})
|
||||
strongSelf.createActionDisposable.set((controller.result
|
||||
|> deliverOnMainQueue).start(next: { [weak controller] result in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak controller] result in
|
||||
var peerIds: [ContactListPeerId] = []
|
||||
if case let .result(peerIdsValue, _) = result {
|
||||
peerIds = peerIdsValue
|
||||
@ -156,11 +156,11 @@ public class ComposeControllerImpl: ViewController, ComposeController {
|
||||
let controller = ContactSelectionControllerImpl(ContactSelectionControllerParams(context: strongSelf.context, autoDismiss: false, title: { $0.Compose_NewEncryptedChatTitle }))
|
||||
strongSelf.createActionDisposable.set((controller.result
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(next: { [weak controller] result in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak controller] result in
|
||||
if let strongSelf = self, let (contactPeers, _, _, _, _) = result, case let .peer(peer, _, _) = contactPeers.first {
|
||||
controller?.dismissSearch()
|
||||
controller?.displayNavigationActivity = true
|
||||
strongSelf.createActionDisposable.set((strongSelf.context.engine.peers.createSecretChat(peerId: peer.id) |> deliverOnMainQueue).start(next: { peerId in
|
||||
strongSelf.createActionDisposable.set((strongSelf.context.engine.peers.createSecretChat(peerId: peer.id) |> deliverOnMainQueue).startStrict(next: { peerId in
|
||||
if let strongSelf = self, let controller = controller {
|
||||
controller.displayNavigationActivity = false
|
||||
(controller.navigationController as? NavigationController)?.replaceAllButRootController(ChatControllerImpl(context: strongSelf.context, chatLocation: .peer(id: peerId)), animated: true)
|
||||
@ -192,7 +192,7 @@ public class ComposeControllerImpl: ViewController, ComposeController {
|
||||
self.contactsNode.openCreateContact = { [weak self] in
|
||||
let _ = (DeviceAccess.authorizationStatus(subject: .contacts)
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(next: { status in
|
||||
|> deliverOnMainQueue).startStandalone(next: { status in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
|
@ -75,7 +75,7 @@ final class ComposeControllerNode: ASDisplayNode {
|
||||
}
|
||||
|
||||
self.presentationDataDisposable = (context.sharedContext.presentationData
|
||||
|> deliverOnMainQueue).start(next: { [weak self] presentationData in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] presentationData in
|
||||
if let strongSelf = self {
|
||||
let previousTheme = strongSelf.presentationData.theme
|
||||
let previousStrings = strongSelf.presentationData.strings
|
||||
|
@ -108,7 +108,7 @@ class ContactMultiselectionControllerImpl: ViewController, ContactMultiselection
|
||||
}
|
||||
|
||||
self.presentationDataDisposable = ((params.updatedPresentationData?.signal ?? params.context.sharedContext.presentationData)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] presentationData in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] presentationData in
|
||||
if let strongSelf = self {
|
||||
let previousTheme = strongSelf.presentationData.theme
|
||||
let previousStrings = strongSelf.presentationData.strings
|
||||
@ -122,7 +122,7 @@ class ContactMultiselectionControllerImpl: ViewController, ContactMultiselection
|
||||
})
|
||||
|
||||
self.limitsConfigurationDisposable = (context.engine.data.get(TelegramEngine.EngineData.Item.Configuration.Limits())
|
||||
|> deliverOnMainQueue).start(next: { [weak self] value in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] value in
|
||||
if let strongSelf = self {
|
||||
strongSelf.limitsConfiguration = value._asLimits()
|
||||
strongSelf.updateTitle()
|
||||
@ -139,7 +139,7 @@ class ContactMultiselectionControllerImpl: ViewController, ContactMultiselection
|
||||
selectedChats.map(TelegramEngine.EngineData.Item.Peer.Peer.init)
|
||||
)
|
||||
)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] peerList in
|
||||
|> deliverOnMainQueue).startStandalone(next: { [weak self] peerList in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
|
@ -235,7 +235,7 @@ final class ContactMultiselectionControllerNode: ASDisplayNode {
|
||||
searchResultsNode.frame = CGRect(origin: CGPoint(), size: layout.size)
|
||||
}
|
||||
|
||||
strongSelf.searchResultsReadyDisposable.set((searchResultsNode.ready |> deliverOnMainQueue).start(next: { _ in
|
||||
strongSelf.searchResultsReadyDisposable.set((searchResultsNode.ready |> deliverOnMainQueue).startStrict(next: { _ in
|
||||
if let strongSelf = self, let searchResultsNode = strongSelf.searchResultsNode {
|
||||
strongSelf.insertSubnode(searchResultsNode, aboveSubnode: strongSelf.contentNode.node)
|
||||
}
|
||||
|
@ -116,7 +116,7 @@ class ContactSelectionControllerImpl: ViewController, ContactSelectionController
|
||||
}
|
||||
|
||||
self.presentationDataDisposable = ((params.updatedPresentationData?.signal ?? params.context.sharedContext.presentationData)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] presentationData in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] presentationData in
|
||||
if let strongSelf = self {
|
||||
let previousTheme = strongSelf.presentationData.theme
|
||||
let previousStrings = strongSelf.presentationData.strings
|
||||
@ -327,7 +327,7 @@ class ContactSelectionControllerImpl: ViewController, ContactSelectionController
|
||||
|
||||
private func openPeer(peer: ContactListPeer, action: ContactListAction) {
|
||||
self.contactsNode.contactListNode.listNode.clearHighlightAnimated(true)
|
||||
self.confirmationDisposable.set((self.confirmation(peer) |> deliverOnMainQueue).start(next: { [weak self] value in
|
||||
self.confirmationDisposable.set((self.confirmation(peer) |> deliverOnMainQueue).startStrict(next: { [weak self] value in
|
||||
if let strongSelf = self {
|
||||
if value {
|
||||
strongSelf._result.set(.single(([peer], action, false, nil, nil)))
|
||||
|
@ -349,7 +349,7 @@ private final class DeviceContactDataManagerPrivateImpl {
|
||||
self.queue = queue
|
||||
self.accessDisposable = (DeviceAccess.authorizationStatus(subject: .contacts)
|
||||
|> delay(2.0, queue: .mainQueue())
|
||||
|> deliverOn(self.queue)).start(next: { [weak self] authorizationStatus in
|
||||
|> deliverOn(self.queue)).startStrict(next: { [weak self] authorizationStatus in
|
||||
guard let strongSelf = self, authorizationStatus != .notDetermined else {
|
||||
return
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ final class EditAccessoryPanelNode: AccessoryPanelNode {
|
||||
override var interfaceInteraction: ChatPanelInterfaceInteraction? {
|
||||
didSet {
|
||||
if let statuses = self.interfaceInteraction?.statuses {
|
||||
self.editingMessageDisposable.set(statuses.editingMessage.start(next: { [weak self] value in
|
||||
self.editingMessageDisposable.set(statuses.editingMessage.startStrict(next: { [weak self] value in
|
||||
if let strongSelf = self {
|
||||
if let value = value {
|
||||
if value.isZero {
|
||||
@ -161,7 +161,7 @@ final class EditAccessoryPanelNode: AccessoryPanelNode {
|
||||
self.addSubnode(self.tapNode)
|
||||
self.addSubnode(self.actionArea)
|
||||
self.messageDisposable.set((context.account.postbox.messageAtId(messageId)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] message in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] message in
|
||||
self?.updateMessage(message)
|
||||
}))
|
||||
}
|
||||
|
@ -331,7 +331,7 @@ final class EmojisChatInputContextPanelNode: ChatInputContextPanelNode {
|
||||
return
|
||||
}
|
||||
|
||||
let _ = self.context.engine.accountData.setEmojiStatus(file: file, expirationDate: nil).start()
|
||||
let _ = self.context.engine.accountData.setEmojiStatus(file: file, expirationDate: nil).startStandalone()
|
||||
|
||||
var animateInAsReplacement = false
|
||||
animateInAsReplacement = false
|
||||
|
@ -102,7 +102,7 @@ final class GalleryHiddenMediaManagerImpl: GalleryHiddenMediaManager {
|
||||
let context = SourceContext(disposable: disposable)
|
||||
self.sourceContexts[index] = context
|
||||
|
||||
disposable.set((signal |> deliverOnMainQueue).start(next: { [weak self, weak context] id in
|
||||
disposable.set((signal |> deliverOnMainQueue).startStrict(next: { [weak self, weak context] id in
|
||||
guard let strongSelf = self, let context = context else {
|
||||
return
|
||||
}
|
||||
|
@ -235,7 +235,7 @@ final class GridMessageItemNode: GridItemNode {
|
||||
self.mediaBadgeNode.isHidden = false
|
||||
|
||||
self.resourceStatus = nil
|
||||
self.fetchStatusDisposable.set((messageMediaFileStatus(context: context, messageId: messageId, file: file) |> deliverOnMainQueue).start(next: { [weak self] status in
|
||||
self.fetchStatusDisposable.set((messageMediaFileStatus(context: context, messageId: messageId, file: file) |> deliverOnMainQueue).startStrict(next: { [weak self] status in
|
||||
if let strongSelf = self, let item = strongSelf.item {
|
||||
strongSelf.resourceStatus = status
|
||||
|
||||
@ -434,7 +434,7 @@ final class GridMessageItemNode: GridItemNode {
|
||||
case .Local:
|
||||
let _ = controllerInteraction.openMessage(message, .default)
|
||||
case .Remote, .Paused:
|
||||
self.fetchDisposable.set(messageMediaFileInteractiveFetched(context: context, message: message, file: file, userInitiated: true).start())
|
||||
self.fetchDisposable.set(messageMediaFileInteractiveFetched(context: context, message: message, file: file, userInitiated: true).startStrict())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -143,7 +143,7 @@ final class HashtagChatInputContextPanelNode: ChatInputContextPanelNode {
|
||||
}
|
||||
}, removeRequested: { [weak self] text in
|
||||
if let strongSelf = self {
|
||||
let _ = strongSelf.context.engine.messages.removeRecentlyUsedHashtag(string: text).start()
|
||||
let _ = strongSelf.context.engine.messages.removeRecentlyUsedHashtag(string: text).startStandalone()
|
||||
strongSelf.revealedHashtag = nil
|
||||
}
|
||||
})
|
||||
|
@ -201,7 +201,7 @@ final class HorizontalListContextResultsChatInputContextPanelNode: ChatInputCont
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
let interfaceInteraction = strongSelf.interfaceInteraction
|
||||
let _ = (toggleGifSaved(account: context.account, fileReference: .standalone(media: file), saved: true)
|
||||
|> deliverOnMainQueue).start(next: { result in
|
||||
|> deliverOnMainQueue).startStandalone(next: { result in
|
||||
switch result {
|
||||
case .generic:
|
||||
interfaceInteraction?.presentController(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_gif", scale: 0.075, colors: [:], title: nil, text: presentationData.strings.Gallery_GifSaved, customUndoText: nil, timeout: nil), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), nil)
|
||||
@ -275,7 +275,7 @@ final class HorizontalListContextResultsChatInputContextPanelNode: ChatInputCont
|
||||
|> map { results -> ChatContextResultCollection? in
|
||||
return results?.results
|
||||
}
|
||||
|> deliverOnMainQueue).start(next: { [weak self] nextResults in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] nextResults in
|
||||
guard let strongSelf = self, let nextResults = nextResults else {
|
||||
return
|
||||
}
|
||||
|
@ -437,7 +437,7 @@ final class HorizontalListContextResultsChatInputPanelItemNode: ListViewItemNode
|
||||
}
|
||||
let dimensions = animatedStickerFile.dimensions ?? PixelDimensions(width: 512, height: 512)
|
||||
let fittedDimensions = dimensions.cgSize.aspectFitted(CGSize(width: 160.0, height: 160.0))
|
||||
strongSelf.fetchDisposable.set(freeMediaFileResourceInteractiveFetched(account: item.context.account, userLocation: .other, fileReference: stickerPackFileReference(animatedStickerFile), resource: animatedStickerFile.resource).start())
|
||||
strongSelf.fetchDisposable.set(freeMediaFileResourceInteractiveFetched(account: item.context.account, userLocation: .other, fileReference: stickerPackFileReference(animatedStickerFile), resource: animatedStickerFile.resource).startStrict())
|
||||
animationNode.setup(source: AnimatedStickerResourceSource(account: item.context.account, resource: animatedStickerFile.resource, isVideo: animatedStickerFile.isVideoSticker), width: Int(fittedDimensions.width), height: Int(fittedDimensions.height), playbackMode: .loop, mode: .cached)
|
||||
}
|
||||
}
|
||||
@ -451,7 +451,7 @@ final class HorizontalListContextResultsChatInputPanelItemNode: ListViewItemNode
|
||||
strongSelf.statusNode.frame = progressFrame
|
||||
|
||||
if let updatedStatusSignal = updatedStatusSignal {
|
||||
strongSelf.statusDisposable.set((updatedStatusSignal |> deliverOnMainQueue).start(next: { [weak strongSelf] status in
|
||||
strongSelf.statusDisposable.set((updatedStatusSignal |> deliverOnMainQueue).startStrict(next: { [weak strongSelf] status in
|
||||
displayLinkDispatcher.dispatch {
|
||||
if let strongSelf = strongSelf {
|
||||
strongSelf.resourceStatus = status
|
||||
|
@ -184,7 +184,7 @@ final class HorizontalStickerGridItemNode: GridItemNode {
|
||||
}
|
||||
animationNode.setup(source: AnimatedStickerResourceSource(account: context.account, resource: item.file.resource, isVideo: item.file.isVideoSticker), width: Int(fittedDimensions.width), height: Int(fittedDimensions.height), playbackMode: .loop, mode: .cached)
|
||||
|
||||
self.stickerFetchedDisposable.set(freeMediaFileResourceInteractiveFetched(account: context.account, userLocation: .other, fileReference: stickerPackFileReference(item.file), resource: item.file.resource).start())
|
||||
self.stickerFetchedDisposable.set(freeMediaFileResourceInteractiveFetched(account: context.account, userLocation: .other, fileReference: stickerPackFileReference(item.file), resource: item.file.resource).startStrict())
|
||||
} else {
|
||||
self.imageNode.alpha = 1.0
|
||||
self.imageNode.setSignal(chatMessageSticker(account: context.account, userLocation: .other, file: item.file, small: true))
|
||||
@ -194,7 +194,7 @@ final class HorizontalStickerGridItemNode: GridItemNode {
|
||||
currentAnimationNode.removeFromSupernode()
|
||||
}
|
||||
|
||||
self.stickerFetchedDisposable.set(freeMediaFileResourceInteractiveFetched(account: context.account, userLocation: .other, fileReference: stickerPackFileReference(item.file), resource: chatMessageStickerResource(file: item.file, small: true)).start())
|
||||
self.stickerFetchedDisposable.set(freeMediaFileResourceInteractiveFetched(account: context.account, userLocation: .other, fileReference: stickerPackFileReference(item.file), resource: chatMessageStickerResource(file: item.file, small: true)).startStrict())
|
||||
}
|
||||
|
||||
if item.file.isPremiumSticker {
|
||||
|
@ -190,7 +190,7 @@ final class HorizontalStickersChatContextPanelNode: ChatInputContextPanelNode {
|
||||
if let strongSelf = self {
|
||||
let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 }
|
||||
let _ = (strongSelf.context.engine.stickers.toggleStickerSaved(file: item.file, saved: !isStarred)
|
||||
|> deliverOnMainQueue).start(next: { result in
|
||||
|> deliverOnMainQueue).startStandalone(next: { result in
|
||||
switch result {
|
||||
case .generic:
|
||||
strongSelf.interfaceInteraction?.presentGlobalOverlayController(UndoOverlayController(presentationData: presentationData, content: .sticker(context: strongSelf.context, file: item.file, loop: true, title: nil, text: !isStarred ? strongSelf.strings.Conversation_StickerAddedToFavorites : strongSelf.strings.Conversation_StickerRemovedFromFavorites, undoText: nil, customAction: nil), elevatedLayout: false, action: { _ in return false }), nil)
|
||||
|
@ -34,6 +34,12 @@ final class InChatPrefetchManager {
|
||||
self.settings = context.sharedContext.currentAutomaticMediaDownloadSettings
|
||||
}
|
||||
|
||||
deinit {
|
||||
for (_, context) in self.contexts {
|
||||
context.fetchDisposable.dispose()
|
||||
}
|
||||
}
|
||||
|
||||
func updateAutoDownloadSettings(_ settings: MediaAutoDownloadSettings) {
|
||||
if self.settings != settings {
|
||||
self.settings = settings
|
||||
@ -105,16 +111,16 @@ final class InChatPrefetchManager {
|
||||
|
||||
if case .full = automaticDownload {
|
||||
if let image = media as? TelegramMediaImage {
|
||||
context.fetchDisposable.set(messageMediaImageInteractiveFetched(fetchManager: self.context.fetchManager, messageId: message.id, messageReference: MessageReference(message), image: image, resource: resource, userInitiated: false, priority: priority, storeToDownloadsPeerId: nil).start())
|
||||
context.fetchDisposable.set(messageMediaImageInteractiveFetched(fetchManager: self.context.fetchManager, messageId: message.id, messageReference: MessageReference(message), image: image, resource: resource, userInitiated: false, priority: priority, storeToDownloadsPeerId: nil).startStrict())
|
||||
} else if let _ = media as? TelegramMediaWebFile {
|
||||
//strongSelf.fetchDisposable.set(chatMessageWebFileInteractiveFetched(account: context.account, image: image).start())
|
||||
//strongSelf.fetchDisposable.set(chatMessageWebFileInteractiveFetched(account: context.account, image: image).startStrict())
|
||||
} else if let file = media as? TelegramMediaFile {
|
||||
let fetchSignal = messageMediaFileInteractiveFetched(fetchManager: self.context.fetchManager, messageId: message.id, messageReference: MessageReference(message), file: file, userInitiated: false, priority: priority)
|
||||
context.fetchDisposable.set(fetchSignal.start())
|
||||
context.fetchDisposable.set(fetchSignal.startStrict())
|
||||
}
|
||||
} else if case .prefetch = automaticDownload, message.id.peerId.namespace != Namespaces.Peer.SecretChat {
|
||||
if let file = media as? TelegramMediaFile, let _ = file.size {
|
||||
context.fetchDisposable.set(preloadVideoResource(postbox: self.context.account.postbox, userLocation: .peer(message.id.peerId), userContentType: MediaResourceUserContentType(file: file), resourceReference: FileMediaReference.message(message: MessageReference(message), media: file).resourceReference(file.resource), duration: 4.0).start())
|
||||
context.fetchDisposable.set(preloadVideoResource(postbox: self.context.account.postbox, userLocation: .peer(message.id.peerId), userContentType: MediaResourceUserContentType(file: file), resourceReference: FileMediaReference.message(message: MessageReference(message), media: file).resourceReference(file.resource), duration: 4.0).startStrict())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -142,7 +142,7 @@ private final class InlineReactionSearchStickersNode: ASDisplayNode, UIScrollVie
|
||||
if let strongSelf = self {
|
||||
let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 }
|
||||
let _ = (strongSelf.context.engine.stickers.toggleStickerSaved(file: item.file, saved: !isStarred)
|
||||
|> deliverOnMainQueue).start(next: { result in
|
||||
|> deliverOnMainQueue).startStandalone(next: { result in
|
||||
switch result {
|
||||
case .generic:
|
||||
strongSelf.getControllerInteraction?()?.presentGlobalOverlayController(UndoOverlayController(presentationData: presentationData, content: .sticker(context: strongSelf.context, file: item.file, loop: true, title: nil, text: !isStarred ? strongSelf.strings.Conversation_StickerAddedToFavorites : strongSelf.strings.Conversation_StickerRemovedFromFavorites, undoText: nil, customAction: nil), elevatedLayout: false, action: { _ in return false }), nil)
|
||||
@ -585,7 +585,7 @@ final class InlineReactionSearchPanel: ChatInputContextPanelNode {
|
||||
self.view.disablesInteractiveKeyboardGestureRecognizer = true
|
||||
|
||||
self.choosingStickerDisposable = (self.stickersNode.choosingSticker
|
||||
|> deliverOnMainQueue).start(next: { [weak self] value in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] value in
|
||||
if let strongSelf = self {
|
||||
strongSelf.controllerInteraction?.updateChoosingSticker(value)
|
||||
}
|
||||
|
@ -120,7 +120,7 @@ final class InstantVideoRadialStatusNode: ASDisplayNode, UIGestureRecognizerDele
|
||||
self.isOpaque = false
|
||||
|
||||
self.statusDisposable = (self.statusValuePromise.get()
|
||||
|> deliverOnMainQueue).start(next: { [weak self] status in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] status in
|
||||
if let strongSelf = self {
|
||||
strongSelf.statusValue = status
|
||||
}
|
||||
|
@ -93,7 +93,7 @@ private final class LargeEmojiActionSheetItemNode: ActionSheetItemNode {
|
||||
|
||||
let dimensions = file.dimensions ?? PixelDimensions(width: 512, height: 512)
|
||||
self.imageNode.setSignal(chatMessageAnimatedSticker(postbox: context.account.postbox, userLocation: .other, file: file, small: false, size: dimensions.cgSize.aspectFilled(CGSize(width: 384.0, height: 384.0)), fitzModifier: fitzModifier, thumbnail: false, synchronousLoad: true), attemptSynchronously: true)
|
||||
self.disposable.set(freeMediaFileInteractiveFetched(account: context.account, userLocation: .other, fileReference: .standalone(media: file)).start())
|
||||
self.disposable.set(freeMediaFileInteractiveFetched(account: context.account, userLocation: .other, fileReference: .standalone(media: file)).startStrict())
|
||||
|
||||
self.setupTimestamp = CACurrentMediaTime()
|
||||
|
||||
|
@ -23,7 +23,7 @@ enum SharedMediaPlayerGroup: Int {
|
||||
|
||||
private let sharedAudioSession: ManagedAudioSession = {
|
||||
let audioSession = ManagedAudioSession()
|
||||
let _ = (audioSession.headsetConnected() |> deliverOnMainQueue).start(next: { value in
|
||||
let _ = (audioSession.headsetConnected() |> deliverOnMainQueue).startStandalone(next: { value in
|
||||
DeviceProximityManager.shared().setGloballyEnabled(!value)
|
||||
})
|
||||
return audioSession
|
||||
@ -77,7 +77,7 @@ public final class MediaManagerImpl: NSObject, MediaManager {
|
||||
if let voiceMediaPlayer = self.voiceMediaPlayer {
|
||||
let account = voiceMediaPlayer.account
|
||||
self.voiceMediaPlayerStateDisposable.set((voiceMediaPlayer.playbackState
|
||||
|> deliverOnMainQueue).start(next: { [weak self, weak voiceMediaPlayer] state in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self, weak voiceMediaPlayer] state in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -222,7 +222,7 @@ public final class MediaManagerImpl: NSObject, MediaManager {
|
||||
var currentGlobalControlsOptions = GlobalControlOptions()
|
||||
|
||||
self.globalControlsDisposable.set((combineLatest(self.globalMediaPlayerState, self.presentationData)
|
||||
|> deliverOnMainQueue).start(next: { stateAndType, presentationData in
|
||||
|> deliverOnMainQueue).startStrict(next: { stateAndType, presentationData in
|
||||
var updatedGlobalControlOptions = GlobalControlOptions()
|
||||
if let (_, stateOrLoading, type) = stateAndType, case let .state(state) = stateOrLoading {
|
||||
if type == .music {
|
||||
@ -332,7 +332,7 @@ public final class MediaManagerImpl: NSObject, MediaManager {
|
||||
} else {
|
||||
return .single(nil)
|
||||
}
|
||||
} |> deliverOnMainQueue).start(next: { image in
|
||||
} |> deliverOnMainQueue).startStrict(next: { image in
|
||||
if var nowPlayingInfo = baseNowPlayingInfo {
|
||||
if let image = image {
|
||||
if #available(iOSApplicationExtension 10.0, iOS 10.0, *) {
|
||||
@ -351,7 +351,7 @@ public final class MediaManagerImpl: NSObject, MediaManager {
|
||||
}))
|
||||
|
||||
self.globalControlsStatusDisposable.set((self.globalControlsStatus.get()
|
||||
|> deliverOnMainQueue).start(next: { next in
|
||||
|> deliverOnMainQueue).startStrict(next: { next in
|
||||
if let next = next {
|
||||
if var nowPlayingInfo = baseNowPlayingInfo {
|
||||
nowPlayingInfo[MPMediaItemPropertyPlaybackDuration] = next.duration as NSNumber
|
||||
@ -403,7 +403,7 @@ public final class MediaManagerImpl: NSObject, MediaManager {
|
||||
return .single(next) |> then(.complete() |> delay(2.0, queue: Queue.concurrentDefaultQueue()))
|
||||
}
|
||||
|
||||
self.mediaPlaybackStateDisposable.set(throttledSignal.start(next: { accountStateAndType in
|
||||
self.mediaPlaybackStateDisposable.set(throttledSignal.startStrict(next: { accountStateAndType in
|
||||
let minimumStoreDuration: Double?
|
||||
if let (account, stateOrLoading, type) = accountStateAndType {
|
||||
switch type {
|
||||
@ -421,13 +421,13 @@ public final class MediaManagerImpl: NSObject, MediaManager {
|
||||
if state.status.timestamp > 5.0 && state.status.timestamp < state.status.duration - 5.0 {
|
||||
storedState = MediaPlaybackStoredState(timestamp: state.status.timestamp, playbackRate: state.status.baseRate > 1.0 ? .x2 : .x1)
|
||||
}
|
||||
let _ = updateMediaPlaybackStoredStateInteractively(engine: TelegramEngine(account: account), messageId: item.message.id, state: storedState).start()
|
||||
let _ = updateMediaPlaybackStoredStateInteractively(engine: TelegramEngine(account: account), messageId: item.message.id, state: storedState).startStandalone()
|
||||
}
|
||||
}
|
||||
}
|
||||
}))
|
||||
|
||||
self.globalAudioSessionForegroundDisposable.set((shouldKeepAudioSession |> deliverOnMainQueue).start(next: { [weak self] value in
|
||||
self.globalAudioSessionForegroundDisposable.set((shouldKeepAudioSession |> deliverOnMainQueue).startStrict(next: { [weak self] value in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -487,7 +487,7 @@ public final class MediaManagerImpl: NSObject, MediaManager {
|
||||
}
|
||||
|
||||
self.setPlaylistByTypeDisposables.set((inputData
|
||||
|> deliverOnMainQueue).start(next: { [weak self] inputData in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] inputData in
|
||||
if let strongSelf = self {
|
||||
let nextPlayerIndex = strongSelf.nextPlayerIndex
|
||||
strongSelf.nextPlayerIndex += 1
|
||||
|
@ -166,7 +166,7 @@ final class MentionChatInputContextPanelNode: ChatInputContextPanelNode {
|
||||
}
|
||||
}, removeRequested: { [weak self] peerId in
|
||||
if let strongSelf = self {
|
||||
let _ = strongSelf.context.engine.peers.removeRecentlyUsedInlineBot(peerId: peerId).start()
|
||||
let _ = strongSelf.context.engine.peers.removeRecentlyUsedInlineBot(peerId: peerId).startStandalone()
|
||||
|
||||
strongSelf.revealedPeerId = nil
|
||||
strongSelf.currentResults = strongSelf.currentResults.filter { $0.id != peerId }
|
||||
|
@ -25,7 +25,7 @@ public final class NotificationContainerController: ViewController {
|
||||
self.statusBar.statusBarStyle = .Ignore
|
||||
|
||||
self.presentationDataDisposable = (context.sharedContext.presentationData
|
||||
|> deliverOnMainQueue).start(next: { [weak self] presentationData in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] presentationData in
|
||||
if let strongSelf = self {
|
||||
let previousTheme = strongSelf.presentationData.theme
|
||||
let previousStrings = strongSelf.presentationData.strings
|
||||
|
@ -102,7 +102,7 @@ public final class NotificationViewControllerImpl {
|
||||
|
||||
var initialPresentationDataAndSettings: InitialPresentationDataAndSettings?
|
||||
let semaphore = DispatchSemaphore(value: 0)
|
||||
let _ = currentPresentationDataAndSettings(accountManager: accountManager, systemUserInterfaceStyle: .light).start(next: { value in
|
||||
let _ = currentPresentationDataAndSettings(accountManager: accountManager, systemUserInterfaceStyle: .light).startStandalone(next: { value in
|
||||
initialPresentationDataAndSettings = value
|
||||
semaphore.signal()
|
||||
})
|
||||
@ -235,7 +235,7 @@ public final class NotificationViewControllerImpl {
|
||||
return (account, imageReference)
|
||||
}
|
||||
}
|
||||
|> deliverOnMainQueue).start(next: { [weak self] accountAndImage in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] accountAndImage in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -243,7 +243,7 @@ public final class NotificationViewControllerImpl {
|
||||
strongSelf.imageNode.setSignal(chatMessagePhoto(postbox: accountAndImage.0.postbox, userLocation: .other, photoReference: imageReference))
|
||||
|
||||
accountAndImage.0.network.shouldExplicitelyKeepWorkerConnections.set(.single(true))
|
||||
strongSelf.fetchedDisposable.set(standaloneChatMessagePhotoInteractiveFetched(account: accountAndImage.0, userLocation: .other, photoReference: imageReference).start())
|
||||
strongSelf.fetchedDisposable.set(standaloneChatMessagePhotoInteractiveFetched(account: accountAndImage.0, userLocation: .other, photoReference: imageReference).startStrict())
|
||||
}
|
||||
}))
|
||||
} else if let file = media as? TelegramMediaFile, let dimensions = file.dimensions {
|
||||
@ -286,7 +286,7 @@ public final class NotificationViewControllerImpl {
|
||||
return (account, fileReference)
|
||||
}
|
||||
}
|
||||
|> deliverOnMainQueue).start(next: { [weak self, weak view] accountAndImage in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self, weak view] accountAndImage in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -321,7 +321,7 @@ public final class NotificationViewControllerImpl {
|
||||
animatedStickerNode.visibility = true
|
||||
|
||||
accountAndImage.0.network.shouldExplicitelyKeepWorkerConnections.set(.single(true))
|
||||
strongSelf.fetchedDisposable.set(freeMediaFileInteractiveFetched(account: accountAndImage.0, userLocation: .other, fileReference: fileReference).start())
|
||||
strongSelf.fetchedDisposable.set(freeMediaFileInteractiveFetched(account: accountAndImage.0, userLocation: .other, fileReference: fileReference).startStrict())
|
||||
} else if file.isSticker {
|
||||
if let animatedStickerNode = strongSelf.animatedStickerNode {
|
||||
animatedStickerNode.removeFromSupernode()
|
||||
@ -332,7 +332,7 @@ public final class NotificationViewControllerImpl {
|
||||
strongSelf.imageNode.setSignal(chatMessageSticker(account: accountAndImage.0, userLocation: .other, file: file, small: false))
|
||||
|
||||
accountAndImage.0.network.shouldExplicitelyKeepWorkerConnections.set(.single(true))
|
||||
strongSelf.fetchedDisposable.set(freeMediaFileInteractiveFetched(account: accountAndImage.0, userLocation: .other, fileReference: fileReference).start())
|
||||
strongSelf.fetchedDisposable.set(freeMediaFileInteractiveFetched(account: accountAndImage.0, userLocation: .other, fileReference: fileReference).startStrict())
|
||||
}
|
||||
}
|
||||
}))
|
||||
|
@ -11,7 +11,7 @@ import PeerInfoUI
|
||||
func openAddContactImpl(context: AccountContext, firstName: String = "", lastName: String = "", phoneNumber: String, label: String = "_$!<Mobile>!$_", present: @escaping (ViewController, Any?) -> Void, pushController: @escaping (ViewController) -> Void, completed: @escaping () -> Void = {}) {
|
||||
let _ = (DeviceAccess.authorizationStatus(subject: .contacts)
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(next: { value in
|
||||
|> deliverOnMainQueue).startStandalone(next: { value in
|
||||
switch value {
|
||||
case .allowed:
|
||||
let contactData = DeviceContactExtendedData(basicData: DeviceContactBasicData(firstName: firstName, lastName: lastName, phoneNumbers: [DeviceContactPhoneNumberData(label: label, value: phoneNumber)]), middleName: "", prefix: "", suffix: "", organization: "", jobTitle: "", department: "", emailAddresses: [], urls: [], addresses: [], birthdayDate: nil, socialProfiles: [], instantMessagingProfiles: [], note: "")
|
||||
|
@ -40,7 +40,7 @@ func openChatMessageImpl(_ params: OpenChatMessageParams) -> Bool {
|
||||
let storyContent = SingleStoryContentContextImpl(context: params.context, storyId: story.storyId, readGlobally: true)
|
||||
let _ = (storyContent.state
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(next: { [weak navigationController] _ in
|
||||
|> deliverOnMainQueue).startStandalone(next: { [weak navigationController] _ in
|
||||
var transitionIn: StoryContainerScreen.TransitionIn? = nil
|
||||
|
||||
var selectedTransitionNode: (ASDisplayNode, CGRect, () -> (UIView?, UIView?))?
|
||||
@ -134,7 +134,7 @@ func openChatMessageImpl(_ params: OpenChatMessageParams) -> Bool {
|
||||
case let .pass(file):
|
||||
let _ = (params.context.account.postbox.mediaBox.resourceData(file.resource, option: .complete(waitUntilFetchStatus: true))
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(next: { data in
|
||||
|> deliverOnMainQueue).startStandalone(next: { data in
|
||||
guard let navigationController = params.navigationController else {
|
||||
return
|
||||
}
|
||||
@ -209,7 +209,7 @@ func openChatMessageImpl(_ params: OpenChatMessageParams) -> Bool {
|
||||
case let .remove(positionInList):
|
||||
params.navigationController?.presentOverlay(controller: UndoOverlayController(presentationData: presentationData, content: .stickersModified(title: isEmoji ? presentationData.strings.EmojiPackActionInfo_RemovedTitle : presentationData.strings.StickerPackActionInfo_RemovedTitle, text: isEmoji ? presentationData.strings.EmojiPackActionInfo_RemovedText(info.title).string : presentationData.strings.StickerPackActionInfo_RemovedText(info.title).string, undo: true, info: info, topItem: items.first, context: params.context), elevatedLayout: true, animateInAsReplacement: animateInAsReplacement, action: { action in
|
||||
if case .undo = action {
|
||||
let _ = params.context.engine.stickers.addStickerPackInteractively(info: info, items: items, positionInList: positionInList).start()
|
||||
let _ = params.context.engine.stickers.addStickerPackInteractively(info: info, items: items, positionInList: positionInList).startStandalone()
|
||||
}
|
||||
return true
|
||||
}))
|
||||
@ -277,13 +277,13 @@ func openChatMessageImpl(_ params: OpenChatMessageParams) -> Bool {
|
||||
case let .story(storyController):
|
||||
params.dismissInput()
|
||||
let _ = (storyController
|
||||
|> deliverOnMainQueue).start(next: { storyController in
|
||||
|> deliverOnMainQueue).startStandalone(next: { storyController in
|
||||
params.navigationController?.pushViewController(storyController)
|
||||
})
|
||||
case let .gallery(gallery):
|
||||
params.dismissInput()
|
||||
let _ = (gallery
|
||||
|> deliverOnMainQueue).start(next: { gallery in
|
||||
|> deliverOnMainQueue).startStandalone(next: { gallery in
|
||||
gallery.centralItemUpdated = { messageId in
|
||||
params.centralItemUpdated?(messageId)
|
||||
}
|
||||
@ -320,7 +320,7 @@ func openChatMessageImpl(_ params: OpenChatMessageParams) -> Bool {
|
||||
}
|
||||
|
||||
let _ = (paramsSignal
|
||||
|> deliverOnMainQueue).start(next: { peer, isContact in
|
||||
|> deliverOnMainQueue).startStandalone(next: { peer, isContact in
|
||||
let contactData: DeviceContactExtendedData
|
||||
if let vCard = contact.vCardData, let vCardData = vCard.data(using: .utf8), let parsed = DeviceContactExtendedData(vcard: vCardData) {
|
||||
contactData = parsed
|
||||
@ -379,7 +379,7 @@ func openChatWallpaper(context: AccountContext, message: Message, present: @esca
|
||||
for media in message.media {
|
||||
if let webpage = media as? TelegramMediaWebpage, case let .Loaded(content) = webpage.content {
|
||||
let _ = (context.sharedContext.resolveUrl(context: context, peerId: nil, url: content.url, skipUrlAuth: true)
|
||||
|> deliverOnMainQueue).start(next: { resolvedUrl in
|
||||
|> deliverOnMainQueue).startStandalone(next: { resolvedUrl in
|
||||
if case let .wallpaper(parameter) = resolvedUrl {
|
||||
let source: WallpaperListSource
|
||||
switch parameter {
|
||||
@ -403,7 +403,7 @@ func openChatTheme(context: AccountContext, message: Message, pushController: @e
|
||||
for media in message.media {
|
||||
if let webpage = media as? TelegramMediaWebpage, case let .Loaded(content) = webpage.content {
|
||||
let _ = (context.sharedContext.resolveUrl(context: context, peerId: nil, url: content.url, skipUrlAuth: true)
|
||||
|> deliverOnMainQueue).start(next: { resolvedUrl in
|
||||
|> deliverOnMainQueue).startStandalone(next: { resolvedUrl in
|
||||
var file: TelegramMediaFile?
|
||||
var settings: TelegramThemeSettings?
|
||||
let themeMimeType = "application/x-tgtheme-ios"
|
||||
|
@ -105,20 +105,20 @@ func openResolvedUrlImpl(_ resolvedUrl: ResolvedUrl, context: AccountContext, ur
|
||||
if payload.isEmpty {
|
||||
if peerId.namespace == Namespaces.Peer.CloudGroup {
|
||||
let _ = (context.engine.peers.addGroupMember(peerId: peerId, memberId: botPeerId)
|
||||
|> deliverOnMainQueue).start(completed: {
|
||||
|> deliverOnMainQueue).startStandalone(completed: {
|
||||
controller?.dismiss()
|
||||
})
|
||||
} else {
|
||||
let _ = (context.engine.peers.addChannelMember(peerId: peerId, memberId: botPeerId)
|
||||
|> deliverOnMainQueue).start(completed: {
|
||||
|> deliverOnMainQueue).startStandalone(completed: {
|
||||
controller?.dismiss()
|
||||
})
|
||||
}
|
||||
} else {
|
||||
let _ = (context.engine.messages.requestStartBotInGroup(botPeerId: botPeerId, groupPeerId: peerId, payload: payload)
|
||||
|> deliverOnMainQueue).start(next: { result in
|
||||
|> deliverOnMainQueue).startStandalone(next: { result in
|
||||
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|
||||
|> deliverOnMainQueue).start(next: { peer in
|
||||
|> deliverOnMainQueue).startStandalone(next: { peer in
|
||||
guard let peer = peer else {
|
||||
return
|
||||
}
|
||||
@ -192,11 +192,11 @@ func openResolvedUrlImpl(_ resolvedUrl: ResolvedUrl, context: AccountContext, ur
|
||||
if let navigationController = navigationController {
|
||||
let _ = ChatControllerImpl.openMessageReplies(context: context, navigationController: navigationController, present: { c, a in
|
||||
present(c, a)
|
||||
}, messageId: replyThreadMessage.messageId, isChannelPost: replyThreadMessage.isChannelPost, atMessage: messageId, displayModalProgress: true).start()
|
||||
}, messageId: replyThreadMessage.messageId, isChannelPost: replyThreadMessage.isChannelPost, atMessage: messageId, displayModalProgress: true).startStandalone()
|
||||
}
|
||||
case let .replyThread(messageId):
|
||||
if let navigationController = navigationController {
|
||||
let _ = context.sharedContext.navigateToForumThread(context: context, peerId: messageId.peerId, threadId: Int64(messageId.id), messageId: nil, navigationController: navigationController, activateInput: nil, keepStack: .always).start()
|
||||
let _ = context.sharedContext.navigateToForumThread(context: context, peerId: messageId.peerId, threadId: Int64(messageId.id), messageId: nil, navigationController: navigationController, activateInput: nil, keepStack: .always).startStandalone()
|
||||
}
|
||||
case let .stickerPack(name, _):
|
||||
dismissInput()
|
||||
@ -219,7 +219,7 @@ func openResolvedUrlImpl(_ resolvedUrl: ResolvedUrl, context: AccountContext, ur
|
||||
case let .remove(positionInList):
|
||||
present(UndoOverlayController(presentationData: presentationData, content: .stickersModified(title: isEmoji ? presentationData.strings.EmojiPackActionInfo_RemovedTitle : presentationData.strings.StickerPackActionInfo_RemovedTitle, text: isEmoji ? presentationData.strings.EmojiPackActionInfo_RemovedText(info.title).string : presentationData.strings.StickerPackActionInfo_RemovedText(info.title).string, undo: true, info: info, topItem: items.first, context: context), elevatedLayout: true, animateInAsReplacement: false, action: { action in
|
||||
if case .undo = action {
|
||||
let _ = context.engine.stickers.addStickerPackInteractively(info: info, items: items, positionInList: positionInList).start()
|
||||
let _ = context.engine.stickers.addStickerPackInteractively(info: info, items: items, positionInList: positionInList).startStandalone()
|
||||
}
|
||||
return true
|
||||
}), nil)
|
||||
@ -268,7 +268,7 @@ func openResolvedUrlImpl(_ resolvedUrl: ResolvedUrl, context: AccountContext, ur
|
||||
let controller = OverlayStatusController(theme: presentationData.theme, type: .loading(cancelled: nil))
|
||||
present(controller, nil)
|
||||
let _ = (context.engine.auth.requestCancelAccountResetData(hash: hash)
|
||||
|> deliverOnMainQueue).start(next: { [weak controller] data in
|
||||
|> deliverOnMainQueue).startStandalone(next: { [weak controller] data in
|
||||
controller?.dismiss()
|
||||
present(confirmPhoneNumberCodeController(context: context, phoneNumber: phone, codeData: data), ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
|
||||
}, error: { [weak controller] error in
|
||||
@ -307,7 +307,7 @@ func openResolvedUrlImpl(_ resolvedUrl: ResolvedUrl, context: AccountContext, ur
|
||||
let _ = (ChatInterfaceState.update(engine: context.engine, peerId: peerId, threadId: nil, { currentState in
|
||||
return currentState.withUpdatedComposeInputState(textInputState)
|
||||
})
|
||||
|> deliverOnMainQueue).start(completed: {
|
||||
|> deliverOnMainQueue).startStandalone(completed: {
|
||||
navigationController?.pushViewController(ChatControllerImpl(context: context, chatLocation: .peer(id: peerId)))
|
||||
})
|
||||
} else {
|
||||
@ -318,7 +318,7 @@ func openResolvedUrlImpl(_ resolvedUrl: ResolvedUrl, context: AccountContext, ur
|
||||
if let to = to {
|
||||
if to.hasPrefix("@") {
|
||||
let _ = (context.engine.peers.resolvePeerByName(name: String(to[to.index(to.startIndex, offsetBy: 1)...]))
|
||||
|> deliverOnMainQueue).start(next: { peer in
|
||||
|> deliverOnMainQueue).startStandalone(next: { peer in
|
||||
if let peer = peer {
|
||||
context.sharedContext.applicationBindings.dismissNativeController()
|
||||
continueWithPeer(peer.id)
|
||||
@ -326,7 +326,7 @@ func openResolvedUrlImpl(_ resolvedUrl: ResolvedUrl, context: AccountContext, ur
|
||||
})
|
||||
} else {
|
||||
let _ = (context.engine.peers.resolvePeerByPhone(phone: to)
|
||||
|> deliverOnMainQueue).start(next: { peer in
|
||||
|> deliverOnMainQueue).startStandalone(next: { peer in
|
||||
if let peer = peer {
|
||||
context.sharedContext.applicationBindings.dismissNativeController()
|
||||
continueWithPeer(peer.id)
|
||||
@ -334,7 +334,7 @@ func openResolvedUrlImpl(_ resolvedUrl: ResolvedUrl, context: AccountContext, ur
|
||||
})
|
||||
/*let query = to.trimmingCharacters(in: CharacterSet(charactersIn: "0123456789").inverted)
|
||||
let _ = (context.account.postbox.searchContacts(query: query)
|
||||
|> deliverOnMainQueue).start(next: { (peers, _) in
|
||||
|> deliverOnMainQueue).startStandalone(next: { (peers, _) in
|
||||
for case let peer as TelegramUser in peers {
|
||||
if peer.phone == query {
|
||||
context.sharedContext.applicationBindings.dismissNativeController()
|
||||
@ -390,7 +390,7 @@ func openResolvedUrlImpl(_ resolvedUrl: ResolvedUrl, context: AccountContext, ur
|
||||
}
|
||||
|
||||
let _ = (signal
|
||||
|> deliverOnMainQueue).start(next: { [weak controller] wallpaper in
|
||||
|> deliverOnMainQueue).startStandalone(next: { [weak controller] wallpaper in
|
||||
controller?.dismiss()
|
||||
let galleryController = WallpaperGalleryController(context: context, source: .wallpaper(wallpaper, options, colors, intensity, rotation, nil))
|
||||
navigationController?.pushViewController(galleryController)
|
||||
@ -805,12 +805,12 @@ func openResolvedUrlImpl(_ resolvedUrl: ResolvedUrl, context: AccountContext, ur
|
||||
return false
|
||||
}
|
||||
}
|
||||
|> deliverOnMainQueue).start(next: { exists in
|
||||
|> deliverOnMainQueue).startStandalone(next: { exists in
|
||||
if exists {
|
||||
let storyContent = SingleStoryContentContextImpl(context: context, storyId: StoryId(peerId: peerId, id: id), readGlobally: true)
|
||||
let _ = (storyContent.state
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(next: { [weak navigationController] _ in
|
||||
|> deliverOnMainQueue).startStandalone(next: { [weak navigationController] _ in
|
||||
let transitionIn: StoryContainerScreen.TransitionIn? = nil
|
||||
|
||||
let storyContainerScreen = StoryContainerScreen(
|
||||
@ -837,7 +837,7 @@ func openResolvedUrlImpl(_ resolvedUrl: ResolvedUrl, context: AccountContext, ur
|
||||
})
|
||||
case let .boost(peerId, status, canApplyStatus):
|
||||
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|
||||
|> deliverOnMainQueue).start(next: { peer in
|
||||
|> deliverOnMainQueue).startStandalone(next: { peer in
|
||||
guard let peer, let status else {
|
||||
return
|
||||
}
|
||||
@ -930,7 +930,7 @@ func openResolvedUrlImpl(_ resolvedUrl: ResolvedUrl, context: AccountContext, ur
|
||||
|
||||
updateImpl = { [weak controller] in
|
||||
if let _ = status.nextLevelBoosts {
|
||||
let _ = context.engine.peers.applyChannelBoost(peerId: peerId).start()
|
||||
let _ = context.engine.peers.applyChannelBoost(peerId: peerId).startStandalone()
|
||||
controller?.updateSubject(nextSubject, count: nextCount)
|
||||
} else {
|
||||
controller?.dismiss()
|
||||
|
@ -246,7 +246,7 @@ func openExternalUrlImpl(context: AccountContext, urlContext: OpenURLContext, ur
|
||||
|
||||
let handleInternalUrl: (String) -> Void = { url in
|
||||
let _ = (context.sharedContext.resolveUrl(context: context, peerId: nil, url: url, skipUrlAuth: true)
|
||||
|> deliverOnMainQueue).start(next: handleResolvedUrl)
|
||||
|> deliverOnMainQueue).startStandalone(next: handleResolvedUrl)
|
||||
}
|
||||
|
||||
if let scheme = parsedUrl.scheme, (scheme == "tg" || scheme == context.sharedContext.applicationBindings.appSpecificScheme) {
|
||||
@ -526,7 +526,7 @@ func openExternalUrlImpl(context: AccountContext, urlContext: OpenURLContext, ur
|
||||
|
||||
if let id = id, !id.isEmpty, let idValue = Int64(id), idValue > 0 {
|
||||
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(idValue))))
|
||||
|> deliverOnMainQueue).start(next: { peer in
|
||||
|> deliverOnMainQueue).startStandalone(next: { peer in
|
||||
if let peer = peer, let controller = context.sharedContext.makePeerInfoController(context: context, updatedPresentationData: nil, peer: peer._asPeer(), mode: .generic, avatarInitiallyExpanded: false, fromChat: false, requestsContext: nil) {
|
||||
navigationController?.pushViewController(controller)
|
||||
}
|
||||
@ -824,7 +824,7 @@ func openExternalUrlImpl(context: AccountContext, urlContext: OpenURLContext, ur
|
||||
var settings = settings
|
||||
settings.backupHostOverride = host
|
||||
return settings
|
||||
}).start()
|
||||
}).startStandalone()
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -961,7 +961,7 @@ func openExternalUrlImpl(context: AccountContext, urlContext: OpenURLContext, ur
|
||||
}
|
||||
|
||||
let _ = (settings
|
||||
|> deliverOnMainQueue).start(next: { settings in
|
||||
|> deliverOnMainQueue).startStandalone(next: { settings in
|
||||
if settings.defaultWebBrowser == nil {
|
||||
if !"".isEmpty && isCompact {
|
||||
let controller = BrowserScreen(context: context, subject: .webPage(url: parsedUrl.absoluteString))
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user