Memory management issues

This commit is contained in:
Ali 2023-09-21 00:12:53 +02:00
parent 5799d7a2d9
commit 62765b241d
123 changed files with 1291 additions and 1332 deletions

View File

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

View File

@ -32,7 +32,7 @@ func archiveContextMenuItems(context: AccountContext, groupId: PeerGroupId, chat
if !unreadChatListPeerIds.isEmpty {
items.append(.action(ContextMenuActionItem(text: strings.ChatList_Context_MarkAllAsRead, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/MarkAsRead"), color: theme.contextMenu.primaryColor) }, action: { _, f in
let _ = (context.engine.messages.markAllChatsAsReadInteractively(items: [(groupId: EngineChatList.Group(groupId), filterPredicate: nil)])
|> deliverOnMainQueue).start(completed: {
|> deliverOnMainQueue).startStandalone(completed: {
f(.default)
})
})))
@ -118,7 +118,7 @@ func chatContextMenuItems(context: AccountContext, peerId: PeerId, promoInfo: Ch
case .recentPeers:
items.append(.action(ContextMenuActionItem(text: strings.ChatList_Context_RemoveFromRecents, textColor: .destructive, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Clear"), color: theme.contextMenu.destructiveColor) }, action: { _, f in
let _ = (context.engine.peers.removeRecentPeer(peerId: peerId)
|> deliverOnMainQueue).start(completed: {
|> deliverOnMainQueue).startStandalone(completed: {
f(.default)
})
})))
@ -126,7 +126,7 @@ func chatContextMenuItems(context: AccountContext, peerId: PeerId, promoInfo: Ch
case .recentSearch:
items.append(.action(ContextMenuActionItem(text: strings.ChatList_Context_RemoveFromRecents, textColor: .destructive, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Clear"), color: theme.contextMenu.destructiveColor) }, action: { _, f in
let _ = (context.engine.peers.removeRecentlySearchedPeer(peerId: peerId)
|> deliverOnMainQueue).start(completed: {
|> deliverOnMainQueue).startStandalone(completed: {
f(.default)
})
})))
@ -135,7 +135,7 @@ func chatContextMenuItems(context: AccountContext, peerId: PeerId, promoInfo: Ch
if recentlySearchedPeers.contains(where: { $0.peer.peerId == peerId }) {
items.append(.action(ContextMenuActionItem(text: strings.ChatList_Context_RemoveFromRecents, textColor: .destructive, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Clear"), color: theme.contextMenu.destructiveColor) }, action: { _, f in
let _ = (context.engine.peers.removeRecentlySearchedPeer(peerId: peerId)
|> deliverOnMainQueue).start(completed: {
|> deliverOnMainQueue).startStandalone(completed: {
f(.default)
})
})))
@ -208,7 +208,7 @@ func chatContextMenuItems(context: AccountContext, peerId: PeerId, promoInfo: Ch
}
return filters
}
|> deliverOnMainQueue).start(completed: {
|> deliverOnMainQueue).startStandalone(completed: {
c.dismiss(completion: {
chatListController?.present(UndoOverlayController(presentationData: presentationData, content: .chatRemovedFromFolder(chatTitle: peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder), folderTitle: title), elevatedLayout: false, animateInAsReplacement: true, action: { _ in
return false
@ -316,7 +316,7 @@ func chatContextMenuItems(context: AccountContext, peerId: PeerId, promoInfo: Ch
}
}
return filters
}).start()
}).startStandalone()
chatListController?.present(UndoOverlayController(presentationData: presentationData, content: .chatAddedToFolder(chatTitle: peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder), folderTitle: title), elevatedLayout: false, animateInAsReplacement: true, action: { _ in
return false
@ -340,12 +340,12 @@ func chatContextMenuItems(context: AccountContext, peerId: PeerId, promoInfo: Ch
if isUnread {
items.append(.action(ContextMenuActionItem(text: strings.ChatList_Context_MarkAsRead, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/MarkAsRead"), color: theme.contextMenu.primaryColor) }, action: { _, f in
let _ = context.engine.messages.togglePeersUnreadMarkInteractively(peerIds: [peerId], setToValue: nil).start()
let _ = context.engine.messages.togglePeersUnreadMarkInteractively(peerIds: [peerId], setToValue: nil).startStandalone()
f(.default)
})))
} else if !isForum {
items.append(.action(ContextMenuActionItem(text: strings.ChatList_Context_MarkAsUnread, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/MarkAsUnread"), color: theme.contextMenu.primaryColor) }, action: { _, f in
let _ = context.engine.messages.togglePeersUnreadMarkInteractively(peerIds: [peerId], setToValue: nil).start()
let _ = context.engine.messages.togglePeersUnreadMarkInteractively(peerIds: [peerId], setToValue: nil).startStandalone()
f(.default)
})))
}
@ -357,7 +357,7 @@ func chatContextMenuItems(context: AccountContext, peerId: PeerId, promoInfo: Ch
items.append(.action(ContextMenuActionItem(text: isArchived ? strings.ChatList_Context_Unarchive : strings.ChatList_Context_Archive, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: isArchived ? "Chat/Context Menu/Unarchive" : "Chat/Context Menu/Archive"), color: theme.contextMenu.primaryColor) }, action: { _, f in
if isArchived {
let _ = (context.engine.peers.updatePeersGroupIdInteractively(peerIds: [peerId], groupId: .root)
|> deliverOnMainQueue).start(completed: {
|> deliverOnMainQueue).startStandalone(completed: {
f(.default)
})
} else {
@ -366,7 +366,7 @@ func chatContextMenuItems(context: AccountContext, peerId: PeerId, promoInfo: Ch
f(.default)
} else {
let _ = (context.engine.peers.updatePeersGroupIdInteractively(peerIds: [peerId], groupId: .archive)
|> deliverOnMainQueue).start(completed: {
|> deliverOnMainQueue).startStandalone(completed: {
f(.default)
})
}
@ -377,7 +377,7 @@ func chatContextMenuItems(context: AccountContext, peerId: PeerId, promoInfo: Ch
if isPinned || chatListFilter == nil || peerId.namespace != Namespaces.Peer.SecretChat {
items.append(.action(ContextMenuActionItem(text: isPinned ? strings.ChatList_Context_Unpin : strings.ChatList_Context_Pin, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: isPinned ? "Chat/Context Menu/Unpin" : "Chat/Context Menu/Pin"), color: theme.contextMenu.primaryColor) }, action: { c, f in
let _ = (context.engine.peers.toggleItemPinned(location: location, itemId: .peer(peerId))
|> deliverOnMainQueue).start(next: { result in
|> deliverOnMainQueue).startStandalone(next: { result in
switch result {
case .done:
f(.default)
@ -447,7 +447,7 @@ func chatContextMenuItems(context: AccountContext, peerId: PeerId, promoInfo: Ch
}
items.append(.action(ContextMenuActionItem(text: isMuted ? strings.ChatList_Context_Unmute : strings.ChatList_Context_Mute, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: isMuted ? "Chat/Context Menu/Unmute" : "Chat/Context Menu/Muted"), color: theme.contextMenu.primaryColor) }, action: { _, f in
let _ = (context.engine.peers.togglePeerMuted(peerId: peerId, threadId: nil)
|> deliverOnMainQueue).start(completed: {
|> deliverOnMainQueue).startStandalone(completed: {
f(.default)
})
})))
@ -500,7 +500,7 @@ func chatContextMenuItems(context: AccountContext, peerId: PeerId, promoInfo: Ch
}
}, completed: {
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|> deliverOnMainQueue).start(next: { peer in
|> deliverOnMainQueue).startStandalone(next: { peer in
guard let peer = peer else {
return
}
@ -562,7 +562,7 @@ func chatForumTopicMenuItems(context: AccountContext, peerId: PeerId, threadId:
f(.default)
let _ = (context.engine.peers.toggleForumChannelTopicPinned(id: peerId, threadId: threadId)
|> deliverOnMainQueue).start(error: { error in
|> deliverOnMainQueue).startStandalone(error: { error in
switch error {
case let .limitReached(count):
if let chatListController = chatListController {
@ -585,7 +585,7 @@ func chatForumTopicMenuItems(context: AccountContext, peerId: PeerId, threadId:
if isUnread {
items.append(.action(ContextMenuActionItem(text: strings.ChatList_Context_MarkAsRead, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/MarkAsRead"), color: theme.contextMenu.primaryColor) }, action: { _, f in
let _ = context.engine.messages.markForumThreadAsRead(peerId: peerId, threadId: threadId).start()
let _ = context.engine.messages.markForumThreadAsRead(peerId: peerId, threadId: threadId).startStandalone()
f(.default)
})))
}
@ -610,7 +610,7 @@ func chatForumTopicMenuItems(context: AccountContext, peerId: PeerId, threadId:
items.append(.action(ContextMenuActionItem(text: isMuted ? strings.ChatList_Context_Unmute : strings.ChatList_Context_Mute, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: isMuted ? "Chat/Context Menu/Unmute" : "Chat/Context Menu/Muted"), color: theme.contextMenu.primaryColor) }, action: { [weak chatListController] c, f in
if isMuted {
let _ = (context.engine.peers.updatePeerMuteSetting(peerId: peerId, threadId: threadId, muteInterval: 0)
|> deliverOnMainQueue).start(completed: {
|> deliverOnMainQueue).startStandalone(completed: {
f(.default)
})
} else {
@ -641,7 +641,7 @@ func chatForumTopicMenuItems(context: AccountContext, peerId: PeerId, threadId:
}, action: { _, f in
f(.default)
let _ = context.engine.peers.updatePeerMuteSetting(peerId: peerId, threadId: threadId, muteInterval: value).start()
let _ = context.engine.peers.updatePeerMuteSetting(peerId: peerId, threadId: threadId, muteInterval: value).startStandalone()
chatListController?.present(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_mute_for", scale: 0.066, colors: [:], title: nil, text: presentationData.strings.PeerInfo_TooltipMutedFor(mutedForTimeIntervalString(strings: presentationData.strings, value: value)).string, customUndoText: nil, timeout: nil), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current)
})))
@ -677,7 +677,7 @@ func chatForumTopicMenuItems(context: AccountContext, peerId: PeerId, threadId:
}, action: { _, f in
f(.default)
let _ = context.engine.peers.updatePeerMuteSetting(peerId: peerId, threadId: threadId, muteInterval: nil).start()
let _ = context.engine.peers.updatePeerMuteSetting(peerId: peerId, threadId: threadId, muteInterval: nil).startStandalone()
let iconColor: UIColor = .white
chatListController?.present(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_profileunmute", scale: 0.075, colors: [
@ -694,7 +694,7 @@ func chatForumTopicMenuItems(context: AccountContext, peerId: PeerId, threadId:
}, action: { _, f in
f(.default)
let _ = context.engine.peers.updatePeerNotificationSoundInteractive(peerId: peerId, threadId: threadId, sound: .default).start()
let _ = context.engine.peers.updatePeerNotificationSoundInteractive(peerId: peerId, threadId: threadId, sound: .default).startStandalone()
chatListController?.present(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_sound_on", scale: 0.056, colors: [:], title: nil, text: presentationData.strings.PeerInfo_TooltipSoundEnabled, customUndoText: nil, timeout: nil), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current)
})))
@ -704,7 +704,7 @@ func chatForumTopicMenuItems(context: AccountContext, peerId: PeerId, threadId:
}, action: { _, f in
f(.default)
let _ = context.engine.peers.updatePeerNotificationSoundInteractive(peerId: peerId, threadId: threadId, sound: .none).start()
let _ = context.engine.peers.updatePeerNotificationSoundInteractive(peerId: peerId, threadId: threadId, sound: .none).startStandalone()
chatListController?.present(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_sound_off", scale: 0.056, colors: [:], title: nil, text: presentationData.strings.PeerInfo_TooltipSoundDisabled, customUndoText: nil, timeout: nil), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current)
})))
@ -718,7 +718,7 @@ func chatForumTopicMenuItems(context: AccountContext, peerId: PeerId, threadId:
let _ = (context.engine.data.get(
TelegramEngine.EngineData.Item.NotificationSettings.Global()
)
|> deliverOnMainQueue).start(next: { globalSettings in
|> deliverOnMainQueue).startStandalone(next: { globalSettings in
let updatePeerSound: (PeerId, PeerMessageSound) -> Signal<Void, NoError> = { peerId, sound in
return context.engine.peers.updatePeerNotificationSoundInteractive(peerId: peerId, threadId: threadId, sound: sound) |> deliverOnMainQueue
}
@ -758,11 +758,11 @@ func chatForumTopicMenuItems(context: AccountContext, peerId: PeerId, threadId:
let exceptionController = notificationPeerExceptionController(context: context, updatedPresentationData: nil, peer: .channel(channel), threadId: threadId, isStories: nil, canRemove: canRemove, defaultSound: defaultSound, defaultStoriesSound: defaultSound, edit: true, updatePeerSound: { peerId, sound in
let _ = (updatePeerSound(peerId, sound)
|> deliverOnMainQueue).start(next: { _ in
|> deliverOnMainQueue).startStandalone(next: { _ in
})
}, updatePeerNotificationInterval: { peerId, muteInterval in
let _ = (updatePeerNotificationInterval(peerId, muteInterval)
|> deliverOnMainQueue).start(next: { _ in
|> deliverOnMainQueue).startStandalone(next: { _ in
if let muteInterval = muteInterval, muteInterval == Int32.max {
let iconColor: UIColor = .white
chatListController?.present(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_profilemute", scale: 0.075, colors: [
@ -776,18 +776,18 @@ func chatForumTopicMenuItems(context: AccountContext, peerId: PeerId, threadId:
})
}, updatePeerDisplayPreviews: { peerId, displayPreviews in
let _ = (updatePeerDisplayPreviews(peerId, displayPreviews)
|> deliverOnMainQueue).start(next: { _ in
|> deliverOnMainQueue).startStandalone(next: { _ in
})
}, updatePeerStoriesMuted: { peerId, mute in
let _ = (updatePeerStoriesMuted(peerId, mute)
|> deliverOnMainQueue).start()
|> deliverOnMainQueue).startStandalone()
}, updatePeerStoriesHideSender: { peerId, hideSender in
let _ = (updatePeerStoriesHideSender(peerId, hideSender)
|> deliverOnMainQueue).start()
|> deliverOnMainQueue).startStandalone()
}, updatePeerStorySound: { peerId, sound in
let _ = (updatePeerStorySound(peerId, sound)
|> deliverOnMainQueue).start()
|> deliverOnMainQueue).startStandalone()
}, removePeerFromExceptions: {
}, modifiedPeer: {
})
@ -801,7 +801,7 @@ func chatForumTopicMenuItems(context: AccountContext, peerId: PeerId, threadId:
}, action: { _, f in
f(.default)
let _ = context.engine.peers.updatePeerMuteSetting(peerId: peerId, threadId: threadId, muteInterval: Int32.max).start()
let _ = context.engine.peers.updatePeerMuteSetting(peerId: peerId, threadId: threadId, muteInterval: Int32.max).startStandalone()
let iconColor: UIColor = .white
chatListController?.present(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_profilemute", scale: 0.075, colors: [
@ -830,7 +830,7 @@ func chatForumTopicMenuItems(context: AccountContext, peerId: PeerId, threadId:
items.append(.action(ContextMenuActionItem(text: threadData.isClosed ? presentationData.strings.ChatList_Context_ReopenTopic : presentationData.strings.ChatList_Context_CloseTopic, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: threadData.isClosed ? "Chat/Context Menu/Play": "Chat/Context Menu/Pause"), color: theme.contextMenu.primaryColor) }, action: { _, f in
f(.default)
let _ = context.engine.peers.setForumChannelTopicClosed(id: peerId, threadId: threadId, isClosed: !threadData.isClosed).start()
let _ = context.engine.peers.setForumChannelTopicClosed(id: peerId, threadId: threadId, isClosed: !threadData.isClosed).startStandalone()
})))
}
if channel.hasPermission(.deleteAllMessages) {
@ -859,9 +859,9 @@ private func openCustomMute(context: AccountContext, peerId: EnginePeer.Id, thre
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
if value <= 0 {
let _ = context.engine.peers.updatePeerMuteSetting(peerId: peerId, threadId: threadId, muteInterval: nil).start()
let _ = context.engine.peers.updatePeerMuteSetting(peerId: peerId, threadId: threadId, muteInterval: nil).startStandalone()
} else {
let _ = context.engine.peers.updatePeerMuteSetting(peerId: peerId, threadId: threadId, muteInterval: value).start()
let _ = context.engine.peers.updatePeerMuteSetting(peerId: peerId, threadId: threadId, muteInterval: value).startStandalone()
let timeString = stringForPreciseRelativeTimestamp(strings: presentationData.strings, relativeTimestamp: Int32(Date().timeIntervalSince1970) + value, relativeTo: Int32(Date().timeIntervalSince1970), dateTimeFormat: presentationData.dateTimeFormat)

View File

@ -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: {},

View File

@ -393,7 +393,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
}
}
self.badgeDisposable = (combineLatest(renderedTotalUnreadCount(accountManager: context.sharedContext.accountManager, engine: context.engine), self.presentationDataValue.get()) |> deliverOnMainQueue).start(next: { [weak self] count, presentationData in
self.badgeDisposable = (combineLatest(renderedTotalUnreadCount(accountManager: context.sharedContext.accountManager, engine: context.engine), self.presentationDataValue.get()) |> deliverOnMainQueue).startStrict(next: { [weak self] count, presentationData in
if let strongSelf = self {
if count.0 == 0 {
strongSelf.tabBarItem.badgeValue = ""
@ -404,7 +404,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
}).strict()
self.presentationDataDisposable = (context.sharedContext.presentationData
|> deliverOnMainQueue).start(next: { [weak self] presentationData in
|> deliverOnMainQueue).startStrict(next: { [weak self] presentationData in
if let strongSelf = self {
let previousTheme = strongSelf.presentationData.theme
let previousStrings = strongSelf.presentationData.strings
@ -500,7 +500,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
if context.statusDisposable == nil {
context.statusDisposable = (engine.account.postbox.mediaBox.resourceStatus(context.entry.resourceReference.resource)
|> deliverOn(self.queue)).start(next: { [weak self, weak context] status in
|> deliverOn(self.queue)).startStrict(next: { [weak self, weak context] status in
guard let strongSelf = self, let context = context else {
return
}
@ -603,7 +603,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|> distinctUntilChanged
|> deliverOnMainQueue)
self.activeDownloadsDisposable = stateSignal.start(next: { [weak self] state in
self.activeDownloadsDisposable = stateSignal.startStrict(next: { [weak self] state in
guard let strongSelf = self else {
return
}
@ -658,7 +658,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
return
}
strongSelf.clearUnseenDownloadsTimer = nil
let _ = markAllRecentDownloadItemsAsSeen(postbox: strongSelf.context.account.postbox).start()
let _ = markAllRecentDownloadItemsAsSeen(postbox: strongSelf.context.account.postbox).startStandalone()
}, queue: .mainQueue())
strongSelf.clearUnseenDownloadsTimer?.start()
}
@ -743,7 +743,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
return storiesConfiguration.posting
}
|> deliverOnMainQueue
).start(next: { [weak self] postingAvailability in
).startStrict(next: { [weak self] postingAvailability in
if let self {
self.storyPostingAvailability = postingAvailability
self.storyPostingAvailabilityValue.set(postingAvailability)
@ -1019,7 +1019,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
}
} else {
if case let .channel(channel) = peer, channel.flags.contains(.isForum), let threadId {
let _ = strongSelf.context.sharedContext.navigateToForumThread(context: strongSelf.context, peerId: peer.id, threadId: threadId, messageId: nil, navigationController: navigationController, activateInput: nil, keepStack: .never).start()
let _ = strongSelf.context.sharedContext.navigateToForumThread(context: strongSelf.context, peerId: peer.id, threadId: threadId, messageId: nil, navigationController: navigationController, activateInput: nil, keepStack: .never).startStandalone()
strongSelf.chatListDisplayNode.clearHighlightAnimated(true)
} else {
var navigationAnimationOptions: NavigationAnimationOptions = []
@ -1040,18 +1040,18 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
switch promoInfo {
case .proxy:
let _ = (ApplicationSpecificNotice.getProxyAdsAcknowledgment(accountManager: strongSelf.context.sharedContext.accountManager)
|> deliverOnMainQueue).start(next: { value in
|> deliverOnMainQueue).startStandalone(next: { value in
guard let strongSelf = self else {
return
}
if !value {
controller.displayPromoAnnouncement(text: strongSelf.presentationData.strings.DialogList_AdNoticeAlert)
let _ = ApplicationSpecificNotice.setProxyAdsAcknowledgment(accountManager: strongSelf.context.sharedContext.accountManager).start()
let _ = ApplicationSpecificNotice.setProxyAdsAcknowledgment(accountManager: strongSelf.context.sharedContext.accountManager).startStandalone()
}
})
case let .psa(type, _):
let _ = (ApplicationSpecificNotice.getPsaAcknowledgment(accountManager: strongSelf.context.sharedContext.accountManager, peerId: peer.id)
|> deliverOnMainQueue).start(next: { value in
|> deliverOnMainQueue).startStandalone(next: { value in
guard let strongSelf = self else {
return
}
@ -1065,7 +1065,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
}
controller.displayPromoAnnouncement(text: text)
let _ = ApplicationSpecificNotice.setPsaAcknowledgment(accountManager: strongSelf.context.sharedContext.accountManager, peerId: peer.id).start()
let _ = ApplicationSpecificNotice.setPsaAcknowledgment(accountManager: strongSelf.context.sharedContext.accountManager, peerId: peer.id).startStandalone()
}
})
}
@ -1082,14 +1082,14 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
return
}
let _ = self.context.engine.privacy.updateGlobalPrivacySettings().start()
let _ = self.context.engine.privacy.updateGlobalPrivacySettings().startStandalone()
let _ = (combineLatest(
ApplicationSpecificNotice.displayChatListArchiveTooltip(accountManager: self.context.sharedContext.accountManager),
self.context.engine.data.get(
TelegramEngine.EngineData.Item.Configuration.GlobalPrivacy()
)
)
|> deliverOnMainQueue).start(next: { [weak self] didDisplayTip, settings in
|> deliverOnMainQueue).startStandalone(next: { [weak self] didDisplayTip, settings in
guard let self else {
return
}
@ -1105,7 +1105,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
if !didDisplayTip {
#if DEBUG
#else
let _ = ApplicationSpecificNotice.setDisplayChatListArchiveTooltip(accountManager: self.context.sharedContext.accountManager).start()
let _ = ApplicationSpecificNotice.setDisplayChatListArchiveTooltip(accountManager: self.context.sharedContext.accountManager).startStandalone()
#endif
self.push(ArchiveInfoScreen(context: self.context, settings: settings))
@ -1121,7 +1121,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
strongSelf.archiveChats(peerIds: [peerId])
} else {
strongSelf.chatListDisplayNode.mainContainerNode.currentItemNode.setCurrentRemovingItemId(ChatListNodeState.ItemId(peerId: peerId, threadId: nil))
let _ = strongSelf.context.engine.peers.updatePeersGroupIdInteractively(peerIds: [peerId], groupId: group ? .archive : .root).start(completed: {
let _ = strongSelf.context.engine.peers.updatePeersGroupIdInteractively(peerIds: [peerId], groupId: group ? .archive : .root).startStandalone(completed: {
guard let strongSelf = self else {
return
}
@ -1133,7 +1133,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
self.chatListDisplayNode.requestOpenMessageFromSearch = { [weak self] peer, threadId, messageId, deactivateOnAction in
if let strongSelf = self {
strongSelf.openMessageFromSearchDisposable.set((strongSelf.context.engine.peers.ensurePeerIsLocallyAvailable(peer: peer)
|> deliverOnMainQueue).start(next: { [weak strongSelf] actualPeer in
|> deliverOnMainQueue).startStrict(next: { [weak strongSelf] actualPeer in
if let strongSelf = strongSelf {
if let navigationController = strongSelf.navigationController as? NavigationController {
var scrollToEndIfExists = false
@ -1145,7 +1145,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
navigationAnimationOptions = .removeOnMasterDetails
}
if case let .channel(channel) = actualPeer, channel.flags.contains(.isForum), let threadId {
let _ = strongSelf.context.sharedContext.navigateToForumThread(context: strongSelf.context, peerId: peer.id, threadId: threadId, messageId: messageId, navigationController: navigationController, activateInput: nil, keepStack: .never).start()
let _ = strongSelf.context.sharedContext.navigateToForumThread(context: strongSelf.context, peerId: peer.id, threadId: threadId, messageId: messageId, navigationController: navigationController, activateInput: nil, keepStack: .never).startStandalone()
} else {
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(actualPeer), subject: .message(id: .id(messageId), highlight: true, timecode: nil), purposefulAction: {
if deactivateOnAction {
@ -1163,7 +1163,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
self.chatListDisplayNode.requestOpenPeerFromSearch = { [weak self] peer, threadId, dismissSearch in
if let strongSelf = self {
let storedPeer = strongSelf.context.engine.peers.ensurePeerIsLocallyAvailable(peer: peer) |> map { _ -> Void in return Void() }
strongSelf.openMessageFromSearchDisposable.set((storedPeer |> deliverOnMainQueue).start(completed: { [weak strongSelf] in
strongSelf.openMessageFromSearchDisposable.set((storedPeer |> deliverOnMainQueue).startStrict(completed: { [weak strongSelf] in
if let strongSelf = strongSelf {
if dismissSearch {
strongSelf.deactivateSearch(animated: true)
@ -1178,7 +1178,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
navigationAnimationOptions = .removeOnMasterDetails
}
if case let .channel(channel) = peer, channel.flags.contains(.isForum), let threadId {
let _ = strongSelf.context.sharedContext.navigateToForumThread(context: strongSelf.context, peerId: peer.id, threadId: threadId, messageId: nil, navigationController: navigationController, activateInput: nil, keepStack: .never).start()
let _ = strongSelf.context.sharedContext.navigateToForumThread(context: strongSelf.context, peerId: peer.id, threadId: threadId, messageId: nil, navigationController: navigationController, activateInput: nil, keepStack: .never).startStandalone()
} else {
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(peer), purposefulAction: { [weak self] in
self?.deactivateSearch(animated: false)
@ -1202,7 +1202,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
actionSheet?.dismissAnimated()
if let strongSelf = self {
let _ = strongSelf.context.engine.peers.removeRecentPeer(peerId: peer.id).start()
let _ = strongSelf.context.engine.peers.removeRecentPeer(peerId: peer.id).startStandalone()
}
})
]),
@ -1255,8 +1255,8 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
controller?.isInProgress = true
let _ = (context.engine.peers.createForumChannelTopic(id: peerId, title: title, iconColor: iconColor, iconFileId: fileId)
|> deliverOnMainQueue).start(next: { topicId in
let _ = context.sharedContext.navigateToForumThread(context: context, peerId: peerId, threadId: topicId, messageId: nil, navigationController: navigationController, activateInput: .text, keepStack: .never).start()
|> deliverOnMainQueue).startStandalone(next: { topicId in
let _ = context.sharedContext.navigateToForumThread(context: context, peerId: peerId, threadId: topicId, messageId: nil, navigationController: navigationController, activateInput: .text, keepStack: .never).startStandalone()
}, error: { _ in
controller?.isInProgress = false
})
@ -1515,7 +1515,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
TelegramEngine.EngineData.Item.Configuration.UserLimits(isPremium: true)
),
filterPeersAreMuted
).start(next: { [weak self] filters, premiumLimits, filterPeersAreMuted in
).startStandalone(next: { [weak self] filters, premiumLimits, filterPeersAreMuted in
guard let strongSelf = self else {
return
}
@ -1542,7 +1542,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
strongSelf.push(controller)
} else {
let _ = (strongSelf.context.engine.peers.currentChatListFilters()
|> deliverOnMainQueue).start(next: { presetList in
|> deliverOnMainQueue).startStandalone(next: { presetList in
guard let strongSelf = self else {
return
}
@ -1593,7 +1593,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
TelegramEngine.EngineData.Item.Configuration.UserLimits(isPremium: true)
),
strongSelf.context.engine.peers.currentChatListFilters()
).start(next: { result, presetList in
).startStandalone(next: { result, presetList in
guard let strongSelf = self else {
return
}
@ -1629,7 +1629,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
}
let _ = (strongSelf.context.engine.peers.currentChatListFilters()
|> deliverOnMainQueue).start(next: { filters in
|> deliverOnMainQueue).startStandalone(next: { filters in
guard let strongSelf = self else {
return
}
@ -1683,7 +1683,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
}
let _ = (strongSelf.context.engine.peers.updateMultiplePeerMuteSettings(peerIds: filterPeersAreMuted.peerIds, muted: !filterPeersAreMuted.areMuted)
|> deliverOnMainQueue).start(completed: {
|> deliverOnMainQueue).startStandalone(completed: {
guard let strongSelf = self else {
return
}
@ -1837,7 +1837,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
self.context.sharedContext.automaticMediaDownloadSettings,
automaticDownloadNetworkType
)
|> deliverOnMainQueue).start(next: { [weak self] resources, automaticMediaDownloadSettings, automaticDownloadNetworkType in
|> deliverOnMainQueue).startStrict(next: { [weak self] resources, automaticMediaDownloadSettings, automaticDownloadNetworkType in
guard let self else {
return
}
@ -1857,7 +1857,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
if let mediaId = info.media.id {
validIds.append(mediaId)
if self.preloadStoryResourceDisposables[mediaId] == nil {
self.preloadStoryResourceDisposables[mediaId] = preloadStoryMedia(context: self.context, peer: info.peer, storyId: info.storyId, media: info.media, reactions: info.reactions).start()
self.preloadStoryResourceDisposables[mediaId] = preloadStoryMedia(context: self.context, peer: info.peer, storyId: info.storyId, media: info.media, reactions: info.reactions).startStrict()
}
}
}
@ -1878,7 +1878,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
self.storiesReady.set(.single(true))
} else {
self.storySubscriptionsDisposable = (self.context.engine.messages.storySubscriptions(isHidden: self.location == .chatList(groupId: .archive))
|> deliverOnMainQueue).start(next: { [weak self] rawStorySubscriptions in
|> deliverOnMainQueue).startStrict(next: { [weak self] rawStorySubscriptions in
guard let self else {
return
}
@ -1929,7 +1929,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
})
})
self.storyProgressDisposable = (self.context.engine.messages.allStoriesUploadProgress()
|> deliverOnMainQueue).start(next: { [weak self] progress in
|> deliverOnMainQueue).startStrict(next: { [weak self] progress in
guard let self else {
return
}
@ -1938,7 +1938,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
if case .chatList(.root) = self.location {
self.storyArchiveSubscriptionsDisposable = (self.context.engine.messages.storySubscriptions(isHidden: true)
|> deliverOnMainQueue).start(next: { [weak self] rawStoryArchiveSubscriptions in
|> deliverOnMainQueue).startStrict(next: { [weak self] rawStoryArchiveSubscriptions in
guard let self else {
return
}
@ -2007,7 +2007,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
if case .chatList(groupId: .root) = self.location, let orderedStorySubscriptions = self.orderedStorySubscriptions, !orderedStorySubscriptions.items.isEmpty {
let _ = (ApplicationSpecificNotice.displayChatListStoriesTooltip(accountManager: self.context.sharedContext.accountManager)
|> deliverOnMainQueue).start(next: { [weak self] didDisplay in
|> deliverOnMainQueue).startStandalone(next: { [weak self] didDisplay in
guard let self else {
return
}
@ -2046,7 +2046,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
self.present(tooltipScreen, in: .current)
#if !DEBUG
let _ = ApplicationSpecificNotice.setDisplayChatListStoriesTooltip(accountManager: self.context.sharedContext.accountManager).start()
let _ = ApplicationSpecificNotice.setDisplayChatListStoriesTooltip(accountManager: self.context.sharedContext.accountManager).startStandalone()
#endif
}
}
@ -2072,7 +2072,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|> mapToSignal { settings -> Signal<Bool, NoError> in
return automaticEnergyUsageShouldBeOn(settings: settings)
}
|> distinctUntilChanged).start(next: { [weak self] isPowerSavingEnabled in
|> distinctUntilChanged).startStrict(next: { [weak self] isPowerSavingEnabled in
guard let self else {
return
}
@ -2098,7 +2098,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
var settings = settings
settings.energyUsageSettings.activationThreshold = 4
return settings
}).start()
}).startStandalone()
}
return false
}), in: .current)
@ -2155,7 +2155,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
let _ = (self.chatListDisplayNode.mainContainerNode.ready
|> filter { $0 }
|> take(1)
|> timeout(0.5, queue: .mainQueue(), alternate: .single(true))).start(next: { [weak self] _ in
|> timeout(0.5, queue: .mainQueue(), alternate: .single(true))).startStandalone(next: { [weak self] _ in
guard let self else {
return
}
@ -2179,12 +2179,12 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
#endif
if let componentView = self.chatListHeaderView(), let storyPeerListView = componentView.storyPeerListView(), let _ = storyPeerListView.lockViewFrame(), !self.didShowPasscodeLockTooltipController, !"".isEmpty {
self.passcodeLockTooltipDisposable.set(combineLatest(queue: .mainQueue(), ApplicationSpecificNotice.getPasscodeLockTips(accountManager: self.context.sharedContext.accountManager), self.context.sharedContext.accountManager.accessChallengeData() |> take(1)).start(next: { [weak self] tooltipValue, passcodeView in
self.passcodeLockTooltipDisposable.set(combineLatest(queue: .mainQueue(), ApplicationSpecificNotice.getPasscodeLockTips(accountManager: self.context.sharedContext.accountManager), self.context.sharedContext.accountManager.accessChallengeData() |> take(1)).startStrict(next: { [weak self] tooltipValue, passcodeView in
if let strongSelf = self {
if !tooltipValue {
let hasPasscode = passcodeView.data.isLockable
if hasPasscode {
let _ = ApplicationSpecificNotice.setPasscodeLockTips(accountManager: strongSelf.context.sharedContext.accountManager).start()
let _ = ApplicationSpecificNotice.setPasscodeLockTips(accountManager: strongSelf.context.sharedContext.accountManager).startStandalone()
let tooltipController = TooltipController(content: .text(strongSelf.presentationData.strings.DialogList_PasscodeLockHelp), baseFontSize: strongSelf.presentationData.listsFontSize.baseDisplaySize, dismissByTapOutside: true)
strongSelf.present(tooltipController, in: .window(.root), with: TooltipControllerPresentationArguments(sourceViewAndRect: { [weak self] in
@ -2237,7 +2237,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
})
})
self.suggestLocalizationDisposable.set((signal |> deliverOnMainQueue).start(next: { [weak self] suggestedLocalization in
self.suggestLocalizationDisposable.set((signal |> deliverOnMainQueue).startStrict(next: { [weak self] suggestedLocalization in
guard let strongSelf = self, let (currentLanguageCode, suggestedLocalization) = suggestedLocalization else {
return
}
@ -2248,12 +2248,12 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
}
}) {
strongSelf.present(controller, in: .window(.root))
_ = strongSelf.context.engine.localization.markSuggestedLocalizationAsSeenInteractively(languageCode: suggestedLocalization.languageCode).start()
_ = strongSelf.context.engine.localization.markSuggestedLocalizationAsSeenInteractively(languageCode: suggestedLocalization.languageCode).startStandalone()
}
}))
self.suggestAutoarchiveDisposable.set((getServerProvidedSuggestions(account: self.context.account)
|> deliverOnMainQueue).start(next: { [weak self] values in
|> deliverOnMainQueue).startStrict(next: { [weak self] values in
guard let strongSelf = self else {
return
}
@ -2269,13 +2269,13 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
guard let strongSelf = self else {
return
}
strongSelf.dismissAutoarchiveDisposable.set(dismissServerProvidedSuggestion(account: strongSelf.context.account, suggestion: .autoarchivePopular).start())
strongSelf.dismissAutoarchiveDisposable.set(dismissServerProvidedSuggestion(account: strongSelf.context.account, suggestion: .autoarchivePopular).startStrict())
}),
TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.ChatList_AutoarchiveSuggestion_OpenSettings, action: {
guard let strongSelf = self else {
return
}
strongSelf.dismissAutoarchiveDisposable.set(dismissServerProvidedSuggestion(account: strongSelf.context.account, suggestion: .autoarchivePopular).start())
strongSelf.dismissAutoarchiveDisposable.set(dismissServerProvidedSuggestion(account: strongSelf.context.account, suggestion: .autoarchivePopular).startStrict())
strongSelf.push(strongSelf.context.sharedContext.makePrivacyAndSecurityController(context: strongSelf.context))
})
], actionLayout: .vertical, parseMarkdown: true), in: .window(.root))
@ -2295,7 +2295,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
return (phoneNumber, entry?.get(ApplicationSpecificCounterNotice.self)?.value)
}
|> deliverOnMainQueue
).start(next: { [weak self] phoneNumber, value in
).startStandalone(next: { [weak self] phoneNumber, value in
guard let strongSelf = self else {
return
}
@ -2321,7 +2321,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
}),
TextAlertAction(type: .destructiveAction, title: strongSelf.presentationData.strings.ForcedPasswordSetup_Intro_DismissActionOK, action: { [weak controller] in
if let strongSelf = self {
let _ = ApplicationSpecificNotice.setForcedPasswordSetup(engine: strongSelf.context.engine, reloginDaysTimeout: nil).start()
let _ = ApplicationSpecificNotice.setForcedPasswordSetup(engine: strongSelf.context.engine, reloginDaysTimeout: nil).startStandalone()
}
controller?.dismiss()
})
@ -2415,7 +2415,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|> take(1)
|> delay(1.0, queue: .mainQueue())
|> deliverOnMainQueue
).start(next: { [weak self] hasFeatured, hasFilters in
).startStrict(next: { [weak self] hasFeatured, hasFilters in
guard let strongSelf = self else {
return
}
@ -2424,7 +2424,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
if hasFeatured {
if let _ = strongSelf.validLayout, let _ = strongSelf.parent as? TabBarController {
let _ = (ApplicationSpecificNotice.incrementChatFolderTips(accountManager: strongSelf.context.sharedContext.accountManager)
|> deliverOnMainQueue).start(next: { count in
|> deliverOnMainQueue).startStandalone(next: { count in
guard let strongSelf = self, let _ = strongSelf.validLayout, let parentController = strongSelf.parent as? TabBarController, let sourceFrame = parentController.frameForControllerTab(controller: strongSelf) else {
return
}
@ -2436,7 +2436,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
let text: String
if hasFilters {
text = strongSelf.presentationData.strings.ChatList_TabIconFoldersTooltipNonEmptyFolders
let _ = strongSelf.context.engine.peers.markChatListFeaturedFiltersAsSeen().start()
let _ = strongSelf.context.engine.peers.markChatListFeaturedFiltersAsSeen().startStandalone()
return
} else {
text = strongSelf.presentationData.strings.ChatList_TabIconFoldersTooltipEmptyFolders
@ -2794,7 +2794,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
TelegramEngine.EngineData.Item.NotificationSettings.Global(),
TelegramEngine.EngineData.Item.Contacts.Top()
)
|> deliverOnMainQueue).start(next: { [weak self] notificationSettings, globalSettings, topSearchPeers in
|> deliverOnMainQueue).startStandalone(next: { [weak self] notificationSettings, globalSettings, topSearchPeers in
guard let self else {
return
}
@ -2853,7 +2853,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
let _ = (self.context.engine.data.get(
TelegramEngine.EngineData.Item.Peer.Peer(id: peer.id)
)
|> deliverOnMainQueue).start(next: { [weak self] peer in
|> deliverOnMainQueue).startStandalone(next: { [weak self] peer in
guard let self, let peer else {
return
}
@ -2934,7 +2934,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
let _ = (self.context.engine.data.get(
TelegramEngine.EngineData.Item.Peer.Peer(id: peer.id)
)
|> deliverOnMainQueue).start(next: { [weak self] peer in
|> deliverOnMainQueue).startStandalone(next: { [weak self] peer in
guard let self else {
return
}
@ -2955,7 +2955,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
guard let self else {
return
}
let _ = self.context.engine.peers.togglePeerStoriesMuted(peerId: peer.id).start()
let _ = self.context.engine.peers.togglePeerStoriesMuted(peerId: peer.id).startStandalone()
let iconColor = UIColor.white
let presentationData = self.context.sharedContext.currentPresentationData.with { $0 }
@ -3245,7 +3245,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
})
return updatedFilters
}
|> deliverOnMainQueue).start(completed: { [weak self] in
|> deliverOnMainQueue).startStandalone(completed: { [weak self] in
guard let strongSelf = self else {
return
}
@ -3276,7 +3276,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
let _ = (pendingSecondaryContext.ready.get()
|> filter { $0 }
|> take(1)
|> deliverOnMainQueue).start(next: { [weak self, weak pendingSecondaryContext] _ in
|> deliverOnMainQueue).startStandalone(next: { [weak self, weak pendingSecondaryContext] _ in
guard let self, let pendingSecondaryContext = pendingSecondaryContext, self.pendingSecondaryContext === pendingSecondaryContext else {
return
}
@ -3308,7 +3308,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
public static func openMoreMenu(context: AccountContext, peerId: EnginePeer.Id, sourceController: ViewController, isViewingAsTopics: Bool, sourceView: UIView, gesture: ContextGesture?) {
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|> deliverOnMainQueue).start(next: { peer in
|> deliverOnMainQueue).startStandalone(next: { peer in
guard case let .channel(channel) = peer else {
return
}
@ -3381,7 +3381,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
let _ = (context.engine.data.get(
TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)
)
|> deliverOnMainQueue).start(next: { peer in
|> deliverOnMainQueue).startStandalone(next: { peer in
guard let sourceController = sourceController, let peer = peer, let controller = context.sharedContext.makePeerInfoController(context: context, updatedPresentationData: nil, peer: peer._asPeer(), mode: .generic, avatarInitiallyExpanded: false, fromChat: false, requestsContext: nil) else {
return
}
@ -3396,7 +3396,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
f(.default)
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|> deliverOnMainQueue).start(next: { peer in
|> deliverOnMainQueue).startStandalone(next: { peer in
guard let sourceController = sourceController, let peer = peer else {
return
}
@ -3431,9 +3431,9 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
controller?.isInProgress = true
let _ = (context.engine.peers.createForumChannelTopic(id: peerId, title: title, iconColor: iconColor, iconFileId: fileId)
|> deliverOnMainQueue).start(next: { topicId in
|> deliverOnMainQueue).startStandalone(next: { topicId in
if let navigationController = (sourceController.navigationController as? NavigationController) {
let _ = context.sharedContext.navigateToForumThread(context: context, peerId: peerId, threadId: topicId, messageId: nil, navigationController: navigationController, activateInput: .text, keepStack: .never).start()
let _ = context.sharedContext.navigateToForumThread(context: context, peerId: peerId, threadId: topicId, messageId: nil, navigationController: navigationController, activateInput: .text, keepStack: .never).startStandalone()
}
}, error: { _ in
controller?.isInProgress = false
@ -3450,11 +3450,11 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
}
func openArchiveMoreMenu(sourceView: UIView, gesture: ContextGesture?) {
let _ = self.context.engine.privacy.updateGlobalPrivacySettings().start()
let _ = self.context.engine.privacy.updateGlobalPrivacySettings().startStandalone()
let _ = (
self.context.engine.messages.chatList(group: .archive, count: 10) |> take(1)
|> deliverOnMainQueue).start(next: { [weak self] archiveChatList in
|> deliverOnMainQueue).startStandalone(next: { [weak self] archiveChatList in
guard let self else {
return
}
@ -3485,7 +3485,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
let _ = (self.context.engine.data.get(
TelegramEngine.EngineData.Item.Configuration.GlobalPrivacy()
)
|> deliverOnMainQueue).start(next: { [weak self] settings in
|> deliverOnMainQueue).startStandalone(next: { [weak self] settings in
guard let self else {
return
}
@ -3518,7 +3518,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
self.context.account.postbox.peerView(id: self.context.account.peerId),
self.context.engine.data.get(TelegramEngine.EngineData.Item.Configuration.UserLimits(isPremium: false))
)
|> deliverOnMainQueue).start(next: { [weak self] countAndFilterItems, peerView, limits in
|> deliverOnMainQueue).startStrict(next: { [weak self] countAndFilterItems, peerView, limits in
guard let strongSelf = self else {
return
}
@ -3665,7 +3665,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
}
let _ = (self.context.engine.peers.currentChatListFilters()
|> deliverOnMainQueue).start(next: { [weak self] filters in
|> deliverOnMainQueue).startStandalone(next: { [weak self] filters in
guard let strongSelf = self else {
return
}
@ -3710,7 +3710,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
markItems.append((EngineChatList.Group(additionalGroupId), filterPredicate))
}
let _ = self.context.engine.messages.markAllChatsAsReadInteractively(items: markItems).start()
let _ = self.context.engine.messages.markAllChatsAsReadInteractively(items: markItems).startStandalone()
break
}
}
@ -3786,7 +3786,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
return true
}
|> timeout(1.0, queue: .mainQueue(), alternate: .single(false))
|> deliverOnMainQueue).start(next: { [weak self] _ in
|> deliverOnMainQueue).startStandalone(next: { [weak self] _ in
guard let self else {
return
}
@ -3834,7 +3834,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
}
}
self.sharedOpenStoryProgressDisposable.set((signal |> deliverOnMainQueue).start(completed: { [weak self] in
self.sharedOpenStoryProgressDisposable.set((signal |> deliverOnMainQueue).startStrict(completed: { [weak self] in
guard let self else {
return
}
@ -3856,7 +3856,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
guard let self else {
return
}
self.sharedOpenStoryProgressDisposable.set(signal.start())
self.sharedOpenStoryProgressDisposable.set(signal.startStrict())
}
)
}))
@ -3977,7 +3977,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
let storyContent = StoryContentContextImpl(context: self.context, isHidden: self.location == .chatList(groupId: .archive), focusedPeerId: peerId, singlePeer: false, fixedOrder: self.fixedStorySubscriptionOrder)
let _ = (storyContent.state
|> take(1)
|> deliverOnMainQueue).start(next: { [weak self] storyContentState in
|> deliverOnMainQueue).startStandalone(next: { [weak self] storyContentState in
guard let self else {
return
}
@ -4058,7 +4058,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
let _ = (strongSelf.context.engine.peers.updateChatListFiltersInteractively { filters in
return filters.filter({ $0.id != id })
}).start()
}).startStandalone()
}
if strongSelf.chatListDisplayNode.mainContainerNode.currentItemNode.chatListFilter?.id == id {
@ -4072,7 +4072,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
let _ = (self.context.engine.peers.currentChatListFilters()
|> take(1)
|> deliverOnMainQueue).start(next: { [weak self] filters in
|> deliverOnMainQueue).startStandalone(next: { [weak self] filters in
guard let self else {
return
}
@ -4089,7 +4089,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
self.context.engine.peers.getExportedChatFolderLinks(id: id),
self.context.engine.peers.requestLeaveChatFolderSuggestions(folderId: id)
)
|> deliverOnMainQueue).start(next: { [weak self] peerData, links, defaultSelectedPeerIds in
|> deliverOnMainQueue).startStandalone(next: { [weak self] peerData, links, defaultSelectedPeerIds in
guard let self else {
return
}
@ -4224,7 +4224,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
//TODO:scroll to top?
let _ = (combineLatest(self.chatListDisplayNode.mainContainerNode.currentItemNode.contentsReady |> take(1), self.context.account.postbox.tailChatListView(groupId: .root, count: 16, summaryComponents: ChatListEntrySummaryComponents(components: [:])) |> take(1))
|> deliverOnMainQueue).start(next: { [weak self] _, chatListView in
|> deliverOnMainQueue).startStandalone(next: { [weak self] _, chatListView in
guard let strongSelf = self else {
return
}
@ -4477,7 +4477,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
signal = .complete()
}
let _ = (signal
|> deliverOnMainQueue).start(completed: { [weak self] in
|> deliverOnMainQueue).startStandalone(completed: { [weak self] in
self?.donePressed()
completion?()
})
@ -4663,7 +4663,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
if !peerIds.isEmpty {
self.chatListDisplayNode.effectiveContainerNode.currentItemNode.setCurrentRemovingItemId(ChatListNodeState.ItemId(peerId: peerIds.first!, threadId: nil))
let _ = (self.context.engine.peers.updatePeersGroupIdInteractively(peerIds: Array(peerIds), groupId: .root)
|> deliverOnMainQueue).start(completed: { [weak self] in
|> deliverOnMainQueue).startStandalone(completed: { [weak self] in
guard let strongSelf = self else {
return
}
@ -4696,12 +4696,12 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
}
self.joinForumDisposable.set((signal
|> deliverOnMainQueue).start(error: { [weak self] error in
|> deliverOnMainQueue).startStrict(error: { [weak self] error in
guard let strongSelf = self else {
return
}
let _ = (strongSelf.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|> deliverOnMainQueue).start(next: { peer in
|> deliverOnMainQueue).startStandalone(next: { peer in
guard let strongSelf = self, let peer = peer else {
return
}
@ -4744,7 +4744,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
updatedValue = settings.isHiddenByDefault
return settings
})
|> deliverOnMainQueue).start(completed: { [weak self] in
|> deliverOnMainQueue).startStandalone(completed: { [weak self] in
guard let strongSelf = self else {
return
}
@ -4773,7 +4773,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
var settings = settings
settings.isHiddenByDefault = false
return settings
}).start()
}).startStandalone()
return true
}
@ -4794,12 +4794,12 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
return state
}
let _ = hideAccountPromoInfoChat(account: self.context.account, peerId: id).start()
let _ = hideAccountPromoInfoChat(account: self.context.account, peerId: id).startStandalone()
}
func deletePeerChat(peerId: PeerId, joined: Bool) {
let _ = (self.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.RenderedPeer(id: peerId))
|> deliverOnMainQueue).start(next: { [weak self] peer in
|> deliverOnMainQueue).startStandalone(next: { [weak self] peer in
guard let strongSelf = self, let peer = peer, let chatPeer = peer.peers[peer.peerId], let mainPeer = peer.chatMainPeer else {
return
}
@ -4921,7 +4921,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
guard let strongSelf = self else {
return
}
let _ = strongSelf.context.engine.privacy.requestUpdatePeerIsBlocked(peerId: peer.peerId, isBlocked: true).start()
let _ = strongSelf.context.engine.privacy.requestUpdatePeerIsBlocked(peerId: peer.peerId, isBlocked: true).startStandalone()
})
}
}))
@ -4949,7 +4949,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
return false
}
if value == .commit {
let _ = strongSelf.context.engine.messages.clearHistoryInteractively(peerId: peerId, threadId: nil, type: type).start(completed: {
let _ = strongSelf.context.engine.messages.clearHistoryInteractively(peerId: peerId, threadId: nil, type: type).startStandalone(completed: {
guard let strongSelf = self else {
return
}
@ -5173,7 +5173,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
if value == .commit {
self.chatListDisplayNode.effectiveContainerNode.currentItemNode.setCurrentRemovingItemId(ChatListNodeState.ItemId(peerId: peerId, threadId: threadId))
let _ = self.context.engine.peers.removeForumChannelThread(id: peerId, threadId: threadId).start(completed: { [weak self] in
let _ = self.context.engine.peers.removeForumChannelThread(id: peerId, threadId: threadId).startStandalone(completed: { [weak self] in
guard let self else {
return
}
@ -5208,16 +5208,16 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
}
private func setPeerThreadStopped(peerId: EnginePeer.Id, threadId: Int64, isStopped: Bool) {
self.actionDisposables.add(self.context.engine.peers.setForumChannelTopicClosed(id: peerId, threadId: threadId, isClosed: isStopped).start())
self.actionDisposables.add(self.context.engine.peers.setForumChannelTopicClosed(id: peerId, threadId: threadId, isClosed: isStopped).startStrict())
}
private func setPeerThreadPinned(peerId: EnginePeer.Id, threadId: Int64, isPinned: Bool) {
self.actionDisposables.add(self.context.engine.peers.toggleForumChannelTopicPinned(id: peerId, threadId: threadId).start())
self.actionDisposables.add(self.context.engine.peers.toggleForumChannelTopicPinned(id: peerId, threadId: threadId).startStrict())
}
private func setPeerThreadHidden(peerId: EnginePeer.Id, threadId: Int64, isHidden: Bool) {
self.actionDisposables.add((self.context.engine.peers.setForumChannelTopicHidden(id: peerId, threadId: threadId, isHidden: isHidden)
|> deliverOnMainQueue).start(completed: { [weak self] in
|> deliverOnMainQueue).startStrict(completed: { [weak self] in
if let strongSelf = self {
strongSelf.chatListDisplayNode.effectiveContainerNode.updateState { state in
var state = state
@ -5350,9 +5350,9 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
ApplicationSpecificNotice.incrementArchiveChatTips(accountManager: self.context.sharedContext.accountManager, count: 1),
hasArchived
)
|> deliverOnMainQueue).start(next: { [weak self] previousHintCount, hasArchived in
|> deliverOnMainQueue).startStandalone(next: { [weak self] previousHintCount, hasArchived in
let _ = (engine.peers.updatePeersGroupIdInteractively(peerIds: peerIds, groupId: .archive)
|> deliverOnMainQueue).start(completed: {
|> deliverOnMainQueue).startStandalone(completed: {
guard let strongSelf = self else {
return
}
@ -5369,7 +5369,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
if value == .undo {
strongSelf.chatListDisplayNode.effectiveContainerNode.currentItemNode.setCurrentRemovingItemId(ChatListNodeState.ItemId(peerId: peerIds[0], threadId: nil))
let _ = (engine.peers.updatePeersGroupIdInteractively(peerIds: peerIds, groupId: .root)
|> deliverOnMainQueue).start(completed: {
|> deliverOnMainQueue).startStandalone(completed: {
guard let strongSelf = self else {
return
}
@ -5472,7 +5472,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
if case let .channel(channel) = chatPeer {
strongSelf.context.peerChannelMemberCategoriesContextsManager.externallyRemoved(peerId: channel.id, memberId: strongSelf.context.account.peerId)
}
let _ = strongSelf.context.engine.peers.removePeerChat(peerId: peerId, reportChatSpam: false, deleteGloballyIfPossible: deleteGloballyIfPossible).start(completed: {
let _ = strongSelf.context.engine.peers.removePeerChat(peerId: peerId, reportChatSpam: false, deleteGloballyIfPossible: deleteGloballyIfPossible).startStandalone(completed: {
guard let strongSelf = self else {
return
}
@ -5549,7 +5549,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
TelegramEngine.EngineData.Item.Configuration.UserLimits(isPremium: true)
)
)
|> deliverOnMainQueue).start(next: { [weak self] presetList, filterItemsAndTotalCount, result in
|> deliverOnMainQueue).startStandalone(next: { [weak self] presetList, filterItemsAndTotalCount, result in
guard let strongSelf = self else {
return
}
@ -5557,7 +5557,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
let (accountPeer, limits, _) = result
let isPremium = accountPeer?.isPremium ?? false
let _ = strongSelf.context.engine.peers.markChatListFeaturedFiltersAsSeen().start()
let _ = strongSelf.context.engine.peers.markChatListFeaturedFiltersAsSeen().startStandalone()
let (_, filterItems) = filterItemsAndTotalCount
var items: [ContextMenuItem] = []
@ -5948,7 +5948,7 @@ private final class ChatListLocationContext {
peerStatus,
parentController.updatedPresentationData.1,
storyPostingAvailable
).start(next: { [weak self] networkState, proxy, passcode, stateAndFilterId, isReorderingTabs, peerStatus, presentationData, storyPostingAvailable in
).startStrict(next: { [weak self] networkState, proxy, passcode, stateAndFilterId, isReorderingTabs, peerStatus, presentationData, storyPostingAvailable in
guard let self else {
return
}
@ -6010,7 +6010,7 @@ private final class ChatListLocationContext {
containerNode.currentItemState,
parentController.updatedPresentationData.1
)
|> deliverOnMainQueue).start(next: { [weak self] peerView, onlineMemberCount, stateAndFilterId, presentationData in
|> deliverOnMainQueue).startStrict(next: { [weak self] peerView, onlineMemberCount, stateAndFilterId, presentationData in
guard let self else {
return
}
@ -6078,7 +6078,7 @@ private final class ChatListLocationContext {
parentController.updatedPresentationData.1,
peerIdsAndOptions,
peerView
).start(next: { [weak self, weak containerNode] presentationData, peerIdsAndOptions, peerView in
).startStrict(next: { [weak self, weak containerNode] presentationData, peerIdsAndOptions, peerView in
guard let strongSelf = self, let containerNode = containerNode, let parentController = strongSelf.parentController else {
return
}
@ -6433,7 +6433,7 @@ private final class ChatListLocationContext {
let _ = (self.context.engine.data.get(
TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)
)
|> deliverOnMainQueue).start(next: { [weak self] peer in
|> deliverOnMainQueue).startStandalone(next: { [weak self] peer in
guard let self, let peer = peer, let controller = self.context.sharedContext.makePeerInfoController(context: self.context, updatedPresentationData: nil, peer: peer._asPeer(), mode: .generic, avatarInitiallyExpanded: false, fromChat: false, requestsContext: nil) else {
return
}

View File

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

View File

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

View File

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

View File

@ -225,7 +225,7 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo
return
}
let _ = (strongSelf.context.engine.peers.clearRecentlySearchedPeers()
|> deliverOnMainQueue).start()
|> deliverOnMainQueue).startStandalone()
})
]), ActionSheetItemGroup(items: [
ActionSheetButtonItem(title: presentationData.strings.Common_Cancel, color: .accent, font: .bold, action: { [weak actionSheet] in
@ -467,7 +467,8 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo
}
}
return suggestedFilters
} |> deliverOnMainQueue).start(next: { [weak self] filters in
}
|> deliverOnMainQueue).startStrict(next: { [weak self] filters in
guard let strongSelf = self else {
return
}
@ -492,7 +493,7 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo
}))
self.presentationDataDisposable = ((updatedPresentationData?.signal ?? context.sharedContext.presentationData)
|> deliverOnMainQueue).start(next: { [weak self] presentationData in
|> deliverOnMainQueue).startStrict(next: { [weak self] presentationData in
if let strongSelf = self {
let previousTheme = strongSelf.presentationData.theme
strongSelf.presentationData = presentationData
@ -505,7 +506,7 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo
if case let .forum(peerId) = location {
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|> deliverOnMainQueue).start(next: { [weak self] peer in
|> deliverOnMainQueue).startStandalone(next: { [weak self] peer in
self?.forumPeer = peer
self?.updateSearchOptions(nil)
})
@ -736,7 +737,7 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo
}
return messages
}
|> deliverOnMainQueue).start(next: { messages in
|> deliverOnMainQueue).startStandalone(next: { messages in
if let strongSelf = self, !messages.isEmpty {
let shareController = ShareController(context: strongSelf.context, subject: .messages(messages.sorted(by: { lhs, rhs in
return lhs.index < rhs.index
@ -768,7 +769,7 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo
}
return messages
}
|> deliverOnMainQueue).start(next: { messages in
|> deliverOnMainQueue).startStandalone(next: { messages in
if let strongSelf = self, !messages.isEmpty {
enum PeerType {
case group
@ -955,7 +956,7 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo
return
}
let _ = (strongSelf.context.account.postbox.mediaBox.removeCachedResources([MediaResourceId(downloadResource.id)], notify: true)
|> deliverOnMainQueue).start(completed: {
|> deliverOnMainQueue).startStandalone(completed: {
f(.dismissWithoutContent)
})
})))
@ -1127,7 +1128,7 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo
private func mediaMessageContextAction(_ message: EngineMessage, node: ASDisplayNode?, rect: CGRect?, gesture anyRecognizer: UIGestureRecognizer?) {
let gesture: ContextGesture? = anyRecognizer as? ContextGesture
let _ = (chatMediaListPreviewControllerData(context: self.context, chatLocation: .peer(id: message.id.peerId), chatLocationContextHolder: Atomic<ChatLocationContextHolder?>(value: nil), message: message._asMessage(), standalone: true, reverseMessageGalleryOrder: false, navigationController: self.navigationController)
|> deliverOnMainQueue).start(next: { [weak self] previewData in
|> deliverOnMainQueue).startStandalone(next: { [weak self] previewData in
guard let strongSelf = self else {
gesture?.cancel()
return
@ -1217,7 +1218,7 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo
}
return messages
}
|> deliverOnMainQueue).start(next: { [weak self] messages in
|> deliverOnMainQueue).startStandalone(next: { [weak self] messages in
guard let strongSelf = self else {
return
}
@ -1246,7 +1247,7 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo
}
let _ = (strongSelf.context.account.postbox.mediaBox.removeCachedResources(Array(resourceIds), force: true, notify: true)
|> deliverOnMainQueue).start(completed: {
|> deliverOnMainQueue).startStandalone(completed: {
guard let strongSelf = self else {
return
}
@ -1267,7 +1268,7 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo
self.context.engine.messages.ensureMessagesAreLocallyAvailable(messages: messages.values.filter { messageIds.contains($0.id) })
self.activeActionDisposable.set((self.context.sharedContext.chatAvailableMessageActions(engine: self.context.engine, accountPeerId: self.context.account.peerId, messageIds: messageIds, messages: messages, peers: peers)
|> deliverOnMainQueue).start(next: { [weak self] actions in
|> deliverOnMainQueue).startStrict(next: { [weak self] actions in
if let strongSelf = self, !actions.options.isEmpty {
let actionSheet = ActionSheetController(presentationData: strongSelf.presentationData)
var items: [ActionSheetItem] = []
@ -1283,7 +1284,7 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo
items.append(ActionSheetButtonItem(title: globalTitle, color: .destructive, action: { [weak actionSheet] in
actionSheet?.dismissAnimated()
if let strongSelf = self {
let _ = strongSelf.context.engine.messages.deleteMessagesInteractively(messageIds: Array(messageIds), type: .forEveryone).start()
let _ = strongSelf.context.engine.messages.deleteMessagesInteractively(messageIds: Array(messageIds), type: .forEveryone).startStandalone()
strongSelf.updateState { state in
return state.withUpdatedSelectedMessageIds(nil)
@ -1299,7 +1300,7 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo
items.append(ActionSheetButtonItem(title: localOptionText, color: .destructive, action: { [weak actionSheet] in
actionSheet?.dismissAnimated()
if let strongSelf = self {
let _ = strongSelf.context.engine.messages.deleteMessagesInteractively(messageIds: Array(messageIds), type: .forLocalPeer).start()
let _ = strongSelf.context.engine.messages.deleteMessagesInteractively(messageIds: Array(messageIds), type: .forLocalPeer).startStandalone()
strongSelf.updateState { state in
return state.withUpdatedSelectedMessageIds(nil)
@ -1362,7 +1363,7 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo
var displayPeers: [EnginePeer] = []
for peer in peers {
let _ = (enqueueMessages(account: strongSelf.context.account, peerId: peer.id, messages: result)
|> deliverOnMainQueue).start(next: { messageIds in
|> deliverOnMainQueue).startStandalone(next: { messageIds in
if let strongSelf = self {
let signals: [Signal<Bool, NoError>] = messageIds.compactMap({ id -> Signal<Bool, NoError>? in
guard let id = id else {
@ -1382,7 +1383,7 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo
strongSelf.shareStatusDisposable = MetaDisposable()
}
strongSelf.shareStatusDisposable?.set((combineLatest(signals)
|> deliverOnMainQueue).start())
|> deliverOnMainQueue).startStrict())
}
})
if case let .secretChat(secretPeer) = peer {
@ -1436,7 +1437,7 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo
let _ = (enqueueMessages(account: strongSelf.context.account, peerId: peerId, messages: messageIds.map { id -> EnqueueMessage in
return .forward(source: id, threadId: threadId, grouping: .auto, attributes: [], correlationId: nil)
})
|> deliverOnMainQueue).start(next: { [weak self] messageIds in
|> deliverOnMainQueue).startStandalone(next: { [weak self] messageIds in
if let strongSelf = self {
let signals: [Signal<Bool, NoError>] = messageIds.compactMap({ id -> Signal<Bool, NoError>? in
guard let id = id else {
@ -1453,7 +1454,7 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo
|> take(1)
})
strongSelf.activeActionDisposable.set((combineLatest(signals)
|> deliverOnMainQueue).start(completed: {
|> deliverOnMainQueue).startStrict(completed: {
guard let strongSelf = self else {
return
}
@ -1475,7 +1476,7 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo
let _ = (ChatInterfaceState.update(engine: strongSelf.context.engine, peerId: peerId, threadId: threadId, { currentState in
return currentState.withUpdatedForwardMessageIds(Array(messageIds))
})
|> deliverOnMainQueue).start(completed: { [weak self] in
|> deliverOnMainQueue).startStandalone(completed: { [weak self] in
if let strongSelf = self {
let proceed: (ChatController) -> Void = { chatController in
chatController.purposefulAction = { [weak self] in
@ -1493,7 +1494,7 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo
strongSelf.activeActionDisposable.set((chatController.ready.get()
|> filter { $0 }
|> take(1)
|> deliverOnMainQueue).start(next: { [weak navigationController] _ in
|> deliverOnMainQueue).startStrict(next: { [weak navigationController] _ in
viewControllers.removeAll(where: { $0 is PeerSelectionController })
navigationController?.setViewControllers(viewControllers, animated: true)
}))
@ -1502,7 +1503,7 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo
if let threadId = threadId {
let _ = (strongSelf.context.sharedContext.chatControllerForForumThread(context: strongSelf.context, peerId: peerId, threadId: threadId)
|> deliverOnMainQueue).start(next: { chatController in
|> deliverOnMainQueue).startStandalone(next: { chatController in
proceed(chatController)
})
} else {

View File

@ -2154,7 +2154,7 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
}, peerSelected: { [weak self] peer, chatPeer, threadId, _ in
interaction.dismissInput()
interaction.openPeer(peer, chatPeer, threadId, false)
let _ = context.engine.peers.addRecentlySearchedPeer(peerId: peer.id).start()
let _ = context.engine.peers.addRecentlySearchedPeer(peerId: peer.id).startStandalone()
self?.listNode.clearHighlightAnimated(true)
}, disabledPeerSelected: { _, _ in
}, togglePeerSelected: { _, _ in
@ -2205,7 +2205,7 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
return
}
let _ = (self.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|> deliverOnMainQueue).start(next: { [weak self] peer in
|> deliverOnMainQueue).startStandalone(next: { [weak self] peer in
guard let self, let peer else {
return
}
@ -2325,14 +2325,14 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
let previousExpandGlobalSearch = Atomic<Bool>(value: false)
let _ = (searchQuery
|> deliverOnMainQueue).start(next: { [weak self, weak listInteraction, weak chatListInteraction] query in
|> deliverOnMainQueue).startStandalone(next: { [weak self, weak listInteraction, weak chatListInteraction] query in
self?.searchQueryValue = query
listInteraction?.searchTextHighightState = query
chatListInteraction?.searchTextHighightState = query
})
let _ = (searchOptions
|> deliverOnMainQueue).start(next: { [weak self] options in
|> deliverOnMainQueue).startStandalone(next: { [weak self] options in
self?.searchOptionsValue = options
})
@ -2384,7 +2384,7 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
return (mappedItems, isSearching)
}
}
|> deliverOnMainQueue).start(next: { [weak self] foundItems in
|> deliverOnMainQueue).startStrict(next: { [weak self] foundItems in
if let strongSelf = self {
let previousSelectedMessageIds = previousSelectedMessages.swap(strongSelf.selectedMessages)
let previousExpandGlobalSearch = previousExpandGlobalSearch.swap(strongSelf.searchStateValue.expandGlobalSearch)
@ -2475,7 +2475,7 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
return
}
let _ = clearRecentDownloadList(postbox: strongSelf.context.account.postbox).start()
let _ = clearRecentDownloadList(postbox: strongSelf.context.account.postbox).startStandalone()
}))
actionSheet.setItemGroups([ActionSheetItemGroup(items: items), ActionSheetItemGroup(items: [
@ -2492,7 +2492,7 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
let _ = ((strongSelf.context.fetchManager as! FetchManagerImpl).entriesSummary
|> take(1)
|> deliverOnMainQueue).start(next: { entries in
|> deliverOnMainQueue).startStandalone(next: { entries in
guard let strongSelf = self, !entries.isEmpty else {
return
}
@ -2599,14 +2599,14 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
}
if case .chats = key, !peersFilter.contains(.excludeRecent) {
self.updatedRecentPeersDisposable.set(context.engine.peers.managedUpdatedRecentPeers().start())
self.updatedRecentPeersDisposable.set(context.engine.peers.managedUpdatedRecentPeers().startStrict())
}
self.recentDisposable.set((combineLatest(queue: .mainQueue(),
presentationDataPromise.get(),
recentItems
)
|> deliverOnMainQueue).start(next: { [weak self] presentationData, entries in
|> deliverOnMainQueue).startStrict(next: { [weak self] presentationData, entries in
if let strongSelf = self {
let previousEntries = previousRecentItems.swap(entries)
@ -2614,7 +2614,7 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
let transition = chatListSearchContainerPreparedRecentTransition(from: previousEntries ?? [], to: entries, context: context, presentationData: presentationData, filter: peersFilter, peerSelected: { peer, threadId in
interaction.openPeer(peer, nil, threadId, true)
if threadId == nil {
let _ = context.engine.peers.addRecentlySearchedPeer(peerId: peer.id).start()
let _ = context.engine.peers.addRecentlySearchedPeer(peerId: peer.id).startStandalone()
}
self?.recentListNode.clearHighlightAnimated(true)
}, disabledPeerSelected: { peer, threadId in
@ -2628,7 +2628,7 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
}, clearRecentlySearchedPeers: {
interaction.clearRecentSearch()
}, deletePeer: { peerId in
let _ = context.engine.peers.removeRecentlySearchedPeer(peerId: peerId).start()
let _ = context.engine.peers.removeRecentlySearchedPeer(peerId: peerId).startStandalone()
}, animationCache: strongSelf.animationCache, animationRenderer: strongSelf.animationRenderer, openStories: { peerId, avatarNode in
interaction.openStories?(peerId, avatarNode)
})
@ -2637,7 +2637,7 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
}))
self.presentationDataDisposable = ((updatedPresentationData?.signal ?? context.sharedContext.presentationData)
|> deliverOnMainQueue).start(next: { [weak self] presentationData in
|> deliverOnMainQueue).startStrict(next: { [weak self] presentationData in
if let strongSelf = self {
strongSelf.presentationData = presentationData
strongSelf.presentationDataPromise.set(.single(ChatListPresentationData(theme: presentationData.theme, fontSize: presentationData.listsFontSize, strings: presentationData.strings, dateTimeFormat: presentationData.dateTimeFormat, nameSortOrder: presentationData.nameSortOrder, nameDisplayOrder: presentationData.nameDisplayOrder, disableAnimations: true)))
@ -2713,7 +2713,7 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
return .single(nil)
}
}
|> deliverOnMainQueue).start(next: { [weak self] playlistStateAndType in
|> deliverOnMainQueue).startStrict(next: { [weak self] playlistStateAndType in
guard let strongSelf = self else {
return
}
@ -2737,7 +2737,7 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
}
self.deletedMessagesDisposable = (context.account.stateManager.deletedMessages
|> deliverOnMainQueue).start(next: { [weak self] messageIds in
|> deliverOnMainQueue).startStrict(next: { [weak self] messageIds in
if let strongSelf = self {
strongSelf.updateState { state in
var state = state
@ -2810,7 +2810,7 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
return
}
strongSelf.scheduledMarkRecentDownloadsAsSeen = false
let _ = markAllRecentDownloadItemsAsSeen(postbox: strongSelf.context.account.postbox).start()
let _ = markAllRecentDownloadItemsAsSeen(postbox: strongSelf.context.account.postbox).startStandalone()
})
}
}
@ -2907,7 +2907,7 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
})
return rate
}
|> deliverOnMainQueue).start(next: { baseRate in
|> deliverOnMainQueue).startStandalone(next: { baseRate in
guard let strongSelf = self, let (_, _, _, _, type, _) = strongSelf.playlistStateAndType else {
return
}
@ -3035,7 +3035,7 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
progressDisposable.dispose()
}
}
|> deliverOnMainQueue).start(next: { index in
|> deliverOnMainQueue).startStrict(next: { index in
guard let strongSelf = self else {
return
}

View File

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

View File

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

View File

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

View File

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

View File

@ -1417,7 +1417,7 @@ public final class ChatListNode: ListView {
}
}, setItemPinned: { [weak self] itemId, _ in
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: context.account.peerId))
|> deliverOnMainQueue).start(next: { peer in
|> deliverOnMainQueue).startStandalone(next: { peer in
guard let strongSelf = self else {
return
}
@ -1433,7 +1433,7 @@ public final class ChatListNode: ListView {
location = .group(groupId._asGroup())
}
let _ = (context.engine.peers.toggleItemPinned(location: location, itemId: itemId)
|> deliverOnMainQueue).start(next: { result in
|> deliverOnMainQueue).startStandalone(next: { result in
if let strongSelf = self {
switch result {
case .done:
@ -1486,7 +1486,7 @@ public final class ChatListNode: ListView {
}
strongSelf.setCurrentRemovingItemId(ChatListNodeState.ItemId(peerId: peerId, threadId: nil))
let _ = (context.engine.peers.togglePeerMuted(peerId: peerId, threadId: nil)
|> deliverOnMainQueue).start(completed: {
|> deliverOnMainQueue).startStandalone(completed: {
self?.updateState { state in
var state = state
state.peerIdWithRevealedOptions = nil
@ -1497,7 +1497,7 @@ public final class ChatListNode: ListView {
}, setPeerThreadMuted: { [weak self] peerId, threadId, value in
self?.setCurrentRemovingItemId(ChatListNodeState.ItemId(peerId: peerId, threadId: threadId))
let _ = (context.engine.peers.updatePeerMuteSetting(peerId: peerId, threadId: threadId, muteInterval: value ? Int32.max : 0)
|> deliverOnMainQueue).start(completed: {
|> deliverOnMainQueue).startStandalone(completed: {
self?.updateState { state in
var state = state
state.peerIdWithRevealedOptions = nil
@ -1523,7 +1523,7 @@ public final class ChatListNode: ListView {
}
self?.setCurrentRemovingItemId(ChatListNodeState.ItemId(peerId: peerId, threadId: nil))
let _ = (context.engine.messages.togglePeersUnreadMarkInteractively(peerIds: [peerId], setToValue: nil)
|> deliverOnMainQueue).start(completed: {
|> deliverOnMainQueue).startStandalone(completed: {
self?.updateState { state in
var state = state
state.peerIdWithRevealedOptions = nil
@ -1568,7 +1568,7 @@ public final class ChatListNode: ListView {
return
}
let _ = (self.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|> deliverOnMainQueue).start(next: { [weak self] peer in
|> deliverOnMainQueue).startStandalone(next: { [weak self] peer in
guard let self, let peer else {
return
}
@ -1586,7 +1586,7 @@ public final class ChatListNode: ListView {
}
Queue.mainQueue().after(0.6) { [weak self] in
if let self {
let _ = dismissServerProvidedSuggestion(account: self.context.account, suggestion: .setupPassword).start()
let _ = dismissServerProvidedSuggestion(account: self.context.account, suggestion: .setupPassword).startStandalone()
}
}
let controller = self.context.sharedContext.makeSetupTwoFactorAuthController(context: self.context)
@ -1597,9 +1597,9 @@ public final class ChatListNode: ListView {
}
Queue.mainQueue().after(0.6) { [weak self] in
if let self {
let _ = dismissServerProvidedSuggestion(account: self.context.account, suggestion: .annualPremium).start()
let _ = dismissServerProvidedSuggestion(account: self.context.account, suggestion: .upgradePremium).start()
let _ = dismissServerProvidedSuggestion(account: self.context.account, suggestion: .restorePremium).start()
let _ = dismissServerProvidedSuggestion(account: self.context.account, suggestion: .annualPremium).startStandalone()
let _ = dismissServerProvidedSuggestion(account: self.context.account, suggestion: .upgradePremium).startStandalone()
let _ = dismissServerProvidedSuggestion(account: self.context.account, suggestion: .restorePremium).startStandalone()
}
}
let controller = self.context.sharedContext.makePremiumIntroController(context: self.context, source: .ads, forceDark: false, dismissed: nil)
@ -1615,7 +1615,7 @@ public final class ChatListNode: ListView {
return !state.sessions.isEmpty
}
|> take(1)
|> deliverOnMainQueue).start(completed: { [weak self] in
|> deliverOnMainQueue).startStandalone(completed: { [weak self] in
guard let self else {
return
}
@ -1648,13 +1648,13 @@ public final class ChatListNode: ListView {
return true
}))
let _ = self.context.engine.privacy.confirmNewSessionReview(id: newSessionReview.id).start()
let _ = self.context.engine.privacy.confirmNewSessionReview(id: newSessionReview.id).startStandalone()
} else {
self.push?(NewSessionInfoScreen(context: self.context, newSessionReview: newSessionReview))
//#if DEBUG
//#else
let _ = self.context.engine.privacy.terminateAnotherSession(id: newSessionReview.id).start()
let _ = self.context.engine.privacy.terminateAnotherSession(id: newSessionReview.id).startStandalone()
//#endif
}
}, openChatFolderUpdates: { [weak self] in
@ -1663,7 +1663,7 @@ public final class ChatListNode: ListView {
}
let _ = (self.chatFolderUpdates.get()
|> take(1)
|> deliverOnMainQueue).start(next: { [weak self] result in
|> deliverOnMainQueue).startStandalone(next: { [weak self] result in
guard let self, let result else {
return
}
@ -1676,13 +1676,13 @@ public final class ChatListNode: ListView {
}
let _ = (self.chatFolderUpdates.get()
|> take(1)
|> deliverOnMainQueue).start(next: { [weak self] result in
|> deliverOnMainQueue).startStandalone(next: { [weak self] result in
guard let self, let result else {
return
}
if let localFilterId = result.chatFolderLinkContents.localFilterId {
let _ = self.context.engine.peers.hideChatFolderUpdates(folderId: localFilterId).start()
let _ = self.context.engine.peers.hideChatFolderUpdates(folderId: localFilterId).startStandalone()
}
})
}, openStories: { [weak self] subject, itemNode in
@ -1743,7 +1743,7 @@ public final class ChatListNode: ListView {
if value {
let _ = (context.sharedContext.accountManager.transaction { transaction -> Void in
ApplicationSpecificNotice.setArchiveIntroDismissed(transaction: transaction, value: true)
}).start()
}).startStandalone()
}
}
}
@ -1756,7 +1756,7 @@ public final class ChatListNode: ListView {
}
self.updateIsMainTabDisposable = (self.isMainTab.get()
|> deliverOnMainQueue).start(next: { [weak self] isMainTab in
|> deliverOnMainQueue).startStrict(next: { [weak self] isMainTab in
guard let self else {
return
}
@ -1766,7 +1766,7 @@ public final class ChatListNode: ListView {
return
}
let _ = context.engine.privacy.cleanupSessionReviews().start()
let _ = context.engine.privacy.cleanupSessionReviews().startStandalone()
let twoStepData: Signal<TwoStepVerificationConfiguration?, NoError> = .single(nil) |> then(context.engine.auth.twoStepVerificationConfiguration() |> map(Optional.init))
@ -2558,7 +2558,7 @@ public final class ChatListNode: ListView {
self.interaction = nodeInteraction
self.chatListDisposable.set(appliedTransition.start())
self.chatListDisposable.set(appliedTransition.startStrict())
let initialLocation: ChatListNodeLocation
switch mode {
@ -2715,7 +2715,7 @@ public final class ChatListNode: ListView {
}
}
}
|> deliverOnMainQueue).start(next: { [weak self] activities in
|> deliverOnMainQueue).startStrict(next: { [weak self] activities in
if let strongSelf = self {
strongSelf.updateState { state in
var state = state
@ -2723,7 +2723,7 @@ public final class ChatListNode: ListView {
return state
}
}
}).strict()
})
self.reorderItem = { [weak self] fromIndex, toIndex, transactionOpaqueState -> Signal<Bool, NoError> in
guard let strongSelf = self, let filteredEntries = (transactionOpaqueState as? ChatListOpaqueTransactionState)?.chatListView.filteredEntries else {
@ -3089,7 +3089,7 @@ public final class ChatListNode: ListView {
}
return nil
}
|> deliverOnMainQueue).start(next: { [weak self] updatedFilter in
|> deliverOnMainQueue).startStrict(next: { [weak self] updatedFilter in
guard let strongSelf = self else {
return
}
@ -3619,7 +3619,7 @@ public final class ChatListNode: ListView {
return .single(nil)
}
}
|> deliverOnMainQueue).start(next: { [weak self] indexAndPeer in
|> deliverOnMainQueue).startStandalone(next: { [weak self] indexAndPeer in
guard let strongSelf = self, let (index, peer) = indexAndPeer else {
return
}
@ -3653,7 +3653,7 @@ public final class ChatListNode: ListView {
}
case let .peerId(peerId):
let _ = (self.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|> deliverOnMainQueue).start(next: { [weak self] peer in
|> deliverOnMainQueue).startStandalone(next: { [weak self] peer in
guard let strongSelf = self, let peer = peer else {
return
}
@ -3665,7 +3665,7 @@ public final class ChatListNode: ListView {
}
let _ = (self.chatListFilterValue.get()
|> take(1)
|> deliverOnMainQueue).start(next: { [weak self] filter in
|> deliverOnMainQueue).startStandalone(next: { [weak self] filter in
guard let self = self else {
return
}
@ -3674,7 +3674,7 @@ public final class ChatListNode: ListView {
}
let _ = (chatListViewForLocation(chatListLocation: .chatList(groupId: groupId), location: .initial(count: 10, filter: filter), account: self.context.account)
|> take(1)
|> deliverOnMainQueue).start(next: { update in
|> deliverOnMainQueue).startStandalone(next: { update in
let items = update.list.items
if items.count > index {
let item = items[9 - index - 1]
@ -4070,5 +4070,5 @@ public class ChatHistoryListSelectionRecognizer: UIPanGestureRecognizer {
}
func hideChatListContacts(context: AccountContext) {
let _ = ApplicationSpecificNotice.setDisplayChatListContacts(accountManager: context.sharedContext.accountManager).start()
let _ = ApplicationSpecificNotice.setDisplayChatListContacts(accountManager: context.sharedContext.accountManager).startStandalone()
}

View File

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

View File

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

View File

@ -6,15 +6,21 @@ public protocol Disposable: AnyObject {
public final class StrictDisposable: Disposable {
private let disposable: Disposable
private let file: String
private let line: Int
private let isDisposed = Atomic<Bool>(value: false)
public init(_ disposable: Disposable) {
public init(_ disposable: Disposable, file: String, line: Int) {
self.disposable = disposable
self.file = file
self.line = line
}
deinit {
#if DEBUG
assert(self.isDisposed.with({ $0 }))
if !self.isDisposed.with({ $0 }) {
assertionFailure("Leaked disposable \(self.disposable) from \(self.file):\(self.line)")
}
#endif
}
@ -25,8 +31,8 @@ public final class StrictDisposable: Disposable {
}
public extension Disposable {
func strict() -> Disposable {
return StrictDisposable(self)
func strict(file: String = #file, line: Int = #line) -> Disposable {
return StrictDisposable(self, file: file, line: line)
}
}

View File

@ -24,11 +24,7 @@ public func |> <T, U>(value: T, function: ((T) -> U)) -> U {
}
private final class SubscriberDisposable<T, E>: Disposable, CustomStringConvertible {
#if DEBUG
private weak var subscriber: Subscriber<T, E>?
#else
private var subscriber: Subscriber<T, E>?
#endif
private var lock = pthread_mutex_t()
private var disposable: Disposable?
@ -78,6 +74,20 @@ public final class Signal<T, E> {
return SubscriberDisposable(subscriber: subscriber, disposable: disposable)
}
public func startStandalone(next: ((T) -> Void)! = nil, error: ((E) -> Void)! = nil, completed: (() -> Void)! = nil) -> Disposable {
let subscriber = Subscriber<T, E>(next: next, error: error, completed: completed)
let disposable = self.generator(subscriber)
subscriber.assignDisposable(disposable)
return SubscriberDisposable(subscriber: subscriber, disposable: disposable)
}
public func startStrict(next: ((T) -> Void)! = nil, error: ((E) -> Void)! = nil, completed: (() -> Void)! = nil, file: String = #file, line: Int = #line) -> Disposable {
let subscriber = Subscriber<T, E>(next: next, error: error, completed: completed)
let disposable = self.generator(subscriber)
subscriber.assignDisposable(disposable)
return SubscriberDisposable(subscriber: subscriber, disposable: disposable).strict(file: file, line: line)
}
public static func single(_ value: T) -> Signal<T, E> {
return Signal<T, E> { subscriber in
subscriber.putNext(value)

View File

@ -72,7 +72,7 @@ private func combineLatestAny<E, R>(_ signals: [Signal<Any, E>], combine: @escap
disposable.add(signalDisposable)
}
return disposable;
return disposable
}
}

View File

@ -64,10 +64,10 @@ public func suspendAwareDelay<T, E>(_ timeout: Double, granularity: Double = 4.0
startFinalTimer()
} else {
var invalidateImpl: (() -> Void)?
let timer = Timer(timeout: granularity, repeat: true, completion: {
let timer = Timer(timeout: granularity, repeat: true, completion: { timer in
let currentTimestamp = CFAbsoluteTimeGetCurrent()
if beginTimestamp + timeout - granularity * 1.1 <= currentTimestamp {
invalidateImpl?()
timer.invalidate()
startFinalTimer()
}
}, queue: queue)

View File

@ -4,10 +4,19 @@ public final class Timer {
private let timer = Atomic<DispatchSourceTimer?>(value: nil)
private let timeout: Double
private let `repeat`: Bool
private let completion: () -> Void
private let completion: (Timer) -> Void
private let queue: Queue
public init(timeout: Double, `repeat`: Bool, completion: @escaping() -> Void, queue: Queue) {
public init(timeout: Double, `repeat`: Bool, completion: @escaping () -> Void, queue: Queue) {
self.timeout = timeout
self.`repeat` = `repeat`
self.completion = { _ in
completion()
}
self.queue = queue
}
public init(timeout: Double, `repeat`: Bool, completion: @escaping (Timer) -> Void, queue: Queue) {
self.timeout = timeout
self.`repeat` = `repeat`
self.completion = completion
@ -22,7 +31,7 @@ public final class Timer {
let timer = DispatchSource.makeTimerSource(queue: self.queue.queue)
timer.setEventHandler(handler: { [weak self] in
if let strongSelf = self {
strongSelf.completion()
strongSelf.completion(strongSelf)
if !strongSelf.`repeat` {
strongSelf.invalidate()
}

View File

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

View File

@ -129,7 +129,7 @@ final class AttachmentFileSearchItem: ItemListControllerSearch {
} else {
return .single(value)
}
}).start(next: { [weak self] value in
}).startStrict(next: { [weak self] value in
self?.updateActivity?(value)
}))
}
@ -421,7 +421,7 @@ public final class AttachmentFileSearchContainerNode: SearchDisplayControllerCon
let previousSearchItems = Atomic<[AttachmentFileSearchEntry]?>(value: nil)
self.searchDisposable.set((combineLatest(searchQuery, foundItems, self.presentationDataPromise.get())
|> deliverOnMainQueue).start(next: { [weak self] query, entries, presentationData in
|> deliverOnMainQueue).startStrict(next: { [weak self] query, entries, presentationData in
if let strongSelf = self {
let previousEntries = previousSearchItems.swap(entries)
updateActivity(false)
@ -432,7 +432,7 @@ public final class AttachmentFileSearchContainerNode: SearchDisplayControllerCon
}))
self.presentationDataDisposable = (context.sharedContext.presentationData
|> deliverOnMainQueue).start(next: { [weak self] presentationData in
|> deliverOnMainQueue).startStrict(next: { [weak self] presentationData in
if let strongSelf = self {
var presentationData = presentationData

View File

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

View File

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

View File

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

View File

@ -224,7 +224,7 @@ final class ChatChannelSubscriberInputPanelNode: ChatInputPanelNode {
strongSelf.isJoining = false
}
}
}).start(error: { [weak self] error in
}).startStrict(error: { [weak self] error in
guard let strongSelf = self, let presentationInterfaceState = strongSelf.presentationInterfaceState, let peer = presentationInterfaceState.renderedPeer?.peer else {
return
}
@ -256,7 +256,7 @@ final class ChatChannelSubscriberInputPanelNode: ChatInputPanelNode {
break
case .muteNotifications, .unmuteNotifications:
if let context = self.context, let presentationInterfaceState = self.presentationInterfaceState, let peer = presentationInterfaceState.renderedPeer?.peer {
self.actionDisposable.set(context.engine.peers.togglePeerMuted(peerId: peer.id, threadId: nil).start())
self.actionDisposable.set(context.engine.peers.togglePeerMuted(peerId: peer.id, threadId: nil).startStrict())
}
case .hidePinnedMessages, .unpinMessages:
self.interfaceInteraction?.unpinAllMessages()

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

@ -434,8 +434,6 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
private let historyDisposable = MetaDisposable()
private let readHistoryDisposable = MetaDisposable()
//private let messageViewQueue = Queue(name: "ChatHistoryListNode processing")
private var dequeuedInitialTransitionOnLayout = false
private var enqueuedHistoryViewTransitions: [ChatHistoryListViewTransition] = []
private var hasActiveTransition = false
@ -667,10 +665,8 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
public init(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>), chatLocation: ChatLocation, chatLocationContextHolder: Atomic<ChatLocationContextHolder?>, tagMask: MessageTags?, source: ChatHistoryListSource = .default, subject: ChatControllerSubject?, controllerInteraction: ChatControllerInteraction, selectedMessages: Signal<Set<MessageId>?, NoError>, mode: ChatHistoryListMode = .bubbles, messageTransitionNode: @escaping () -> ChatMessageTransitionNode? = { nil }) {
var tagMask = tagMask
var appendMessagesFromTheSameGroup = false
if case .pinnedMessages = subject {
tagMask = .pinned
appendMessagesFromTheSameGroup = true
}
self.context = context
@ -692,14 +688,12 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
self.chatPresentationDataPromise = Promise()
self.prefetchManager = InChatPrefetchManager(context: context)
var displayAdPeer: PeerId?
//var sparseScrollPeerId: PeerId?
switch subject {
case .none, .message:
if case let .peer(peerId) = chatLocation {
displayAdPeer = peerId
//sparseScrollPeerId = peerId
}
default:
break
@ -713,12 +707,6 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
self.adMessagesContext = nil
adMessages = .single((nil, []))
}
/*if case .bubbles = mode, let peerId = sparseScrollPeerId {
self.sparseScrollingContext = context.engine.messages.sparseMessageScrollingContext(peerId: peerId)
} else {
self.sparseScrollingContext = nil
}*/
let clientId = Atomic<Int32>(value: nextClientId)
self.clientId = clientId
@ -726,46 +714,10 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
super.init()
self.adMessagesDisposable = (adMessages
|> deliverOnMainQueue).start(next: { [weak self] interPostInterval, messages in
guard let self else {
return
}
if let interPostInterval = interPostInterval {
self.pendingDynamicAdMessages = messages
self.pendingDynamicAdMessageInterval = Int(interPostInterval)
if self.remainingDynamicAdMessageInterval == nil {
self.remainingDynamicAdMessageInterval = Int(interPostInterval)
}
if self.remainingDynamicAdMessageDistance == nil {
self.remainingDynamicAdMessageDistance = self.bounds.height
}
self.allAdMessages = (messages.first, [], 0)
} else {
var adPeerId: PeerId?
adPeerId = messages.first?.author?.id
if self.preloadAdPeerId != adPeerId {
self.preloadAdPeerId = adPeerId
if let adPeerId = adPeerId {
let combinedDisposable = DisposableSet()
self.preloadAdPeerDisposable.set(combinedDisposable)
combinedDisposable.add(self.context.account.viewTracker.polledChannel(peerId: adPeerId).start())
combinedDisposable.add(self.context.account.addAdditionalPreloadHistoryPeerId(peerId: adPeerId))
} else {
self.preloadAdPeerDisposable.set(nil)
}
}
self.allAdMessages = (messages.first, [], 0)
}
})
self.clipsToBounds = false
self.beginAdMessageManagement(adMessages: adMessages)
self.accessibilityPageScrolledString = { [weak self] row, count in
if let strongSelf = self {
return strongSelf.currentPresentationData.strings.VoiceOver_ScrollStatus(row, count).string
@ -799,7 +751,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
}
self.translationProcessingManager.process = { [weak self, weak context] messageIds in
if let context = context, let toLang = self?.toLang {
let _ = translateMessageIds(context: context, messageIds: Array(messageIds), toLang: toLang).start()
let _ = translateMessageIds(context: context, messageIds: Array(messageIds), toLang: toLang).startStandalone()
}
}
@ -838,23 +790,261 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
case .list:
break
}
//self.snapToBottomInsetUntilFirstInteraction = true
let messageViewQueue = Queue.mainQueue() //self.messageViewQueue
self.beginChatHistoryTransitions(
selectedMessages: selectedMessages,
messageTransitionNode: messageTransitionNode
)
self.beginReadHistoryManagement()
if let subject = subject, case let .message(messageSubject, highlight, _) = subject {
let initialSearchLocation: ChatHistoryInitialSearchLocation
switch messageSubject {
case let .id(id):
initialSearchLocation = .id(id)
case let .timestamp(timestamp):
if let peerId = self.chatLocation.peerId {
initialSearchLocation = .index(MessageIndex(id: MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: 1), timestamp: timestamp))
} else {
//TODO:implement
initialSearchLocation = .index(MessageIndex.absoluteUpperBound())
}
}
self.chatHistoryLocationValue = ChatHistoryLocationInput(content: .InitialSearch(location: initialSearchLocation, count: historyMessageCount, highlight: highlight), id: 0)
} else if let subject = subject, case let .pinnedMessages(maybeMessageId) = subject, let messageId = maybeMessageId {
self.chatHistoryLocationValue = ChatHistoryLocationInput(content: .InitialSearch(location: .id(messageId), count: historyMessageCount, highlight: true), id: 0)
} else {
self.chatHistoryLocationValue = ChatHistoryLocationInput(content: .Initial(count: historyMessageCount), id: 0)
}
self.chatHistoryLocationPromise.set(self.chatHistoryLocationValue!)
self.generalScrollDirectionUpdated = { [weak self] direction in
guard let strongSelf = self else {
return
}
let prefetchDirectionIsToLater = direction == .up
if strongSelf.currentPrefetchDirectionIsToLater != prefetchDirectionIsToLater {
strongSelf.currentPrefetchDirectionIsToLater = prefetchDirectionIsToLater
if strongSelf.currentPrefetchDirectionIsToLater {
strongSelf.prefetchManager.updateMessages(strongSelf.currentLaterPrefetchMessages, directionIsToLater: strongSelf.currentPrefetchDirectionIsToLater)
} else {
strongSelf.prefetchManager.updateMessages(strongSelf.currentEarlierPrefetchMessages, directionIsToLater: strongSelf.currentPrefetchDirectionIsToLater)
}
}
}
self.displayedItemRangeChanged = { [weak self] displayedRange, opaqueTransactionState in
if let strongSelf = self, let transactionState = opaqueTransactionState as? ChatHistoryTransactionOpaqueState {
strongSelf.processDisplayedItemRangeChanged(displayedRange: displayedRange, transactionState: transactionState)
}
}
self.refreshDisplayedItemRangeTimer = SwiftSignalKit.Timer(timeout: 10.0, repeat: true, completion: { [weak self] in
guard let strongSelf = self else {
return
}
strongSelf.updateVisibleItemRange(force: true)
}, queue: .mainQueue())
self.refreshDisplayedItemRangeTimer?.start()
self.beginPresentationDataManagement(updated: updatedPresentationData.signal)
self.visibleContentOffsetChanged = { [weak self] offset in
if let strongSelf = self {
strongSelf.contentPositionChanged(offset)
if strongSelf.tagMask == nil {
var atBottom = false
var offsetFromBottom: CGFloat?
switch offset {
case let .known(offsetValue):
if offsetValue.isLessThanOrEqualTo(0.0) {
atBottom = true
offsetFromBottom = offsetValue
}
//print("offsetValue: \(offsetValue)")
default:
break
}
if atBottom != strongSelf.isScrollAtBottomPosition {
strongSelf.isScrollAtBottomPosition = atBottom
strongSelf.updateReadHistoryActions()
strongSelf.isScrollAtBottomPositionUpdated?()
}
strongSelf.maybeUpdateOverscrollAction(offset: offsetFromBottom)
}
}
}
self.loadedMessagesFromCachedDataDisposable = (self._cachedPeerDataAndMessages.get() |> map { dataAndMessages -> MessageId? in
return dataAndMessages.0?.messageIds.first
} |> distinctUntilChanged(isEqual: { $0 == $1 })
|> mapToSignal { messageId -> Signal<Void, NoError> in
if let messageId = messageId {
return context.engine.messages.getMessagesLoadIfNecessary([messageId]) |> map { _ -> Void in return Void() }
} else {
return .complete()
}
}).startStrict()
self.beganInteractiveDragging = { [weak self] _ in
self?.isInteractivelyScrollingValue = true
self?.isInteractivelyScrollingPromise.set(true)
self?.beganDragging?()
//self?.updateHistoryScrollingArea(transition: .immediate)
}
self.endedInteractiveDragging = { [weak self] _ in
guard let strongSelf = self else {
return
}
if strongSelf.offerNextChannelToRead, strongSelf.currentOverscrollExpandProgress >= 0.99 {
if let nextChannelToRead = strongSelf.nextChannelToRead {
strongSelf.freezeOverscrollControl = true
strongSelf.openNextChannelToRead?(nextChannelToRead.peer, nextChannelToRead.location)
} else {
strongSelf.freezeOverscrollControlProgress = true
strongSelf.scroller.contentInset = UIEdgeInsets(top: 94.0 + 12.0, left: 0.0, bottom: 0.0, right: 0.0)
Queue.mainQueue().after(0.3, {
let animator = DisplayLinkAnimator(duration: 0.2, from: 1.0, to: 0.0, update: { rawT in
guard let strongSelf = self else {
return
}
let t = listViewAnimationCurveEaseInOut(rawT)
let value = (94.0 + 12.0) * t
strongSelf.scroller.contentInset = UIEdgeInsets(top: value, left: 0.0, bottom: 0.0, right: 0.0)
}, completion: {
guard let strongSelf = self else {
return
}
strongSelf.contentInsetAnimator = nil
strongSelf.scroller.contentInset = UIEdgeInsets()
strongSelf.freezeOverscrollControlProgress = false
})
strongSelf.contentInsetAnimator = animator
})
}
}
}
self.didEndScrolling = { [weak self] _ in
guard let strongSelf = self else {
return
}
strongSelf.isInteractivelyScrollingValue = false
strongSelf.isInteractivelyScrollingPromise.set(false)
//strongSelf.updateHistoryScrollingArea(transition: .immediate)
}
/*self.updateScrollingIndicator = { [weak self] scrollingState, transition in
guard let strongSelf = self else {
return
}
strongSelf.scrollingState = scrollingState
strongSelf.updateHistoryScrollingArea(transition: transition)
}*/
let selectionRecognizer = ChatHistoryListSelectionRecognizer(target: self, action: #selector(self.selectionPanGesture(_:)))
selectionRecognizer.shouldBegin = { [weak self] in
guard let strongSelf = self else {
return false
}
return strongSelf.isSelectionGestureEnabled
}
self.view.addGestureRecognizer(selectionRecognizer)
self.loadNextGenericReactionEffect(context: context)
}
deinit {
self.historyDisposable.dispose()
self.readHistoryDisposable.dispose()
self.interactiveReadActionDisposable?.dispose()
self.interactiveReadReactionsDisposable?.dispose()
self.canReadHistoryDisposable?.dispose()
self.loadedMessagesFromCachedDataDisposable?.dispose()
self.preloadAdPeerDisposable.dispose()
self.refreshDisplayedItemRangeTimer?.invalidate()
self.genericReactionEffectDisposable?.dispose()
self.adMessagesDisposable?.dispose()
self.presentationDataDisposable?.dispose()
}
private func beginAdMessageManagement(adMessages: Signal<(interPostInterval: Int32?, messages: [Message]), NoError>) {
self.adMessagesDisposable = (adMessages
|> deliverOnMainQueue).startStrict(next: { [weak self] interPostInterval, messages in
guard let self else {
return
}
if let interPostInterval = interPostInterval {
self.pendingDynamicAdMessages = messages
self.pendingDynamicAdMessageInterval = Int(interPostInterval)
if self.remainingDynamicAdMessageInterval == nil {
self.remainingDynamicAdMessageInterval = Int(interPostInterval)
}
if self.remainingDynamicAdMessageDistance == nil {
self.remainingDynamicAdMessageDistance = self.bounds.height
}
self.allAdMessages = (messages.first, [], 0)
} else {
var adPeerId: PeerId?
adPeerId = messages.first?.author?.id
if self.preloadAdPeerId != adPeerId {
self.preloadAdPeerId = adPeerId
if let adPeerId = adPeerId {
let combinedDisposable = DisposableSet()
self.preloadAdPeerDisposable.set(combinedDisposable)
combinedDisposable.add(self.context.account.viewTracker.polledChannel(peerId: adPeerId).startStrict())
combinedDisposable.add(self.context.account.addAdditionalPreloadHistoryPeerId(peerId: adPeerId))
} else {
self.preloadAdPeerDisposable.set(nil)
}
}
self.allAdMessages = (messages.first, [], 0)
}
}).strict()
}
private func beginChatHistoryTransitions(
selectedMessages: Signal<Set<MessageId>?, NoError>,
messageTransitionNode: @escaping () -> ChatMessageTransitionNode?
) {
let context = self.context
let chatLocation = self.chatLocation
let subject = self.subject
let source = self.source
let tagMask = self.tagMask
let chatLocationContextHolder = self.chatLocationContextHolder
let controllerInteraction = self.controllerInteraction
let mode = self.mode
var appendMessagesFromTheSameGroup = false
if case .pinnedMessages = subject {
appendMessagesFromTheSameGroup = true
}
let fixedCombinedReadStates = Atomic<MessageHistoryViewReadState?>(value: nil)
var isScheduledMessages = false
if let subject = subject, case .scheduledMessages = subject {
if let subject = self.subject, case .scheduledMessages = subject {
isScheduledMessages = true
}
var isAuxiliaryChat = isScheduledMessages
if case .replyThread = chatLocation {
if case .replyThread = self.chatLocation {
isAuxiliaryChat = true
}
var additionalData: [AdditionalMessageHistoryViewData] = []
if case let .peer(peerId) = chatLocation {
if case let .peer(peerId) = self.chatLocation {
additionalData.append(.cachedPeerData(peerId))
additionalData.append(.cachedPeerDataMessages(peerId))
additionalData.append(.peerNotificationSettings(peerId))
@ -871,7 +1061,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
if !isAuxiliaryChat {
additionalData.append(.totalUnreadState)
}
if case let .replyThread(replyThreadMessage) = chatLocation {
if case let .replyThread(replyThreadMessage) = self.chatLocation {
additionalData.append(.cachedPeerData(replyThreadMessage.messageId.peerId))
additionalData.append(.peerNotificationSettings(replyThreadMessage.messageId.peerId))
if replyThreadMessage.messageId.peerId.namespace == Namespaces.Peer.CloudChannel {
@ -887,7 +1077,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
let historyViewUpdate: Signal<(ChatHistoryViewUpdate, Int, ChatHistoryLocationInput?, ClosedRange<Int32>?), NoError>
var isFirstTime = true
var updateAllOnEachVersion = false
if case let .custom(messages, at, _) = source {
if case let .custom(messages, at, _) = self.source {
updateAllOnEachVersion = true
historyViewUpdate = messages
|> map { messages, _, hasMore in
@ -1030,8 +1220,8 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
let availableReactions: Signal<AvailableReactions?, NoError> = (context as! AccountContextImpl).availableReactions
let defaultReaction = combineLatest(
context.engine.data.subscribe(TelegramEngine.EngineData.Item.Peer.Peer(id: context.account.peerId)),
context.account.postbox.preferencesView(keys: [PreferencesKeys.reactionSettings])
self.context.engine.data.subscribe(TelegramEngine.EngineData.Item.Peer.Peer(id: context.account.peerId)),
self.context.account.postbox.preferencesView(keys: [PreferencesKeys.reactionSettings])
)
|> map { peer, preferencesView -> MessageReaction.Reaction? in
let reactionSettings: ReactionSettings
@ -1087,8 +1277,8 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
)
let maxReadStoryId: Signal<Int32?, NoError>
if let peerId = chatLocation.peerId, peerId.namespace == Namespaces.Peer.CloudUser {
maxReadStoryId = context.account.postbox.combinedView(keys: [PostboxViewKey.storiesState(key: .peer(peerId))])
if let peerId = self.chatLocation.peerId, peerId.namespace == Namespaces.Peer.CloudUser {
maxReadStoryId = self.context.account.postbox.combinedView(keys: [PostboxViewKey.storiesState(key: .peer(peerId))])
|> map { views -> Int32? in
guard let view = views.views[PostboxViewKey.storiesState(key: .peer(peerId))] as? StoryStatesView else {
return nil
@ -1104,6 +1294,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
maxReadStoryId = .single(nil)
}
let messageViewQueue = Queue.mainQueue()
let historyViewTransitionDisposable = combineLatest(queue: messageViewQueue,
historyViewUpdate,
self.chatPresentationDataPromise.get(),
@ -1123,7 +1314,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
self.allAdMessagesPromise.get(),
translationState,
maxReadStoryId
).start(next: { [weak self] update, chatPresentationData, selectedMessages, updatingMedia, networkType, animatedEmojiStickers, additionalAnimatedEmojiStickers, customChannelDiscussionReadState, customThreadOutgoingReadState, availableReactions, defaultReaction, accountPeer, suggestAudioTranscription, promises, topicAuthorId, allAdMessages, translationState, maxReadStoryId in
).startStrict(next: { [weak self] update, chatPresentationData, selectedMessages, updatingMedia, networkType, animatedEmojiStickers, additionalAnimatedEmojiStickers, customChannelDiscussionReadState, customThreadOutgoingReadState, availableReactions, defaultReaction, accountPeer, suggestAudioTranscription, promises, topicAuthorId, allAdMessages, translationState, maxReadStoryId in
let (historyAppearsCleared, pendingUnpinnedAllMessages, pendingRemovedMessages, currentlyPlayingMessageIdAndType, scrollToMessageId, chatHasBots) = promises
func applyHole() {
@ -1266,7 +1457,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
var translateToLanguage: String?
if let translationState, isPremium && translationState.isEnabled {
var languageCode = translationState.toLang ?? presentationData.strings.baseLanguageCode
var languageCode = translationState.toLang ?? chatPresentationData.strings.baseLanguageCode
let rawSuffix = "-raw"
if languageCode.hasSuffix(rawSuffix) {
languageCode = String(languageCode.dropLast(rawSuffix.count))
@ -1487,12 +1678,14 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
}
})
self.historyDisposable.set(historyViewTransitionDisposable)
self.historyDisposable.set(historyViewTransitionDisposable.strict())
}
private func beginReadHistoryManagement() {
let previousMaxIncomingMessageIndexByNamespace = Atomic<[MessageId.Namespace: MessageIndex]>(value: [:])
let readHistory = combineLatest(self.maxVisibleIncomingMessageIndex.get(), self.canReadHistory.get())
self.readHistoryDisposable.set((readHistory |> deliverOnMainQueue).start(next: { [weak self] messageIndex, canRead in
self.readHistoryDisposable.set((readHistory |> deliverOnMainQueue).startStrict(next: { [weak self] messageIndex, canRead in
guard let strongSelf = self else {
return
}
@ -1512,16 +1705,16 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
return dict
}
if apply {
switch chatLocation {
switch strongSelf.chatLocation {
case .peer, .replyThread, .feed:
if !strongSelf.context.sharedContext.immediateExperimentalUISettings.skipReadHistory {
strongSelf.context.applyMaxReadIndex(for: chatLocation, contextHolder: chatLocationContextHolder, messageIndex: messageIndex)
strongSelf.context.applyMaxReadIndex(for: strongSelf.chatLocation, contextHolder: strongSelf.chatLocationContextHolder, messageIndex: messageIndex)
}
}
}
}))
}).strict())
self.canReadHistoryDisposable = (self.canReadHistory.get() |> deliverOnMainQueue).start(next: { [weak self, weak context] value in
self.canReadHistoryDisposable = (self.canReadHistory.get() |> deliverOnMainQueue).startStrict(next: { [weak self, weak context] value in
if let strongSelf = self {
if strongSelf.canReadHistoryValue != value {
strongSelf.canReadHistoryValue = value
@ -1536,70 +1729,22 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
strongSelf.attemptReadingReactions()
}
}
})
if let subject = subject, case let .message(messageSubject, highlight, _) = subject {
let initialSearchLocation: ChatHistoryInitialSearchLocation
switch messageSubject {
case let .id(id):
initialSearchLocation = .id(id)
case let .timestamp(timestamp):
if let peerId = self.chatLocation.peerId {
initialSearchLocation = .index(MessageIndex(id: MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: 1), timestamp: timestamp))
} else {
//TODO:implement
initialSearchLocation = .index(MessageIndex.absoluteUpperBound())
}
}
self.chatHistoryLocationValue = ChatHistoryLocationInput(content: .InitialSearch(location: initialSearchLocation, count: historyMessageCount, highlight: highlight), id: 0)
} else if let subject = subject, case let .pinnedMessages(maybeMessageId) = subject, let messageId = maybeMessageId {
self.chatHistoryLocationValue = ChatHistoryLocationInput(content: .InitialSearch(location: .id(messageId), count: historyMessageCount, highlight: true), id: 0)
} else {
self.chatHistoryLocationValue = ChatHistoryLocationInput(content: .Initial(count: historyMessageCount), id: 0)
}
self.chatHistoryLocationPromise.set(self.chatHistoryLocationValue!)
self.generalScrollDirectionUpdated = { [weak self] direction in
guard let strongSelf = self else {
return
}
let prefetchDirectionIsToLater = direction == .up
if strongSelf.currentPrefetchDirectionIsToLater != prefetchDirectionIsToLater {
strongSelf.currentPrefetchDirectionIsToLater = prefetchDirectionIsToLater
if strongSelf.currentPrefetchDirectionIsToLater {
strongSelf.prefetchManager.updateMessages(strongSelf.currentLaterPrefetchMessages, directionIsToLater: strongSelf.currentPrefetchDirectionIsToLater)
} else {
strongSelf.prefetchManager.updateMessages(strongSelf.currentEarlierPrefetchMessages, directionIsToLater: strongSelf.currentPrefetchDirectionIsToLater)
}
}
}
self.displayedItemRangeChanged = { [weak self] displayedRange, opaqueTransactionState in
if let strongSelf = self, let transactionState = opaqueTransactionState as? ChatHistoryTransactionOpaqueState {
strongSelf.processDisplayedItemRangeChanged(displayedRange: displayedRange, transactionState: transactionState)
}
}
self.refreshDisplayedItemRangeTimer = SwiftSignalKit.Timer(timeout: 10.0, repeat: true, completion: { [weak self] in
guard let strongSelf = self else {
return
}
strongSelf.updateVisibleItemRange(force: true)
}, queue: .mainQueue())
self.refreshDisplayedItemRangeTimer?.start()
let appConfiguration = context.account.postbox.preferencesView(keys: [PreferencesKeys.appConfiguration])
}).strict()
}
private func beginPresentationDataManagement(updated: Signal<PresentationData, NoError>) {
let appConfiguration = self.context.account.postbox.preferencesView(keys: [PreferencesKeys.appConfiguration])
|> take(1)
|> map { view in
return view.values[PreferencesKeys.appConfiguration]?.get(AppConfiguration.self) ?? .defaultValue
}
var didSetPresentationData = false
self.presentationDataDisposable = (
combineLatest(queue: .mainQueue(),
updatedPresentationData.signal,
appConfiguration)
|> deliverOnMainQueue).start(next: { [weak self] presentationData, appConfiguration in
self.presentationDataDisposable = (combineLatest(queue: .mainQueue(),
updated,
appConfiguration
)
|> deliverOnMainQueue).startStrict(next: { [weak self] presentationData, appConfiguration in
if let strongSelf = self {
let previousTheme = strongSelf.currentPresentationData.theme
let previousStrings = strongSelf.currentPresentationData.strings
@ -1619,9 +1764,9 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
strongSelf.forEachItemHeaderNode { itemHeaderNode in
if let dateNode = itemHeaderNode as? ChatMessageDateHeaderNode {
dateNode.updatePresentationData(chatPresentationData, context: context)
dateNode.updatePresentationData(chatPresentationData, context: strongSelf.context)
} else if let avatarNode = itemHeaderNode as? ChatMessageAvatarHeaderNode {
avatarNode.updatePresentationData(chatPresentationData, context: context)
avatarNode.updatePresentationData(chatPresentationData, context: strongSelf.context)
} else if let dateNode = itemHeaderNode as? ListMessageDateHeaderNode {
dateNode.updateThemeAndStrings(theme: presentationData.theme, strings: presentationData.strings)
}
@ -1629,129 +1774,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
strongSelf.chatPresentationDataPromise.set(.single(chatPresentationData))
}
}
})
self.visibleContentOffsetChanged = { [weak self] offset in
if let strongSelf = self {
strongSelf.contentPositionChanged(offset)
if strongSelf.tagMask == nil {
var atBottom = false
var offsetFromBottom: CGFloat?
switch offset {
case let .known(offsetValue):
if offsetValue.isLessThanOrEqualTo(0.0) {
atBottom = true
offsetFromBottom = offsetValue
}
//print("offsetValue: \(offsetValue)")
default:
break
}
if atBottom != strongSelf.isScrollAtBottomPosition {
strongSelf.isScrollAtBottomPosition = atBottom
strongSelf.updateReadHistoryActions()
strongSelf.isScrollAtBottomPositionUpdated?()
}
strongSelf.maybeUpdateOverscrollAction(offset: offsetFromBottom)
}
}
}
self.loadedMessagesFromCachedDataDisposable = (self._cachedPeerDataAndMessages.get() |> map { dataAndMessages -> MessageId? in
return dataAndMessages.0?.messageIds.first
} |> distinctUntilChanged(isEqual: { $0 == $1 })
|> mapToSignal { messageId -> Signal<Void, NoError> in
if let messageId = messageId {
return context.engine.messages.getMessagesLoadIfNecessary([messageId]) |> map { _ -> Void in return Void() }
} else {
return .complete()
}
}).start()
self.beganInteractiveDragging = { [weak self] _ in
self?.isInteractivelyScrollingValue = true
self?.isInteractivelyScrollingPromise.set(true)
self?.beganDragging?()
//self?.updateHistoryScrollingArea(transition: .immediate)
}
self.endedInteractiveDragging = { [weak self] _ in
guard let strongSelf = self else {
return
}
if strongSelf.offerNextChannelToRead, strongSelf.currentOverscrollExpandProgress >= 0.99 {
if let nextChannelToRead = strongSelf.nextChannelToRead {
strongSelf.freezeOverscrollControl = true
strongSelf.openNextChannelToRead?(nextChannelToRead.peer, nextChannelToRead.location)
} else {
strongSelf.freezeOverscrollControlProgress = true
strongSelf.scroller.contentInset = UIEdgeInsets(top: 94.0 + 12.0, left: 0.0, bottom: 0.0, right: 0.0)
Queue.mainQueue().after(0.3, {
let animator = DisplayLinkAnimator(duration: 0.2, from: 1.0, to: 0.0, update: { rawT in
guard let strongSelf = self else {
return
}
let t = listViewAnimationCurveEaseInOut(rawT)
let value = (94.0 + 12.0) * t
strongSelf.scroller.contentInset = UIEdgeInsets(top: value, left: 0.0, bottom: 0.0, right: 0.0)
}, completion: {
guard let strongSelf = self else {
return
}
strongSelf.contentInsetAnimator = nil
strongSelf.scroller.contentInset = UIEdgeInsets()
strongSelf.freezeOverscrollControlProgress = false
})
strongSelf.contentInsetAnimator = animator
})
}
}
}
self.didEndScrolling = { [weak self] _ in
guard let strongSelf = self else {
return
}
strongSelf.isInteractivelyScrollingValue = false
strongSelf.isInteractivelyScrollingPromise.set(false)
//strongSelf.updateHistoryScrollingArea(transition: .immediate)
}
/*self.updateScrollingIndicator = { [weak self] scrollingState, transition in
guard let strongSelf = self else {
return
}
strongSelf.scrollingState = scrollingState
strongSelf.updateHistoryScrollingArea(transition: transition)
}*/
let selectionRecognizer = ChatHistoryListSelectionRecognizer(target: self, action: #selector(self.selectionPanGesture(_:)))
selectionRecognizer.shouldBegin = { [weak self] in
guard let strongSelf = self else {
return false
}
return strongSelf.isSelectionGestureEnabled
}
self.view.addGestureRecognizer(selectionRecognizer)
self.loadNextGenericReactionEffect(context: context)
}
deinit {
self.historyDisposable.dispose()
self.readHistoryDisposable.dispose()
self.interactiveReadActionDisposable?.dispose()
self.interactiveReadReactionsDisposable?.dispose()
self.canReadHistoryDisposable?.dispose()
self.loadedMessagesFromCachedDataDisposable?.dispose()
self.preloadAdPeerDisposable.dispose()
self.refreshDisplayedItemRangeTimer?.invalidate()
self.genericReactionEffectDisposable?.dispose()
self.adMessagesDisposable?.dispose()
}).strict()
}
private func attemptReadingReactions() {
@ -1774,7 +1797,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
private func loadNextGenericReactionEffect(context: AccountContext) {
self.genericReactionEffectDisposable?.dispose()
self.genericReactionEffectDisposable = (ReactionContextNode.randomGenericReactionEffect(context: context) |> deliverOnMainQueue).start(next: { [weak self] path in
self.genericReactionEffectDisposable = (ReactionContextNode.randomGenericReactionEffect(context: context) |> deliverOnMainQueue).startStrict(next: { [weak self] path in
guard let strongSelf = self else {
return
}
@ -2389,7 +2412,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
self.messageWithReactionsProcessingManager.add(messageIdsWithPossibleReactions)
}
if !downloadableResourceIds.isEmpty {
let _ = markRecentDownloadItemsAsSeen(postbox: self.context.account.postbox, items: downloadableResourceIds).start()
let _ = markRecentDownloadItemsAsSeen(postbox: self.context.account.postbox, items: downloadableResourceIds).startStandalone()
}
if !messageIdsWithInactiveExtendedMedia.isEmpty {
self.extendedMediaProcessingManager.update(messageIdsWithInactiveExtendedMedia)

View File

@ -1,5 +0,0 @@
import Postbox
import UIKit
import Display

View File

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

View File

@ -1,6 +0,0 @@
import Foundation
import Postbox
import TelegramCore
import Display
import AccountContext

View File

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

View File

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

View File

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

View File

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

View File

@ -21,7 +21,7 @@ func interactiveChatLinkPreviewsEnabled(accountManager: AccountManager<TelegramA
return Signal { subscriber in
Queue.mainQueue().async {
displayAlert(InteractiveChatLinkPreviewsResult({ result in
let _ = ApplicationSpecificNotice.setSecretChatLinkPreviews(accountManager: accountManager, value: result).start()
let _ = ApplicationSpecificNotice.setSecretChatLinkPreviews(accountManager: accountManager, value: result).startStandalone()
subscriber.putNext(result)
subscriber.putCompletion()
}))

View File

@ -288,7 +288,7 @@ final class ChatMediaInputStickerGridItemNode: GridItemNode {
self.imageNode.setSignal(chatMessageAnimatedSticker(postbox: item.context.account.postbox, userLocation: .other, file: item.stickerItem.file, small: false, size: dimensions.cgSize.aspectFitted(fittedSize)))
}
self.updateVisibility()
self.stickerFetchedDisposable.set(freeMediaFileResourceInteractiveFetched(account: item.context.account, userLocation: .other, fileReference: stickerPackFileReference(item.stickerItem.file), resource: item.stickerItem.file.resource).start())
self.stickerFetchedDisposable.set(freeMediaFileResourceInteractiveFetched(account: item.context.account, userLocation: .other, fileReference: stickerPackFileReference(item.stickerItem.file), resource: item.stickerItem.file.resource).startStrict())
} else {
if let animationNode = self.animationNode {
animationNode.visibility = false
@ -298,7 +298,7 @@ final class ChatMediaInputStickerGridItemNode: GridItemNode {
self.didSetUpAnimationNode = false
}
self.imageNode.setSignal(chatMessageSticker(account: item.context.account, userLocation: .other, file: item.stickerItem.file, small: !item.large, synchronousLoad: synchronousLoads && isVisible))
self.stickerFetchedDisposable.set(freeMediaFileResourceInteractiveFetched(account: item.context.account, userLocation: .other, fileReference: stickerPackFileReference(item.stickerItem.file), resource: chatMessageStickerResource(file: item.stickerItem.file, small: !item.large)).start())
self.stickerFetchedDisposable.set(freeMediaFileResourceInteractiveFetched(account: item.context.account, userLocation: .other, fileReference: stickerPackFileReference(item.stickerItem.file), resource: chatMessageStickerResource(file: item.stickerItem.file, small: !item.large)).startStrict())
}
self.currentState = (item.context, item.stickerItem, dimensions.cgSize)

View File

@ -251,7 +251,7 @@ class ChatMessageActionBubbleContentNode: ChatMessageBubbleContentNode {
strongSelf.insertSubnode(imageNode, at: 0)
strongSelf.insertSubnode(strongSelf.mediaBackgroundNode, at: 0)
}
strongSelf.fetchDisposable.set(chatMessagePhotoInteractiveFetched(context: item.context, userLocation: .peer(item.message.id.peerId), photoReference: .message(message: MessageReference(item.message), media: image), displayAtSize: nil, storeToDownloadsPeerId: nil).start())
strongSelf.fetchDisposable.set(chatMessagePhotoInteractiveFetched(context: item.context, userLocation: .peer(item.message.id.peerId), photoReference: .message(message: MessageReference(item.message), media: image), displayAtSize: nil, storeToDownloadsPeerId: nil).startStrict())
let updateImageSignal = chatMessagePhoto(postbox: item.context.account.postbox, userLocation: .peer(item.message.id.peerId), photoReference: .message(message: MessageReference(item.message), media: image), synchronousLoad: synchronousLoads)
imageNode.setSignal(updateImageSignal, attemptSynchronously: synchronousLoads)

View File

@ -585,11 +585,11 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
let dimensions = telegramFile.dimensions ?? PixelDimensions(width: 512, height: 512)
self.imageNode.setSignal(chatMessageAnimatedSticker(postbox: item.context.account.postbox, userLocation: .peer(item.message.id.peerId), file: telegramFile, small: false, size: dimensions.cgSize.aspectFitted(CGSize(width: 384.0, height: 384.0)), thumbnail: false, synchronousLoad: synchronousLoad), attemptSynchronously: synchronousLoad)
self.updateVisibility()
self.disposable.set(freeMediaFileInteractiveFetched(account: item.context.account, userLocation: .peer(item.message.id.peerId), fileReference: .message(message: MessageReference(item.message), media: telegramFile)).start())
self.disposable.set(freeMediaFileInteractiveFetched(account: item.context.account, userLocation: .peer(item.message.id.peerId), fileReference: .message(message: MessageReference(item.message), media: telegramFile)).startStrict())
if telegramFile.isPremiumSticker {
if let effect = telegramFile.videoThumbnails.first {
self.disposables.add(freeMediaFileResourceInteractiveFetched(account: item.context.account, userLocation: .peer(item.message.id.peerId), fileReference: .message(message: MessageReference(item.message), media: telegramFile), resource: effect.resource) .start())
self.disposables.add(freeMediaFileResourceInteractiveFetched(account: item.context.account, userLocation: .peer(item.message.id.peerId), fileReference: .message(message: MessageReference(item.message), media: telegramFile), resource: effect.resource).startStrict())
}
}
}
@ -663,7 +663,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
let fillSize = emojiFile.isCustomEmoji ? CGSize(width: 512.0, height: 512.0) : CGSize(width: 384.0, height: 384.0)
self.imageNode.setSignal(chatMessageAnimatedSticker(postbox: item.context.account.postbox, userLocation: .peer(item.message.id.peerId), file: emojiFile, small: false, size: dimensions.cgSize.aspectFilled(fillSize), fitzModifier: fitzModifier, thumbnail: false, synchronousLoad: synchronousLoad), attemptSynchronously: synchronousLoad)
self.disposable.set(freeMediaFileInteractiveFetched(account: item.context.account, userLocation: .peer(item.message.id.peerId), fileReference: .standalone(media: emojiFile)).start())
self.disposable.set(freeMediaFileInteractiveFetched(account: item.context.account, userLocation: .peer(item.message.id.peerId), fileReference: .standalone(media: emojiFile)).startStrict())
}
let textEmoji = item.message.text.strippedEmoji
@ -687,7 +687,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
if let animationItems = animationItems {
for (_, animationItem) in animationItems {
self.disposables.add(freeMediaFileInteractiveFetched(account: item.context.account, userLocation: .peer(item.message.id.peerId), fileReference: .standalone(media: animationItem.file)).start())
self.disposables.add(freeMediaFileInteractiveFetched(account: item.context.account, userLocation: .peer(item.message.id.peerId), fileReference: .standalone(media: animationItem.file)).startStrict())
}
}
}
@ -2279,7 +2279,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
if shouldPlay {
let _ = (appConfiguration
|> deliverOnMainQueue).start(next: { [weak self] appConfiguration in
|> deliverOnMainQueue).startStandalone(next: { [weak self] appConfiguration in
guard let strongSelf = self else {
return
}
@ -2297,7 +2297,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
strongSelf.mediaPlayer = mediaPlayer
strongSelf.mediaStatusDisposable.set((mediaPlayer.status
|> deliverOnMainQueue).start(next: { [weak self] status in
|> deliverOnMainQueue).startStrict(next: { [weak self] status in
if let strongSelf = self {
if let haptic = haptic, !haptic.active {
haptic.start(time: 0.0)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -175,7 +175,7 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
actionSheet?.dismissAnimated()
if let strongSelf = self {
let _ = (strongSelf.context.engine.peers.revokePeerExportedInvitation(peerId: peer.id, link: inviteLink)
|> deliverOnMainQueue).start(completed: { [weak self] in
|> deliverOnMainQueue).startStandalone(completed: { [weak self] in
self?.eventLogContext.reload()
})
}
@ -237,7 +237,7 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
}, enqueueMessage: { _ in
}, sendSticker: nil, sendEmoji: nil, setupTemporaryHiddenMedia: { _, _, _ in }, chatAvatarHiddenMedia: { signal, media in
if let strongSelf = self {
strongSelf.temporaryHiddenGalleryMediaDisposable.set((signal |> deliverOnMainQueue).start(next: { messageId in
strongSelf.temporaryHiddenGalleryMediaDisposable.set((signal |> deliverOnMainQueue).startStrict(next: { messageId in
if let strongSelf = self, let controllerInteraction = strongSelf.controllerInteraction {
var messageIdAndMedia: [MessageId: [Media]] = [:]
@ -302,7 +302,7 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
|> map(Optional.init)
}
strongSelf.resolvePeerByNameDisposable.set((resolveSignal
|> deliverOnMainQueue).start(next: { peer in
|> deliverOnMainQueue).startStrict(next: { peer in
if let strongSelf = self, !hashtag.isEmpty {
let searchController = HashtagSearchController(context: strongSelf.context, peer: peer.flatMap(EnginePeer.init), query: hashtag)
strongSelf.pushController(searchController)
@ -390,7 +390,7 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
actionSheet?.dismissAnimated()
if let strongSelf = self {
let _ = (strongSelf.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|> deliverOnMainQueue).start(next: { peer in
|> deliverOnMainQueue).startStandalone(next: { peer in
if let strongSelf = self, let peer = peer {
strongSelf.openPeer(peer: peer)
}
@ -608,10 +608,10 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
return .complete()
}
self.historyDisposable = appliedTransition.start()
self.historyDisposable = appliedTransition.startStrict()
let mediaManager = self.context.sharedContext.mediaManager
self.galleryHiddenMesageAndMediaDisposable.set(mediaManager.galleryHiddenMediaManager.hiddenIds().start(next: { [weak self] ids in
self.galleryHiddenMesageAndMediaDisposable.set(mediaManager.galleryHiddenMediaManager.hiddenIds().startStrict(next: { [weak self] ids in
if let strongSelf = self, let controllerInteraction = strongSelf.controllerInteraction {
var messageIdAndMedia: [MessageId: [Media]] = [:]
@ -806,7 +806,7 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
}), .window(.root), nil)
} else {
let peerSignal: Signal<Peer?, NoError> = .single(peer._asPeer())
self.navigationActionDisposable.set((peerSignal |> take(1) |> deliverOnMainQueue).start(next: { [weak self] peer in
self.navigationActionDisposable.set((peerSignal |> take(1) |> deliverOnMainQueue).startStrict(next: { [weak self] peer in
if let strongSelf = self, let peer = peer {
if peer is TelegramChannel, let navigationController = strongSelf.getNavigationController() {
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(EnginePeer(peer)), peekData: peekData, animated: true))
@ -823,7 +823,7 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
private func openPeerMention(_ name: String) {
self.navigationActionDisposable.set((self.context.engine.peers.resolvePeerByName(name: name, ageLimit: 10)
|> take(1)
|> deliverOnMainQueue).start(next: { [weak self] peer in
|> deliverOnMainQueue).startStrict(next: { [weak self] peer in
if let strongSelf = self {
if let peer = peer {
if let infoController = strongSelf.context.sharedContext.makePeerInfoController(context: strongSelf.context, updatedPresentationData: nil, peer: peer._asPeer(), mode: .generic, avatarInitiallyExpanded: false, fromChat: false, requestsContext: nil) {
@ -903,7 +903,7 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
if let strongSelf = self {
f(.default)
strongSelf.banDisposables.set((strongSelf.context.engine.peers.fetchChannelParticipant(peerId: strongSelf.peer.id, participantId: author.id)
|> deliverOnMainQueue).start(next: { participant in
|> deliverOnMainQueue).startStrict(next: { participant in
if let strongSelf = self {
strongSelf.presentController(channelBannedMemberController(context: strongSelf.context, peerId: strongSelf.peer.id, memberId: author.id, initialParticipant: participant, updated: { _ in }, upgradedToSupergroup: { _, f in f() }), .window(.root), ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
}
@ -926,7 +926,7 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
if let strongSelf = self {
strongSelf.reportFalsePositiveDisposables.set((strongSelf.context.engine.peers.reportAntiSpamFalsePositive(peerId: message.id.peerId, messageId: message.id)
|> deliverOnMainQueue).start(), forKey: message.id)
|> deliverOnMainQueue).startStrict(), forKey: message.id)
Queue.mainQueue().after(0.2, {
strongSelf.presentController(UndoOverlayController(presentationData: strongSelf.presentationData, content: .universal(animation: "anim_antispam", scale: 0.066, colors: [:], title: nil, text: strongSelf.presentationData.strings.Group_AdminLog_AntiSpamFalsePositiveReportedText, customUndoText: nil, timeout: nil), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), .current, nil)
@ -956,7 +956,7 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
}
private func openUrl(_ url: String) {
self.navigationActionDisposable.set((self.context.sharedContext.resolveUrl(context: self.context, peerId: nil, url: url, skipUrlAuth: true) |> deliverOnMainQueue).start(next: { [weak self] result in
self.navigationActionDisposable.set((self.context.sharedContext.resolveUrl(context: self.context, peerId: nil, url: url, skipUrlAuth: true) |> deliverOnMainQueue).startStrict(next: { [weak self] result in
if let strongSelf = self {
switch result {
case let .externalUrl(url):
@ -991,7 +991,7 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
}
case let .replyThread(messageId):
if let navigationController = strongSelf.getNavigationController() {
let _ = strongSelf.context.sharedContext.navigateToForumThread(context: strongSelf.context, peerId: messageId.peerId, threadId: Int64(messageId.id), messageId: nil, navigationController: navigationController, activateInput: nil, keepStack: .always).start()
let _ = strongSelf.context.sharedContext.navigateToForumThread(context: strongSelf.context, peerId: messageId.peerId, threadId: Int64(messageId.id), messageId: nil, navigationController: navigationController, activateInput: nil, keepStack: .always).startStandalone()
}
case let .stickerPack(name, type):
let _ = type

View File

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

View File

@ -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, _, _):

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -11,7 +11,7 @@ import PeerInfoUI
func openAddContactImpl(context: AccountContext, firstName: String = "", lastName: String = "", phoneNumber: String, label: String = "_$!<Mobile>!$_", present: @escaping (ViewController, Any?) -> Void, pushController: @escaping (ViewController) -> Void, completed: @escaping () -> Void = {}) {
let _ = (DeviceAccess.authorizationStatus(subject: .contacts)
|> take(1)
|> deliverOnMainQueue).start(next: { value in
|> deliverOnMainQueue).startStandalone(next: { value in
switch value {
case .allowed:
let contactData = DeviceContactExtendedData(basicData: DeviceContactBasicData(firstName: firstName, lastName: lastName, phoneNumbers: [DeviceContactPhoneNumberData(label: label, value: phoneNumber)]), middleName: "", prefix: "", suffix: "", organization: "", jobTitle: "", department: "", emailAddresses: [], urls: [], addresses: [], birthdayDate: nil, socialProfiles: [], instantMessagingProfiles: [], note: "")

View File

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

View File

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

View File

@ -246,7 +246,7 @@ func openExternalUrlImpl(context: AccountContext, urlContext: OpenURLContext, ur
let handleInternalUrl: (String) -> Void = { url in
let _ = (context.sharedContext.resolveUrl(context: context, peerId: nil, url: url, skipUrlAuth: true)
|> deliverOnMainQueue).start(next: handleResolvedUrl)
|> deliverOnMainQueue).startStandalone(next: handleResolvedUrl)
}
if let scheme = parsedUrl.scheme, (scheme == "tg" || scheme == context.sharedContext.applicationBindings.appSpecificScheme) {
@ -526,7 +526,7 @@ func openExternalUrlImpl(context: AccountContext, urlContext: OpenURLContext, ur
if let id = id, !id.isEmpty, let idValue = Int64(id), idValue > 0 {
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(idValue))))
|> deliverOnMainQueue).start(next: { peer in
|> deliverOnMainQueue).startStandalone(next: { peer in
if let peer = peer, let controller = context.sharedContext.makePeerInfoController(context: context, updatedPresentationData: nil, peer: peer._asPeer(), mode: .generic, avatarInitiallyExpanded: false, fromChat: false, requestsContext: nil) {
navigationController?.pushViewController(controller)
}
@ -824,7 +824,7 @@ func openExternalUrlImpl(context: AccountContext, urlContext: OpenURLContext, ur
var settings = settings
settings.backupHostOverride = host
return settings
}).start()
}).startStandalone()
return
}
}
@ -961,7 +961,7 @@ func openExternalUrlImpl(context: AccountContext, urlContext: OpenURLContext, ur
}
let _ = (settings
|> deliverOnMainQueue).start(next: { settings in
|> deliverOnMainQueue).startStandalone(next: { settings in
if settings.defaultWebBrowser == nil {
if !"".isEmpty && isCompact {
let controller = BrowserScreen(context: context, subject: .webPage(url: parsedUrl.absoluteString))

Some files were not shown because too many files have changed in this diff Show More