diff --git a/build-system/Make/ProjectGeneration.py b/build-system/Make/ProjectGeneration.py index 05a326f441..00d15eb602 100644 --- a/build-system/Make/ProjectGeneration.py +++ b/build-system/Make/ProjectGeneration.py @@ -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) diff --git a/submodules/ChatListUI/Sources/ChatContextMenus.swift b/submodules/ChatListUI/Sources/ChatContextMenus.swift index 6aed02affe..eedd3286ab 100644 --- a/submodules/ChatListUI/Sources/ChatContextMenus.swift +++ b/submodules/ChatListUI/Sources/ChatContextMenus.swift @@ -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 = { 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) diff --git a/submodules/ChatListUI/Sources/ChatListContainerItemNode.swift b/submodules/ChatListUI/Sources/ChatListContainerItemNode.swift index 4e8268e557..4d9d6eadac 100644 --- a/submodules/ChatListUI/Sources/ChatListContainerItemNode.swift +++ b/submodules/ChatListUI/Sources/ChatListContainerItemNode.swift @@ -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: {}, diff --git a/submodules/ChatListUI/Sources/ChatListController.swift b/submodules/ChatListUI/Sources/ChatListController.swift index 56b8177ad4..95e39c27fa 100644 --- a/submodules/ChatListUI/Sources/ChatListController.swift +++ b/submodules/ChatListUI/Sources/ChatListController.swift @@ -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 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 } diff --git a/submodules/ChatListUI/Sources/ChatListControllerNode.swift b/submodules/ChatListUI/Sources/ChatListControllerNode.swift index 967149393a..56badaf2f3 100644 --- a/submodules/ChatListUI/Sources/ChatListControllerNode.swift +++ b/submodules/ChatListUI/Sources/ChatListControllerNode.swift @@ -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 } diff --git a/submodules/ChatListUI/Sources/ChatListEmptyNode.swift b/submodules/ChatListUI/Sources/ChatListEmptyNode.swift index 89244fcee2..b57a74f469 100644 --- a/submodules/ChatListUI/Sources/ChatListEmptyNode.swift +++ b/submodules/ChatListUI/Sources/ChatListEmptyNode.swift @@ -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() + }) } } diff --git a/submodules/ChatListUI/Sources/ChatListFilterPresetListController.swift b/submodules/ChatListUI/Sources/ChatListFilterPresetListController.swift index cf6ae8cf49..5fb2f708a8 100644 --- a/submodules/ChatListUI/Sources/ChatListFilterPresetListController.swift +++ b/submodules/ChatListUI/Sources/ChatListFilterPresetListController.swift @@ -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] = [] diff --git a/submodules/ChatListUI/Sources/ChatListSearchContainerNode.swift b/submodules/ChatListUI/Sources/ChatListSearchContainerNode.swift index 9c3002c1ae..10d4f962b7 100644 --- a/submodules/ChatListUI/Sources/ChatListSearchContainerNode.swift +++ b/submodules/ChatListUI/Sources/ChatListSearchContainerNode.swift @@ -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(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] = messageIds.compactMap({ id -> Signal? 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] = messageIds.compactMap({ id -> Signal? 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 { diff --git a/submodules/ChatListUI/Sources/ChatListSearchListPaneNode.swift b/submodules/ChatListUI/Sources/ChatListSearchListPaneNode.swift index 4838fde890..9eddb113e4 100644 --- a/submodules/ChatListUI/Sources/ChatListSearchListPaneNode.swift +++ b/submodules/ChatListUI/Sources/ChatListSearchListPaneNode.swift @@ -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(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 } diff --git a/submodules/ChatListUI/Sources/ChatListSearchMediaNode.swift b/submodules/ChatListUI/Sources/ChatListSearchMediaNode.swift index dd0ea13f4e..0beacce7f5 100644 --- a/submodules/ChatListUI/Sources/ChatListSearchMediaNode.swift +++ b/submodules/ChatListUI/Sources/ChatListSearchMediaNode.swift @@ -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 } diff --git a/submodules/ChatListUI/Sources/ChatListSearchMessageSelectionPanelNode.swift b/submodules/ChatListUI/Sources/ChatListSearchMessageSelectionPanelNode.swift index 438625d3b2..854d2153ef 100644 --- a/submodules/ChatListUI/Sources/ChatListSearchMessageSelectionPanelNode.swift +++ b/submodules/ChatListUI/Sources/ChatListSearchMessageSelectionPanelNode.swift @@ -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 { diff --git a/submodules/ChatListUI/Sources/ChatListSearchPaneContainerNode.swift b/submodules/ChatListUI/Sources/ChatListSearchPaneContainerNode.swift index d045de8389..44c30394ce 100644 --- a/submodules/ChatListUI/Sources/ChatListSearchPaneContainerNode.swift +++ b/submodules/ChatListUI/Sources/ChatListSearchPaneContainerNode.swift @@ -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() diff --git a/submodules/ChatListUI/Sources/Node/ChatListItem.swift b/submodules/ChatListUI/Sources/Node/ChatListItem.swift index ae68de007a..84c38c6da3 100644 --- a/submodules/ChatListUI/Sources/Node/ChatListItem.swift +++ b/submodules/ChatListUI/Sources/Node/ChatListItem.swift @@ -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() } } })) diff --git a/submodules/ChatListUI/Sources/Node/ChatListNode.swift b/submodules/ChatListUI/Sources/Node/ChatListNode.swift index b61603b2b5..88dfea28dd 100644 --- a/submodules/ChatListUI/Sources/Node/ChatListNode.swift +++ b/submodules/ChatListUI/Sources/Node/ChatListNode.swift @@ -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 = .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 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() } diff --git a/submodules/MediaPlayer/Sources/MediaPlayerNode.swift b/submodules/MediaPlayer/Sources/MediaPlayerNode.swift index 08c7790a76..76e2c06b36 100644 --- a/submodules/MediaPlayer/Sources/MediaPlayerNode.swift +++ b/submodules/MediaPlayer/Sources/MediaPlayerNode.swift @@ -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)) } } diff --git a/submodules/PeerInfoAvatarListNode/Sources/PeerInfoAvatarListNode.swift b/submodules/PeerInfoAvatarListNode/Sources/PeerInfoAvatarListNode.swift index ed47632b05..ae72b2baab 100644 --- a/submodules/PeerInfoAvatarListNode/Sources/PeerInfoAvatarListNode.swift +++ b/submodules/PeerInfoAvatarListNode/Sources/PeerInfoAvatarListNode.swift @@ -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 } diff --git a/submodules/SSignalKit/SwiftSignalKit/Source/Disposable.swift b/submodules/SSignalKit/SwiftSignalKit/Source/Disposable.swift index e1ec9fe473..3d742fcb36 100644 --- a/submodules/SSignalKit/SwiftSignalKit/Source/Disposable.swift +++ b/submodules/SSignalKit/SwiftSignalKit/Source/Disposable.swift @@ -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(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) } } diff --git a/submodules/SSignalKit/SwiftSignalKit/Source/Signal.swift b/submodules/SSignalKit/SwiftSignalKit/Source/Signal.swift index 4923e5e784..356c0422e1 100644 --- a/submodules/SSignalKit/SwiftSignalKit/Source/Signal.swift +++ b/submodules/SSignalKit/SwiftSignalKit/Source/Signal.swift @@ -24,11 +24,7 @@ public func |> (value: T, function: ((T) -> U)) -> U { } private final class SubscriberDisposable: Disposable, CustomStringConvertible { - #if DEBUG private weak var subscriber: Subscriber? - #else - private var subscriber: Subscriber? - #endif private var lock = pthread_mutex_t() private var disposable: Disposable? @@ -78,6 +74,20 @@ public final class Signal { return SubscriberDisposable(subscriber: subscriber, disposable: disposable) } + public func startStandalone(next: ((T) -> Void)! = nil, error: ((E) -> Void)! = nil, completed: (() -> Void)! = nil) -> Disposable { + let subscriber = Subscriber(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(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 { return Signal { subscriber in subscriber.putNext(value) diff --git a/submodules/SSignalKit/SwiftSignalKit/Source/Signal_Combine.swift b/submodules/SSignalKit/SwiftSignalKit/Source/Signal_Combine.swift index 2bef75b640..67afdc211a 100644 --- a/submodules/SSignalKit/SwiftSignalKit/Source/Signal_Combine.swift +++ b/submodules/SSignalKit/SwiftSignalKit/Source/Signal_Combine.swift @@ -72,7 +72,7 @@ private func combineLatestAny(_ signals: [Signal], combine: @escap disposable.add(signalDisposable) } - return disposable; + return disposable } } diff --git a/submodules/SSignalKit/SwiftSignalKit/Source/Signal_Timing.swift b/submodules/SSignalKit/SwiftSignalKit/Source/Signal_Timing.swift index 573982f99a..471be0a67d 100644 --- a/submodules/SSignalKit/SwiftSignalKit/Source/Signal_Timing.swift +++ b/submodules/SSignalKit/SwiftSignalKit/Source/Signal_Timing.swift @@ -64,10 +64,10 @@ public func suspendAwareDelay(_ 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) diff --git a/submodules/SSignalKit/SwiftSignalKit/Source/Timer.swift b/submodules/SSignalKit/SwiftSignalKit/Source/Timer.swift index af8738dd1f..3005c055e7 100644 --- a/submodules/SSignalKit/SwiftSignalKit/Source/Timer.swift +++ b/submodules/SSignalKit/SwiftSignalKit/Source/Timer.swift @@ -4,10 +4,19 @@ public final class Timer { private let timer = Atomic(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() } diff --git a/submodules/TelegramUI/Sources/AttachmentFileController.swift b/submodules/TelegramUI/Sources/AttachmentFileController.swift index f92270b25e..e5621608c8 100644 --- a/submodules/TelegramUI/Sources/AttachmentFileController.swift +++ b/submodules/TelegramUI/Sources/AttachmentFileController.swift @@ -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)) } diff --git a/submodules/TelegramUI/Sources/AttachmentFileSearchItem.swift b/submodules/TelegramUI/Sources/AttachmentFileSearchItem.swift index 5c124c065b..a27c6612ca 100644 --- a/submodules/TelegramUI/Sources/AttachmentFileSearchItem.swift +++ b/submodules/TelegramUI/Sources/AttachmentFileSearchItem.swift @@ -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 diff --git a/submodules/TelegramUI/Sources/ChatBotInfoItem.swift b/submodules/TelegramUI/Sources/ChatBotInfoItem.swift index f450b25a81..cd34983cc4 100644 --- a/submodules/TelegramUI/Sources/ChatBotInfoItem.swift +++ b/submodules/TelegramUI/Sources/ChatBotInfoItem.swift @@ -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) } diff --git a/submodules/TelegramUI/Sources/ChatBotStartInputPanelNode.swift b/submodules/TelegramUI/Sources/ChatBotStartInputPanelNode.swift index 1b5f9c6be4..ced09c1229 100644 --- a/submodules/TelegramUI/Sources/ChatBotStartInputPanelNode.swift +++ b/submodules/TelegramUI/Sources/ChatBotStartInputPanelNode.swift @@ -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 } diff --git a/submodules/TelegramUI/Sources/ChatButtonKeyboardInputNode.swift b/submodules/TelegramUI/Sources/ChatButtonKeyboardInputNode.swift index 0c71d4b08f..a92e298b64 100644 --- a/submodules/TelegramUI/Sources/ChatButtonKeyboardInputNode.swift +++ b/submodules/TelegramUI/Sources/ChatButtonKeyboardInputNode.swift @@ -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 } diff --git a/submodules/TelegramUI/Sources/ChatChannelSubscriberInputPanelNode.swift b/submodules/TelegramUI/Sources/ChatChannelSubscriberInputPanelNode.swift index d2b1b0e65c..74276d1072 100644 --- a/submodules/TelegramUI/Sources/ChatChannelSubscriberInputPanelNode.swift +++ b/submodules/TelegramUI/Sources/ChatChannelSubscriberInputPanelNode.swift @@ -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() diff --git a/submodules/TelegramUI/Sources/ChatController.swift b/submodules/TelegramUI/Sources/ChatController.swift index 625f2e12b8..422dc1a0bc 100644 --- a/submodules/TelegramUI/Sources/ChatController.swift +++ b/submodules/TelegramUI/Sources/ChatController.swift @@ -806,7 +806,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } strongSelf.present(statusController, in: .window(.root)) strongSelf.createVoiceChatDisposable.set((strongSelf.context.engine.calls.createGroupCall(peerId: message.id.peerId, title: nil, scheduleDate: nil, isExternalStream: false) - |> deliverOnMainQueue).start(next: { [weak self] info in + |> deliverOnMainQueue).startStrict(next: { [weak self] info in guard let strongSelf = self else { return } @@ -909,7 +909,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G settings = WallpaperSettings(blur: options.contains(.blur), motion: options.contains(.motion), colors: baseSettings?.colors ?? [], intensity: intensity, rotation: baseSettings?.rotation) } let _ = (strongSelf.context.engine.themes.setExistingChatWallpaper(messageId: message.id, settings: settings) - |> deliverOnMainQueue).start() + |> deliverOnMainQueue).startStandalone() Queue.mainQueue().after(0.1) { wallpaperPreviewController?.dismiss() } @@ -1042,7 +1042,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G self?.controllerInteraction?.sendEmoji(text, attribute, false) } : nil, setupTemporaryHiddenMedia: { signal, centralIndex, galleryMedia in if let strongSelf = self { - strongSelf.temporaryHiddenGalleryMediaDisposable.set((signal |> deliverOnMainQueue).start(next: { entry in + strongSelf.temporaryHiddenGalleryMediaDisposable.set((signal |> deliverOnMainQueue).startStrict(next: { entry in if let strongSelf = self, let controllerInteraction = strongSelf.controllerInteraction { var messageIdAndMedia: [MessageId: [Media]] = [:] @@ -1062,7 +1062,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } }, 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]] = [:] @@ -1117,14 +1117,14 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G if let timestamp = timestamp { storedState = MediaPlaybackStoredState(timestamp: timestamp, playbackRate: AudioPlaybackRate(playbackRate)) } - let _ = updateMediaPlaybackStoredStateInteractively(engine: strongSelf.context.engine, messageId: messageId, state: storedState).start() + let _ = updateMediaPlaybackStoredStateInteractively(engine: strongSelf.context.engine, messageId: messageId, state: storedState).startStandalone() }, editMedia: { [weak self] messageId, snapshots, transitionCompletion in guard let strongSelf = self else { return } let _ = (strongSelf.context.engine.data.get(TelegramEngine.EngineData.Item.Messages.Message(id: messageId)) - |> deliverOnMainQueue).start(next: { [weak self] message in + |> deliverOnMainQueue).startStandalone(next: { [weak self] message in guard let strongSelf = self, let message = message else { return } @@ -1221,7 +1221,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G peerMessageSelectedReactions(context: strongSelf.context, message: topMessage), topMessageReactions(context: strongSelf.context, message: topMessage), ApplicationSpecificNotice.getChatTextSelectionTips(accountManager: strongSelf.context.sharedContext.accountManager) - ).start(next: { peer, actions, allowedReactions, selectedReactions, topReactions, chatTextSelectionTips in + ).startStandalone(next: { peer, actions, allowedReactions, selectedReactions, topReactions, chatTextSelectionTips in guard let strongSelf = self else { return } @@ -1266,7 +1266,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G let numberOfComponents = message.text.components(separatedBy: CharacterSet.whitespacesAndNewlines).count let displayTextSelectionTip = numberOfComponents >= 3 && !message.text.isEmpty && chatTextSelectionTips < 3 && !isAd if displayTextSelectionTip { - let _ = ApplicationSpecificNotice.incrementChatTextSelectionTips(accountManager: strongSelf.context.sharedContext.accountManager).start() + let _ = ApplicationSpecificNotice.incrementChatTextSelectionTips(accountManager: strongSelf.context.sharedContext.accountManager).startStandalone() tip = .textSelection } } @@ -1568,31 +1568,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } } - let _ = updateMessageReactionsInteractively(account: strongSelf.context.account, messageId: message.id, reactions: mappedUpdatedReactions, isLarge: isLarge, storeAsRecentlyUsed: true).start() - - /*let currentReactions = mergedMessageReactions(attributes: message.attributes)?.reactions ?? [] - var updatedReactions: [MessageReaction.Reaction] = currentReactions.filter(\.isSelected).map(\.value) - - var isFirst = true - for attribute in topMessage.attributes { - if let attribute = attribute as? ReactionsMessageAttribute { - for existingReaction in attribute.reactions { - if existingReaction.value == reaction.reaction { - if existingReaction.isSelected { - updatedReaction = nil - } - isFirst = false - } - } - } else if let attribute = attribute as? PendingReactionsMessageAttribute { - if let current = attribute.value, current == reaction.reaction { - updatedReaction = nil - } - } - } - - - let _ = updateMessageReactionsInteractively(account: strongSelf.context.account, messageId: message.id, reaction: updatedReaction, isLarge: isLarge).start()*/ + let _ = updateMessageReactionsInteractively(account: strongSelf.context.account, messageId: message.id, reactions: mappedUpdatedReactions, isLarge: isLarge, storeAsRecentlyUsed: true).startStandalone() } strongSelf.forEachController({ controller in @@ -1618,7 +1594,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G strongSelf.context.engine.stickers.availableReactions(), strongSelf.context.engine.stickers.resolveInlineStickers(fileIds: customFileIds) ) - |> deliverOnMainQueue).start(next: { availableReactions, customEmoji in + |> deliverOnMainQueue).startStandalone(next: { availableReactions, customEmoji in guard let strongSelf = self else { return } @@ -1696,7 +1672,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } itemsAndIndices.sort(by: { $0.2 < $1.2 }) for (info, items, index) in itemsAndIndices.reversed() { - let _ = context.engine.stickers.addStickerPackInteractively(info: info, items: items, positionInList: index).start() + let _ = context.engine.stickers.addStickerPackInteractively(info: info, items: items, positionInList: index).startStandalone() } } return true @@ -1713,7 +1689,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G case let .remove(positionInList): strongSelf.presentInGlobalOverlay(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 })) @@ -1797,7 +1773,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } let _ = (peerMessageAllowedReactions(context: strongSelf.context, message: message) - |> deliverOnMainQueue).start(next: { allowedReactions in + |> deliverOnMainQueue).startStandalone(next: { allowedReactions in guard let strongSelf = self else { return } @@ -1990,7 +1966,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } } - let _ = updateMessageReactionsInteractively(account: strongSelf.context.account, messageId: message.id, reactions: mappedUpdatedReactions, isLarge: false, storeAsRecentlyUsed: false).start() + let _ = updateMessageReactionsInteractively(account: strongSelf.context.account, messageId: message.id, reactions: mappedUpdatedReactions, isLarge: false, storeAsRecentlyUsed: false).startStandalone() } }) }, activateMessagePinch: { [weak self] sourceNode in @@ -2026,7 +2002,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G self?.navigateToMessage(from: nil, to: .id(id, nil), forceInCurrentChat: false) }, navigateToThreadMessage: { [weak self] peerId, threadId, messageId in if let context = self?.context, let navigationController = self?.effectiveNavigationController { - let _ = context.sharedContext.navigateToForumThread(context: context, peerId: peerId, threadId: threadId, messageId: messageId, navigationController: navigationController, activateInput: nil, keepStack: .always).start() + let _ = context.sharedContext.navigateToForumThread(context: context, peerId: peerId, threadId: threadId, messageId: messageId, navigationController: navigationController, activateInput: nil, keepStack: .always).startStandalone() } }, tapMessage: nil, clickThroughMessage: { [weak self] in self?.chatDisplayNode.dismissInput() @@ -2228,12 +2204,12 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G }) let _ = (ApplicationSpecificNotice.getEmojiTooltip(accountManager: strongSelf.context.sharedContext.accountManager) - |> deliverOnMainQueue).start(next: { count in + |> deliverOnMainQueue).startStandalone(next: { count in guard let strongSelf = self else { return } if count < 2 { - let _ = ApplicationSpecificNotice.incrementEmojiTooltip(accountManager: strongSelf.context.sharedContext.accountManager).start() + let _ = ApplicationSpecificNotice.incrementEmojiTooltip(accountManager: strongSelf.context.sharedContext.accountManager).startStandalone() Queue.mainQueue().after(0.5, { strongSelf.displayEmojiTooltip() @@ -2306,7 +2282,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } let _ = (strongSelf.context.engine.data.get(TelegramEngine.EngineData.Item.Messages.Message(id: messageId)) - |> deliverOnMainQueue).start(next: { message in + |> deliverOnMainQueue).startStandalone(next: { message in guard let strongSelf = self, let message = message else { return } @@ -2373,7 +2349,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G if let botPeer = botPeer { let _ = (ApplicationSpecificNotice.getBotGameNotice(accountManager: strongSelf.context.sharedContext.accountManager, peerId: botPeer.id) - |> deliverOnMainQueue).start(next: { value in + |> deliverOnMainQueue).startStandalone(next: { value in guard let strongSelf = self else { return } @@ -2383,7 +2359,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } else { strongSelf.present(textAlertController(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, title: nil, text: strongSelf.presentationData.strings.Conversation_BotInteractiveUrlAlert(EnginePeer(botPeer).displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder)).string, actions: [TextAlertAction(type: .genericAction, title: strongSelf.presentationData.strings.Common_Cancel, action: { }), TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: { if let strongSelf = self { - let _ = ApplicationSpecificNotice.setBotGameNotice(accountManager: strongSelf.context.sharedContext.accountManager, peerId: botPeer.id).start() + let _ = ApplicationSpecificNotice.setBotGameNotice(accountManager: strongSelf.context.sharedContext.accountManager, peerId: botPeer.id).startStandalone() openBot() } })]), in: .window(.root), with: nil) @@ -2426,7 +2402,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G |> afterDisposed { updateProgress() }) - |> deliverOnMainQueue).start(error: { error in + |> deliverOnMainQueue).startStrict(error: { error in let controller = ownershipTransferController(context: context, updatedPresentationData: strongSelf.updatedPresentationData, initialError: error, present: { c, a in strongSelf.present(c, in: .window(.root), with: a) }, commit: { password in @@ -2444,7 +2420,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G |> afterDisposed { updateProgress() }) - |> deliverOnMainQueue).start(next: { result in + |> deliverOnMainQueue).startStrict(next: { result in proceedWithResult(result) })) } @@ -2494,7 +2470,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G }) } } - })) |> deliverOnMainQueue).start(next: { peer, result in + })) |> deliverOnMainQueue).startStrict(next: { peer, result in if let strongSelf = self { switch result { case .default: @@ -2543,7 +2519,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G }) } } - }) |> deliverOnMainQueue).start(next: { [weak self] result in + }) |> deliverOnMainQueue).startStrict(next: { [weak self] result in if let strongSelf = self { switch result { case let .accepted(url): @@ -2576,7 +2552,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } if let botStart = strongSelf.botStart, case let .automatic(returnToPeerId, scheduled) = botStart.behavior { let _ = (strongSelf.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: returnToPeerId)) - |> deliverOnMainQueue).start(next: { peer in + |> deliverOnMainQueue).startStandalone(next: { peer in if let strongSelf = self, let peer = peer { strongSelf.openPeer(peer: peer, navigation: .chat(textInputState: ChatTextInputState(inputText: NSAttributedString(string: inputString)), subject: scheduled ? .scheduledMessages : nil, peekData: nil), fromMessage: nil) } @@ -2584,7 +2560,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } else { if let peerId = peerId { 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, navigation: .chat(textInputState: ChatTextInputState(inputText: NSAttributedString(string: inputString)), subject: nil, peekData: nil), fromMessage: nil) } @@ -2618,7 +2594,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G strongSelf.present(textAlertController(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, title: strongSelf.presentationData.strings.Conversation_ShareBotLocationConfirmationTitle, text: strongSelf.presentationData.strings.Conversation_ShareBotLocationConfirmation, actions: [TextAlertAction(type: .genericAction, title: strongSelf.presentationData.strings.Common_Cancel, action: {}), TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: { if let strongSelf = self, let locationManager = strongSelf.context.sharedContext.locationManager { let _ = (currentLocationManagerCoordinate(manager: locationManager, timeout: 5.0) - |> deliverOnMainQueue).start(next: { coordinate in + |> deliverOnMainQueue).startStandalone(next: { coordinate in if let strongSelf = self { if let coordinate = coordinate { strongSelf.sendMessages([.message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: TelegramMediaMap(latitude: coordinate.latitude, longitude: coordinate.longitude, heading: nil, accuracyRadius: nil, geoPlace: nil, venue: nil, liveBroadcastingTimeout: nil, liveProximityNotificationRadius: nil)), replyToMessageId: nil, replyToStoryId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])]) @@ -2643,7 +2619,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G strongSelf.present(textAlertController(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, title: strongSelf.presentationData.strings.Conversation_ShareBotContactConfirmationTitle, text: strongSelf.presentationData.strings.Conversation_ShareBotContactConfirmation, actions: [TextAlertAction(type: .genericAction, title: strongSelf.presentationData.strings.Common_Cancel, action: {}), TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: { if let strongSelf = self { let _ = (strongSelf.context.account.postbox.loadedPeerWithId(strongSelf.context.account.peerId) - |> deliverOnMainQueue).start(next: { peer in + |> deliverOnMainQueue).startStandalone(next: { peer in if let peer = peer as? TelegramUser, let phone = peer.phone, !phone.isEmpty { strongSelf.sendMessages([.message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: TelegramMediaContact(firstName: peer.firstName ?? "", lastName: peer.lastName ?? "", phoneNumber: phone, peerId: peer.id, vCardData: nil)), replyToMessageId: nil, replyToStoryId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])]) } @@ -2786,7 +2762,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G peerIds.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 } @@ -2843,7 +2819,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G |> map { view -> Peer? in return peerViewMainPeer(view) } - |> deliverOnMainQueue).start(next: { peer in + |> deliverOnMainQueue).startStandalone(next: { peer in guard let peer = peer else { return } @@ -2959,7 +2935,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G 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, navigation: .chat(textInputState: nil, subject: nil, peekData: nil), fromMessage: nil) } @@ -3046,7 +3022,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G peerSignal = strongSelf.context.account.postbox.loadedPeerWithId(peerId) |> map(Optional.init) let _ = (peerSignal - |> deliverOnMainQueue).start(next: { peer in + |> deliverOnMainQueue).startStandalone(next: { peer in if let strongSelf = self { let searchController = HashtagSearchController(context: strongSelf.context, peer: peer.flatMap(EnginePeer.init), query: hashtag) strongSelf.effectiveNavigationController?.pushViewController(searchController) @@ -3114,7 +3090,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G |> map { result -> String? in return result } - |> deliverOnMainQueue).start(next: { link in + |> deliverOnMainQueue).startStandalone(next: { link in if let link = link { UIPasteboard.general.string = link + "?t=\(Int32(timecode))" @@ -3185,7 +3161,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } |> runOn(Queue.mainQueue()) |> delay(0.15, queue: Queue.mainQueue()) - let progressDisposable = progressSignal.start() + let progressDisposable = progressSignal.startStrict() signal = signal |> afterDisposed { @@ -3197,7 +3173,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G disposable.set(nil) } disposable.set((signal - |> deliverOnMainQueue).start(next: { [weak self] info in + |> deliverOnMainQueue).startStrict(next: { [weak self] info in if let strongSelf = self, let info = info { let actionSheet = ActionSheetController(presentationData: strongSelf.presentationData) var items: [ActionSheetItem] = [] @@ -3246,7 +3222,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } let _ = (strongSelf.context.engine.data.get(TelegramEngine.EngineData.Item.Messages.Message(id: messageId)) - |> deliverOnMainQueue).start(next: { message in + |> deliverOnMainQueue).startStandalone(next: { message in guard let strongSelf = self, let message = message else { return } @@ -3331,7 +3307,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } if id.namespace == Namespaces.Message.ScheduledCloud { let _ = (strongSelf.context.engine.data.get(TelegramEngine.EngineData.Item.Messages.MessageGroup(id: id)) - |> deliverOnMainQueue).start(next: { messages in + |> deliverOnMainQueue).startStandalone(next: { messages in guard let strongSelf = self, let message = messages.filter({ $0.id == id }).first else { return } @@ -3375,7 +3351,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G }) } else { let _ = (strongSelf.context.engine.messages.failedMessageGroup(id: id) - |> deliverOnMainQueue).start(next: { messages in + |> deliverOnMainQueue).startStandalone(next: { messages in guard let strongSelf = self else { return } @@ -3416,7 +3392,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Resend"), color: theme.actionSheet.primaryTextColor) }, action: { [weak self] _, f in if let strongSelf = self { - let _ = resendMessages(account: strongSelf.context.account, messageIds: selectedGroup.map({ $0.id })).start() + let _ = resendMessages(account: strongSelf.context.account, messageIds: selectedGroup.map({ $0.id })).startStandalone() } f(.dismissWithoutContent) }))) @@ -3425,7 +3401,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Resend"), color: theme.actionSheet.primaryTextColor) }, action: { [weak self] _, f in if let strongSelf = self { - let _ = resendMessages(account: strongSelf.context.account, messageIds: messages.map({ $0.id })).start() + let _ = resendMessages(account: strongSelf.context.account, messageIds: messages.map({ $0.id })).startStandalone() } f(.dismissWithoutContent) }))) @@ -3434,7 +3410,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Delete"), color: theme.actionSheet.destructiveActionTextColor) }, action: { [weak self] controller, f in if let strongSelf = self { - let _ = strongSelf.context.engine.messages.deleteMessagesInteractively(messageIds: [id], type: .forLocalPeer).start() + let _ = strongSelf.context.engine.messages.deleteMessagesInteractively(messageIds: [id], type: .forLocalPeer).startStandalone() } f(.dismissWithoutContent) }))) @@ -3499,7 +3475,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } let signal = strongSelf.context.engine.messages.requestMessageSelectPollOption(messageId: id, opaqueIdentifiers: opaqueIdentifiers) disposables.set((signal - |> deliverOnMainQueue).start(next: { resultPoll in + |> deliverOnMainQueue).startStrict(next: { resultPoll in guard let strongSelf = self, let resultPoll = resultPoll else { return } @@ -3577,7 +3553,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } let _ = strongSelf.presentVoiceMessageDiscardAlert(action: { let _ = (strongSelf.context.engine.data.get(TelegramEngine.EngineData.Item.Messages.Message(id: messageId)) - |> deliverOnMainQueue).start(next: { message in + |> deliverOnMainQueue).startStandalone(next: { message in guard let message = message else { return } @@ -3673,14 +3649,14 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } return } else { - let _ = strongSelf.context.engine.messages.sendScheduledMessageNowInteractively(messageId: messageIds.first!).start() + let _ = strongSelf.context.engine.messages.sendScheduledMessageNowInteractively(messageId: messageIds.first!).startStandalone() } } }, editScheduledMessagesTime: { [weak self] messageIds in if let strongSelf = self, let messageId = messageIds.first { let _ = strongSelf.presentVoiceMessageDiscardAlert(action: { let _ = (strongSelf.context.engine.data.get(TelegramEngine.EngineData.Item.Messages.Message(id: messageId)) - |> deliverOnMainQueue).start(next: { [weak self] message in + |> deliverOnMainQueue).startStandalone(next: { [weak self] message in guard let strongSelf = self, let message = message else { return } @@ -3695,7 +3671,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } let inlineStickers: [MediaId: TelegramMediaFile] = [:] - strongSelf.editMessageDisposable.set((strongSelf.context.engine.messages.requestEditMessage(messageId: messageId, text: message.text, media: .keep, entities: entities, inlineStickers: inlineStickers, disableUrlPreview: false, scheduleTime: time) |> deliverOnMainQueue).start(next: { result in + strongSelf.editMessageDisposable.set((strongSelf.context.engine.messages.requestEditMessage(messageId: messageId, text: message.text, media: .keep, entities: entities, inlineStickers: inlineStickers, disableUrlPreview: false, scheduleTime: time) |> deliverOnMainQueue).startStrict(next: { result in }, error: { error in })) } @@ -3747,7 +3723,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G let f = { let _ = (context.sharedContext.accountManager.sharedData(keys: [ApplicationSpecificSharedDataKeys.translationSettings]) |> take(1) - |> deliverOnMainQueue).start(next: { [weak self] sharedData in + |> deliverOnMainQueue).startStandalone(next: { [weak self] sharedData in guard let strongSelf = self else { return } @@ -3765,7 +3741,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G let (_, language) = canTranslateText(context: context, text: text.string, showTranslate: translationSettings.showTranslate, showTranslateIfTopical: showTranslateIfTopical, ignoredLanguages: translationSettings.ignoredLanguages) - let _ = ApplicationSpecificNotice.incrementTranslationSuggestion(accountManager: context.sharedContext.accountManager, timestamp: Int32(Date().timeIntervalSince1970)).start() + let _ = ApplicationSpecificNotice.incrementTranslationSuggestion(accountManager: context.sharedContext.accountManager, timestamp: Int32(Date().timeIntervalSince1970)).startStandalone() let controller = TranslateScreen(context: context, text: text.string, canCopy: canCopy, fromLanguage: language, ignoredLanguages: translationSettings.ignoredLanguages) controller.pushController = { [weak self] c in @@ -3821,7 +3797,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } let _ = strongSelf.presentVoiceMessageDiscardAlert(action: { let _ = (strongSelf.context.engine.data.get(TelegramEngine.EngineData.Item.Messages.Message(id: messageId)) - |> deliverOnMainQueue).start(next: { message in + |> deliverOnMainQueue).startStandalone(next: { message in guard let message = message else { return } @@ -3894,7 +3870,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } let _ = (dataSignal - |> deliverOnMainQueue).start(next: { [weak self] peer, message in + |> deliverOnMainQueue).startStandalone(next: { [weak self] peer, message in guard let strongSelf = self, let peer = peer, peer.smallProfileImage != nil else { return } @@ -3999,7 +3975,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G return .complete() } } - |> deliverOnMainQueue).start(next: { [weak self] messageIdAndStatsDatacenterId in + |> deliverOnMainQueue).startStandalone(next: { [weak self] messageIdAndStatsDatacenterId in guard let strongSelf = self, let (id, statsDatacenterId) = messageIdAndStatsDatacenterId, let statsDatacenterId = statsDatacenterId else { return } @@ -4015,7 +3991,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G if draw { let _ = (strongSelf.context.engine.data.get(TelegramEngine.EngineData.Item.Messages.Message(id: messageId)) - |> deliverOnMainQueue).start(next: { [weak self] message in + |> deliverOnMainQueue).startStandalone(next: { [weak self] message in guard let strongSelf = self, let message = message else { return } @@ -4101,7 +4077,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G let currentTimestamp = Int32(Date().timeIntervalSince1970) let _ = (ApplicationSpecificNotice.getInteractiveEmojiSyncTip(accountManager: strongSelf.context.sharedContext.accountManager) - |> deliverOnMainQueue).start(next: { [weak self] count, timestamp in + |> deliverOnMainQueue).startStandalone(next: { [weak self] count, timestamp in if let strongSelf = self, count < 3 && currentTimestamp > timestamp + 24 * 60 * 60 { strongSelf.interactiveEmojiSyncDisposable.set( (strongSelf.peerInputActivitiesPromise.get() @@ -4118,12 +4094,12 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G |> map { _ -> Bool in return true } - |> timeout(2.0, queue: Queue.mainQueue(), alternate: .single(false))).start(next: { [weak self] responded in + |> timeout(2.0, queue: Queue.mainQueue(), alternate: .single(false))).startStrict(next: { [weak self] responded in if let strongSelf = self { if !responded { strongSelf.present(UndoOverlayController(presentationData: strongSelf.presentationData, content: .sticker(context: strongSelf.context, file: file, loop: true, title: nil, text: strongSelf.presentationData.strings.Conversation_InteractiveEmojiSyncTip(EnginePeer(peer).compactDisplayTitle).string, undoText: nil, customAction: nil), elevatedLayout: false, action: { _ in return false }), in: .current) - let _ = ApplicationSpecificNotice.incrementInteractiveEmojiSyncTip(accountManager: strongSelf.context.sharedContext.accountManager, timestamp: currentTimestamp).start() + let _ = ApplicationSpecificNotice.incrementInteractiveEmojiSyncTip(accountManager: strongSelf.context.sharedContext.accountManager, timestamp: currentTimestamp).startStandalone() } } }) @@ -4144,7 +4120,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } let _ = updatePresentationThemeSettingsInteractively(accountManager: strongSelf.context.sharedContext.accountManager, { current in return current.withUpdatedLargeEmoji(true) - }).start() + }).startStandalone() strongSelf.present(UndoOverlayController(presentationData: strongSelf.presentationData, content: .emoji(name: "TwoFactorSetupRememberSuccess", text: strongSelf.presentationData.strings.Conversation_LargeEmojiEnabled), elevatedLayout: false, action: { _ in return false }), in: .current) }) @@ -4287,7 +4263,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G |> afterDisposed { updateProgress() }) - |> deliverOnMainQueue).start(next: { [weak self] url in + |> deliverOnMainQueue).startStrict(next: { [weak self] url in guard let strongSelf = self else { return } @@ -4327,7 +4303,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G |> afterDisposed { updateProgress() }) - |> deliverOnMainQueue).start(next: { [weak self] result in + |> deliverOnMainQueue).startStrict(next: { [weak self] result in guard let strongSelf = self else { return } @@ -4356,7 +4332,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G botPeer = bot } let _ = (ApplicationSpecificNotice.getBotGameNotice(accountManager: strongSelf.context.sharedContext.accountManager, peerId: botPeer.id) - |> deliverOnMainQueue).start(next: { value in + |> deliverOnMainQueue).startStandalone(next: { value in guard let strongSelf = self else { return } @@ -4365,7 +4341,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G openWebView() } else { let controller = webAppLaunchConfirmationController(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, peer: botPeer, completion: { _ in - let _ = ApplicationSpecificNotice.setBotGameNotice(accountManager: strongSelf.context.sharedContext.accountManager, peerId: botPeer.id).start() + let _ = ApplicationSpecificNotice.setBotGameNotice(accountManager: strongSelf.context.sharedContext.accountManager, peerId: botPeer.id).startStandalone() openWebView() }, showMore: nil) strongSelf.present(controller, in: .window(.root)) @@ -4396,7 +4372,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G navigationData = .chat(textInputState: nil, subject: subject, peekData: nil) } let _ = (self.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: id)) - |> deliverOnMainQueue).start(next: { [weak self] peer in + |> deliverOnMainQueue).startStandalone(next: { [weak self] peer in if let self, let peer = peer { self.openPeer(peer: peer, navigation: navigationData, fromMessage: nil) } @@ -4486,7 +4462,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G return } if case .user = peerType { - let _ = context.engine.peers.sendBotRequestedPeer(messageId: messageId, buttonId: buttonId, requestedPeerId: peer.id).start() + let _ = context.engine.peers.sendBotRequestedPeer(messageId: messageId, buttonId: buttonId, requestedPeerId: peer.id).startStandalone() controller?.dismiss() } else { var isChannel = false @@ -4495,7 +4471,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } let peerName = peer.displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder) presentConfirmation(peerName, isChannel, { - let _ = context.engine.peers.sendBotRequestedPeer(messageId: messageId, buttonId: buttonId, requestedPeerId: peer.id).start() + let _ = context.engine.peers.sendBotRequestedPeer(messageId: messageId, buttonId: buttonId, requestedPeerId: peer.id).startStandalone() controller?.dismiss() }) } @@ -4510,7 +4486,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G complete() }) }, completion: { peerId, dismiss in - let _ = context.engine.peers.sendBotRequestedPeer(messageId: messageId, buttonId: buttonId, requestedPeerId: peerId).start() + let _ = context.engine.peers.sendBotRequestedPeer(messageId: messageId, buttonId: buttonId, requestedPeerId: peerId).startStandalone() dismiss() }) createGroupController.navigationPresentation = .modal @@ -4521,7 +4497,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G complete() }) }, completion: { peerId, dismiss in - let _ = context.engine.peers.sendBotRequestedPeer(messageId: messageId, buttonId: buttonId, requestedPeerId: peerId).start() + let _ = context.engine.peers.sendBotRequestedPeer(messageId: messageId, buttonId: buttonId, requestedPeerId: peerId).startStandalone() dismiss() }) createChannelController.navigationPresentation = .modal @@ -4531,7 +4507,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G self.push(controller) }, saveMediaToFiles: { [weak self] messageId in let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Messages.Message(id: messageId)) - |> deliverOnMainQueue).start(next: { message in + |> deliverOnMainQueue).startStandalone(next: { message in guard let self, let message else { return } @@ -4585,7 +4561,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } |> runOn(Queue.mainQueue()) |> delay(0.15, queue: Queue.mainQueue()) - let progressDisposable = progressSignal.start() + let progressDisposable = progressSignal.startStrict() signal = signal |> afterDisposed { @@ -4597,7 +4573,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G disposable?.set(nil) } disposable.set((signal - |> deliverOnMainQueue).start(next: { [weak self] state, _ in + |> deliverOnMainQueue).startStrict(next: { [weak self] state, _ in guard let self else { return } @@ -4694,7 +4670,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G let storyContent = SingleStoryContentContextImpl(context: self.context, storyId: storyId, readGlobally: true) let _ = (storyContent.state |> take(1) - |> deliverOnMainQueue).start(next: { [weak self] _ in + |> deliverOnMainQueue).startStandalone(next: { [weak self] _ in guard let self else { return } @@ -4924,7 +4900,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G let chatLocationPeerId: PeerId? = chatLocation.peerId self.accountPeerDisposable = (context.account.postbox.peerView(id: context.account.peerId) - |> deliverOnMainQueue).start(next: { [weak self] peerView in + |> deliverOnMainQueue).startStrict(next: { [weak self] peerView in if let strongSelf = self { let isPremium = peerView.peers[peerView.peerId]?.isPremium ?? false strongSelf.updateChatPresentationInterfaceState(animated: false, interactive: false, { @@ -5111,7 +5087,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } self.titleDisposable.set((combineLatest(queue: Queue.mainQueue(), peerView.get(), onlineMemberCount, displayedCountSignal, subtitleTextSignal, self.presentationInterfaceStatePromise.get(), hasPeerInfo) - |> deliverOnMainQueue).start(next: { [weak self] peerView, onlineMemberCount, displayedCount, subtitleText, presentationInterfaceState, hasPeerInfo in + |> deliverOnMainQueue).startStrict(next: { [weak self] peerView, onlineMemberCount, displayedCount, subtitleText, presentationInterfaceState, hasPeerInfo in if let strongSelf = self { var isScheduledMessages = false if case .scheduledMessages = presentationInterfaceState.subject { @@ -5230,7 +5206,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G self.reportIrrelvantGeoNoticePromise.get(), displayedCountSignal, threadInfo - ).start(next: { [weak self] peerView, globalNotificationSettings, onlineMemberCount, hasScheduledMessages, peerReportNotice, pinnedCount, threadInfo in + ).startStrict(next: { [weak self] peerView, globalNotificationSettings, onlineMemberCount, hasScheduledMessages, peerReportNotice, pinnedCount, threadInfo in if let strongSelf = self { if strongSelf.peerView === peerView && strongSelf.reportIrrelvantGeoNotice == peerReportNotice && strongSelf.hasScheduledMessages == hasScheduledMessages && strongSelf.threadInfo == threadInfo { return @@ -5480,7 +5456,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G if let peerDiscussionId = peerDiscussionId { let combinedDisposable = DisposableSet() strongSelf.preloadHistoryPeerIdDisposable.set(combinedDisposable) - combinedDisposable.add(strongSelf.context.account.viewTracker.polledChannel(peerId: peerDiscussionId).start()) + combinedDisposable.add(strongSelf.context.account.viewTracker.polledChannel(peerId: peerDiscussionId).startStrict()) combinedDisposable.add(strongSelf.context.account.addAdditionalPreloadHistoryPeerId(peerId: peerDiscussionId)) } else { strongSelf.preloadHistoryPeerIdDisposable.set(nil) @@ -5543,7 +5519,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G ApplicationSpecificNotice.getNextChatSuggestionTip(accountManager: strongSelf.context.sharedContext.accountManager) ) |> then(.complete() |> delay(1.0, queue: .mainQueue())) - |> restart).start(next: { nextPeer, nextChatSuggestionTip in + |> restart).startStrict(next: { nextPeer, nextChatSuggestionTip in guard let strongSelf = self else { return } @@ -5561,7 +5537,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G if let nextPeerId = nextPeerId { let combinedDisposable = DisposableSet() strongSelf.preloadNextChatPeerIdDisposable.set(combinedDisposable) - combinedDisposable.add(strongSelf.context.account.viewTracker.polledChannel(peerId: nextPeerId).start()) + combinedDisposable.add(strongSelf.context.account.viewTracker.polledChannel(peerId: nextPeerId).startStrict()) combinedDisposable.add(strongSelf.context.account.addAdditionalPreloadHistoryPeerId(peerId: nextPeerId)) } else { strongSelf.preloadNextChatPeerIdDisposable.set(nil) @@ -5710,7 +5686,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G onlineMemberCount, hasScheduledMessages ) - |> deliverOnMainQueue).start(next: { [weak self] peerView, messageAndTopic, onlineMemberCount, hasScheduledMessages in + |> deliverOnMainQueue).startStrict(next: { [weak self] peerView, messageAndTopic, onlineMemberCount, hasScheduledMessages in if let strongSelf = self { strongSelf.hasScheduledMessages = hasScheduledMessages @@ -5987,7 +5963,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } self.botCallbackAlertMessageDisposable = (self.botCallbackAlertMessage.get() - |> deliverOnMainQueue).start(next: { [weak self] message in + |> deliverOnMainQueue).startStrict(next: { [weak self] message in if let strongSelf = self { strongSelf.updateChatPresentationInterfaceState(animated: true, interactive: false, { return $0.updatedTitlePanelContext { @@ -6034,7 +6010,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G }) self.audioRecorderDisposable = (self.audioRecorder.get() - |> deliverOnMainQueue).start(next: { [weak self] audioRecorder in + |> deliverOnMainQueue).startStrict(next: { [weak self] audioRecorder in if let strongSelf = self { if strongSelf.audioRecorderValue !== audioRecorder { strongSelf.audioRecorderValue = audioRecorder @@ -6064,7 +6040,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } audioRecorder.start() strongSelf.audioRecorderStatusDisposable = (audioRecorder.recordingState - |> deliverOnMainQueue).start(next: { value in + |> deliverOnMainQueue).startStrict(next: { value in if case .stopped = value { self?.stopMediaRecorder() } @@ -6078,7 +6054,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G }) self.videoRecorderDisposable = (self.videoRecorder.get() - |> deliverOnMainQueue).start(next: { [weak self] videoRecorder in + |> deliverOnMainQueue).startStrict(next: { [weak self] videoRecorder in if let strongSelf = self { if strongSelf.videoRecorderValue !== videoRecorder { let previousVideoRecorderValue = strongSelf.videoRecorderValue @@ -6146,7 +6122,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G if let activitySpace = activitySpace { self.inputActivityDisposable = (self.typingActivityPromise.get() - |> deliverOnMainQueue).start(next: { [weak self] value in + |> deliverOnMainQueue).startStrict(next: { [weak self] value in if let strongSelf = self, strongSelf.presentationInterfaceState.interfaceState.editMessage == nil && strongSelf.presentationInterfaceState.subject != .scheduledMessages && strongSelf.presentationInterfaceState.currentSendAsPeerId == nil { strongSelf.context.account.updateLocalInputActivity(peerId: activitySpace, activity: .typingText, isPresent: value) } @@ -6160,7 +6136,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G return .single(false) |> delay(2.0, queue: Queue.mainQueue()) } } - |> deliverOnMainQueue).start(next: { [weak self] value in + |> deliverOnMainQueue).startStrict(next: { [weak self] value in if let strongSelf = self, strongSelf.presentationInterfaceState.interfaceState.editMessage == nil && strongSelf.presentationInterfaceState.subject != .scheduledMessages && strongSelf.presentationInterfaceState.currentSendAsPeerId == nil { if value { strongSelf.context.account.updateLocalInputActivity(peerId: activitySpace, activity: .typingText, isPresent: false) @@ -6170,7 +6146,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G }) self.recordingActivityDisposable = (self.recordingActivityPromise.get() - |> deliverOnMainQueue).start(next: { [weak self] value in + |> deliverOnMainQueue).startStrict(next: { [weak self] value in if let strongSelf = self, strongSelf.presentationInterfaceState.interfaceState.editMessage == nil && strongSelf.presentationInterfaceState.subject != .scheduledMessages && strongSelf.presentationInterfaceState.currentSendAsPeerId == nil { strongSelf.acquiredRecordingActivityDisposable?.dispose() switch value { @@ -6230,7 +6206,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G themeEmoticon, self.themeEmoticonAndDarkAppearancePreviewPromise.get(), chatWallpaper - ).start(next: { [weak self] presentationData, themeSettings, chatThemes, themeEmoticon, themeEmoticonAndDarkAppearance, chatWallpaper in + ).startStrict(next: { [weak self] presentationData, themeSettings, chatThemes, themeEmoticon, themeEmoticonAndDarkAppearance, chatWallpaper in if let strongSelf = self { let (themeEmoticonPreview, darkAppearancePreview) = themeEmoticonAndDarkAppearance @@ -6377,7 +6353,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G }) self.automaticMediaDownloadSettingsDisposable = (context.sharedContext.automaticMediaDownloadSettings - |> deliverOnMainQueue).start(next: { [weak self] downloadSettings in + |> deliverOnMainQueue).startStrict(next: { [weak self] downloadSettings in if let strongSelf = self, strongSelf.automaticMediaDownloadSettings != downloadSettings { strongSelf.automaticMediaDownloadSettings = downloadSettings strongSelf.controllerInteraction?.automaticMediaDownloadSettings = downloadSettings @@ -6387,7 +6363,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } }) - self.stickerSettingsDisposable = combineLatest(queue: Queue.mainQueue(), context.sharedContext.accountManager.sharedData(keys: [ApplicationSpecificSharedDataKeys.stickerSettings]), self.disableStickerAnimationsPromise.get()).start(next: { [weak self] sharedData, disableStickerAnimations in + self.stickerSettingsDisposable = combineLatest(queue: Queue.mainQueue(), context.sharedContext.accountManager.sharedData(keys: [ApplicationSpecificSharedDataKeys.stickerSettings]), self.disableStickerAnimationsPromise.get()).startStrict(next: { [weak self] sharedData, disableStickerAnimations in var stickerSettings = StickerSettings.defaultSettings if let value = sharedData.entries[ApplicationSpecificSharedDataKeys.stickerSettings]?.get(StickerSettings.self) { stickerSettings = value @@ -6407,7 +6383,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G var wasInForeground = true self.applicationInForegroundDisposable = (context.sharedContext.applicationBindings.applicationInForeground |> distinctUntilChanged - |> deliverOn(Queue.mainQueue())).start(next: { [weak self] value in + |> deliverOn(Queue.mainQueue())).startStrict(next: { [weak self] value in if let strongSelf = self, strongSelf.isNodeLoaded { if !value { strongSelf.saveInterfaceState() @@ -6426,7 +6402,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G if case let .peer(peerId) = chatLocation, peerId.namespace == Namespaces.Peer.SecretChat { self.applicationInFocusDisposable = (context.sharedContext.applicationBindings.applicationIsActive |> distinctUntilChanged - |> deliverOn(Queue.mainQueue())).start(next: { [weak self] value in + |> deliverOn(Queue.mainQueue())).startStrict(next: { [weak self] value in guard let strongSelf = self, strongSelf.isNodeLoaded else { return } @@ -6436,7 +6412,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G self.canReadHistoryDisposable = (combineLatest(context.sharedContext.applicationBindings.applicationInForeground, self.canReadHistory.get()) |> map { a, b in return a && b - } |> deliverOnMainQueue).start(next: { [weak self] value in + } |> deliverOnMainQueue).startStrict(next: { [weak self] value in if let strongSelf = self, strongSelf.canReadHistoryValue != value { strongSelf.canReadHistoryValue = value strongSelf.raiseToListen?.enabled = value @@ -6445,7 +6421,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } }) - self.networkStateDisposable = (context.account.networkState |> deliverOnMainQueue).start(next: { [weak self] state in + self.networkStateDisposable = (context.account.networkState |> deliverOnMainQueue).startStrict(next: { [weak self] state in if let strongSelf = self, case .standard(previewing: false) = strongSelf.presentationInterfaceState.mode { strongSelf.chatTitleView?.networkState = state } @@ -6545,6 +6521,10 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G self.premiumGiftSuggestionDisposable?.dispose() self.powerSavingMonitoringDisposable?.dispose() self.saveMediaDisposable?.dispose() + self.choosingStickerActivityDisposable?.dispose() + self.automaticMediaDownloadSettingsDisposable?.dispose() + self.stickerSettingsDisposable?.dispose() + self.searchQuerySuggestionState?.1.dispose() } deallocate() } @@ -6835,7 +6815,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G let viewDisposable = MetaDisposable() let referenceDisposable = (referenceMessage - |> deliverOnMainQueue).start(next: { referenceMessage in + |> deliverOnMainQueue).startStrict(next: { referenceMessage in referenceMessageValue = referenceMessage if !initializedView { initializedView = true @@ -6845,7 +6825,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G referenceId = loaded.id } viewDisposable.set((pinnedHistorySignal(anchorMessageId: referenceId, count: loadCount) - |> deliverOnMainQueue).start(next: { next in + |> deliverOnMainQueue).startStrict(next: { next in view = next updateState() })) @@ -7014,7 +6994,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G currentAccountPeer, self.context.account.postbox.peerView(id: peerId), self.context.engine.peers.sendAsAvailablePeers(peerId: peerId)) - ).start(next: { [weak self] currentAccountPeer, peerView, peers in + ).startStrict(next: { [weak self] currentAccountPeer, peerView, peers in guard let strongSelf = self else { return } @@ -7222,7 +7202,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } } - self.buttonKeyboardMessageDisposable = self.chatDisplayNode.historyNode.buttonKeyboardMessage.start(next: { [weak self] message in + self.buttonKeyboardMessageDisposable = self.chatDisplayNode.historyNode.buttonKeyboardMessage.startStrict(next: { [weak self] message in if let strongSelf = self { var buttonKeyboardMessageUpdated = false if let currentButtonKeyboardMessage = strongSelf.presentationInterfaceState.keyboardButtonsMessage, let message = message { @@ -7359,7 +7339,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } else if peerId.namespace != Namespaces.Peer.SecretChat && peerId != context.account.peerId && self.subject != .scheduledMessages { self.premiumGiftSuggestionDisposable = (ApplicationSpecificNotice.dismissedPremiumGiftSuggestion(accountManager: self.context.sharedContext.accountManager, peerId: peerId) - |> deliverOnMainQueue).start(next: { [weak self] counter in + |> deliverOnMainQueue).startStrict(next: { [weak self] counter in if let strongSelf = self { strongSelf.updateChatPresentationInterfaceState(animated: strongSelf.willAppear, interactive: strongSelf.willAppear, { state in return state.updatedSuggestPremiumGift(counter == 0) @@ -7402,7 +7382,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G return .single(nil) } } - |> deliverOnMainQueue).start(next: { [weak self] chatTranslationState in + |> deliverOnMainQueue).startStrict(next: { [weak self] chatTranslationState in if let strongSelf = self { strongSelf.updateChatPresentationInterfaceState(animated: strongSelf.willAppear, interactive: strongSelf.willAppear, { state in return state.updatedTranslationState(chatTranslationState) @@ -7419,7 +7399,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G isForum, threadData, isGeneralThreadClosed - ).start(next: { [weak self] cachedDataAndMessages, hasPendingMessages, isTopReplyThreadMessageShown, topPinnedMessage, customEmojiAvailable, isForum, threadData, isGeneralThreadClosed in + ).startStrict(next: { [weak self] cachedDataAndMessages, hasPendingMessages, isTopReplyThreadMessageShown, topPinnedMessage, customEmojiAvailable, isForum, threadData, isGeneralThreadClosed in if let strongSelf = self { let (cachedData, messages) = cachedDataAndMessages @@ -7532,7 +7512,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G let inviteRequestsContext = strongSelf.context.engine.peers.peerInvitationImporters(peerId: peerId, subject: .requests(query: nil)) strongSelf.inviteRequestsContext = inviteRequestsContext - strongSelf.inviteRequestsDisposable.set((combineLatest(queue: Queue.mainQueue(), inviteRequestsContext.state, ApplicationSpecificNotice.dismissedInvitationRequests(accountManager: strongSelf.context.sharedContext.accountManager, peerId: peerId))).start(next: { [weak self] requestsState, dismissedInvitationRequests in + strongSelf.inviteRequestsDisposable.set((combineLatest(queue: Queue.mainQueue(), inviteRequestsContext.state, ApplicationSpecificNotice.dismissedInvitationRequests(accountManager: strongSelf.context.sharedContext.accountManager, peerId: peerId))).startStrict(next: { [weak self] requestsState, dismissedInvitationRequests in guard let strongSelf = self else { return } @@ -7590,7 +7570,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } else if let inviteRequestsContext = strongSelf.inviteRequestsContext { let _ = (inviteRequestsContext.state |> take(1) - |> deliverOnMainQueue).start(next: { [weak inviteRequestsContext] state in + |> deliverOnMainQueue).startStandalone(next: { [weak inviteRequestsContext] state in if state.count != inviteRequestsPending { inviteRequestsContext?.loadMore() } @@ -7662,7 +7642,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } } - self.historyStateDisposable = self.chatDisplayNode.historyNode.historyState.get().start(next: { [weak self] state in + self.historyStateDisposable = self.chatDisplayNode.historyNode.historyState.get().startStrict(next: { [weak self] state in if let strongSelf = self { strongSelf.updateChatPresentationInterfaceState(animated: true, interactive: strongSelf.isViewLoaded && strongSelf.view.window != nil, { $0.updatedChatHistoryState(state) @@ -7703,7 +7683,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G |> take(1) |> timeout(0.8, queue: .concurrentDefaultQueue(), alternate: Signal { _ in preconditionFailure() - })).start() + })).startStandalone() } self.chatDisplayNode.historyNode.contentPositionChanged = { [weak self] offset in @@ -7768,7 +7748,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G strongSelf.updateItemNodesHighlightedStates(animated: initial) strongSelf.scrolledToMessageIdValue = ScrolledToMessageId(id: index.id, allowedReplacementDirection: []) - strongSelf.messageContextDisposable.set((Signal.complete() |> delay(0.7, queue: Queue.mainQueue())).start(completed: { + strongSelf.messageContextDisposable.set((Signal.complete() |> delay(0.7, queue: Queue.mainQueue())).startStrict(completed: { if let strongSelf = self, let controllerInteraction = strongSelf.controllerInteraction { if controllerInteraction.highlightedState == highlightedState { controllerInteraction.highlightedState = nil @@ -7978,7 +7958,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } let _ = (signal - |> deliverOnMainQueue).start(next: { messageIds in + |> deliverOnMainQueue).startStandalone(next: { messageIds in if let strongSelf = self { if case .scheduledMessages = strongSelf.presentationInterfaceState.subject { } else { @@ -8016,7 +7996,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } if let messageId = strongSelf.presentationInterfaceState.interfaceState.editMessage?.messageId { let _ = (strongSelf.context.engine.data.get(TelegramEngine.EngineData.Item.Messages.Message(id: messageId)) - |> deliverOnMainQueue).start(next: { message in + |> deliverOnMainQueue).startStandalone(next: { message in guard let strongSelf = self, let editMessageState = strongSelf.presentationInterfaceState.editMessageState, case let .media(options) = editMessageState.content else { return } @@ -8117,7 +8097,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G self.chatDisplayNode.navigateButtons.mentionsPressed = { [weak self] in if let strongSelf = self, strongSelf.isNodeLoaded, let peerId = strongSelf.chatLocation.peerId { let signal = strongSelf.context.engine.messages.earliestUnseenPersonalMentionMessage(peerId: peerId, threadId: strongSelf.chatLocation.threadId) - strongSelf.navigationActionDisposable.set((signal |> deliverOnMainQueue).start(next: { result in + strongSelf.navigationActionDisposable.set((signal |> deliverOnMainQueue).startStrict(next: { result in if let strongSelf = self { switch result { case let .result(messageId): @@ -8155,7 +8135,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G guard let strongSelf = self, let peerId = strongSelf.chatLocation.peerId else { return } - let _ = clearPeerUnseenPersonalMessagesInteractively(account: strongSelf.context.account, peerId: peerId, threadId: strongSelf.chatLocation.threadId).start() + let _ = clearPeerUnseenPersonalMessagesInteractively(account: strongSelf.context.account, peerId: peerId, threadId: strongSelf.chatLocation.threadId).startStandalone() } ))) let items = ContextController.Items(content: .list(menuItems)) @@ -8174,7 +8154,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G self.chatDisplayNode.navigateButtons.reactionsPressed = { [weak self] in if let strongSelf = self, strongSelf.isNodeLoaded, let peerId = strongSelf.chatLocation.peerId { let signal = strongSelf.context.engine.messages.earliestUnseenPersonalReactionMessage(peerId: peerId, threadId: strongSelf.chatLocation.threadId) - strongSelf.navigationActionDisposable.set((signal |> deliverOnMainQueue).start(next: { result in + strongSelf.navigationActionDisposable.set((signal |> deliverOnMainQueue).startStrict(next: { result in if let strongSelf = self { switch result { case let .result(messageId): @@ -8322,7 +8302,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G guard let strongSelf = self, let peerId = strongSelf.chatLocation.peerId else { return } - let _ = clearPeerUnseenReactionsInteractively(account: strongSelf.context.account, peerId: peerId, threadId: strongSelf.chatLocation.threadId).start() + let _ = clearPeerUnseenReactionsInteractively(account: strongSelf.context.account, peerId: peerId, threadId: strongSelf.chatLocation.threadId).startStandalone() } ))) let items = ContextController.Items(content: .list(menuItems)) @@ -8436,7 +8416,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G if let strongSelf = self { if let messageIds = strongSelf.presentationInterfaceState.interfaceState.selectionState?.selectedIds, !messageIds.isEmpty { strongSelf.messageContextDisposable.set((strongSelf.context.sharedContext.chatAvailableMessageActions(engine: strongSelf.context.engine, accountPeerId: strongSelf.context.account.peerId, messageIds: messageIds) - |> deliverOnMainQueue).start(next: { actions in + |> deliverOnMainQueue).startStrict(next: { actions in if let strongSelf = self, !actions.options.isEmpty { if let banAuthor = actions.banAuthor { strongSelf.presentBanMessageOptions(accountPeerId: strongSelf.context.account.peerId, author: banAuthor, messageIds: messageIds, options: actions.options) @@ -8470,7 +8450,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G dismissAction() strongSelf.updateChatPresentationInterfaceState(animated: true, interactive: true, { $0.updatedInterfaceState { $0.withoutSelectionState() } }, completion: { _ in let _ = (strongSelf.context.engine.peers.reportPeerMessages(messageIds: Array(messageIds), reason: reportReason, message: message) - |> deliverOnMainQueue).start(completed: { + |> deliverOnMainQueue).startStandalone(completed: { strongSelf.present(UndoOverlayController(presentationData: presentationData, content: .emoji(name: "PoliceCar", text: presentationData.strings.Report_Succeed), elevatedLayout: false, action: { _ in return false }), in: .current) }) }) @@ -8533,10 +8513,10 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G guard let strongSelf = self else { return } - let _ = strongSelf.context.engine.privacy.requestUpdatePeerIsBlocked(peerId: peer.id, isBlocked: true).start() + let _ = strongSelf.context.engine.privacy.requestUpdatePeerIsBlocked(peerId: peer.id, isBlocked: true).startStandalone() let context = strongSelf.context - let _ = context.engine.messages.deleteAllMessagesWithForwardAuthor(peerId: message.id.peerId, forwardAuthorId: peer.id, namespace: Namespaces.Message.Cloud).start() - let _ = strongSelf.context.engine.peers.reportRepliesMessage(messageId: message.id, deleteMessage: true, deleteHistory: true, reportSpam: reportSpam).start() + let _ = context.engine.messages.deleteAllMessagesWithForwardAuthor(peerId: message.id.peerId, forwardAuthorId: peer.id, namespace: Namespaces.Message.Cloud).startStandalone() + let _ = strongSelf.context.engine.peers.reportRepliesMessage(messageId: message.id, deleteMessage: true, deleteHistory: true, reportSpam: reportSpam).startStandalone() }) ] as [ActionSheetItem]) @@ -8550,7 +8530,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G if let strongSelf = self, !messages.isEmpty { let messageIds = Set(messages.map { $0.id }) strongSelf.messageContextDisposable.set((strongSelf.context.sharedContext.chatAvailableMessageActions(engine: strongSelf.context.engine, accountPeerId: strongSelf.context.account.peerId, messageIds: messageIds) - |> deliverOnMainQueue).start(next: { actions in + |> deliverOnMainQueue).startStrict(next: { actions in if let strongSelf = self, !actions.options.isEmpty { if let banAuthor = actions.banAuthor { if let contextController = contextController { @@ -8574,10 +8554,10 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } } if isAction && (actions.options == .deleteGlobally || actions.options == .deleteLocally) { - let _ = strongSelf.context.engine.messages.deleteMessagesInteractively(messageIds: Array(messageIds), type: actions.options == .deleteLocally ? .forLocalPeer : .forEveryone).start() + let _ = strongSelf.context.engine.messages.deleteMessagesInteractively(messageIds: Array(messageIds), type: actions.options == .deleteLocally ? .forLocalPeer : .forEveryone).startStandalone() completion(.dismissWithoutContent) } else if (messages.first?.flags.isSending ?? false) { - let _ = strongSelf.context.engine.messages.deleteMessagesInteractively(messageIds: Array(messageIds), type: .forEveryone, deleteAllInGroup: true).start() + let _ = strongSelf.context.engine.messages.deleteMessagesInteractively(messageIds: Array(messageIds), type: .forEveryone, deleteAllInGroup: true).startStandalone() completion(.dismissWithoutContent) } else { if actions.options.intersection([.deleteLocally, .deleteGlobally]).isEmpty { @@ -8832,7 +8812,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G |> map { messages -> [EngineMessage] in return messages.values.compactMap { $0 } } - |> deliverOnMainQueue).start(next: { messages in + |> deliverOnMainQueue).startStandalone(next: { messages in if let strongSelf = self, !messages.isEmpty { strongSelf.updateChatPresentationInterfaceState(animated: true, interactive: true, { $0.updatedInterfaceState({ $0.withoutSelectionState() }) }) @@ -8951,7 +8931,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G let _ = (strongSelf.context.account.postbox.messageAtId(editMessage.messageId) |> deliverOnMainQueue) - .start(next: { [weak self] currentMessage in + .startStandalone(next: { [weak self] currentMessage in if let strongSelf = self { if let currentMessage = currentMessage { let currentEntities = currentMessage.textEntitiesAttribute?.entities ?? [] @@ -9018,7 +8998,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } else { let _ = (strongSelf.searchResult.get() |> take(1) - |> deliverOnMainQueue).start(next: { [weak self] searchResult in + |> deliverOnMainQueue).startStandalone(next: { [weak self] searchResult in if let strongSelf = self, let (searchResult, searchState, searchLocation) = searchResult { let controller = ChatSearchResultsController(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, location: searchLocation, searchQuery: searchData.query, searchResult: searchResult, searchState: searchState, navigateToMessageIndex: { index in guard let strongSelf = self else { @@ -9126,7 +9106,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G 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 peer = peer else { return } @@ -9143,7 +9123,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G return } 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, navigation: .default, fromMessage: nil) } @@ -9152,7 +9132,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G self?.navigationButtonAction(.openChatInfo(expandAvatar: false)) }, togglePeerNotifications: { [weak self] in if let strongSelf = self, let peerId = strongSelf.chatLocation.peerId { - let _ = strongSelf.context.engine.peers.togglePeerMuted(peerId: peerId, threadId: strongSelf.chatLocation.threadId).start() + let _ = strongSelf.context.engine.peers.togglePeerMuted(peerId: peerId, threadId: strongSelf.chatLocation.threadId).startStandalone() } }, sendContextResult: { [weak self] results, result, node, rect in guard let strongSelf = self else { @@ -9210,7 +9190,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G isScheduled = true } 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, navigation: .withBotStartPayload(ChatControllerInitialBotStart(payload: payload, behavior: .automatic(returnToPeerId: currentPeerId, scheduled: isScheduled))), fromMessage: nil) } @@ -9279,7 +9259,8 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } let hasOngoingCall: Signal = strongSelf.context.sharedContext.hasOngoingCall.get() let _ = (hasOngoingCall - |> deliverOnMainQueue).start(next: { hasOngoingCall in + |> take(1) + |> deliverOnMainQueue).startStandalone(next: { hasOngoingCall in guard let strongSelf = self, strongSelf.beginMediaRecordingRequestId == requestId else { return } @@ -9601,7 +9582,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G }) if let updatedMode = updatedMode, updatedMode == .video { - let _ = ApplicationSpecificNotice.incrementChatMediaMediaRecordingTips(accountManager: strongSelf.context.sharedContext.accountManager, count: 3).start() + let _ = ApplicationSpecificNotice.incrementChatMediaMediaRecordingTips(accountManager: strongSelf.context.sharedContext.accountManager, count: 3).startStandalone() } strongSelf.displayMediaRecordingTooltip() @@ -9618,7 +9599,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G if let peer = peer as? TelegramSecretChat { let controller = ChatSecretAutoremoveTimerActionSheetController(context: strongSelf.context, currentValue: peer.messageAutoremoveTimeout == nil ? 0 : peer.messageAutoremoveTimeout!, applyValue: { value in if let strongSelf = self { - let _ = strongSelf.context.engine.peers.setChatMessageAutoremoveTimeoutInteractively(peerId: peer.id, timeout: value == 0 ? nil : value).start() + let _ = strongSelf.context.engine.peers.setChatMessageAutoremoveTimeoutInteractively(peerId: peer.id, timeout: value == 0 ? nil : value).startStandalone() } }) strongSelf.present(controller, in: .window(.root)) @@ -9693,7 +9674,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G disposable = MetaDisposable() strongSelf.unpinMessageDisposable = disposable } - disposable.set(strongSelf.context.engine.messages.requestUpdatePinnedMessage(peerId: currentPeerId, update: .pin(id: messageId, silent: !notify, forThisPeerOnlyIfPossible: forThisPeerOnlyIfPossible)).start(completed: { + disposable.set(strongSelf.context.engine.messages.requestUpdatePinnedMessage(peerId: currentPeerId, update: .pin(id: messageId, silent: !notify, forThisPeerOnlyIfPossible: forThisPeerOnlyIfPossible)).startStrict(completed: { guard let strongSelf = self else { return } @@ -9767,7 +9748,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G |> take(1) let _ = (topPinnedMessage - |> deliverOnMainQueue).start(next: { value in + |> deliverOnMainQueue).startStandalone(next: { value in guard let strongSelf = self else { return } @@ -9863,7 +9844,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G switch action { case .commit: disposable.set((strongSelf.context.engine.messages.requestUpdatePinnedMessage(peerId: peer.id, update: .clear(id: id)) - |> deliverOnMainQueue).start(error: { _ in + |> deliverOnMainQueue).startStrict(error: { _ in guard let strongSelf = self else { return } @@ -9913,7 +9894,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G switch action { case .commit: let _ = (strongSelf.context.engine.messages.requestUpdatePinnedMessage(peerId: peer.id, update: .clear(id: id)) - |> deliverOnMainQueue).start(completed: { + |> deliverOnMainQueue).startStandalone(completed: { Queue.mainQueue().after(1.0, { guard let strongSelf = self else { return @@ -9933,7 +9914,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G ) } else { disposable.set((strongSelf.context.engine.messages.requestUpdatePinnedMessage(peerId: peer.id, update: .clear(id: id)) - |> deliverOnMainQueue).start()) + |> deliverOnMainQueue).startStrict()) } } } @@ -10010,7 +9991,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G |> take(1) let _ = (topPinnedMessage - |> deliverOnMainQueue).start(next: { topPinnedMessage in + |> deliverOnMainQueue).startStandalone(next: { topPinnedMessage in guard let strongSelf = self, let topPinnedMessage = topPinnedMessage else { return } @@ -10062,7 +10043,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G return (result, !isSaved) } } - |> deliverOnMainQueue).start(next: { [weak self] result, added in + |> deliverOnMainQueue).startStandalone(next: { [weak self] result, added in if let strongSelf = self { switch result { case .generic: @@ -10181,7 +10162,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } |> runOn(Queue.mainQueue()) |> delay(0.3, queue: Queue.mainQueue()) - let progressDisposable = progressSignal.start() + let progressDisposable = progressSignal.startStrict() signal = signal |> afterDisposed { @@ -10194,7 +10175,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } disposables.set((signal - |> deliverOnMainQueue).start(completed: { [weak self] in + |> deliverOnMainQueue).startStrict(completed: { [weak self] in guard let self else { return } @@ -10255,7 +10236,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } } disposables.set((signal - |> deliverOnMainQueue).start(error: { _ in + |> deliverOnMainQueue).startStrict(error: { _ in }, completed: { guard let strongSelf = self else { return @@ -10285,7 +10266,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G return } let _ = (strongSelf.context.engine.peers.updatePeersGroupIdInteractively(peerIds: [peerId], groupId: .root) - |> deliverOnMainQueue).start() + |> deliverOnMainQueue).startStandalone() }, openLinkEditing: { [weak self] in if let strongSelf = self { var selectionRange: Range? @@ -10342,10 +10323,10 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G return } strongSelf.reportIrrelvantGeoDisposable = (strongSelf.context.engine.peers.reportPeer(peerId: peerId, reason: .irrelevantLocation, message: "") - |> deliverOnMainQueue).start(completed: { [weak self] in + |> deliverOnMainQueue).startStrict(completed: { [weak self] in if let strongSelf = self { strongSelf.reportIrrelvantGeoNoticePromise.set(.single(true)) - let _ = ApplicationSpecificNotice.setIrrelevantPeerGeoReport(engine: strongSelf.context.engine, peerId: peerId).start() + let _ = ApplicationSpecificNotice.setIrrelevantPeerGeoReport(engine: strongSelf.context.engine, peerId: peerId).startStandalone() strongSelf.present(UndoOverlayController(presentationData: strongSelf.presentationData, content: .emoji(name: "PoliceCar", text: strongSelf.presentationData.strings.Report_Succeed), elevatedLayout: false, action: { _ in return false }), in: .current) } @@ -10387,7 +10368,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G strongSelf.supportedOrientations = ViewControllerSupportedOrientations(regularSize: .all, compactSize: .portrait) } - let _ = ApplicationSpecificNotice.incrementChatMessageOptionsTip(accountManager: strongSelf.context.sharedContext.accountManager, count: 4).start() + let _ = ApplicationSpecificNotice.incrementChatMessageOptionsTip(accountManager: strongSelf.context.sharedContext.accountManager, count: 4).startStandalone() var hasEntityKeyboard = false if case .media = strongSelf.presentationInterfaceState.inputMode { @@ -10396,7 +10377,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G let _ = (strongSelf.context.account.viewTracker.peerView(peerId) |> take(1) - |> deliverOnMainQueue).start(next: { [weak self] peerView in + |> deliverOnMainQueue).startStandalone(next: { [weak self] peerView in guard let strongSelf = self, let peer = peerViewMainPeer(peerView) else { return } @@ -10412,7 +10393,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } if sendWhenOnlineAvailable { - let _ = ApplicationSpecificNotice.incrementSendWhenOnlineTip(accountManager: strongSelf.context.sharedContext.accountManager, count: 4).start() + let _ = ApplicationSpecificNotice.incrementSendWhenOnlineTip(accountManager: strongSelf.context.sharedContext.accountManager, count: 4).startStandalone() } let controller = ChatSendMessageActionSheetController(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, peerId: strongSelf.presentationInterfaceState.chatLocation.peerId, forwardMessageIds: strongSelf.presentationInterfaceState.interfaceState.forwardMessageIds, hasEntityKeyboard: hasEntityKeyboard, gesture: gesture, sourceSendButton: node, textInputNode: textInputNode, canSendWhenOnline: sendWhenOnlineAvailable, completion: { [weak self] in @@ -10670,7 +10651,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G |> map { messages -> [EngineMessage] in return messages.values.compactMap { $0 } } - |> deliverOnMainQueue).start(next: { [weak self] messages in + |> deliverOnMainQueue).startStandalone(next: { [weak self] messages in guard let strongSelf = self else { return } @@ -10776,7 +10757,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G guard let strongSelf = self, let peerId = strongSelf.chatLocation.peerId, let threadId = strongSelf.chatLocation.threadId else { return } - let _ = strongSelf.context.engine.peers.setForumChannelTopicClosed(id: peerId, threadId: threadId, isClosed: false).start() + let _ = strongSelf.context.engine.peers.setForumChannelTopicClosed(id: peerId, threadId: threadId, isClosed: false).startStandalone() }, toggleTranslation: { [weak self] type in guard let strongSelf = self, let peerId = strongSelf.chatLocation.peerId else { return @@ -10784,7 +10765,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G let _ = (updateChatTranslationStateInteractively(engine: strongSelf.context.engine, peerId: peerId, { current in return current?.withIsEnabled(type == .translated) }) - |> deliverOnMainQueue).start(completed: { [weak self] in + |> deliverOnMainQueue).startStandalone(completed: { [weak self] in if let strongSelf = self, type == .translated { Queue.mainQueue().after(0.15) { strongSelf.chatDisplayNode.historyNode.refreshPollActionsForVisibleMessages() @@ -10803,7 +10784,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } let _ = updateChatTranslationStateInteractively(engine: strongSelf.context.engine, peerId: peerId, { current in return current?.withToLang(langCode).withIsEnabled(true) - }).start() + }).startStandalone() }, addDoNotTranslateLanguage: { [weak self] langCode in guard let strongSelf = self, let peerId = strongSelf.chatLocation.peerId else { return @@ -10825,10 +10806,10 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G updated.ignoredLanguages = Array(ignoredLanguages) } return updated - }).start() + }).startStandalone() let _ = updateChatTranslationStateInteractively(engine: strongSelf.context.engine, peerId: peerId, { current in return nil - }).start() + }).startStandalone() let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 } var languageCode = presentationData.strings.baseLanguageCode @@ -10853,7 +10834,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } let context = strongSelf.context let presentationData = strongSelf.presentationData - let _ = context.engine.messages.togglePeerMessagesTranslationHidden(peerId: peerId, hidden: true).start() + let _ = context.engine.messages.togglePeerMessagesTranslationHidden(peerId: peerId, hidden: true).startStandalone() var text: String = "" if let peer = strongSelf.presentationInterfaceState.renderedPeer?.peer { @@ -10872,7 +10853,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } strongSelf.present(UndoOverlayController(presentationData: presentationData, content: .image(image: generateTintedImage(image: UIImage(bundleImageName: "Chat/Title Panels/Translate"), color: .white)!, title: nil, text: text, round: false, undoText: presentationData.strings.Undo_Undo), elevatedLayout: false, animateInAsReplacement: false, action: { action in if case .undo = action { - let _ = context.engine.messages.togglePeerMessagesTranslationHidden(peerId: peerId, hidden: false).start() + let _ = context.engine.messages.togglePeerMessagesTranslationHidden(peerId: peerId, hidden: false).startStandalone() } return true }), in: .current) @@ -10882,7 +10863,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } strongSelf.presentAttachmentPremiumGift() Queue.mainQueue().after(0.5) { - let _ = ApplicationSpecificNotice.incrementDismissedPremiumGiftSuggestion(accountManager: strongSelf.context.sharedContext.accountManager, peerId: peerId).start() + let _ = ApplicationSpecificNotice.incrementDismissedPremiumGiftSuggestion(accountManager: strongSelf.context.sharedContext.accountManager, peerId: peerId).startStandalone() } }, requestLayout: { [weak self] transition in if let strongSelf = self, let layout = strongSelf.validLayout { @@ -10901,7 +10882,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G return .single(value) |> then(.complete() |> delay(0.2, queue: Queue.mainQueue())) } self.buttonUnreadCountDisposable = (throttledUnreadCountSignal - |> deliverOnMainQueue).start(next: { [weak self] count in + |> deliverOnMainQueue).startStrict(next: { [weak self] count in guard let strongSelf = self else { return } @@ -10914,7 +10895,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G TelegramEngine.EngineData.Item.Messages.TotalReadCounters(), TelegramEngine.EngineData.Item.Peer.NotificationSettings(id: peerId) ) - |> deliverOnMainQueue).start(next: { [weak self] peerUnreadCount, totalReadCounters, notificationSettings in + |> deliverOnMainQueue).startStrict(next: { [weak self] peerUnreadCount, totalReadCounters, notificationSettings in guard let strongSelf = self else { return } @@ -10939,7 +10920,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } }) - self.chatUnreadMentionCountDisposable = (self.context.account.viewTracker.unseenPersonalMessagesAndReactionCount(peerId: peerId, threadId: nil) |> deliverOnMainQueue).start(next: { [weak self] mentionCount, reactionCount in + self.chatUnreadMentionCountDisposable = (self.context.account.viewTracker.unseenPersonalMessagesAndReactionCount(peerId: peerId, threadId: nil) |> deliverOnMainQueue).startStrict(next: { [weak self] mentionCount, reactionCount in if let strongSelf = self { if case let .standard(previewing) = strongSelf.presentationInterfaceState.mode, previewing { strongSelf.chatDisplayNode.navigateButtons.mentionCount = 0 @@ -10951,7 +10932,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } }) } else if let peerId = self.chatLocation.peerId, let threadId = self.chatLocation.threadId { - self.chatUnreadMentionCountDisposable = (self.context.account.viewTracker.unseenPersonalMessagesAndReactionCount(peerId: peerId, threadId: threadId) |> deliverOnMainQueue).start(next: { [weak self] mentionCount, reactionCount in + self.chatUnreadMentionCountDisposable = (self.context.account.viewTracker.unseenPersonalMessagesAndReactionCount(peerId: peerId, threadId: threadId) |> deliverOnMainQueue).startStrict(next: { [weak self] mentionCount, reactionCount in if let strongSelf = self { if case let .standard(previewing) = strongSelf.presentationInterfaceState.mode, previewing { strongSelf.chatDisplayNode.navigateButtons.mentionCount = 0 @@ -11012,7 +10993,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } } } - |> deliverOnMainQueue).start(next: { [weak self] activities in + |> deliverOnMainQueue).startStrict(next: { [weak self] activities in if let strongSelf = self { let displayActivities = activities.filter({ switch $0.1 { @@ -11050,7 +11031,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G if let peerId = peerId { self.sentMessageEventsDisposable.set((self.context.account.pendingMessageManager.deliveredMessageEvents(peerId: peerId) - |> deliverOnMainQueue).start(next: { [weak self] namespace, silent in + |> deliverOnMainQueue).startStrict(next: { [weak self] namespace, silent in if let strongSelf = self { let inAppNotificationSettings = strongSelf.context.sharedContext.currentInAppNotificationSettings.with { $0 } if inAppNotificationSettings.playSounds && !silent { @@ -11065,13 +11046,13 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G strongSelf.displayChecksTooltip() } strongSelf.shouldDisplayChecksTooltip = false - strongSelf.checksTooltipDisposable.set(dismissServerProvidedSuggestion(account: strongSelf.context.account, suggestion: .newcomerTicks).start()) + strongSelf.checksTooltipDisposable.set(dismissServerProvidedSuggestion(account: strongSelf.context.account, suggestion: .newcomerTicks).startStrict()) } } })) self.failedMessageEventsDisposable.set((self.context.account.pendingMessageManager.failedMessageEvents(peerId: peerId) - |> deliverOnMainQueue).start(next: { [weak self] reason in + |> deliverOnMainQueue).startStrict(next: { [weak self] reason in if let strongSelf = self, strongSelf.currentFailedMessagesAlertController == nil { let text: String var title: String? @@ -11116,7 +11097,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G self.sentPeerMediaMessageEventsDisposable.set( (self.context.account.pendingPeerMediaUploadManager.sentMessageEvents(peerId: peerId) - |> deliverOnMainQueue).start(next: { [weak self] _ in + |> deliverOnMainQueue).startStrict(next: { [weak self] _ in if let self { self.chatDisplayNode.historyNode.scrollToEndOfHistory() } @@ -11135,7 +11116,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G self.chatDisplayNode.interfaceInteraction = interfaceInteraction self.context.sharedContext.mediaManager.galleryHiddenMediaManager.addTarget(self) - self.galleryHiddenMesageAndMediaDisposable.set(self.context.sharedContext.mediaManager.galleryHiddenMediaManager.hiddenIds().start(next: { [weak self] ids in + self.galleryHiddenMesageAndMediaDisposable.set(self.context.sharedContext.mediaManager.galleryHiddenMediaManager.hiddenIds().startStrict(next: { [weak self] ids in if let strongSelf = self, let controllerInteraction = strongSelf.controllerInteraction { var messageIdAndMedia: [MessageId: [Media]] = [:] @@ -11171,7 +11152,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G self.hasActiveGroupCallDisposable = ((callManager.currentGroupCallSignal |> map { call -> Bool in return call != nil - }) |> deliverOnMainQueue).start(next: { [weak self] hasActiveGroupCall in + }) |> deliverOnMainQueue).startStrict(next: { [weak self] hasActiveGroupCall in self?.updateChatPresentationInterfaceState(animated: true, interactive: false, { state in return state.updatedHasActiveGroupCall(hasActiveGroupCall) }) @@ -11234,7 +11215,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G return } if let navigationController = strongSelf.effectiveNavigationController { - let _ = ApplicationSpecificNotice.incrementNextChatSuggestionTip(accountManager: strongSelf.context.sharedContext.accountManager).start() + let _ = ApplicationSpecificNotice.incrementNextChatSuggestionTip(accountManager: strongSelf.context.sharedContext.accountManager).startStandalone() let snapshotState = strongSelf.chatDisplayNode.prepareSnapshotState( titleViewSnapshotState: strongSelf.chatTitleView?.prepareSnapshotState(), @@ -11299,7 +11280,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G if case let .replyThread(message) = self.chatLocation, message.isForumPost { if self.keepMessageCountersSyncrhonizedDisposable == nil { - self.keepMessageCountersSyncrhonizedDisposable = self.context.engine.messages.keepMessageCountersSyncrhonized(peerId: message.messageId.peerId, threadId: Int64(message.messageId.id)).start() + self.keepMessageCountersSyncrhonizedDisposable = self.context.engine.messages.keepMessageCountersSyncrhonized(peerId: message.messageId.peerId, threadId: Int64(message.messageId.id)).startStrict() } } @@ -11377,9 +11358,11 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G self.chatDisplayNode.loadInputPanels(theme: self.presentationInterfaceState.theme, strings: self.presentationInterfaceState.strings, fontSize: self.presentationInterfaceState.fontSize) - self.recentlyUsedInlineBotsDisposable = (self.context.engine.peers.recentlyUsedInlineBots() |> deliverOnMainQueue).start(next: { [weak self] peers in - self?.recentlyUsedInlineBotsValue = peers.filter({ $0.1 >= 0.14 }).map({ $0.0._asPeer() }) - }) + if self.recentlyUsedInlineBotsDisposable == nil { + self.recentlyUsedInlineBotsDisposable = (self.context.engine.peers.recentlyUsedInlineBots() |> deliverOnMainQueue).startStrict(next: { [weak self] peers in + self?.recentlyUsedInlineBotsValue = peers.filter({ $0.1 >= 0.14 }).map({ $0.0._asPeer() }) + }) + } if case .standard(false) = self.presentationInterfaceState.mode, self.raiseToListen == nil { self.raiseToListen = RaiseToListenManager(shouldActivate: { [weak self] in @@ -11472,7 +11455,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G self.screenCaptureManager = ScreenCaptureDetectionManager(check: { [weak self] in if let strongSelf = self, strongSelf.traceVisibility() { if strongSelf.canReadHistoryValue { - let _ = strongSelf.context.engine.messages.addSecretChatMessageScreenshot(peerId: peerId).start() + let _ = strongSelf.context.engine.messages.addSecretChatMessageScreenshot(peerId: peerId).startStandalone() } return true } else { @@ -11490,7 +11473,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } }) if !loginCodesToInvalidate.isEmpty { - let _ = strongSelf.context.engine.auth.invalidateLoginCodes(codes: loginCodesToInvalidate).start() + let _ = strongSelf.context.engine.auth.invalidateLoginCodes(codes: loginCodesToInvalidate).startStandalone() } return true } else { @@ -11501,7 +11484,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } if case let .peer(peerId) = self.chatLocation { - let _ = self.context.engine.peers.checkPeerChatServiceActions(peerId: peerId).start() + let _ = self.context.engine.peers.checkPeerChatServiceActions(peerId: peerId).startStandalone() } if self.chatDisplayNode.frameForInputActionButton() != nil { @@ -11509,9 +11492,9 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G if !inputText.isEmpty { if inputText.count > 4 { let _ = (ApplicationSpecificNotice.getChatMessageOptionsTip(accountManager: self.context.sharedContext.accountManager) - |> deliverOnMainQueue).start(next: { [weak self] counter in + |> deliverOnMainQueue).startStandalone(next: { [weak self] counter in if let strongSelf = self, counter < 3 { - let _ = ApplicationSpecificNotice.incrementChatMessageOptionsTip(accountManager: strongSelf.context.sharedContext.accountManager).start() + let _ = ApplicationSpecificNotice.incrementChatMessageOptionsTip(accountManager: strongSelf.context.sharedContext.accountManager).startStandalone() strongSelf.displaySendingOptionsTooltip() } }) @@ -11531,7 +11514,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } if canSendMedia && self.presentationInterfaceState.voiceMessagesAvailable { let _ = (ApplicationSpecificNotice.getChatMediaMediaRecordingTips(accountManager: self.context.sharedContext.accountManager) - |> deliverOnMainQueue).start(next: { [weak self] counter in + |> deliverOnMainQueue).startStandalone(next: { [weak self] counter in guard let strongSelf = self else { return } @@ -11542,7 +11525,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G displayTip = true } if displayTip { - let _ = ApplicationSpecificNotice.incrementChatMediaMediaRecordingTips(accountManager: strongSelf.context.sharedContext.accountManager).start() + let _ = ApplicationSpecificNotice.incrementChatMediaMediaRecordingTips(accountManager: strongSelf.context.sharedContext.accountManager).startStandalone() strongSelf.displayMediaRecordingTooltip() } }) @@ -11551,7 +11534,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } self.editMessageErrorsDisposable.set((self.context.account.pendingUpdateMessageManager.errors - |> deliverOnMainQueue).start(next: { [weak self] (_, error) in + |> deliverOnMainQueue).startStrict(next: { [weak self] (_, error) in guard let strongSelf = self else { return } @@ -11569,7 +11552,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G if case let .peer(peerId) = self.chatLocation { let context = self.context - self.keepPeerInfoScreenDataHotDisposable.set(keepPeerInfoScreenDataHot(context: context, peerId: peerId, chatLocation: self.chatLocation, chatLocationContextHolder: self.chatLocationContextHolder).start()) + self.keepPeerInfoScreenDataHotDisposable.set(keepPeerInfoScreenDataHot(context: context, peerId: peerId, chatLocation: self.chatLocation, chatLocationContextHolder: self.chatLocationContextHolder).startStrict()) if peerId.namespace == Namespaces.Peer.CloudUser { self.preloadAvatarDisposable.set((peerInfoProfilePhotosWithCache(context: context, peerId: peerId) @@ -11584,7 +11567,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G return combineLatest(signals) |> mapToSignal { _ in return .never() } - }).start()) + }).startStrict()) } } @@ -11608,7 +11591,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G |> suspendAwareDelay(Double(remainingTime), granularity: 2.0, queue: .mainQueue()) ) |> deliverOnMainQueue - ).start(next: { [weak self] peerView, _ in + ).startStrict(next: { [weak self] peerView, _ in guard let strongSelf = self, let peer = peerViewMainPeer(peerView) else { return } @@ -11631,7 +11614,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } strongSelf.peekTimerDisposable.set( (strongSelf.context.engine.peers.joinChatInteractively(with: peekData.linkData) - |> deliverOnMainQueue).start(next: { peerId in + |> deliverOnMainQueue).startStrict(next: { peerId in guard let strongSelf = self else { return } @@ -11660,7 +11643,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } self.checksTooltipDisposable.set((getServerProvidedSuggestions(account: self.context.account) - |> deliverOnMainQueue).start(next: { [weak self] values in + |> deliverOnMainQueue).startStrict(next: { [weak self] values in guard let strongSelf = self, strongSelf.chatLocation.peerId != strongSelf.context.account.peerId else { return } @@ -11672,7 +11655,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G if case let .peer(peerId) = self.chatLocation { self.peerSuggestionsDisposable.set((getPeerSpecificServerProvidedSuggestions(postbox: self.context.account.postbox, peerId: peerId) - |> deliverOnMainQueue).start(next: { [weak self] values in + |> deliverOnMainQueue).startStrict(next: { [weak self] values in guard let strongSelf = self else { return } @@ -11708,14 +11691,14 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G let attributedText = parseMarkdownIntoAttributedString(presentationData.strings.BroadcastGroups_ConfirmationAlert_Text, attributes: MarkdownAttributes(body: body, bold: bold, link: body, linkAttribute: { _ in return nil }), textAlignment: .center) let alertController = richTextAlertController(context: context, title: attributedTitle, text: attributedText, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: { - let _ = dismissPeerSpecificServerProvidedSuggestion(account: context.account, peerId: peerId, suggestion: .convertToGigagroup).start() + let _ = dismissPeerSpecificServerProvidedSuggestion(account: context.account, peerId: peerId, suggestion: .convertToGigagroup).startStandalone() }), TextAlertAction(type: .defaultAction, title: presentationData.strings.BroadcastGroups_ConfirmationAlert_Convert, action: { [weak controller] in controller?.dismiss() - let _ = dismissPeerSpecificServerProvidedSuggestion(account: context.account, peerId: peerId, suggestion: .convertToGigagroup).start() + let _ = dismissPeerSpecificServerProvidedSuggestion(account: context.account, peerId: peerId, suggestion: .convertToGigagroup).startStandalone() let _ = (convertGroupToGigagroup(account: context.account, peerId: peerId) - |> deliverOnMainQueue).start(completed: { + |> deliverOnMainQueue).startStandalone(completed: { let participantsLimit = context.currentLimitsConfiguration.with { $0 }.maxSupergroupMemberCount strongSelf.present(UndoOverlayController(presentationData: presentationData, content: .gigagroupConversion(text: presentationData.strings.BroadcastGroups_Success(presentationStringsFormattedNumber(participantsLimit, presentationData.dateTimeFormat.decimalSeparator)).string), elevatedLayout: false, action: { _ in return false }), in: .current) }) @@ -11773,7 +11756,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G |> mapToSignal { settings -> Signal in return automaticEnergyUsageShouldBeOn(settings: settings) } - |> distinctUntilChanged).start(next: { [weak self] isPowerSavingEnabled in + |> distinctUntilChanged).startStrict(next: { [weak self] isPowerSavingEnabled in guard let self else { return } @@ -11799,7 +11782,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G var settings = settings settings.energyUsageSettings.activationThreshold = 4 return settings - }).start() + }).startStandalone() } return false }), in: .current) @@ -11862,7 +11845,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } let _ = ChatInterfaceState.update(engine: self.context.engine, peerId: peerId, threadId: threadId, { _ in return interfaceState - }).start() + }).startStandalone() } override public func viewWillLeaveNavigation() { @@ -12021,13 +12004,13 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G return } let _ = (ApplicationSpecificNotice.updateInlineBotLocationRequestState(accountManager: strongSelf.context.sharedContext.accountManager, peerId: peerId, timestamp: Int32(Date().timeIntervalSince1970 + 10 * 60)) - |> deliverOnMainQueue).start(next: { value in + |> deliverOnMainQueue).startStandalone(next: { value in guard let strongSelf = self, value else { return } strongSelf.present(textAlertController(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, title: nil, text: strongSelf.presentationData.strings.Conversation_ShareInlineBotLocationConfirmation, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_Cancel, action: { }), TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: { - let _ = ApplicationSpecificNotice.setInlineBotLocationRequest(accountManager: strongSelf.context.sharedContext.accountManager, peerId: peerId, value: 0).start() + let _ = ApplicationSpecificNotice.setInlineBotLocationRequest(accountManager: strongSelf.context.sharedContext.accountManager, peerId: peerId, value: 0).startStandalone() })]), in: .window(.root)) }) }) @@ -12053,7 +12036,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G var inScope = true var inScopeResult: ((ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult?)? self.contextQueryStates[kind] = (query, (signal - |> deliverOnMainQueue).start(next: { [weak self] result in + |> deliverOnMainQueue).startStrict(next: { [weak self] result in if let strongSelf = self { if Thread.isMainThread && inScope { inScope = false @@ -12077,9 +12060,9 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G break case let .inlineBotLocationRequest(peerId): strongSelf.present(textAlertController(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, title: nil, text: strongSelf.presentationData.strings.Conversation_ShareInlineBotLocationConfirmation, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_Cancel, action: { - let _ = ApplicationSpecificNotice.setInlineBotLocationRequest(accountManager: strongSelf.context.sharedContext.accountManager, peerId: peerId, value: Int32(Date().timeIntervalSince1970 + 10 * 60)).start() + let _ = ApplicationSpecificNotice.setInlineBotLocationRequest(accountManager: strongSelf.context.sharedContext.accountManager, peerId: peerId, value: Int32(Date().timeIntervalSince1970 + 10 * 60)).startStandalone() }), TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: { - let _ = ApplicationSpecificNotice.setInlineBotLocationRequest(accountManager: strongSelf.context.sharedContext.accountManager, peerId: peerId, value: 0).start() + let _ = ApplicationSpecificNotice.setInlineBotLocationRequest(accountManager: strongSelf.context.sharedContext.accountManager, peerId: peerId, value: 0).startStandalone() })]), in: .window(.root)) } } @@ -12104,9 +12087,9 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G if case let .peer(peerId) = self.chatLocation, peerId.namespace == Namespaces.Peer.SecretChat { if case .contextRequest = query { let _ = (ApplicationSpecificNotice.getSecretChatInlineBotUsage(accountManager: self.context.sharedContext.accountManager) - |> deliverOnMainQueue).start(next: { [weak self] value in + |> deliverOnMainQueue).startStandalone(next: { [weak self] value in if let strongSelf = self, !value { - let _ = ApplicationSpecificNotice.setSecretChatInlineBotUsage(accountManager: strongSelf.context.sharedContext.accountManager).start() + let _ = ApplicationSpecificNotice.setSecretChatInlineBotUsage(accountManager: strongSelf.context.sharedContext.accountManager).startStandalone() strongSelf.present(textAlertController(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, title: nil, text: strongSelf.presentationData.strings.Conversation_SecretChatContextBotAlert, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {})]), in: .window(.root)) } }) @@ -12127,7 +12110,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G self.searchQuerySuggestionState?.1.dispose() var inScope = true var inScopeResult: ((ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult?)? - self.searchQuerySuggestionState = (updatedSearchQuerySuggestionState, (updatedSearchQuerySuggestionSignal |> deliverOnMainQueue).start(next: { [weak self] result in + self.searchQuerySuggestionState = (updatedSearchQuerySuggestionState, (updatedSearchQuerySuggestionSignal |> deliverOnMainQueue).startStrict(next: { [weak self] result in if let strongSelf = self { if Thread.isMainThread && inScope { inScope = false @@ -12188,7 +12171,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } } - self.urlPreviewQueryState = (updatedUrlPreviewUrl, (filteredPreviewSignal |> deliverOnMainQueue).start(next: { [weak self] (result) in + self.urlPreviewQueryState = (updatedUrlPreviewUrl, (filteredPreviewSignal |> deliverOnMainQueue).startStrict(next: { [weak self] (result) in if let strongSelf = self { if Thread.isMainThread && inScope { inScope = false @@ -12220,7 +12203,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G self.editingUrlPreviewQueryState?.1.dispose() var inScope = true var inScopeResult: ((TelegramMediaWebpage?) -> TelegramMediaWebpage?)? - self.editingUrlPreviewQueryState = (updatedEditingUrlPreviewUrl, (updatedEditingUrlPreviewSignal |> deliverOnMainQueue).start(next: { [weak self] result in + self.editingUrlPreviewQueryState = (updatedEditingUrlPreviewUrl, (updatedEditingUrlPreviewSignal |> deliverOnMainQueue).startStrict(next: { [weak self] result in if let strongSelf = self { if Thread.isMainThread && inScope { inScope = false @@ -12488,7 +12471,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G 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: { self?.chatDisplayNode.historyNode.historyAppearsCleared = false }) return true @@ -12528,7 +12511,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G return (false, false) } } - |> deliverOnMainQueue).start(next: { [weak self] parameters in + |> deliverOnMainQueue).startStandalone(next: { [weak self] parameters in guard let strongSelf = self else { return } @@ -12764,7 +12747,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G case let .peer(peerView): self.navigationActionDisposable.set((peerView.get() |> take(1) - |> deliverOnMainQueue).start(next: { [weak self] peerView in + |> deliverOnMainQueue).startStrict(next: { [weak self] peerView in if let strongSelf = self, let peer = peerView.peers[peerView.peerId], peer.restrictionText(platform: "ios", contentSettings: strongSelf.context.currentContentSettings.with { $0 }) == nil && !strongSelf.presentationInterfaceState.isNotAccessible { if peer.id == strongSelf.context.account.peerId { if let peer = strongSelf.presentationInterfaceState.renderedPeer?.chatMainPeer, let infoController = strongSelf.context.sharedContext.makePeerInfoController(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, peer: peer, mode: .generic, avatarInitiallyExpanded: false, fromChat: true, requestsContext: nil) { @@ -12814,14 +12797,14 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G case let .peer(peerView): self.navigationActionDisposable.set((peerView.get() |> take(1) - |> deliverOnMainQueue).start(next: { [weak self] peerView in + |> deliverOnMainQueue).startStrict(next: { [weak self] peerView in guard let strongSelf = self, let peer = peerView.peers[peerView.peerId] else { return } let peerId = peer.id let _ = (strongSelf.context.engine.resources.collectCacheUsageStats(peerId: peer.id) - |> deliverOnMainQueue).start(next: { [weak self, weak controller] result in + |> deliverOnMainQueue).startStandalone(next: { [weak self, weak controller] result in controller?.dismiss() guard let strongSelf = self, case let .result(stats) = result, let categories = stats.media[peer.id] else { @@ -12956,7 +12939,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } |> runOn(Queue.mainQueue()) |> delay(0.15, queue: Queue.mainQueue()) - let progressDisposable = progressSignal.start() + let progressDisposable = progressSignal.startStrict() signal = signal |> afterDisposed { @@ -12968,7 +12951,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G disposable.set(nil) } disposable.set((signal - |> deliverOnMainQueue).start(completed: { [weak self] in + |> deliverOnMainQueue).startStrict(completed: { [weak self] in if let strongSelf = self, let _ = strongSelf.validLayout { strongSelf.present(UndoOverlayController(presentationData: presentationData, content: .succeed(text: presentationData.strings.ClearCache_Success("\(dataSizeString(selectedSize, formatting: DataSizeStringFormatting(presentationData: presentationData)))", stringForDeviceType()).string, timeout: nil), elevatedLayout: false, action: { _ in return false }), in: .current) } @@ -13039,7 +13022,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G private func editMessageMediaWithLegacySignals(_ signals: [Any]) { let _ = (legacyAssetPickerEnqueueMessages(context: self.context, account: self.context.account, signals: signals) - |> deliverOnMainQueue).start(next: { [weak self] messages in + |> deliverOnMainQueue).startStandalone(next: { [weak self] messages in self?.editMessageMediaWithMessages(messages.map { $0.message }) }) } @@ -13069,7 +13052,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G let entry = transaction.getSharedData(ApplicationSpecificSharedDataKeys.generatedMediaStoreSettings)?.get(GeneratedMediaStoreSettings.self) return entry ?? GeneratedMediaStoreSettings.defaultSettings } - |> deliverOnMainQueue).start(next: { [weak self] settings in + |> deliverOnMainQueue).startStandalone(next: { [weak self] settings in guard let strongSelf = self, let peer = strongSelf.presentationInterfaceState.renderedPeer?.peer else { return } @@ -13214,7 +13197,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G |> afterDisposed { updateProgress() }) - |> deliverOnMainQueue).start(next: { [weak self] url in + |> deliverOnMainQueue).startStrict(next: { [weak self] url in guard let strongSelf = self else { return } @@ -13272,7 +13255,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G |> `catch` { _ -> Signal in return .single(nil) } - ).start(next: { [weak self] value, attachMenuBots, attachMenuBot in + ).startStandalone(next: { [weak self] value, attachMenuBots, attachMenuBot in guard let self else { return } @@ -13291,9 +13274,9 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G if let isAttachMenuBotInstalled, let attachMenuBot { if !isAttachMenuBotInstalled { let controller = webAppTermsAlertController(context: context, updatedPresentationData: self.updatedPresentationData, bot: attachMenuBot, completion: { allowWrite in - let _ = ApplicationSpecificNotice.setBotGameNotice(accountManager: context.sharedContext.accountManager, peerId: botPeer.id).start() + let _ = ApplicationSpecificNotice.setBotGameNotice(accountManager: context.sharedContext.accountManager, peerId: botPeer.id).startStandalone() let _ = (context.engine.messages.addBotToAttachMenu(botId: botPeer.id, allowWrite: allowWrite) - |> deliverOnMainQueue).start(error: { _ in + |> deliverOnMainQueue).startStandalone(error: { _ in }, completed: { openBotApp(allowWrite, true) }) @@ -13304,7 +13287,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } } else { let controller = webAppLaunchConfirmationController(context: context, updatedPresentationData: self.updatedPresentationData, peer: botPeer, requestWriteAccess: botApp.flags.contains(.notActivated) && botApp.flags.contains(.requiresWriteAccess), completion: { allowWrite in - let _ = ApplicationSpecificNotice.setBotGameNotice(accountManager: context.sharedContext.accountManager, peerId: botPeer.id).start() + let _ = ApplicationSpecificNotice.setBotGameNotice(accountManager: context.sharedContext.accountManager, peerId: botPeer.id).startStandalone() openBotApp(allowWrite, false) }, showMore: { [weak self] in if let self { @@ -13474,7 +13457,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G premiumGiftOptions = [] } - let _ = combineLatest(queue: Queue.mainQueue(), buttons, dataSettings).start(next: { [weak self] buttonsAndInitialButton, dataSettings in + let _ = combineLatest(queue: Queue.mainQueue(), buttons, dataSettings).startStandalone(next: { [weak self] buttonsAndInitialButton, dataSettings in guard let strongSelf = self else { return } @@ -13506,10 +13489,10 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G strongSelf.present(UndoOverlayController(presentationData: presentationData, content: content, elevatedLayout: false, position: .top, action: { _ in return false }), in: .current) } else { let _ = (context.engine.messages.getAttachMenuBot(botId: botId) - |> deliverOnMainQueue).start(next: { bot in + |> deliverOnMainQueue).startStandalone(next: { bot in let controller = webAppTermsAlertController(context: context, updatedPresentationData: strongSelf.updatedPresentationData, bot: bot, completion: { allowWrite in let _ = (context.engine.messages.addBotToAttachMenu(botId: botId, allowWrite: allowWrite) - |> deliverOnMainQueue).start(error: { _ in + |> deliverOnMainQueue).startStandalone(error: { _ in }, completed: { strongSelf.presentAttachmentBot(botId: botId, payload: botPayload, justInstalled: true) @@ -13596,7 +13579,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } let message: EnqueueMessage = .message(text: "", attributes: [], inlineStickers: [:], mediaReference: mediaReference, replyToMessageId: nil, replyToStoryId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: []) let _ = (enqueueMessages(account: strongSelf.context.account, peerId: peerId, messages: strongSelf.transformEnqueueMessages([message])) - |> deliverOnMainQueue).start(next: { [weak self] _ in + |> deliverOnMainQueue).startStandalone(next: { [weak self] _ in if let strongSelf = self, strongSelf.presentationInterfaceState.subject != .scheduledMessages { strongSelf.chatDisplayNode.historyNode.scrollToEndOfHistory() } @@ -13623,7 +13606,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G selfPeerId = strongSelf.context.account.peerId } let _ = (strongSelf.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: selfPeerId)) - |> deliverOnMainQueue).start(next: { [weak self] selfPeer in + |> deliverOnMainQueue).startStandalone(next: { [weak self] selfPeer in guard let strongSelf = self, let selfPeer = selfPeer else { return } @@ -13659,7 +13642,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G contactsController.navigationPresentation = .modal completion(contactsController, contactsController.mediaPickerContext) strongSelf.controllerNavigationDisposable.set((contactsController.result - |> deliverOnMainQueue).start(next: { [weak self] peers in + |> deliverOnMainQueue).startStrict(next: { [weak self] peers in if let strongSelf = self, let (peers, _, silent, scheduleTime, text) = peers { var textEnqueueMessage: EnqueueMessage? if let text = text, text.length > 0 { @@ -13753,7 +13736,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } } strongSelf.controllerNavigationDisposable.set((dataSignal - |> deliverOnMainQueue).start(next: { peerAndContactData in + |> deliverOnMainQueue).startStrict(next: { peerAndContactData in if let strongSelf = self, let contactData = peerAndContactData.1, contactData.basicData.phoneNumbers.count != 0 { if contactData.isPrimitive { let phone = contactData.basicData.phoneNumbers[0].value @@ -13829,7 +13812,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G completion(controller, controller.mediaPickerContext) strongSelf.controllerNavigationDisposable.set(nil) - let _ = ApplicationSpecificNotice.incrementDismissedPremiumGiftSuggestion(accountManager: context.sharedContext.accountManager, peerId: peer.id).start() + let _ = ApplicationSpecificNotice.incrementDismissedPremiumGiftSuggestion(accountManager: context.sharedContext.accountManager, peerId: peer.id).startStandalone() } case let .app(bot): var payload: String? @@ -13902,7 +13885,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G let entry = transaction.getSharedData(ApplicationSpecificSharedDataKeys.generatedMediaStoreSettings)?.get(GeneratedMediaStoreSettings.self) return entry ?? GeneratedMediaStoreSettings.defaultSettings } - |> deliverOnMainQueue).start(next: { [weak self] settings in + |> deliverOnMainQueue).startStandalone(next: { [weak self] settings in guard let strongSelf = self, let peer = strongSelf.presentationInterfaceState.renderedPeer?.peer else { return } @@ -14179,7 +14162,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G strongSelf.present(legacyController, in: .window(.root)) controller.present(in: emptyController, sourceView: nil, animated: true) - let presentationDisposable = strongSelf.updatedPresentationData.1.start(next: { [weak controller] presentationData in + let presentationDisposable = strongSelf.updatedPresentationData.1.startStrict(next: { [weak controller] presentationData in if let controller = controller { controller.pallete = legacyMenuPaletteFromTheme(presentationData.theme, forceDark: false) } @@ -14206,7 +14189,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G TelegramEngine.EngineData.Item.Configuration.UserLimits(isPremium: false), TelegramEngine.EngineData.Item.Configuration.UserLimits(isPremium: true) ) - |> deliverOnMainQueue).start(next: { [weak self] result in + |> deliverOnMainQueue).startStandalone(next: { [weak self] result in guard let strongSelf = self else { return } @@ -14220,7 +14203,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G signals.append(iCloudFileDescription(url)) } strongSelf.enqueueMediaMessageDisposable.set((combineLatest(signals) - |> deliverOnMainQueue).start(next: { results in + |> deliverOnMainQueue).startStrict(next: { results in if let strongSelf = self { let replyMessageId = strongSelf.presentationInterfaceState.interfaceState.replyMessageId @@ -14409,7 +14392,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } } |> switchToLatest - |> deliverOnMainQueue).start(next: { [weak self] settings, searchBotsConfiguration in + |> deliverOnMainQueue).startStandalone(next: { [weak self] settings, searchBotsConfiguration in guard let strongSelf = self, let peer = strongSelf.presentationInterfaceState.renderedPeer?.peer else { return } @@ -14421,7 +14404,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G slowModeEnabled = true } - let _ = legacyAssetPicker(context: strongSelf.context, presentationData: strongSelf.presentationData, editingMedia: editingMedia, fileMode: fileMode, peer: peer, threadTitle: strongSelf.threadInfo?.title, saveEditedPhotos: settings.storeEditedPhotos, allowGrouping: true, selectionLimit: selectionLimit).start(next: { generator in + let _ = legacyAssetPicker(context: strongSelf.context, presentationData: strongSelf.presentationData, editingMedia: editingMedia, fileMode: fileMode, peer: peer, threadTitle: strongSelf.threadInfo?.title, saveEditedPhotos: settings.storeEditedPhotos, allowGrouping: true, selectionLimit: selectionLimit).startStandalone(next: { generator in if let strongSelf = self { let legacyController = LegacyController(presentation: fileMode ? .navigation : .custom, theme: strongSelf.presentationData.theme, initialLayout: strongSelf.validLayout) legacyController.navigationPresentation = .modal @@ -14518,7 +14501,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } let _ = (self.context.engine.data.get(TelegramEngine.EngineData.Item.Configuration.SearchBots()) - |> deliverOnMainQueue).start(next: { [weak self] configuration in + |> deliverOnMainQueue).startStandalone(next: { [weak self] configuration in if let strongSelf = self { let controller = WebSearchController(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, peer: EnginePeer(peer), chatLocation: strongSelf.chatLocation, configuration: configuration, mode: .media(attachment: attachment, completion: { [weak self] results, selectionState, editingState, silentPosting in self?.attachmentController?.dismiss(animated: true, completion: nil) @@ -14639,7 +14622,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G selfPeerId = self.context.account.peerId } let _ = (self.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: selfPeerId)) - |> deliverOnMainQueue).start(next: { [weak self] selfPeer in + |> deliverOnMainQueue).startStandalone(next: { [weak self] selfPeer in guard let strongSelf = self, let selfPeer = selfPeer else { return } @@ -14672,7 +14655,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G self.chatDisplayNode.dismissInput() self.effectiveNavigationController?.pushViewController(contactsController) self.controllerNavigationDisposable.set((contactsController.result - |> deliverOnMainQueue).start(next: { [weak self] peers in + |> deliverOnMainQueue).startStrict(next: { [weak self] peers in if let strongSelf = self, let (peers, _, _, _, _) = peers { if peers.count > 1 { var enqueueMessages: [EnqueueMessage] = [] @@ -14754,7 +14737,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } } strongSelf.controllerNavigationDisposable.set((dataSignal - |> deliverOnMainQueue).start(next: { peerAndContactData in + |> deliverOnMainQueue).startStrict(next: { peerAndContactData in if let strongSelf = self, let contactData = peerAndContactData.1, contactData.basicData.phoneNumbers.count != 0 { if contactData.isPrimitive { let phone = contactData.basicData.phoneNumbers[0].value @@ -14848,7 +14831,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G switch action { case .tap: 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.controllerInteraction?.openPeer(peer, .default, nil, .default) } @@ -14941,7 +14924,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G switch action { case .tap: 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.controllerInteraction?.openPeer(peer, .default, nil, .default) } @@ -15055,7 +15038,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G switch action { case .tap: 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.controllerInteraction?.openPeer(peer, .default, nil, .default) } @@ -15201,7 +15184,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G if let stickerPackReference = stickerPackReference { let _ = (self.context.engine.stickers.loadedStickerPack(reference: stickerPackReference, forceActualized: false) - |> deliverOnMainQueue).start(next: { [weak self] stickerPack in + |> deliverOnMainQueue).startStandalone(next: { [weak self] stickerPack in if let strongSelf = self, case let .result(info, _, _) = stickerPack { strongSelf.present(UndoOverlayController(presentationData: strongSelf.presentationData, content: .sticker(context: strongSelf.context, file: file, loop: true, title: info.title, text: strongSelf.presentationData.strings.Stickers_PremiumPackInfoText, undoText: strongSelf.presentationData.strings.Stickers_PremiumPackView, customAction: nil), elevatedLayout: false, action: { [weak self] action in if let strongSelf = self, action == .undo { @@ -15253,7 +15236,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G self.presentEmojiList(references: [stickerPackReference]) /*let _ = (self.context.engine.stickers.loadedStickerPack(reference: stickerPackReference, forceActualized: false) - |> deliverOnMainQueue).start(next: { [weak self] stickerPack in + |> deliverOnMainQueue).startStandalone(next: { [weak self] stickerPack in if let strongSelf = self, case let .result(info, _, _) = stickerPack { strongSelf.present(UndoOverlayController(presentationData: strongSelf.presentationData, content: .sticker(context: strongSelf.context, file: file, loop: true, title: nil, text: strongSelf.presentationData.strings.Stickers_EmojiPackInfoText(info.title).string, undoText: strongSelf.presentationData.strings.Stickers_PremiumPackView, customAction: nil), elevatedLayout: false, action: { [weak self] action in if let strongSelf = self, action == .undo { @@ -15384,7 +15367,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G self.commitPurposefulAction() let _ = (enqueueMessages(account: self.context.account, peerId: peerId, messages: self.transformEnqueueMessages(messages)) - |> deliverOnMainQueue).start(next: { [weak self] _ in + |> deliverOnMainQueue).startStandalone(next: { [weak self] _ in if let strongSelf = self, strongSelf.presentationInterfaceState.subject != .scheduledMessages { strongSelf.chatDisplayNode.historyNode.scrollToEndOfHistory() } @@ -15404,7 +15387,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G private func enqueueMediaMessages(signals: [Any]?, silentPosting: Bool, scheduleTime: Int32? = nil, getAnimatedTransitionSource: ((String) -> UIView?)? = nil, completion: @escaping () -> Void = {}) { self.enqueueMediaMessageDisposable.set((legacyAssetPickerEnqueueMessages(context: self.context, account: self.context.account, signals: signals!) - |> deliverOnMainQueue).start(next: { [weak self] items in + |> deliverOnMainQueue).startStrict(next: { [weak self] items in if let strongSelf = self { var completionImpl: (() -> Void)? = completion @@ -15522,7 +15505,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G let entry = transaction.getSharedData(ApplicationSpecificSharedDataKeys.generatedMediaStoreSettings)?.get(GeneratedMediaStoreSettings.self) return entry ?? GeneratedMediaStoreSettings.defaultSettings } - |> deliverOnMainQueue).start(next: { [weak self] settings in + |> deliverOnMainQueue).startStandalone(next: { [weak self] settings in if let strongSelf = self, let peer = strongSelf.presentationInterfaceState.renderedPeer?.peer { strongSelf.chatDisplayNode.dismissInput() let controller = mediaPasteboardScreen( @@ -15546,7 +15529,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } private func enqueueGifData(_ data: Data) { - self.enqueueMediaMessageDisposable.set((legacyEnqueueGifMessage(account: self.context.account, data: data) |> deliverOnMainQueue).start(next: { [weak self] message in + self.enqueueMediaMessageDisposable.set((legacyEnqueueGifMessage(account: self.context.account, data: data) |> deliverOnMainQueue).startStrict(next: { [weak self] message in if let strongSelf = self { let replyMessageId = strongSelf.presentationInterfaceState.interfaceState.replyMessageId strongSelf.chatDisplayNode.setupSendActionOnViewUpdate({ @@ -15564,7 +15547,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } private func enqueueVideoData(_ data: Data) { - self.enqueueMediaMessageDisposable.set((legacyEnqueueGifMessage(account: self.context.account, data: data) |> deliverOnMainQueue).start(next: { [weak self] message in + self.enqueueMediaMessageDisposable.set((legacyEnqueueGifMessage(account: self.context.account, data: data) |> deliverOnMainQueue).startStrict(next: { [weak self] message in if let strongSelf = self { let replyMessageId = strongSelf.presentationInterfaceState.interfaceState.replyMessageId strongSelf.chatDisplayNode.setupSendActionOnViewUpdate({ @@ -15583,7 +15566,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G private func enqueueStickerImage(_ image: UIImage, isMemoji: Bool) { let size = image.size.aspectFitted(CGSize(width: 512.0, height: 512.0)) - self.enqueueMediaMessageDisposable.set((convertToWebP(image: image, targetSize: size, targetBoundingSize: size, quality: 0.9) |> deliverOnMainQueue).start(next: { [weak self] data in + self.enqueueMediaMessageDisposable.set((convertToWebP(image: image, targetSize: size, targetBoundingSize: size, quality: 0.9) |> deliverOnMainQueue).startStrict(next: { [weak self] data in if let strongSelf = self, !data.isEmpty { let resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max)) strongSelf.context.account.postbox.mediaBox.storeResourceData(resource.id, data: data) @@ -15818,7 +15801,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G return panelState.withUpdatedMediaRecordingState(.waitingForPreview) } }) - let _ = (audioRecorderValue.takenRecordedData() |> deliverOnMainQueue).start(next: { [weak self] data in + let _ = (audioRecorderValue.takenRecordedData() |> deliverOnMainQueue).startStandalone(next: { [weak self] data in if let strongSelf = self, let data = data { if data.duration < 0.5 { strongSelf.recorderFeedback?.error() @@ -15845,7 +15828,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G case .send: self.chatDisplayNode.updateRecordedMediaDeleted(false) let _ = (audioRecorderValue.takenRecordedData() - |> deliverOnMainQueue).start(next: { [weak self] data in + |> deliverOnMainQueue).startStandalone(next: { [weak self] data in if let strongSelf = self, let data = data { if data.duration < 0.5 { strongSelf.recorderFeedback?.error() @@ -15997,7 +15980,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } let _ = (enqueueMessages(account: self.context.account, peerId: peerId, messages: transformedMessages) - |> deliverOnMainQueue).start(next: { [weak self] _ in + |> deliverOnMainQueue).startStandalone(next: { [weak self] _ in if let strongSelf = self, strongSelf.presentationInterfaceState.subject != .scheduledMessages { strongSelf.chatDisplayNode.historyNode.scrollToEndOfHistory() } @@ -16087,7 +16070,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G }) searchDisposable.set((search - |> deliverOnMainQueue).start(next: { [weak self] results, updatedState in + |> deliverOnMainQueue).startStrict(next: { [weak self] results, updatedState in guard let strongSelf = self else { return } @@ -16135,7 +16118,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } searchDisposable.set((self.context.engine.messages.searchMessages(location: searchState.location, query: searchState.query, state: loadMoreState, limit: limit) |> delay(0.2, queue: Queue.mainQueue()) - |> deliverOnMainQueue).start(next: { [weak self] results, updatedState in + |> deliverOnMainQueue).startStrict(next: { [weak self] results, updatedState in guard let strongSelf = self else { return } @@ -16213,11 +16196,11 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G progressDisposable.dispose() } } - |> deliverOnMainQueue).start(next: { index in + |> deliverOnMainQueue).startStrict(next: { index in if index.1 { if !progressStarted { progressStarted = true - progressDisposable.set(progressSignal.start()) + progressDisposable.set(progressSignal.startStrict()) } } }, completed: { [weak self] in @@ -16277,11 +16260,11 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G progressDisposable.dispose() } } - |> deliverOnMainQueue).start(next: { index in + |> deliverOnMainQueue).startStrict(next: { index in if index.1 { if !progressStarted { progressStarted = true - progressDisposable.set(progressSignal.start()) + progressDisposable.set(progressSignal.startStrict()) } } }, completed: { [weak self] in @@ -16354,7 +16337,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G return } - strongSelf.messageIndexDisposable.set((strongSelf.context.engine.messages.searchMessageIdByTimestamp(peerId: peerId, threadId: threadId, timestamp: timestamp) |> deliverOnMainQueue).start(next: { messageId in + strongSelf.messageIndexDisposable.set((strongSelf.context.engine.messages.searchMessageIdByTimestamp(peerId: peerId, threadId: threadId, timestamp: timestamp) |> deliverOnMainQueue).startStrict(next: { messageId in if let strongSelf = self { strongSelf.loadingMessage.set(.single(nil)) if let messageId = messageId { @@ -16391,7 +16374,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G return } - strongSelf.messageIndexDisposable.set((strongSelf.context.engine.messages.searchMessageIdByTimestamp(peerId: peerId, threadId: threadId, timestamp: timestamp) |> deliverOnMainQueue).start(next: { messageId in + strongSelf.messageIndexDisposable.set((strongSelf.context.engine.messages.searchMessageIdByTimestamp(peerId: peerId, threadId: threadId, timestamp: timestamp) |> deliverOnMainQueue).startStrict(next: { messageId in if let strongSelf = self { strongSelf.loadingMessage.set(.single(nil)) if let messageId = messageId { @@ -16518,14 +16501,14 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G |> runOn(.mainQueue()) let progress = (progressSignal - |> delay(0.15, queue: .mainQueue())).start() + |> delay(0.15, queue: .mainQueue())).startStrict() self.navigationActionDisposable.set((ChatControllerImpl.openMessageReplies(context: self.context, updatedPresentationData: self.updatedPresentationData, navigationController: navigationController, present: { [weak self] c, a in self?.present(c, in: .window(.root), with: a) }, messageId: messageId, isChannelPost: isChannelPost, atMessage: atMessageId, displayModalProgress: displayModalProgress) |> afterDisposed { progress.dispose() - }).start()) + }).startStrict()) }) } @@ -16543,7 +16526,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } let disposable = (fetchAndPreloadReplyThreadInfo(context: context, subject: isChannelPost ? .channelPost(messageId) : .groupMessage(messageId), atMessageId: atMessageId, preload: true) - |> deliverOnMainQueue).start(next: { [weak statusController] result in + |> deliverOnMainQueue).startStrict(next: { [weak statusController] result in if displayModalProgress { statusController?.dismiss() } @@ -16619,7 +16602,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G self.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: messageId.peerId)), self.context.engine.messages.getMessagesLoadIfNecessary([messageId], strategy: .local) ) - |> deliverOnMainQueue).start(next: { [weak self] peer, messages in + |> deliverOnMainQueue).startStandalone(next: { [weak self] peer, messages in guard let self, let peer = peer else { return } @@ -16642,7 +16625,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G TelegramEngine.EngineData.Item.Peer.Peer(id: messageId.peerId), TelegramEngine.EngineData.Item.Messages.Message(id: messageId) ) - |> deliverOnMainQueue).start(next: { [weak self] peer, message in + |> deliverOnMainQueue).startStandalone(next: { [weak self] peer, message in guard let self, let peer = peer else { return } @@ -16771,7 +16754,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G progressDisposable.dispose() } } - |> deliverOnMainQueue).start(next: { [weak self] index in + |> deliverOnMainQueue).startStrict(next: { [weak self] index in if let strongSelf = self, let index = index.0 { strongSelf.chatDisplayNode.historyNode.scrollToMessage(from: scrollFromIndex, to: index, animated: animated, scrollPosition: scrollPosition) completion?() @@ -16827,14 +16810,14 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } } |> take(1) - self.messageIndexDisposable.set((signal |> deliverOnMainQueue).start(next: { [weak self] index in + self.messageIndexDisposable.set((signal |> deliverOnMainQueue).startStrict(next: { [weak self] index in if let strongSelf = self { if let index = index { strongSelf.chatDisplayNode.historyNode.scrollToMessage(from: fromIndex, to: index, animated: animated, scrollPosition: scrollPosition) completion?() } else { let _ = (strongSelf.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: messageLocation.peerId)) - |> deliverOnMainQueue).start(next: { peer in + |> deliverOnMainQueue).startStandalone(next: { peer in guard let strongSelf = self, let peer = peer else { return } @@ -16853,7 +16836,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G })) } else { let _ = (self.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: messageLocation.peerId)) - |> deliverOnMainQueue).start(next: { [weak self] peer in + |> deliverOnMainQueue).startStandalone(next: { [weak self] peer in guard let self, let peer = peer else { return } @@ -16873,7 +16856,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G let _ = (self.context.engine.data.get(EngineDataMap( messageIds.map(TelegramEngine.EngineData.Item.Messages.Message.init) )) - |> deliverOnMainQueue).start(next: { [weak self] messages in + |> deliverOnMainQueue).startStandalone(next: { [weak self] messages in self?.forwardMessages(messages: messages.values.compactMap { $0?._asMessage() }, options: options, resetCurrent: resetCurrent) }) } @@ -16947,7 +16930,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G 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] = messageIds.compactMap({ id -> Signal? in guard let id = id else { @@ -16967,7 +16950,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G strongSelf.shareStatusDisposable = MetaDisposable() } strongSelf.shareStatusDisposable?.set((combineLatest(signals) - |> deliverOnMainQueue).start()) + |> deliverOnMainQueue).startStrict()) } }) @@ -17065,7 +17048,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G strongSelf.present(UndoOverlayController(presentationData: presentationData, content: .forward(savedMessages: true, text: messages.count == 1 ? presentationData.strings.Conversation_ForwardTooltip_SavedMessages_One : presentationData.strings.Conversation_ForwardTooltip_SavedMessages_Many), elevatedLayout: false, animateInAsReplacement: true, action: { [weak self] value in if case .info = value, let strongSelf = self { let _ = (strongSelf.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: strongSelf.context.account.peerId)) - |> deliverOnMainQueue).start(next: { peer in + |> deliverOnMainQueue).startStandalone(next: { peer in guard let strongSelf = self, let peer = peer, let navigationController = strongSelf.effectiveNavigationController else { return } @@ -17080,7 +17063,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G let _ = (enqueueMessages(account: strongSelf.context.account, peerId: peerId, messages: messages.map { message -> EnqueueMessage in return .forward(source: message.id, threadId: nil, grouping: .auto, attributes: [], correlationId: nil) }) - |> deliverOnMainQueue).start(next: { messageIds in + |> deliverOnMainQueue).startStandalone(next: { messageIds in if let strongSelf = self { let signals: [Signal] = messageIds.compactMap({ id -> Signal? in guard let id = id else { @@ -17100,7 +17083,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G strongSelf.shareStatusDisposable = MetaDisposable() } strongSelf.shareStatusDisposable?.set((combineLatest(signals) - |> deliverOnMainQueue).start()) + |> deliverOnMainQueue).startStrict()) } }) strongSelf.updateChatPresentationInterfaceState(animated: false, interactive: true, { $0.updatedInterfaceState({ $0.withoutSelectionState() }) }) @@ -17128,7 +17111,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G let _ = (ChatInterfaceState.update(engine: strongSelf.context.engine, peerId: peerId, threadId: threadId, { currentState in return currentState.withUpdatedForwardMessageIds(messages.map { $0.id }).withUpdatedForwardOptionsState(ChatInterfaceForwardOptionsState(hideNames: !hasNotOwnMessages, hideCaptions: false, unhideNamesOnCaptionChange: false)) }) - |> deliverOnMainQueue).start(completed: { + |> deliverOnMainQueue).startStandalone(completed: { if let strongSelf = self { let proceed: (ChatController) -> Void = { chatController in strongSelf.updateChatPresentationInterfaceState(animated: false, interactive: true, { $0.updatedInterfaceState({ $0.withoutSelectionState() }) }) @@ -17152,7 +17135,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G strongSelf.controllerNavigationDisposable.set((chatController.ready.get() |> SwiftSignalKit.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) })) @@ -17160,7 +17143,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } 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 { @@ -17218,7 +17201,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } else { peerSignal = self.context.account.postbox.loadedPeerWithId(peer.id) |> map(Optional.init) } - 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 { var mode: PeerInfoControllerMode = .generic if let _ = fromMessage, let chatPeerId = chatPeerId { @@ -17244,7 +17227,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G let _ = (ChatInterfaceState.update(engine: self.context.engine, peerId: peer.id, threadId: nil, { currentState in return currentState.withUpdatedComposeInputState(textInputState) }) - |> deliverOnMainQueue).start(completed: { [weak self] in + |> deliverOnMainQueue).startStandalone(completed: { [weak self] in if let strongSelf = self, let navigationController = strongSelf.effectiveNavigationController { strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(peer), subject: subject, updateTextInputState: textInputState, peekData: peekData)) } @@ -17292,7 +17275,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G let _ = (ChatInterfaceState.update(engine: strongSelf.context.engine, peerId: peerId, threadId: threadId, { currentState in return currentState.withUpdatedComposeInputState(textInputState) }) - |> deliverOnMainQueue).start(completed: { + |> deliverOnMainQueue).startStandalone(completed: { if let strongSelf = self { strongSelf.updateChatPresentationInterfaceState(animated: false, interactive: true, { $0.updatedInterfaceState({ $0.withoutSelectionState() }) }) @@ -17305,7 +17288,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G strongSelf.controllerNavigationDisposable.set((chatController.ready.get() |> filter { $0 } |> take(1) - |> deliverOnMainQueue).start(next: { _ in + |> deliverOnMainQueue).startStrict(next: { _ in if let strongController = controller { strongController.dismiss() } @@ -17470,7 +17453,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G strongSelf.startBot(strongSelf.presentationInterfaceState.botStartPayload) } } - })).start()) + })).startStrict()) } private func reportPeer() { @@ -17532,15 +17515,15 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G guard let strongSelf = self else { return } - let _ = strongSelf.context.engine.privacy.requestUpdatePeerIsBlocked(peerId: peer.id, isBlocked: true).start() + let _ = strongSelf.context.engine.privacy.requestUpdatePeerIsBlocked(peerId: peer.id, isBlocked: true).startStandalone() if let _ = chatPeer as? TelegramSecretChat { - let _ = strongSelf.context.engine.peers.terminateSecretChat(peerId: chatPeer.id, requestRemoteHistoryRemoval: true).start() + let _ = strongSelf.context.engine.peers.terminateSecretChat(peerId: chatPeer.id, requestRemoteHistoryRemoval: true).startStandalone() } if deleteChat { - let _ = strongSelf.context.engine.peers.removePeerChat(peerId: chatPeer.id, reportChatSpam: reportSpam).start() + let _ = strongSelf.context.engine.peers.removePeerChat(peerId: chatPeer.id, reportChatSpam: reportSpam).startStandalone() strongSelf.effectiveNavigationController?.filterController(strongSelf, animated: true) } else if reportSpam { - let _ = strongSelf.context.engine.peers.reportPeer(peerId: peer.id, reason: .spam, message: "").start() + let _ = strongSelf.context.engine.peers.reportPeer(peerId: peer.id, reason: .spam, message: "").startStandalone() } }) ] as [ActionSheetItem]) @@ -17591,7 +17574,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G private func shareAccountContact() { let _ = (self.context.account.postbox.loadedPeerWithId(self.context.account.peerId) - |> deliverOnMainQueue).start(next: { [weak self] accountPeer in + |> deliverOnMainQueue).startStandalone(next: { [weak self] accountPeer in guard let strongSelf = self else { return } @@ -17611,7 +17594,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G return } let _ = (strongSelf.context.engine.contacts.acceptAndShareContact(peerId: peer.id) - |> deliverOnMainQueue).start(error: { _ in + |> deliverOnMainQueue).startStandalone(error: { _ in guard let strongSelf = self else { return } @@ -17664,7 +17647,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G |> afterDisposed({ Queue.mainQueue().async { } - })).start()) + })).startStrict()) } private func deleteChat(reportChatSpam: Bool) { @@ -17673,10 +17656,10 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } self.commitPurposefulAction() self.chatDisplayNode.historyNode.disconnect() - let _ = self.context.engine.peers.removePeerChat(peerId: peerId, reportChatSpam: reportChatSpam).start() + let _ = self.context.engine.peers.removePeerChat(peerId: peerId, reportChatSpam: reportChatSpam).startStandalone() self.effectiveNavigationController?.popToRoot(animated: true) - let _ = self.context.engine.privacy.requestUpdatePeerIsBlocked(peerId: peerId, isBlocked: true).start() + let _ = self.context.engine.privacy.requestUpdatePeerIsBlocked(peerId: peerId, isBlocked: true).startStandalone() } private func startBot(_ payload: String?) { @@ -17688,7 +17671,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G startingBot.set(true) self.editMessageDisposable.set((self.context.engine.messages.requestStartBot(botPeerId: peerId, payload: payload) |> deliverOnMainQueue |> afterDisposed({ startingBot.set(false) - })).start(completed: { [weak self] in + })).startStrict(completed: { [weak self] in if let strongSelf = self { strongSelf.updateChatPresentationInterfaceState(animated: true, interactive: true, { $0.updatedBotStartPayload(nil) }) } @@ -17737,7 +17720,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G dismissWebAppContollers() strongSelf.navigationActionDisposable.set((strongSelf.context.account.postbox.loadedPeerWithId(peerId.id) |> take(1) - |> deliverOnMainQueue).start(next: { [weak self] peer in + |> deliverOnMainQueue).startStrict(next: { [weak self] peer in if let strongSelf = self, peer.restrictionText(platform: "ios", contentSettings: strongSelf.context.currentContentSettings.with { $0 }) == nil { if let infoController = strongSelf.context.sharedContext.makePeerInfoController(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, peer: peer, mode: .generic, avatarInitiallyExpanded: false, fromChat: false, requestsContext: nil) { strongSelf.effectiveNavigationController?.pushViewController(infoController) @@ -17760,8 +17743,8 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } commit() case let .withBotApp(botAppStart): - let _ = (strongSelf.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId.id)) - |> deliverOnMainQueue).start(next: { [weak self] peer in + let _ = (strongSelf.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId.id)) + |> deliverOnMainQueue).startStrict(next: { [weak self] peer in if let strongSelf = self, let peer { strongSelf.presentBotApp(botApp: botAppStart.botApp, botPeer: peer, payload: botAppStart.payload, concealed: concealed, commit: { dismissWebAppContollers() @@ -17821,7 +17804,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } do { self.navigationActionDisposable.set((self.context.engine.peers.fetchChannelParticipant(peerId: peerId, participantId: author.id) - |> deliverOnMainQueue).start(next: { [weak self] participant in + |> deliverOnMainQueue).startStrict(next: { [weak self] participant in if let strongSelf = self { let canBan = participant?.canBeBannedBy(peerId: accountPeerId) ?? true @@ -17874,13 +17857,13 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G if let strongSelf = self { strongSelf.updateChatPresentationInterfaceState(animated: true, interactive: true, { $0.updatedInterfaceState { $0.withoutSelectionState() } }) if actions.contains(3) { - let _ = strongSelf.context.engine.messages.deleteAllMessagesWithAuthor(peerId: peerId, authorId: author.id, namespace: Namespaces.Message.Cloud).start() - let _ = strongSelf.context.engine.messages.clearAuthorHistory(peerId: peerId, memberId: author.id).start() + let _ = strongSelf.context.engine.messages.deleteAllMessagesWithAuthor(peerId: peerId, authorId: author.id, namespace: Namespaces.Message.Cloud).startStandalone() + let _ = strongSelf.context.engine.messages.clearAuthorHistory(peerId: peerId, memberId: author.id).startStandalone() } else if actions.contains(0) { - let _ = strongSelf.context.engine.messages.deleteMessagesInteractively(messageIds: Array(messageIds), type: .forEveryone).start() + let _ = strongSelf.context.engine.messages.deleteMessagesInteractively(messageIds: Array(messageIds), type: .forEveryone).startStandalone() } if actions.contains(1) { - let _ = strongSelf.context.engine.peers.removePeerMember(peerId: peerId, memberId: author.id).start() + let _ = strongSelf.context.engine.peers.removePeerMember(peerId: peerId, memberId: author.id).startStandalone() } } })) @@ -17915,7 +17898,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G actionSheet?.dismissAnimated() if let strongSelf = self { strongSelf.updateChatPresentationInterfaceState(animated: true, interactive: true, { $0.updatedInterfaceState { $0.withoutSelectionState() } }) - let _ = strongSelf.context.engine.messages.deleteMessagesInteractively(messageIds: Array(messageIds), type: .forEveryone).start() + let _ = strongSelf.context.engine.messages.deleteMessagesInteractively(messageIds: Array(messageIds), type: .forEveryone).startStandalone() } })) } @@ -17942,7 +17925,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G contextItems.append(.action(ContextMenuActionItem(text: globalTitle, textColor: .destructive, icon: { _ in nil }, action: { [weak self] _, f in if let strongSelf = self { strongSelf.updateChatPresentationInterfaceState(animated: true, interactive: true, { $0.updatedInterfaceState { $0.withoutSelectionState() } }) - let _ = strongSelf.context.engine.messages.deleteMessagesInteractively(messageIds: Array(messageIds), type: .forEveryone).start() + let _ = strongSelf.context.engine.messages.deleteMessagesInteractively(messageIds: Array(messageIds), type: .forEveryone).startStandalone() f(.dismissWithoutContent) } }))) @@ -17950,7 +17933,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G actionSheet?.dismissAnimated() if let strongSelf = self { strongSelf.updateChatPresentationInterfaceState(animated: true, interactive: true, { $0.updatedInterfaceState { $0.withoutSelectionState() } }) - let _ = strongSelf.context.engine.messages.deleteMessagesInteractively(messageIds: Array(messageIds), type: .forEveryone).start() + let _ = strongSelf.context.engine.messages.deleteMessagesInteractively(messageIds: Array(messageIds), type: .forEveryone).startStandalone() } })) } @@ -17972,7 +17955,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G contextItems.append(.action(ContextMenuActionItem(text: localOptionText, textColor: .destructive, icon: { _ in nil }, action: { [weak self] _, f in if let strongSelf = self { strongSelf.updateChatPresentationInterfaceState(animated: true, interactive: true, { $0.updatedInterfaceState { $0.withoutSelectionState() } }) - let _ = strongSelf.context.engine.messages.deleteMessagesInteractively(messageIds: Array(messageIds), type: unsendPersonalMessages ? .forEveryone : .forLocalPeer).start() + let _ = strongSelf.context.engine.messages.deleteMessagesInteractively(messageIds: Array(messageIds), type: unsendPersonalMessages ? .forEveryone : .forLocalPeer).startStandalone() f(.dismissWithoutContent) } }))) @@ -17980,7 +17963,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G actionSheet?.dismissAnimated() if let strongSelf = self { strongSelf.updateChatPresentationInterfaceState(animated: true, interactive: true, { $0.updatedInterfaceState { $0.withoutSelectionState() } }) - let _ = strongSelf.context.engine.messages.deleteMessagesInteractively(messageIds: Array(messageIds), type: unsendPersonalMessages ? .forEveryone : .forLocalPeer).start() + let _ = strongSelf.context.engine.messages.deleteMessagesInteractively(messageIds: Array(messageIds), type: unsendPersonalMessages ? .forEveryone : .forLocalPeer).startStandalone() } })) } @@ -18185,11 +18168,11 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G self.sendingOptionsTooltipController?.dismiss() let _ = (ApplicationSpecificNotice.getSendWhenOnlineTip(accountManager: self.context.sharedContext.accountManager) - |> deliverOnMainQueue).start(next: { [weak self] counter in + |> deliverOnMainQueue).startStandalone(next: { [weak self] counter in if let strongSelf = self, counter < 3 { let _ = (strongSelf.context.account.viewTracker.peerView(peerId) |> take(1) - |> deliverOnMainQueue).start(next: { [weak self] peerView in + |> deliverOnMainQueue).startStandalone(next: { [weak self] peerView in guard let strongSelf = self, let peer = peerViewMainPeer(peerView) else { return } @@ -18206,7 +18189,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } if sendWhenOnlineAvailable { - let _ = ApplicationSpecificNotice.incrementSendWhenOnlineTip(accountManager: strongSelf.context.sharedContext.accountManager).start() + let _ = ApplicationSpecificNotice.incrementSendWhenOnlineTip(accountManager: strongSelf.context.sharedContext.accountManager).startStandalone() let tooltipController = TooltipController(content: .text(strongSelf.presentationData.strings.Conversation_SendWhenOnlineTooltip), baseFontSize: strongSelf.presentationData.listsFontSize.baseDisplaySize, timeout: 3.0, dismissByTapOutside: true, dismissImmediatelyOnLayoutUpdate: true, padding: 2.0) strongSelf.sendingOptionsTooltipController = tooltipController @@ -18708,7 +18691,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G self.updateSlowmodeStatusTimerValue = slowmodeActiveUntilTimestamp self.updateSlowmodeStatusDisposable.set((Signal.complete() |> suspendAwareDelay(Double(remainingTime), granularity: 1.0, queue: .mainQueue()) - |> deliverOnMainQueue).start(completed: { [weak self] in + |> deliverOnMainQueue).startStrict(completed: { [weak self] in guard let strongSelf = self else { return } @@ -18829,7 +18812,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G switch action { case .commit: let _ = (strongSelf.context.engine.messages.requestUnpinAllMessages(peerId: peerId, threadId: strongSelf.chatLocation.threadId) - |> deliverOnMainQueue).start(error: { _ in + |> deliverOnMainQueue).startStandalone(error: { _ in }, completed: { guard let strongSelf = self else { return @@ -18861,7 +18844,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } let _ = (self.context.account.viewTracker.peerView(peerId) |> take(1) - |> deliverOnMainQueue).start(next: { [weak self] peerView in + |> deliverOnMainQueue).startStandalone(next: { [weak self] peerView in guard let strongSelf = self, let peer = peerViewMainPeer(peerView) else { return } @@ -18928,7 +18911,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } let _ = (strongSelf.context.engine.peers.setChatMessageAutoremoveTimeoutInteractively(peerId: peer.id, timeout: value == 0 ? nil : value) - |> deliverOnMainQueue).start(completed: { + |> deliverOnMainQueue).startStandalone(completed: { guard let strongSelf = self else { return } @@ -19025,7 +19008,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } let _ = (combineLatest(queue: Queue.mainQueue(), self.chatThemeEmoticonPromise.get(), animatedEmojiStickers) - |> take(1)).start(next: { [weak self] themeEmoticon, animatedEmojiStickers in + |> take(1)).startStandalone(next: { [weak self] themeEmoticon, animatedEmojiStickers in guard let strongSelf = self, let peer = strongSelf.presentationInterfaceState.renderedPeer?.peer else { return } @@ -19119,17 +19102,17 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G guard let strongSelf = self, let peerId else { return } - let _ = strongSelf.context.engine.themes.setChatWallpaper(peerId: peerId, wallpaper: nil).start() + let _ = strongSelf.context.engine.themes.setChatWallpaper(peerId: peerId, wallpaper: nil).startStandalone() }, completion: { [weak self] emoticon in guard let strongSelf = self, let peerId else { return } if canResetWallpaper && emoticon != nil { - let _ = context.engine.themes.setChatWallpaper(peerId: peerId, wallpaper: nil).start() + let _ = context.engine.themes.setChatWallpaper(peerId: peerId, wallpaper: nil).startStandalone() } strongSelf.themeEmoticonAndDarkAppearancePreviewPromise.set(.single((emoticon ?? "", nil))) - let _ = context.engine.themes.setChatTheme(peerId: peerId, emoticon: emoticon).start(completed: { [weak self] in + let _ = context.engine.themes.setChatTheme(peerId: peerId, emoticon: emoticon).startStandalone(completed: { [weak self] in if let strongSelf = self { strongSelf.themeEmoticonAndDarkAppearancePreviewPromise.set(.single((nil, nil))) } @@ -19197,7 +19180,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } itemsAndIndices.sort(by: { $0.2 < $1.2 }) for (info, items, index) in itemsAndIndices.reversed() { - let _ = context.engine.stickers.addStickerPackInteractively(info: info, items: items, positionInList: index).start() + let _ = context.engine.stickers.addStickerPackInteractively(info: info, items: items, positionInList: index).startStandalone() } } return true @@ -19213,7 +19196,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G case let .remove(positionInList): strongSelf.presentInGlobalOverlay(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 })) diff --git a/submodules/TelegramUI/Sources/ChatControllerNode.swift b/submodules/TelegramUI/Sources/ChatControllerNode.swift index 938dd8ae5b..1cf5007752 100644 --- a/submodules/TelegramUI/Sources/ChatControllerNode.swift +++ b/submodules/TelegramUI/Sources/ChatControllerNode.swift @@ -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 } diff --git a/submodules/TelegramUI/Sources/ChatEmptyNode.swift b/submodules/TelegramUI/Sources/ChatEmptyNode.swift index 7020896e47..6c7c7ffe6f 100644 --- a/submodules/TelegramUI/Sources/ChatEmptyNode.swift +++ b/submodules/TelegramUI/Sources/ChatEmptyNode.swift @@ -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 diff --git a/submodules/TelegramUI/Sources/ChatHistoryListNode.swift b/submodules/TelegramUI/Sources/ChatHistoryListNode.swift index 682fa385ef..ca7e55eb8e 100644 --- a/submodules/TelegramUI/Sources/ChatHistoryListNode.swift +++ b/submodules/TelegramUI/Sources/ChatHistoryListNode.swift @@ -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), chatLocation: ChatLocation, chatLocationContextHolder: Atomic, tagMask: MessageTags?, source: ChatHistoryListSource = .default, subject: ChatControllerSubject?, controllerInteraction: ChatControllerInteraction, selectedMessages: Signal?, 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(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 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?, 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(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?), 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 = (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 - 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) { + 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 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) diff --git a/submodules/TelegramUI/Sources/ChatHistoryLocation.swift b/submodules/TelegramUI/Sources/ChatHistoryLocation.swift deleted file mode 100644 index 267303fa00..0000000000 --- a/submodules/TelegramUI/Sources/ChatHistoryLocation.swift +++ /dev/null @@ -1,5 +0,0 @@ -import Postbox -import UIKit -import Display - - diff --git a/submodules/TelegramUI/Sources/ChatHistorySearchContainerNode.swift b/submodules/TelegramUI/Sources/ChatHistorySearchContainerNode.swift index 470f874842..fd150168c3 100644 --- a/submodules/TelegramUI/Sources/ChatHistorySearchContainerNode.swift +++ b/submodules/TelegramUI/Sources/ChatHistorySearchContainerNode.swift @@ -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))) diff --git a/submodules/TelegramUI/Sources/ChatInfo.swift b/submodules/TelegramUI/Sources/ChatInfo.swift deleted file mode 100644 index 2e6de9bead..0000000000 --- a/submodules/TelegramUI/Sources/ChatInfo.swift +++ /dev/null @@ -1,6 +0,0 @@ -import Foundation -import Postbox -import TelegramCore -import Display -import AccountContext - diff --git a/submodules/TelegramUI/Sources/ChatInstantVideoMessageDurationNode.swift b/submodules/TelegramUI/Sources/ChatInstantVideoMessageDurationNode.swift index 0387adf15b..64e726819e 100644 --- a/submodules/TelegramUI/Sources/ChatInstantVideoMessageDurationNode.swift +++ b/submodules/TelegramUI/Sources/ChatInstantVideoMessageDurationNode.swift @@ -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 } diff --git a/submodules/TelegramUI/Sources/ChatInterfaceInputContexts.swift b/submodules/TelegramUI/Sources/ChatInterfaceInputContexts.swift index b662dad3c7..86b6179f78 100644 --- a/submodules/TelegramUI/Sources/ChatInterfaceInputContexts.swift +++ b/submodules/TelegramUI/Sources/ChatInterfaceInputContexts.swift @@ -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 diff --git a/submodules/TelegramUI/Sources/ChatInterfaceStateContextMenus.swift b/submodules/TelegramUI/Sources/ChatInterfaceStateContextMenus.swift index f30d9c5106..f5295318d3 100644 --- a/submodules/TelegramUI/Sources/ChatInterfaceStateContextMenus.swift +++ b/submodules/TelegramUI/Sources/ChatInterfaceStateContextMenus.swift @@ -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 } diff --git a/submodules/TelegramUI/Sources/ChatInviteRequestsTitlePanelNode.swift b/submodules/TelegramUI/Sources/ChatInviteRequestsTitlePanelNode.swift index 50c9f7d6c3..acf983bd3e 100644 --- a/submodules/TelegramUI/Sources/ChatInviteRequestsTitlePanelNode.swift +++ b/submodules/TelegramUI/Sources/ChatInviteRequestsTitlePanelNode.swift @@ -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? { diff --git a/submodules/TelegramUI/Sources/ChatLinkPreview.swift b/submodules/TelegramUI/Sources/ChatLinkPreview.swift index 30bb9cccff..7dd4ac4884 100644 --- a/submodules/TelegramUI/Sources/ChatLinkPreview.swift +++ b/submodules/TelegramUI/Sources/ChatLinkPreview.swift @@ -21,7 +21,7 @@ func interactiveChatLinkPreviewsEnabled(accountManager: AccountManager 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) diff --git a/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift b/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift index f02d565b51..ccd35c446a 100644 --- a/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift @@ -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) } diff --git a/submodules/TelegramUI/Sources/ChatMessageDateHeader.swift b/submodules/TelegramUI/Sources/ChatMessageDateHeader.swift index 9e6e0ed637..c48afe8e2b 100644 --- a/submodules/TelegramUI/Sources/ChatMessageDateHeader.swift +++ b/submodules/TelegramUI/Sources/ChatMessageDateHeader.swift @@ -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() } } })) diff --git a/submodules/TelegramUI/Sources/ChatMessageInteractiveFileNode.swift b/submodules/TelegramUI/Sources/ChatMessageInteractiveFileNode.swift index 0fcf04717e..a7c93266b8 100644 --- a/submodules/TelegramUI/Sources/ChatMessageInteractiveFileNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageInteractiveFileNode.swift @@ -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 diff --git a/submodules/TelegramUI/Sources/ChatMessageInteractiveInstantVideoNode.swift b/submodules/TelegramUI/Sources/ChatMessageInteractiveInstantVideoNode.swift index dc621a2614..ab55076e46 100644 --- a/submodules/TelegramUI/Sources/ChatMessageInteractiveInstantVideoNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageInteractiveInstantVideoNode.swift @@ -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 } diff --git a/submodules/TelegramUI/Sources/ChatMessageInteractiveMediaNode.swift b/submodules/TelegramUI/Sources/ChatMessageInteractiveMediaNode.swift index 803997ee00..1c42d3c5cd 100644 --- a/submodules/TelegramUI/Sources/ChatMessageInteractiveMediaNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageInteractiveMediaNode.swift @@ -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 { diff --git a/submodules/TelegramUI/Sources/ChatMessageItemView.swift b/submodules/TelegramUI/Sources/ChatMessageItemView.swift index bfb83f0a95..83a14c8e01 100644 --- a/submodules/TelegramUI/Sources/ChatMessageItemView.swift +++ b/submodules/TelegramUI/Sources/ChatMessageItemView.swift @@ -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) } diff --git a/submodules/TelegramUI/Sources/ChatMessagePollBubbleContentNode.swift b/submodules/TelegramUI/Sources/ChatMessagePollBubbleContentNode.swift index 508370a227..1ebd825c24 100644 --- a/submodules/TelegramUI/Sources/ChatMessagePollBubbleContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessagePollBubbleContentNode.swift @@ -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 } diff --git a/submodules/TelegramUI/Sources/ChatMessageProfilePhotoSuggestionContentNode.swift b/submodules/TelegramUI/Sources/ChatMessageProfilePhotoSuggestionContentNode.swift index 08ccb9b37e..63db8c989d 100644 --- a/submodules/TelegramUI/Sources/ChatMessageProfilePhotoSuggestionContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageProfilePhotoSuggestionContentNode.swift @@ -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) diff --git a/submodules/TelegramUI/Sources/ChatMessageSelectionInputPanelNode.swift b/submodules/TelegramUI/Sources/ChatMessageSelectionInputPanelNode.swift index b72a27bf36..68799369fc 100644 --- a/submodules/TelegramUI/Sources/ChatMessageSelectionInputPanelNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageSelectionInputPanelNode.swift @@ -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 { diff --git a/submodules/TelegramUI/Sources/ChatMessageStickerItemNode.swift b/submodules/TelegramUI/Sources/ChatMessageStickerItemNode.swift index 18fb6c4d5e..c8d04374bf 100644 --- a/submodules/TelegramUI/Sources/ChatMessageStickerItemNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageStickerItemNode.swift @@ -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 diff --git a/submodules/TelegramUI/Sources/ChatMessageStoryMentionContentNode.swift b/submodules/TelegramUI/Sources/ChatMessageStoryMentionContentNode.swift index b693a284f9..b8fcbd37d0 100644 --- a/submodules/TelegramUI/Sources/ChatMessageStoryMentionContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageStoryMentionContentNode.swift @@ -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) diff --git a/submodules/TelegramUI/Sources/ChatMessageWallpaperBubbleContentNode.swift b/submodules/TelegramUI/Sources/ChatMessageWallpaperBubbleContentNode.swift index 759b4108a2..28bf565523 100644 --- a/submodules/TelegramUI/Sources/ChatMessageWallpaperBubbleContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageWallpaperBubbleContentNode.swift @@ -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) } diff --git a/submodules/TelegramUI/Sources/ChatPinnedMessageTitlePanelNode.swift b/submodules/TelegramUI/Sources/ChatPinnedMessageTitlePanelNode.swift index dd88f18de9..492b8e057f 100644 --- a/submodules/TelegramUI/Sources/ChatPinnedMessageTitlePanelNode.swift +++ b/submodules/TelegramUI/Sources/ChatPinnedMessageTitlePanelNode.swift @@ -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) } diff --git a/submodules/TelegramUI/Sources/ChatQrCodeScreen.swift b/submodules/TelegramUI/Sources/ChatQrCodeScreen.swift index d9351ad97a..4e342ba699 100644 --- a/submodules/TelegramUI/Sources/ChatQrCodeScreen.swift +++ b/submodules/TelegramUI/Sources/ChatQrCodeScreen.swift @@ -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 } diff --git a/submodules/TelegramUI/Sources/ChatRecentActionsController.swift b/submodules/TelegramUI/Sources/ChatRecentActionsController.swift index 803e1fc426..59e0b23261 100644 --- a/submodules/TelegramUI/Sources/ChatRecentActionsController.swift +++ b/submodules/TelegramUI/Sources/ChatRecentActionsController.swift @@ -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 diff --git a/submodules/TelegramUI/Sources/ChatRecentActionsControllerNode.swift b/submodules/TelegramUI/Sources/ChatRecentActionsControllerNode.swift index fd1e2c6d4b..ae11529790 100644 --- a/submodules/TelegramUI/Sources/ChatRecentActionsControllerNode.swift +++ b/submodules/TelegramUI/Sources/ChatRecentActionsControllerNode.swift @@ -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 = .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 diff --git a/submodules/TelegramUI/Sources/ChatRecentActionsFilterController.swift b/submodules/TelegramUI/Sources/ChatRecentActionsFilterController.swift index fbd1414348..f593ba2378 100644 --- a/submodules/TelegramUI/Sources/ChatRecentActionsFilterController.swift +++ b/submodules/TelegramUI/Sources/ChatRecentActionsFilterController.swift @@ -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) { diff --git a/submodules/TelegramUI/Sources/ChatRecordingPreviewInputPanelNode.swift b/submodules/TelegramUI/Sources/ChatRecordingPreviewInputPanelNode.swift index dd54726612..f71207b47d 100644 --- a/submodules/TelegramUI/Sources/ChatRecordingPreviewInputPanelNode.swift +++ b/submodules/TelegramUI/Sources/ChatRecordingPreviewInputPanelNode.swift @@ -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, _, _): diff --git a/submodules/TelegramUI/Sources/ChatSearchInputPanelNode.swift b/submodules/TelegramUI/Sources/ChatSearchInputPanelNode.swift index c142100215..5f8c39dff3 100644 --- a/submodules/TelegramUI/Sources/ChatSearchInputPanelNode.swift +++ b/submodules/TelegramUI/Sources/ChatSearchInputPanelNode.swift @@ -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() } } diff --git a/submodules/TelegramUI/Sources/ChatSearchNavigationContentNode.swift b/submodules/TelegramUI/Sources/ChatSearchNavigationContentNode.swift index b590793441..aded8da70e 100644 --- a/submodules/TelegramUI/Sources/ChatSearchNavigationContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatSearchNavigationContentNode.swift @@ -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 }) } diff --git a/submodules/TelegramUI/Sources/ChatSearchResultsContollerNode.swift b/submodules/TelegramUI/Sources/ChatSearchResultsContollerNode.swift index 44c423aa20..7507ddce47 100644 --- a/submodules/TelegramUI/Sources/ChatSearchResultsContollerNode.swift +++ b/submodules/TelegramUI/Sources/ChatSearchResultsContollerNode.swift @@ -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) diff --git a/submodules/TelegramUI/Sources/ChatSearchResultsController.swift b/submodules/TelegramUI/Sources/ChatSearchResultsController.swift index b5e607ccb6..4e35b65cbd 100644 --- a/submodules/TelegramUI/Sources/ChatSearchResultsController.swift +++ b/submodules/TelegramUI/Sources/ChatSearchResultsController.swift @@ -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)) diff --git a/submodules/TelegramUI/Sources/ChatSecretAutoremoveTimerActionSheet.swift b/submodules/TelegramUI/Sources/ChatSecretAutoremoveTimerActionSheet.swift index c1bc4e7f40..aa1d97af6b 100644 --- a/submodules/TelegramUI/Sources/ChatSecretAutoremoveTimerActionSheet.swift +++ b/submodules/TelegramUI/Sources/ChatSecretAutoremoveTimerActionSheet.swift @@ -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) } diff --git a/submodules/TelegramUI/Sources/ChatSendAsPeerListContextItem.swift b/submodules/TelegramUI/Sources/ChatSendAsPeerListContextItem.swift index c504c53dad..ba3e4481ad 100644 --- a/submodules/TelegramUI/Sources/ChatSendAsPeerListContextItem.swift +++ b/submodules/TelegramUI/Sources/ChatSendAsPeerListContextItem.swift @@ -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 diff --git a/submodules/TelegramUI/Sources/ChatTextInputAudioRecordingTimeNode.swift b/submodules/TelegramUI/Sources/ChatTextInputAudioRecordingTimeNode.swift index 7905048a82..7fe344d6f4 100644 --- a/submodules/TelegramUI/Sources/ChatTextInputAudioRecordingTimeNode.swift +++ b/submodules/TelegramUI/Sources/ChatTextInputAudioRecordingTimeNode.swift @@ -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 diff --git a/submodules/TelegramUI/Sources/ChatTextInputPanelNode.swift b/submodules/TelegramUI/Sources/ChatTextInputPanelNode.swift index 2b73d68029..6b3f7e1909 100644 --- a/submodules/TelegramUI/Sources/ChatTextInputPanelNode.swift +++ b/submodules/TelegramUI/Sources/ChatTextInputPanelNode.swift @@ -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 diff --git a/submodules/TelegramUI/Sources/ChatThemeScreen.swift b/submodules/TelegramUI/Sources/ChatThemeScreen.swift index 02cf6a12ef..31fdad5224 100644 --- a/submodules/TelegramUI/Sources/ChatThemeScreen.swift +++ b/submodules/TelegramUI/Sources/ChatThemeScreen.swift @@ -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() } } }) diff --git a/submodules/TelegramUI/Sources/ChatTranslationPanelNode.swift b/submodules/TelegramUI/Sources/ChatTranslationPanelNode.swift index 0c5d6f3666..c6ac0b2fe6 100644 --- a/submodules/TelegramUI/Sources/ChatTranslationPanelNode.swift +++ b/submodules/TelegramUI/Sources/ChatTranslationPanelNode.swift @@ -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() { diff --git a/submodules/TelegramUI/Sources/ChatUnblockInputPanelNode.swift b/submodules/TelegramUI/Sources/ChatUnblockInputPanelNode.swift index c8eb3bbf8f..8d6fd461a2 100644 --- a/submodules/TelegramUI/Sources/ChatUnblockInputPanelNode.swift +++ b/submodules/TelegramUI/Sources/ChatUnblockInputPanelNode.swift @@ -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 { diff --git a/submodules/TelegramUI/Sources/CommandMenuChatInputContextPanelNode.swift b/submodules/TelegramUI/Sources/CommandMenuChatInputContextPanelNode.swift index bb631876d6..0e0a6b9d25 100644 --- a/submodules/TelegramUI/Sources/CommandMenuChatInputContextPanelNode.swift +++ b/submodules/TelegramUI/Sources/CommandMenuChatInputContextPanelNode.swift @@ -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) } diff --git a/submodules/TelegramUI/Sources/ComposeController.swift b/submodules/TelegramUI/Sources/ComposeController.swift index 5e1215ecd7..871f7f855d 100644 --- a/submodules/TelegramUI/Sources/ComposeController.swift +++ b/submodules/TelegramUI/Sources/ComposeController.swift @@ -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 } diff --git a/submodules/TelegramUI/Sources/ComposeControllerNode.swift b/submodules/TelegramUI/Sources/ComposeControllerNode.swift index 270dec9376..380d2f4ec8 100644 --- a/submodules/TelegramUI/Sources/ComposeControllerNode.swift +++ b/submodules/TelegramUI/Sources/ComposeControllerNode.swift @@ -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 diff --git a/submodules/TelegramUI/Sources/ContactMultiselectionController.swift b/submodules/TelegramUI/Sources/ContactMultiselectionController.swift index f729f1e4bb..3b2d204a86 100644 --- a/submodules/TelegramUI/Sources/ContactMultiselectionController.swift +++ b/submodules/TelegramUI/Sources/ContactMultiselectionController.swift @@ -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 } diff --git a/submodules/TelegramUI/Sources/ContactMultiselectionControllerNode.swift b/submodules/TelegramUI/Sources/ContactMultiselectionControllerNode.swift index b11833b811..fdfddc9fab 100644 --- a/submodules/TelegramUI/Sources/ContactMultiselectionControllerNode.swift +++ b/submodules/TelegramUI/Sources/ContactMultiselectionControllerNode.swift @@ -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) } diff --git a/submodules/TelegramUI/Sources/ContactSelectionController.swift b/submodules/TelegramUI/Sources/ContactSelectionController.swift index 0a5dbe166a..d52f0cfc65 100644 --- a/submodules/TelegramUI/Sources/ContactSelectionController.swift +++ b/submodules/TelegramUI/Sources/ContactSelectionController.swift @@ -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))) diff --git a/submodules/TelegramUI/Sources/DeviceContactDataManager.swift b/submodules/TelegramUI/Sources/DeviceContactDataManager.swift index 7e6f3a62c2..b3597c8669 100644 --- a/submodules/TelegramUI/Sources/DeviceContactDataManager.swift +++ b/submodules/TelegramUI/Sources/DeviceContactDataManager.swift @@ -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 } diff --git a/submodules/TelegramUI/Sources/EditAccessoryPanelNode.swift b/submodules/TelegramUI/Sources/EditAccessoryPanelNode.swift index ced54568b6..c6e029ff09 100644 --- a/submodules/TelegramUI/Sources/EditAccessoryPanelNode.swift +++ b/submodules/TelegramUI/Sources/EditAccessoryPanelNode.swift @@ -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) })) } diff --git a/submodules/TelegramUI/Sources/EmojisChatInputContextPanelNode.swift b/submodules/TelegramUI/Sources/EmojisChatInputContextPanelNode.swift index 47120d618b..cd8f5216be 100644 --- a/submodules/TelegramUI/Sources/EmojisChatInputContextPanelNode.swift +++ b/submodules/TelegramUI/Sources/EmojisChatInputContextPanelNode.swift @@ -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 diff --git a/submodules/TelegramUI/Sources/GalleryHiddenMediaManager.swift b/submodules/TelegramUI/Sources/GalleryHiddenMediaManager.swift index 88bf0090a1..8f99915865 100644 --- a/submodules/TelegramUI/Sources/GalleryHiddenMediaManager.swift +++ b/submodules/TelegramUI/Sources/GalleryHiddenMediaManager.swift @@ -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 } diff --git a/submodules/TelegramUI/Sources/GridMessageItem.swift b/submodules/TelegramUI/Sources/GridMessageItem.swift index 20db9157d1..5a05b2dc7a 100644 --- a/submodules/TelegramUI/Sources/GridMessageItem.swift +++ b/submodules/TelegramUI/Sources/GridMessageItem.swift @@ -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()) } } } diff --git a/submodules/TelegramUI/Sources/HashtagChatInputContextPanelNode.swift b/submodules/TelegramUI/Sources/HashtagChatInputContextPanelNode.swift index 3fa1600733..456025e761 100644 --- a/submodules/TelegramUI/Sources/HashtagChatInputContextPanelNode.swift +++ b/submodules/TelegramUI/Sources/HashtagChatInputContextPanelNode.swift @@ -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 } }) diff --git a/submodules/TelegramUI/Sources/HorizontalListContextResultsChatInputContextPanelNode.swift b/submodules/TelegramUI/Sources/HorizontalListContextResultsChatInputContextPanelNode.swift index 2e348b2b75..c2daa7b013 100644 --- a/submodules/TelegramUI/Sources/HorizontalListContextResultsChatInputContextPanelNode.swift +++ b/submodules/TelegramUI/Sources/HorizontalListContextResultsChatInputContextPanelNode.swift @@ -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 } diff --git a/submodules/TelegramUI/Sources/HorizontalListContextResultsChatInputPanelItem.swift b/submodules/TelegramUI/Sources/HorizontalListContextResultsChatInputPanelItem.swift index 7c245e3530..6d7b4d1150 100644 --- a/submodules/TelegramUI/Sources/HorizontalListContextResultsChatInputPanelItem.swift +++ b/submodules/TelegramUI/Sources/HorizontalListContextResultsChatInputPanelItem.swift @@ -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 diff --git a/submodules/TelegramUI/Sources/HorizontalStickerGridItem.swift b/submodules/TelegramUI/Sources/HorizontalStickerGridItem.swift index ff842a3761..3d15ecc22a 100755 --- a/submodules/TelegramUI/Sources/HorizontalStickerGridItem.swift +++ b/submodules/TelegramUI/Sources/HorizontalStickerGridItem.swift @@ -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 { diff --git a/submodules/TelegramUI/Sources/HorizontalStickersChatContextPanelNode.swift b/submodules/TelegramUI/Sources/HorizontalStickersChatContextPanelNode.swift index a9390cb990..b64eb6a485 100755 --- a/submodules/TelegramUI/Sources/HorizontalStickersChatContextPanelNode.swift +++ b/submodules/TelegramUI/Sources/HorizontalStickersChatContextPanelNode.swift @@ -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) diff --git a/submodules/TelegramUI/Sources/InChatPrefetchManager.swift b/submodules/TelegramUI/Sources/InChatPrefetchManager.swift index 2323bf66de..d87ae27290 100644 --- a/submodules/TelegramUI/Sources/InChatPrefetchManager.swift +++ b/submodules/TelegramUI/Sources/InChatPrefetchManager.swift @@ -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()) } } } diff --git a/submodules/TelegramUI/Sources/InlineReactionSearchPanel.swift b/submodules/TelegramUI/Sources/InlineReactionSearchPanel.swift index ed12f33b39..22f646c30c 100644 --- a/submodules/TelegramUI/Sources/InlineReactionSearchPanel.swift +++ b/submodules/TelegramUI/Sources/InlineReactionSearchPanel.swift @@ -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) } diff --git a/submodules/TelegramUI/Sources/InstantVideoRadialStatusNode.swift b/submodules/TelegramUI/Sources/InstantVideoRadialStatusNode.swift index 6357439f1f..af53ab9b1d 100644 --- a/submodules/TelegramUI/Sources/InstantVideoRadialStatusNode.swift +++ b/submodules/TelegramUI/Sources/InstantVideoRadialStatusNode.swift @@ -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 } diff --git a/submodules/TelegramUI/Sources/LargeEmojiActionSheetItem.swift b/submodules/TelegramUI/Sources/LargeEmojiActionSheetItem.swift index 8be374d62a..d16fd2d030 100644 --- a/submodules/TelegramUI/Sources/LargeEmojiActionSheetItem.swift +++ b/submodules/TelegramUI/Sources/LargeEmojiActionSheetItem.swift @@ -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() diff --git a/submodules/TelegramUI/Sources/MediaManager.swift b/submodules/TelegramUI/Sources/MediaManager.swift index 05b6aebaf7..0cfec96a8c 100644 --- a/submodules/TelegramUI/Sources/MediaManager.swift +++ b/submodules/TelegramUI/Sources/MediaManager.swift @@ -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 diff --git a/submodules/TelegramUI/Sources/MentionChatInputContextPanelNode.swift b/submodules/TelegramUI/Sources/MentionChatInputContextPanelNode.swift index 972f9b7710..d30cf203bd 100644 --- a/submodules/TelegramUI/Sources/MentionChatInputContextPanelNode.swift +++ b/submodules/TelegramUI/Sources/MentionChatInputContextPanelNode.swift @@ -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 } diff --git a/submodules/TelegramUI/Sources/MultiplexedSoftwareVideoNode.swift b/submodules/TelegramUI/Sources/MultiplexedSoftwareVideoNode.swift deleted file mode 100644 index 8b13789179..0000000000 --- a/submodules/TelegramUI/Sources/MultiplexedSoftwareVideoNode.swift +++ /dev/null @@ -1 +0,0 @@ - diff --git a/submodules/TelegramUI/Sources/NotificationContainerController.swift b/submodules/TelegramUI/Sources/NotificationContainerController.swift index b5d8e6adbf..607f7fc2a8 100644 --- a/submodules/TelegramUI/Sources/NotificationContainerController.swift +++ b/submodules/TelegramUI/Sources/NotificationContainerController.swift @@ -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 diff --git a/submodules/TelegramUI/Sources/NotificationContentContext.swift b/submodules/TelegramUI/Sources/NotificationContentContext.swift index 950bfccdfe..f63a5778f6 100644 --- a/submodules/TelegramUI/Sources/NotificationContentContext.swift +++ b/submodules/TelegramUI/Sources/NotificationContentContext.swift @@ -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()) } } })) diff --git a/submodules/TelegramUI/Sources/OpenAddContact.swift b/submodules/TelegramUI/Sources/OpenAddContact.swift index 0bbe48d981..b4c860dbc9 100644 --- a/submodules/TelegramUI/Sources/OpenAddContact.swift +++ b/submodules/TelegramUI/Sources/OpenAddContact.swift @@ -11,7 +11,7 @@ import PeerInfoUI func openAddContactImpl(context: AccountContext, firstName: String = "", lastName: String = "", phoneNumber: String, label: String = "_$!!$_", 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: "") diff --git a/submodules/TelegramUI/Sources/OpenChatMessage.swift b/submodules/TelegramUI/Sources/OpenChatMessage.swift index 0e772d43fc..3471adcb02 100644 --- a/submodules/TelegramUI/Sources/OpenChatMessage.swift +++ b/submodules/TelegramUI/Sources/OpenChatMessage.swift @@ -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" diff --git a/submodules/TelegramUI/Sources/OpenResolvedUrl.swift b/submodules/TelegramUI/Sources/OpenResolvedUrl.swift index b9a668adb1..bb3af9aeae 100644 --- a/submodules/TelegramUI/Sources/OpenResolvedUrl.swift +++ b/submodules/TelegramUI/Sources/OpenResolvedUrl.swift @@ -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() diff --git a/submodules/TelegramUI/Sources/OpenUrl.swift b/submodules/TelegramUI/Sources/OpenUrl.swift index dcd978e43a..43ae831659 100644 --- a/submodules/TelegramUI/Sources/OpenUrl.swift +++ b/submodules/TelegramUI/Sources/OpenUrl.swift @@ -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)) diff --git a/submodules/TelegramUI/Sources/OverlayAudioPlayerController.swift b/submodules/TelegramUI/Sources/OverlayAudioPlayerController.swift index 79d79fdfe8..5682f9d023 100644 --- a/submodules/TelegramUI/Sources/OverlayAudioPlayerController.swift +++ b/submodules/TelegramUI/Sources/OverlayAudioPlayerController.swift @@ -59,7 +59,7 @@ final class OverlayAudioPlayerControllerImpl: ViewController, OverlayAudioPlayer }, requestShare: { [weak self] messageId in if let strongSelf = self { let _ = (strongSelf.context.engine.data.get(TelegramEngine.EngineData.Item.Messages.Message(id: messageId)) - |> deliverOnMainQueue).start(next: { message in + |> deliverOnMainQueue).startStandalone(next: { message in if let strongSelf = self, let message = message { let shareController = ShareController(context: strongSelf.context, subject: .messages([message._asMessage()]), showInChat: { message in if let strongSelf = self { @@ -74,7 +74,7 @@ final class OverlayAudioPlayerControllerImpl: ViewController, OverlayAudioPlayer peerIds.map(TelegramEngine.EngineData.Item.Peer.Peer.init) ) ) - |> deliverOnMainQueue).start(next: { [weak self] peerList in + |> deliverOnMainQueue).startStandalone(next: { [weak self] peerList in if let strongSelf = self { let peers = peerList.compactMap { $0 } let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 } diff --git a/submodules/TelegramUI/Sources/OverlayAudioPlayerControllerNode.swift b/submodules/TelegramUI/Sources/OverlayAudioPlayerControllerNode.swift index 3aa7812721..78cc7bde7b 100644 --- a/submodules/TelegramUI/Sources/OverlayAudioPlayerControllerNode.swift +++ b/submodules/TelegramUI/Sources/OverlayAudioPlayerControllerNode.swift @@ -302,7 +302,7 @@ final class OverlayAudioPlayerControllerNode: ViewControllerTracingNode, UIGestu return false } - 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 { if strongSelf.presentationData.theme !== presentationData.theme || strongSelf.presentationData.strings !== presentationData.strings { strongSelf.updatePresentationData(presentationData) @@ -583,7 +583,7 @@ final class OverlayAudioPlayerControllerNode: ViewControllerTracingNode, UIGestu let updateSizeAndInsets = ListViewUpdateSizeAndInsets(size: listNodeSize, insets: insets, duration: 0.0, curve: .Default(duration: nil)) historyNode.updateLayout(transition: .immediate, updateSizeAndInsets: updateSizeAndInsets) } - self.replacementHistoryNodeReadyDisposable.set((historyNode.historyState.get() |> take(1) |> deliverOnMainQueue).start(next: { [weak self] _ in + self.replacementHistoryNodeReadyDisposable.set((historyNode.historyState.get() |> take(1) |> deliverOnMainQueue).startStrict(next: { [weak self] _ in if let strongSelf = self { strongSelf.replaceWithReadyUpdatedHistoryNode() } diff --git a/submodules/TelegramUI/Sources/OverlayPlayerControlsNode.swift b/submodules/TelegramUI/Sources/OverlayPlayerControlsNode.swift index ad6774419f..dcb25facb6 100644 --- a/submodules/TelegramUI/Sources/OverlayPlayerControlsNode.swift +++ b/submodules/TelegramUI/Sources/OverlayPlayerControlsNode.swift @@ -342,7 +342,7 @@ final class OverlayPlayerControlsNode: ASDisplayNode { self.rightDurationLabel.status = mappedStatus self.scrubbingDisposable = (self.scrubberNode.scrubbingPosition - |> deliverOnMainQueue).start(next: { [weak self] value in + |> deliverOnMainQueue).startStrict(next: { [weak self] value in guard let strongSelf = self else { return } @@ -370,7 +370,7 @@ final class OverlayPlayerControlsNode: ASDisplayNode { }) self.statusDisposable = (delayedStatus - |> deliverOnMainQueue).start(next: { [weak self] value in + |> deliverOnMainQueue).startStrict(next: { [weak self] value in guard let strongSelf = self else { return } @@ -483,7 +483,7 @@ final class OverlayPlayerControlsNode: ASDisplayNode { }) self.chapterDisposable = combineLatest(queue: Queue.mainQueue(), mappedStatus, self.chaptersPromise.get()) - .start(next: { [weak self] status, chapters in + .startStrict(next: { [weak self] status, chapters in if let strongSelf = self, status.duration > 1.0, chapters.count > 0 { let previousChapter = strongSelf.currentChapter var currentChapter: MediaPlayerScrubbingChapter? @@ -968,7 +968,7 @@ final class OverlayPlayerControlsNode: ASDisplayNode { } let _ = updateMusicPlaybackSettingsInteractively(accountManager: self.accountManager, { return $0.withUpdatedOrder(nextOrder) - }).start() + }).startStandalone() self.control?(.setOrder(nextOrder)) } } @@ -986,7 +986,7 @@ final class OverlayPlayerControlsNode: ASDisplayNode { } let _ = updateMusicPlaybackSettingsInteractively(accountManager: self.accountManager, { return $0.withUpdatedLooping(nextLooping) - }).start() + }).startStandalone() self.control?(.setLooping(nextLooping)) } } diff --git a/submodules/TelegramUI/Sources/PeerMessagesMediaPlaylist.swift b/submodules/TelegramUI/Sources/PeerMessagesMediaPlaylist.swift index 44d712c54c..0dc5768525 100644 --- a/submodules/TelegramUI/Sources/PeerMessagesMediaPlaylist.swift +++ b/submodules/TelegramUI/Sources/PeerMessagesMediaPlaylist.swift @@ -517,7 +517,7 @@ final class PeerMessagesMediaPlaylist: SharedMediaPlaylist { } } |> take(1) - |> deliverOnMainQueue).start(next: { [weak self] _ in + |> deliverOnMainQueue).startStrict(next: { [weak self] _ in self?.currentItemDisappeared?() })) } else { @@ -559,7 +559,7 @@ final class PeerMessagesMediaPlaylist: SharedMediaPlaylist { } |> take(1) |> deliverOnMainQueue - self.navigationDisposable.set(historySignal.start(next: { [weak self] messageAndAroundMessages in + self.navigationDisposable.set(historySignal.startStrict(next: { [weak self] messageAndAroundMessages in if let strongSelf = self { assert(strongSelf.loadingItem) @@ -578,7 +578,7 @@ final class PeerMessagesMediaPlaylist: SharedMediaPlaylist { case let .custom(messages, at, _): self.navigationDisposable.set((messages |> take(1) - |> deliverOnMainQueue).start(next: { [weak self] messages in + |> deliverOnMainQueue).startStrict(next: { [weak self] messages in if let strongSelf = self { assert(strongSelf.loadingItem) @@ -602,7 +602,7 @@ final class PeerMessagesMediaPlaylist: SharedMediaPlaylist { default: self.navigationDisposable.set((self.context.account.postbox.messageAtId(messageId) |> take(1) - |> deliverOnMainQueue).start(next: { [weak self] message in + |> deliverOnMainQueue).startStrict(next: { [weak self] message in if let strongSelf = self { assert(strongSelf.loadingItem) @@ -712,7 +712,7 @@ final class PeerMessagesMediaPlaylist: SharedMediaPlaylist { } |> take(1) |> deliverOnMainQueue - self.navigationDisposable.set(historySignal.start(next: { [weak self] messageAndAroundMessages in + self.navigationDisposable.set(historySignal.startStrict(next: { [weak self] messageAndAroundMessages in if let strongSelf = self { assert(strongSelf.loadingItem) @@ -734,7 +734,7 @@ final class PeerMessagesMediaPlaylist: SharedMediaPlaylist { case .singleMessage: self.navigationDisposable.set((self.context.account.postbox.messageAtId(index.id) |> take(1) - |> deliverOnMainQueue).start(next: { [weak self] message in + |> deliverOnMainQueue).startStrict(next: { [weak self] message in if let strongSelf = self { assert(strongSelf.loadingItem) @@ -816,7 +816,7 @@ final class PeerMessagesMediaPlaylist: SharedMediaPlaylist { } |> take(1) |> deliverOnMainQueue - self.navigationDisposable.set(historySignal.start(next: { [weak self] messageAndAroundMessages, previousMessagesCount, shouldLoadMore in + self.navigationDisposable.set(historySignal.startStrict(next: { [weak self] messageAndAroundMessages, previousMessagesCount, shouldLoadMore in if let strongSelf = self { assert(strongSelf.loadingItem) @@ -828,7 +828,7 @@ final class PeerMessagesMediaPlaylist: SharedMediaPlaylist { loadMore?() strongSelf.loadMoreDisposable.set((messages - |> deliverOnMainQueue).start(next: { messages, totalCount, hasMore in + |> deliverOnMainQueue).startStrict(next: { messages, totalCount, hasMore in guard let strongSelf = self else { return } @@ -869,7 +869,7 @@ final class PeerMessagesMediaPlaylist: SharedMediaPlaylist { default: break } - let _ = self.context.engine.messages.markMessageContentAsConsumedInteractively(messageId: item.message.id).start() + let _ = self.context.engine.messages.markMessageContentAsConsumedInteractively(messageId: item.message.id).startStandalone() } } } diff --git a/submodules/TelegramUI/Sources/PeersNearbyManager.swift b/submodules/TelegramUI/Sources/PeersNearbyManager.swift index dc44ce6199..1cc01c4f94 100644 --- a/submodules/TelegramUI/Sources/PeersNearbyManager.swift +++ b/submodules/TelegramUI/Sources/PeersNearbyManager.swift @@ -35,7 +35,7 @@ final class PeersNearbyManagerImpl: PeersNearbyManager { return state.visibilityExpires } |> deliverOnMainQueue - |> distinctUntilChanged).start(next: { [weak self] visibility in + |> distinctUntilChanged).startStrict(next: { [weak self] visibility in if let strongSelf = self { strongSelf.visibilityUpdated(visible: visibility != nil) } @@ -60,7 +60,7 @@ final class PeersNearbyManagerImpl: PeersNearbyManager { } let signal = (poll |> then(.complete() |> suspendAwareDelay(locationUpdateTimePeriod, queue: Queue.concurrentDefaultQueue()))) |> restart - self.locationDisposable.set(signal.start(next: { [weak self] coordinate in + self.locationDisposable.set(signal.startStrict(next: { [weak self] coordinate in if let strongSelf = self, let coordinate = coordinate { let location = CLLocation(latitude: coordinate.latitude, longitude: coordinate.longitude) var update = true @@ -81,6 +81,6 @@ final class PeersNearbyManagerImpl: PeersNearbyManager { } private func updateLocation(_ location: CLLocation) { - self.updateDisposable.set(self.engine.peersNearby.updatePeersNearbyVisibility(update: .location(latitude: location.coordinate.latitude, longitude: location.coordinate.longitude), background: true).start()) + self.updateDisposable.set(self.engine.peersNearby.updatePeersNearbyVisibility(update: .location(latitude: location.coordinate.latitude, longitude: location.coordinate.longitude), background: true).startStrict()) } } diff --git a/submodules/TelegramUI/Sources/PollResultsController.swift b/submodules/TelegramUI/Sources/PollResultsController.swift index 131364aa82..32e0c379fc 100644 --- a/submodules/TelegramUI/Sources/PollResultsController.swift +++ b/submodules/TelegramUI/Sources/PollResultsController.swift @@ -333,7 +333,7 @@ public func pollResultsController(context: AccountContext, messageId: EngineMess }, expandOption: { optionId in let _ = (resultsContext.state |> take(1) - |> deliverOnMainQueue).start(next: { [weak resultsContext] state in + |> deliverOnMainQueue).startStandalone(next: { [weak resultsContext] state in if let optionState = state.options[optionId] { updateState { state in var state = state diff --git a/submodules/TelegramUI/Sources/PrefetchManager.swift b/submodules/TelegramUI/Sources/PrefetchManager.swift index 4bc128c4f0..2398ada772 100644 --- a/submodules/TelegramUI/Sources/PrefetchManager.swift +++ b/submodules/TelegramUI/Sources/PrefetchManager.swift @@ -92,7 +92,7 @@ private final class PrefetchManagerInnerImpl { } self.listDisposable = (combineLatest(orderedPreloadMedia, sharedContext.automaticMediaDownloadSettings, networkType) - |> deliverOn(self.queue)).start(next: { [weak self] orderedPreloadMedia, automaticDownloadSettings, networkType in + |> deliverOn(self.queue)).startStrict(next: { [weak self] orderedPreloadMedia, automaticDownloadSettings, networkType in self?.updateOrderedPreloadMedia(orderedPreloadMedia, automaticDownloadSettings: automaticDownloadSettings, networkType: networkType) }) } @@ -172,16 +172,16 @@ private final class PrefetchManagerInnerImpl { if case .full = automaticDownload { if let image = media as? TelegramMediaImage { - context.fetchDisposable.set(messageMediaImageInteractiveFetched(fetchManager: self.fetchManager, messageId: mediaItem.media.index.id, messageReference: MessageReference(peer: mediaItem.media.peer, author: nil, id: mediaItem.media.index.id, timestamp: mediaItem.media.index.timestamp, incoming: true, secret: false), image: image, resource: resource._asResource(), userInitiated: false, priority: priority, storeToDownloadsPeerId: nil).start()) + context.fetchDisposable.set(messageMediaImageInteractiveFetched(fetchManager: self.fetchManager, messageId: mediaItem.media.index.id, messageReference: MessageReference(peer: mediaItem.media.peer, author: nil, id: mediaItem.media.index.id, timestamp: mediaItem.media.index.timestamp, incoming: true, secret: false), image: image, resource: resource._asResource(), 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.fetchManager, messageId: mediaItem.media.index.id, messageReference: MessageReference(peer: mediaItem.media.peer, author: nil, id: mediaItem.media.index.id, timestamp: mediaItem.media.index.timestamp, incoming: true, secret: false), file: file, userInitiated: false, priority: priority) - context.fetchDisposable.set(fetchSignal.start()) + context.fetchDisposable.set(fetchSignal.startStrict()) } } else if case .prefetch = automaticDownload, mediaItem.media.peer.id.namespace != Namespaces.Peer.SecretChat { if let file = media as? TelegramMediaFile, let _ = file.size { - context.fetchDisposable.set(preloadVideoResource(postbox: self.account.postbox, userLocation: .peer(mediaItem.media.index.id.peerId), userContentType: MediaResourceUserContentType(file: file), resourceReference: FileMediaReference.message(message: MessageReference(peer: mediaItem.media.peer, author: nil, id: mediaItem.media.index.id, timestamp: mediaItem.media.index.timestamp, incoming: true, secret: false), media: file).resourceReference(file.resource), duration: 4.0).start()) + context.fetchDisposable.set(preloadVideoResource(postbox: self.account.postbox, userLocation: .peer(mediaItem.media.index.id.peerId), userContentType: MediaResourceUserContentType(file: file), resourceReference: FileMediaReference.message(message: MessageReference(peer: mediaItem.media.peer, author: nil, id: mediaItem.media.index.id, timestamp: mediaItem.media.index.timestamp, incoming: true, secret: false), media: file).resourceReference(file.resource), duration: 4.0).startStrict()) } } } @@ -216,7 +216,7 @@ private final class PrefetchManagerInnerImpl { if case .full = automaticDownload { let fetchSignal = freeMediaFileInteractiveFetched(fetchManager: self.fetchManager, fileReference: .standalone(media: media), priority: priority) - context.fetchDisposable.set(fetchSignal.start()) + context.fetchDisposable.set(fetchSignal.startStrict()) } order += 1 @@ -258,7 +258,7 @@ private final class PrefetchManagerInnerImpl { } else { return .complete() } - }).start()) + }).startStrict()) } } diff --git a/submodules/TelegramUI/Sources/PrepareSecretThumbnailData.swift b/submodules/TelegramUI/Sources/PrepareSecretThumbnailData.swift deleted file mode 100644 index bfac43b181..0000000000 --- a/submodules/TelegramUI/Sources/PrepareSecretThumbnailData.swift +++ /dev/null @@ -1,6 +0,0 @@ -import Foundation -import UIKit -import Display -import TelegramCore - - diff --git a/submodules/TelegramUI/Sources/ReplyAccessoryPanelNode.swift b/submodules/TelegramUI/Sources/ReplyAccessoryPanelNode.swift index e665bc4c19..725598e990 100644 --- a/submodules/TelegramUI/Sources/ReplyAccessoryPanelNode.swift +++ b/submodules/TelegramUI/Sources/ReplyAccessoryPanelNode.swift @@ -103,7 +103,7 @@ final class ReplyAccessoryPanelNode: AccessoryPanelNode { self.addSubnode(self.actionArea) self.messageDisposable.set((context.account.postbox.messageView(messageId) - |> deliverOnMainQueue).start(next: { [weak self] messageView in + |> deliverOnMainQueue).startStrict(next: { [weak self] messageView in if let strongSelf = self { if messageView.message == nil { Queue.mainQueue().justDispatch { diff --git a/submodules/TelegramUI/Sources/ShareExtensionContext.swift b/submodules/TelegramUI/Sources/ShareExtensionContext.swift deleted file mode 100644 index e0f73bbae7..0000000000 --- a/submodules/TelegramUI/Sources/ShareExtensionContext.swift +++ /dev/null @@ -1,3 +0,0 @@ -import Foundation -import UIKit - diff --git a/submodules/TelegramUI/Sources/SharedMediaPlayer.swift b/submodules/TelegramUI/Sources/SharedMediaPlayer.swift index 979f24b4b6..fadde9a21a 100644 --- a/submodules/TelegramUI/Sources/SharedMediaPlayer.swift +++ b/submodules/TelegramUI/Sources/SharedMediaPlayer.swift @@ -154,7 +154,7 @@ final class SharedMediaPlayer { switch playbackItem { case let .audio(player): let audioLevelPipe = self.audioLevelPipe - self.audioLevelDisposable.set((player.audioLevelEvents.start(next: { [weak audioLevelPipe] value in + self.audioLevelDisposable.set((player.audioLevelEvents.startStrict(next: { [weak audioLevelPipe] value in audioLevelPipe?.putNext(value) }))) default: @@ -203,7 +203,7 @@ final class SharedMediaPlayer { } self.stateDisposable = (playlist.state - |> deliverOnMainQueue).start(next: { [weak self] state in + |> deliverOnMainQueue).startStrict(next: { [weak self] state in if let strongSelf = self { let previousPlaybackItem = strongSelf.playbackItem strongSelf.updatePrefetchItems(item: state.item, previousItem: state.previousItem, nextItem: state.nextItem, ordering: state.order) @@ -341,7 +341,7 @@ final class SharedMediaPlayer { } } |> take(1) - |> deliverOnMainQueue).start(next: { next in + |> deliverOnMainQueue).startStrict(next: { next in if let strongSelf = self { strongSelf.playlist.onItemPlaybackStarted(item) } @@ -363,7 +363,7 @@ final class SharedMediaPlayer { }) self.playbackStateValueDisposable = (self.playbackState - |> deliverOnMainQueue).start(next: { [weak self] value in + |> deliverOnMainQueue).startStrict(next: { [weak self] value in self?._playbackStateValue = value }) @@ -512,7 +512,7 @@ final class SharedMediaPlayer { return .complete() } } - self.prefetchDisposable.set((fetchedCurrentSignal |> then(fetchedNextSignal)).start()) + self.prefetchDisposable.set((fetchedCurrentSignal |> then(fetchedNextSignal)).startStrict()) } else { self.prefetchDisposable.set(nil) } diff --git a/submodules/TelegramUI/Sources/SharedNotificationManager.swift b/submodules/TelegramUI/Sources/SharedNotificationManager.swift index 8c884da025..c2a945ef66 100644 --- a/submodules/TelegramUI/Sources/SharedNotificationManager.swift +++ b/submodules/TelegramUI/Sources/SharedNotificationManager.swift @@ -57,7 +57,7 @@ public final class SharedNotificationManager { self.pollLiveLocationOnce = pollLiveLocationOnce self.inForegroundDisposable = (inForeground - |> deliverOnMainQueue).start(next: { [weak self] value in + |> deliverOnMainQueue).startStrict(next: { [weak self] value in guard let strongSelf = self else { return } @@ -74,7 +74,7 @@ public final class SharedNotificationManager { } return combineLatest(signals) } - |> deliverOnMainQueue).start(next: { [weak self] accountsAndKeys in + |> deliverOnMainQueue).startStrict(next: { [weak self] accountsAndKeys in guard let strongSelf = self else { return } @@ -133,7 +133,7 @@ public final class SharedNotificationManager { return .single(messageIds) |> delay(1.0, queue: Queue.mainQueue()) } - |> deliverOnMainQueue).start(next: { [weak self, weak context] _ in + |> deliverOnMainQueue).startStrict(next: { [weak self, weak context] _ in guard let strongSelf = self else { return } @@ -375,7 +375,7 @@ public final class SharedNotificationManager { self.clearNotificationsManager?.clearAll() if let accountManager = self.accountManager { - let _ = logoutFromAccount(id: account.id, accountManager: accountManager, alreadyLoggedOutRemotely: true).start() + let _ = logoutFromAccount(id: account.id, accountManager: accountManager, alreadyLoggedOutRemotely: true).startStandalone() } return } @@ -497,7 +497,7 @@ public final class SharedNotificationManager { return nil } } - |> distinctUntilChanged(isEqual: { $0?.1 == $1?.1 })).start(next: { [weak self] peerAndInternalId in + |> distinctUntilChanged(isEqual: { $0?.1 == $1?.1 })).startStrict(next: { [weak self] peerAndInternalId in self?.updateNotificationCall(call: peerAndInternalId, strings: strings, nameOrder: .firstLast) })) } else { diff --git a/submodules/TelegramUI/Sources/SharedWakeupManager.swift b/submodules/TelegramUI/Sources/SharedWakeupManager.swift index b7b8517ea6..a5ba84a9dd 100644 --- a/submodules/TelegramUI/Sources/SharedWakeupManager.swift +++ b/submodules/TelegramUI/Sources/SharedWakeupManager.swift @@ -80,7 +80,7 @@ public final class SharedWakeupManager { self.acquireIdleExtension = acquireIdleExtension self.inForegroundDisposable = (inForeground - |> deliverOnMainQueue).start(next: { [weak self] value in + |> deliverOnMainQueue).startStrict(next: { [weak self] value in guard let strongSelf = self else { return } @@ -99,7 +99,7 @@ public final class SharedWakeupManager { }) self.hasActiveAudioSessionDisposable = (hasActiveAudioSession - |> deliverOnMainQueue).start(next: { [weak self] value in + |> deliverOnMainQueue).startStrict(next: { [weak self] value in guard let strongSelf = self else { return } @@ -107,7 +107,7 @@ public final class SharedWakeupManager { strongSelf.checkTasks() }) - self.managedPausedInBackgroundPlayer = combineLatest(queue: .mainQueue(), mediaManager.activeGlobalMediaPlayerAccountId, inForeground).start(next: { [weak mediaManager] accountAndActive, inForeground in + self.managedPausedInBackgroundPlayer = combineLatest(queue: .mainQueue(), mediaManager.activeGlobalMediaPlayerAccountId, inForeground).startStrict(next: { [weak mediaManager] accountAndActive, inForeground in guard let mediaManager = mediaManager else { return } @@ -180,7 +180,7 @@ public final class SharedWakeupManager { } return combineLatest(signals) } - |> deliverOnMainQueue).start(next: { [weak self] accountsAndTasks in + |> deliverOnMainQueue).startStrict(next: { [weak self] accountsAndTasks in guard let strongSelf = self else { return } diff --git a/submodules/TelegramUI/Sources/SpotlightContacts.swift b/submodules/TelegramUI/Sources/SpotlightContacts.swift index 037bab4510..3437c5e1a4 100644 --- a/submodules/TelegramUI/Sources/SpotlightContacts.swift +++ b/submodules/TelegramUI/Sources/SpotlightContacts.swift @@ -251,7 +251,7 @@ private final class SpotlightDataContextImpl { } return true })) - |> deliverOn(self.queue)).start(next: { [weak self] items in + |> deliverOn(self.queue)).startStrict(next: { [weak self] items in guard let strongSelf = self else { return } @@ -259,6 +259,10 @@ private final class SpotlightDataContextImpl { }) } + deinit { + self.listDisposable?.dispose() + } + private func updateContacts(items: [EnginePeer.Id: SpotlightIndexStorageItem]) { self.indexStorage.update(items: items) } diff --git a/submodules/TelegramUI/Sources/StoreDownloadedMedia.swift b/submodules/TelegramUI/Sources/StoreDownloadedMedia.swift index 74b48423b7..6945c7a741 100644 --- a/submodules/TelegramUI/Sources/StoreDownloadedMedia.swift +++ b/submodules/TelegramUI/Sources/StoreDownloadedMedia.swift @@ -127,7 +127,7 @@ private final class DownloadedMediaStoreContext { return combineLatest(collection |> take(1), postbox.mediaBox.resourceData(resource)) } } - |> deliverOn(queue)).start(next: { collection, data in + |> deliverOn(queue)).startStrict(next: { collection, data in if !data.complete { return } @@ -293,7 +293,7 @@ final class DownloadedMediaStoreManagerImpl: DownloadedMediaStoreManager { let _ = (self.postbox.transaction({ transaction -> [(index: Int32, message: Message, mediaId: MediaId)] in return _internal_getSynchronizeAutosaveItemOperations(transaction: transaction) }) - |> deliverOnMainQueue).start(next: { [weak self] items in + |> deliverOnMainQueue).startStandalone(next: { [weak self] items in guard let self else { return } @@ -308,7 +308,7 @@ final class DownloadedMediaStoreManagerImpl: DownloadedMediaStoreManager { let _ = self.postbox.transaction({ transaction -> Void in return _internal_removeSyncrhonizeAutosaveItemOperations(transaction: transaction, indices: items.map(\.index)) - }).start() + }).startStandalone() }) } } diff --git a/submodules/TelegramUI/Sources/SuppressContactsWarning.swift b/submodules/TelegramUI/Sources/SuppressContactsWarning.swift index daccca51c3..2253502fb5 100644 --- a/submodules/TelegramUI/Sources/SuppressContactsWarning.swift +++ b/submodules/TelegramUI/Sources/SuppressContactsWarning.swift @@ -16,7 +16,7 @@ func presentContactsWarningSuppressionImpl(context: AccountContext, present: (Vi }), TextAlertAction(type: .defaultAction, title: presentationData.strings.Contacts_PermissionsEnable, action: { let _ = (DeviceAccess.authorizationStatus(subject: .contacts) |> take(1) - |> deliverOnMainQueue).start(next: { status in + |> deliverOnMainQueue).startStandalone(next: { status in switch status { case .notDetermined: DeviceAccess.authorizeAccess(to: .contacts) diff --git a/submodules/TelegramUI/Sources/TelegramRootController.swift b/submodules/TelegramUI/Sources/TelegramRootController.swift index 192e60a1ec..e9b13bca42 100644 --- a/submodules/TelegramUI/Sources/TelegramRootController.swift +++ b/submodules/TelegramUI/Sources/TelegramRootController.swift @@ -93,7 +93,7 @@ public final class TelegramRootController: NavigationController, TelegramRootCon super.init(mode: .automaticMasterDetail, theme: NavigationControllerTheme(presentationTheme: self.presentationData.theme)) self.presentationDataDisposable = (context.sharedContext.presentationData - |> deliverOnMainQueue).start(next: { [weak self] presentationData in + |> deliverOnMainQueue).startStrict(next: { [weak self] presentationData in if let strongSelf = self { strongSelf.detailsPlaceholderNode?.updatePresentationData(presentationData) @@ -109,12 +109,12 @@ public final class TelegramRootController: NavigationController, TelegramRootCon if context.sharedContext.applicationBindings.isMainApp { self.applicationInFocusDisposable = (context.sharedContext.applicationBindings.applicationIsActive |> distinctUntilChanged - |> deliverOn(Queue.mainQueue())).start(next: { value in + |> deliverOn(Queue.mainQueue())).startStrict(next: { value in context.sharedContext.mainWindow?.setForceBadgeHidden(!value) }) self.storyUploadEventsDisposable = (context.engine.messages.allStoriesUploadEvents() - |> deliverOnMainQueue).start(next: { [weak self] event in + |> deliverOnMainQueue).startStrict(next: { [weak self] event in guard let self else { return } @@ -395,7 +395,7 @@ public final class TelegramRootController: NavigationController, TelegramRootCon storyTarget = target let _ = (self.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: targetPeerId)) - |> deliverOnMainQueue).start(next: { [weak self] peer in + |> deliverOnMainQueue).startStandalone(next: { [weak self] peer in guard let self, let peer else { return } @@ -437,7 +437,7 @@ public final class TelegramRootController: NavigationController, TelegramRootCon |> filter { $0 } |> take(1) |> timeout(isPeerArchived ? 0.5 : 0.25, queue: .mainQueue(), alternate: .single(true)) - |> deliverOnMainQueue).start(completed: { [weak chatListController] in + |> deliverOnMainQueue).startStandalone(completed: { [weak chatListController] in guard let chatListController else { return } @@ -461,7 +461,7 @@ public final class TelegramRootController: NavigationController, TelegramRootCon let entities = generateChatInputTextEntities(caption) Logger.shared.log("MediaEditor", "Calling uploadStory for image, randomId \(randomId)") let _ = (context.engine.messages.uploadStory(target: target, media: .image(dimensions: dimensions, data: imageData, stickers: stickers), mediaAreas: mediaAreas, text: caption.string, entities: entities, pin: options.pin, privacy: options.privacy, isForwardingDisabled: options.isForwardingDisabled, period: options.timeout, randomId: randomId) - |> deliverOnMainQueue).start(next: { stableId in + |> deliverOnMainQueue).startStandalone(next: { stableId in moveStorySource(engine: context.engine, peerId: context.account.peerId, from: randomId, to: Int64(stableId)) }) @@ -495,7 +495,7 @@ public final class TelegramRootController: NavigationController, TelegramRootCon Logger.shared.log("MediaEditor", "Calling uploadStory for video, randomId \(randomId)") let entities = generateChatInputTextEntities(caption) let _ = (context.engine.messages.uploadStory(target: target, media: .video(dimensions: dimensions, duration: duration, resource: resource, firstFrameFile: firstFrameFile, stickers: stickers), mediaAreas: mediaAreas, text: caption.string, entities: entities, pin: options.pin, privacy: options.privacy, isForwardingDisabled: options.isForwardingDisabled, period: options.timeout, randomId: randomId) - |> deliverOnMainQueue).start(next: { stableId in + |> deliverOnMainQueue).startStandalone(next: { stableId in moveStorySource(engine: context.engine, peerId: context.account.peerId, from: randomId, to: Int64(stableId)) }) diff --git a/submodules/TelegramUI/Sources/ThemeUpdateManager.swift b/submodules/TelegramUI/Sources/ThemeUpdateManager.swift index f61684fdec..c157d3ef20 100644 --- a/submodules/TelegramUI/Sources/ThemeUpdateManager.swift +++ b/submodules/TelegramUI/Sources/ThemeUpdateManager.swift @@ -42,7 +42,7 @@ final class ThemeUpdateManagerImpl: ThemeUpdateManager { |> map { sharedData -> PresentationThemeSettings in return sharedData.entries[ApplicationSpecificSharedDataKeys.presentationThemeSettings]?.get(PresentationThemeSettings.self) ?? PresentationThemeSettings.defaultSettings } - |> deliverOn(queue)).start(next: { [weak self] themeSettings in + |> deliverOn(queue)).startStrict(next: { [weak self] themeSettings in self?.presentationThemeSettingsUpdated(themeSettings) }) } diff --git a/submodules/TelegramUI/Sources/UpgradedAccounts.swift b/submodules/TelegramUI/Sources/UpgradedAccounts.swift deleted file mode 100644 index 8b13789179..0000000000 --- a/submodules/TelegramUI/Sources/UpgradedAccounts.swift +++ /dev/null @@ -1 +0,0 @@ - diff --git a/submodules/TelegramUI/Sources/VerticalListContextResultsChatInputContextPanelNode.swift b/submodules/TelegramUI/Sources/VerticalListContextResultsChatInputContextPanelNode.swift index 2a88a34827..9e8a8f9da6 100644 --- a/submodules/TelegramUI/Sources/VerticalListContextResultsChatInputContextPanelNode.swift +++ b/submodules/TelegramUI/Sources/VerticalListContextResultsChatInputContextPanelNode.swift @@ -213,7 +213,7 @@ final class VerticalListContextResultsChatInputContextPanelNode: ChatInputContex interfaceInteraction.botSwitchChatWithPayload(results.botId, switchPeer.startParam) } else if let webView = results.webView { let _ = (strongSelf.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: results.botId)) - |> deliverOnMainQueue).start(next: { bot in + |> deliverOnMainQueue).startStandalone(next: { bot in if let bot { interfaceInteraction.openWebView(webView.text, webView.url, true, .inline(bot: bot)) } @@ -358,7 +358,7 @@ final class VerticalListContextResultsChatInputContextPanelNode: ChatInputContex |> 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 } diff --git a/submodules/TelegramUI/Sources/VerticalListContextResultsChatInputPanelItem.swift b/submodules/TelegramUI/Sources/VerticalListContextResultsChatInputPanelItem.swift index 1521267f3d..bdc3979960 100644 --- a/submodules/TelegramUI/Sources/VerticalListContextResultsChatInputPanelItem.swift +++ b/submodules/TelegramUI/Sources/VerticalListContextResultsChatInputPanelItem.swift @@ -350,7 +350,7 @@ final class VerticalListContextResultsChatInputPanelItemNode: ListViewItemNode { let progressFrame = CGRect(origin: CGPoint(x: iconFrame.minX + floorToScreenPixels((iconFrame.width - progressSize.width) / 2.0), y: iconFrame.minY + floorToScreenPixels((iconFrame.height - progressSize.height) / 2.0)), size: progressSize) 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 diff --git a/submodules/TelegramUI/Sources/WallpaperUploadManager.swift b/submodules/TelegramUI/Sources/WallpaperUploadManager.swift index 760ca4b77d..5b20cb4bdf 100644 --- a/submodules/TelegramUI/Sources/WallpaperUploadManager.swift +++ b/submodules/TelegramUI/Sources/WallpaperUploadManager.swift @@ -56,7 +56,7 @@ final class WallpaperUploadManagerImpl: WallpaperUploadManager { init(sharedContext: SharedAccountContext, account: Account, presentationData: Signal) { self.sharedContext = sharedContext self.account = account - self.presentationDataDisposable.set(presentationData.start(next: { [weak self] presentationData in + self.presentationDataDisposable.set(presentationData.startStrict(next: { [weak self] presentationData in if let strongSelf = self { strongSelf.presentationDataUpdated(presentationData) } diff --git a/submodules/TelegramUI/Sources/WidgetDataContext.swift b/submodules/TelegramUI/Sources/WidgetDataContext.swift index 87b02168dd..bec08ce9e6 100644 --- a/submodules/TelegramUI/Sources/WidgetDataContext.swift +++ b/submodules/TelegramUI/Sources/WidgetDataContext.swift @@ -38,7 +38,7 @@ private final class WidgetReloadManager { init(inForeground: Signal) { self.inForegroundDisposable = (inForeground |> distinctUntilChanged - |> deliverOnMainQueue).start(next: { [weak self] value in + |> deliverOnMainQueue).startStrict(next: { [weak self] value in guard let strongSelf = self else { return } @@ -255,7 +255,7 @@ final class WidgetDataContext { } } |> distinctUntilChanged - |> deliverOnMainQueue).start(next: { [weak self] _ in + |> deliverOnMainQueue).startStrict(next: { [weak self] _ in self?.reloadManager.requestReload() }) @@ -286,7 +286,7 @@ final class WidgetDataContext { chatSavedMessages: presentationData.strings.DialogList_SavedMessages ) } - |> distinctUntilChanged).start(next: { value in + |> distinctUntilChanged).startStrict(next: { value in let path = widgetPresentationDataPath(rootPath: basePath) if let data = try? JSONEncoder().encode(value) { let _ = try? data.write(to: URL(fileURLWithPath: path), options: [.atomic]) @@ -313,7 +313,7 @@ final class WidgetDataContext { incomingCallString: incomingCallString ) } - |> distinctUntilChanged).start(next: { value in + |> distinctUntilChanged).startStrict(next: { value in let path = notificationsPresentationDataPath(rootPath: basePath) if let data = try? JSONEncoder().encode(value) { let _ = try? data.write(to: URL(fileURLWithPath: path), options: [.atomic])