diff --git a/submodules/ItemListPeerItem/BUILD b/submodules/ItemListPeerItem/BUILD index 784835efe7..a4a85f437a 100644 --- a/submodules/ItemListPeerItem/BUILD +++ b/submodules/ItemListPeerItem/BUILD @@ -27,6 +27,8 @@ swift_library( "//submodules/ComponentFlow:ComponentFlow", "//submodules/TelegramUI/Components/EmojiStatusComponent:EmojiStatusComponent", "//submodules/CheckNode", + "//submodules/TelegramUI/Components/AnimationCache", + "//submodules/TelegramUI/Components/MultiAnimationRenderer", ], visibility = [ "//visibility:public", diff --git a/submodules/ItemListPeerItem/Sources/ItemListPeerItem.swift b/submodules/ItemListPeerItem/Sources/ItemListPeerItem.swift index 440b8785a7..4d8cebf90d 100644 --- a/submodules/ItemListPeerItem/Sources/ItemListPeerItem.swift +++ b/submodules/ItemListPeerItem/Sources/ItemListPeerItem.swift @@ -17,6 +17,8 @@ import AccountContext import ComponentFlow import EmojiStatusComponent import CheckNode +import AnimationCache +import MultiAnimationRenderer private final class ShimmerEffectNode: ASDisplayNode { private var currentBackgroundColor: UIColor? @@ -319,10 +321,126 @@ public struct ItemListPeerItemShimmering { } public final class ItemListPeerItem: ListViewItem, ItemListItem { + public enum Context { + public final class Custom { + public let accountPeerId: EnginePeer.Id + public let postbox: Postbox + public let network: Network + public let animationCache: AnimationCache + public let animationRenderer: MultiAnimationRenderer + public let isPremiumDisabled: Bool + public let resolveInlineStickers: ([Int64]) -> Signal<[Int64: TelegramMediaFile], NoError> + + public init( + accountPeerId: EnginePeer.Id, + postbox: Postbox, + network: Network, + animationCache: AnimationCache, + animationRenderer: MultiAnimationRenderer, + isPremiumDisabled: Bool, + resolveInlineStickers: @escaping ([Int64]) -> Signal<[Int64: TelegramMediaFile], NoError> + ) { + self.accountPeerId = accountPeerId + self.postbox = postbox + self.network = network + self.animationCache = animationCache + self.animationRenderer = animationRenderer + self.isPremiumDisabled = isPremiumDisabled + self.resolveInlineStickers = resolveInlineStickers + } + } + + case account(AccountContext) + case custom(Custom) + + public var accountPeerId: EnginePeer.Id { + switch self { + case let .account(context): + return context.account.peerId + case let .custom(custom): + return custom.accountPeerId + } + } + + public var postbox: Postbox { + switch self { + case let .account(context): + return context.account.postbox + case let .custom(custom): + return custom.postbox + } + } + + public var network: Network { + switch self { + case let .account(context): + return context.account.network + case let .custom(custom): + return custom.network + } + } + + public var animationCache: AnimationCache { + switch self { + case let .account(context): + return context.animationCache + case let .custom(custom): + return custom.animationCache + } + } + + public var animationRenderer: MultiAnimationRenderer { + switch self { + case let .account(context): + return context.animationRenderer + case let .custom(custom): + return custom.animationRenderer + } + } + + public var isPremiumDisabled: Bool { + switch self { + case let .account(context): + return PremiumConfiguration.with(appConfiguration: context.currentAppConfiguration.with({ $0 })).isPremiumDisabled + case let .custom(custom): + return custom.isPremiumDisabled + } + } + + public var resolveInlineStickers: ([Int64]) -> Signal<[Int64: TelegramMediaFile], NoError> { + switch self { + case let .account(context): + return { fileIds in + return context.engine.stickers.resolveInlineStickers(fileIds: fileIds) + } + case let .custom(custom): + return custom.resolveInlineStickers + } + } + + public var energyUsageSettings: EnergyUsageSettings { + switch self { + case let .account(context): + return context.sharedContext.energyUsageSettings + case .custom: + return .default + } + } + + public var contentSettings: ContentSettings { + switch self { + case let .account(context): + return context.currentContentSettings.with { $0 } + case .custom: + return .default + } + } + } + let presentationData: ItemListPresentationData let dateTimeFormat: PresentationDateTimeFormat let nameDisplayOrder: PresentationPersonNameOrder - let context: AccountContext + let context: Context let peer: EnginePeer let threadInfo: EngineMessageHistoryThread.Info? let height: ItemListPeerItemHeight @@ -358,7 +476,126 @@ public final class ItemListPeerItem: ListViewItem, ItemListItem { let storyStats: PeerStoryStats? let openStories: ((UIView) -> Void)? - public init(presentationData: ItemListPresentationData, dateTimeFormat: PresentationDateTimeFormat, nameDisplayOrder: PresentationPersonNameOrder, context: AccountContext, peer: EnginePeer, threadInfo: EngineMessageHistoryThread.Info? = nil, height: ItemListPeerItemHeight = .peerList, aliasHandling: ItemListPeerItemAliasHandling = .standard, nameColor: ItemListPeerItemNameColor = .primary, nameStyle: ItemListPeerItemNameStyle = .distinctBold, presence: EnginePeer.Presence?, text: ItemListPeerItemText, label: ItemListPeerItemLabel, editing: ItemListPeerItemEditing, revealOptions: ItemListPeerItemRevealOptions? = nil, switchValue: ItemListPeerItemSwitch?, enabled: Bool, highlighted: Bool = false, selectable: Bool, highlightable: Bool = true, animateFirstAvatarTransition: Bool = true, sectionId: ItemListSectionId, action: (() -> Void)?, setPeerIdWithRevealedOptions: @escaping (EnginePeer.Id?, EnginePeer.Id?) -> Void, removePeer: @escaping (EnginePeer.Id) -> Void, toggleUpdated: ((Bool) -> Void)? = nil, contextAction: ((ASDisplayNode, ContextGesture?) -> Void)? = nil, hasTopStripe: Bool = true, hasTopGroupInset: Bool = true, noInsets: Bool = false, noCorners: Bool = false, tag: ItemListItemTag? = nil, header: ListViewItemHeader? = nil, shimmering: ItemListPeerItemShimmering? = nil, displayDecorations: Bool = true, disableInteractiveTransitionIfNecessary: Bool = false, storyStats: PeerStoryStats? = nil, openStories: ((UIView) -> Void)? = nil) { + public init( + presentationData: ItemListPresentationData, + dateTimeFormat: PresentationDateTimeFormat, + nameDisplayOrder: PresentationPersonNameOrder, + context: AccountContext, + peer: EnginePeer, + threadInfo: EngineMessageHistoryThread.Info? = nil, + height: ItemListPeerItemHeight = .peerList, + aliasHandling: ItemListPeerItemAliasHandling = .standard, + nameColor: ItemListPeerItemNameColor = .primary, + nameStyle: ItemListPeerItemNameStyle = .distinctBold, + presence: EnginePeer.Presence?, + text: ItemListPeerItemText, + label: ItemListPeerItemLabel, + editing: ItemListPeerItemEditing, + revealOptions: ItemListPeerItemRevealOptions? = nil, + switchValue: ItemListPeerItemSwitch?, + enabled: Bool, + highlighted: Bool = false, + selectable: Bool, + highlightable: Bool = true, + animateFirstAvatarTransition: Bool = true, + sectionId: ItemListSectionId, + action: (() -> Void)?, + setPeerIdWithRevealedOptions: @escaping (EnginePeer.Id?, EnginePeer.Id?) -> Void, + removePeer: @escaping (EnginePeer.Id) -> Void, + toggleUpdated: ((Bool) -> Void)? = nil, + contextAction: ((ASDisplayNode, ContextGesture?) -> Void)? = nil, + hasTopStripe: Bool = true, + hasTopGroupInset: Bool = true, + noInsets: Bool = false, + noCorners: Bool = false, + tag: ItemListItemTag? = nil, + header: ListViewItemHeader? = nil, + shimmering: ItemListPeerItemShimmering? = nil, + displayDecorations: Bool = true, + disableInteractiveTransitionIfNecessary: Bool = false, + storyStats: PeerStoryStats? = nil, + openStories: ((UIView) -> Void)? = nil + ) { + self.presentationData = presentationData + self.dateTimeFormat = dateTimeFormat + self.nameDisplayOrder = nameDisplayOrder + self.context = .account(context) + self.peer = peer + self.threadInfo = threadInfo + self.height = height + self.aliasHandling = aliasHandling + self.nameColor = nameColor + self.nameStyle = nameStyle + self.presence = presence + self.text = text + self.label = label + self.editing = editing + self.revealOptions = revealOptions + self.switchValue = switchValue + self.enabled = enabled + self.highlighted = highlighted + self.selectable = selectable + self.highlightable = highlightable + self.animateFirstAvatarTransition = animateFirstAvatarTransition + self.sectionId = sectionId + self.action = action + self.setPeerIdWithRevealedOptions = setPeerIdWithRevealedOptions + self.removePeer = removePeer + self.toggleUpdated = toggleUpdated + self.contextAction = contextAction + self.hasTopStripe = hasTopStripe + self.hasTopGroupInset = hasTopGroupInset + self.noInsets = noInsets + self.noCorners = noCorners + self.tag = tag + self.header = header + self.shimmering = shimmering + self.displayDecorations = displayDecorations + self.disableInteractiveTransitionIfNecessary = disableInteractiveTransitionIfNecessary + self.storyStats = storyStats + self.openStories = openStories + } + + public init( + presentationData: ItemListPresentationData, + dateTimeFormat: PresentationDateTimeFormat, + nameDisplayOrder: PresentationPersonNameOrder, + context: Context, + peer: EnginePeer, + threadInfo: EngineMessageHistoryThread.Info? = nil, + height: ItemListPeerItemHeight = .peerList, + aliasHandling: ItemListPeerItemAliasHandling = .standard, + nameColor: ItemListPeerItemNameColor = .primary, + nameStyle: ItemListPeerItemNameStyle = .distinctBold, + presence: EnginePeer.Presence?, + text: ItemListPeerItemText, + label: ItemListPeerItemLabel, + editing: ItemListPeerItemEditing, + revealOptions: ItemListPeerItemRevealOptions? = nil, + switchValue: ItemListPeerItemSwitch?, + enabled: Bool, + highlighted: Bool = false, + selectable: Bool, + highlightable: Bool = true, + animateFirstAvatarTransition: Bool = true, + sectionId: ItemListSectionId, + action: (() -> Void)?, + setPeerIdWithRevealedOptions: @escaping (EnginePeer.Id?, EnginePeer.Id?) -> Void, + removePeer: @escaping (EnginePeer.Id) -> Void, + toggleUpdated: ((Bool) -> Void)? = nil, + contextAction: ((ASDisplayNode, ContextGesture?) -> Void)? = nil, + hasTopStripe: Bool = true, + hasTopGroupInset: Bool = true, + noInsets: Bool = false, + noCorners: Bool = false, + tag: ItemListItemTag? = nil, + header: ListViewItemHeader? = nil, + shimmering: ItemListPeerItemShimmering? = nil, + displayDecorations: Bool = true, + disableInteractiveTransitionIfNecessary: Bool = false, + storyStats: PeerStoryStats? = nil, + openStories: ((UIView) -> Void)? = nil + ) { self.presentationData = presentationData self.dateTimeFormat = dateTimeFormat self.nameDisplayOrder = nameDisplayOrder @@ -666,9 +903,7 @@ public class ItemListPeerItemNode: ItemListRevealOptionsItemNode, ItemListItemNo var updatedLabelBadgeImage: UIImage? var credibilityIcon: EmojiStatusComponent.Content? - let premiumConfiguration = PremiumConfiguration.with(appConfiguration: item.context.currentAppConfiguration.with { $0 }) - - if case .threatSelfAsSaved = item.aliasHandling, item.peer.id == item.context.account.peerId { + if case .threatSelfAsSaved = item.aliasHandling, item.peer.id == item.context.accountPeerId { } else { if item.peer.isScam { credibilityIcon = .text(color: item.presentationData.theme.chat.message.incoming.scamColor, string: item.presentationData.strings.Message_ScamAccount.uppercased()) @@ -678,7 +913,7 @@ public class ItemListPeerItemNode: ItemListRevealOptionsItemNode, ItemListItemNo credibilityIcon = .animation(content: .customEmoji(fileId: emojiStatus.fileId), size: CGSize(width: 20.0, height: 20.0), placeholderColor: item.presentationData.theme.list.mediaPlaceholderColor, themeColor: item.presentationData.theme.list.itemAccentColor, loopMode: .count(2)) } else if item.peer.isVerified { credibilityIcon = .verified(fillColor: item.presentationData.theme.list.itemCheckColors.fillColor, foregroundColor: item.presentationData.theme.list.itemCheckColors.foregroundColor, sizeType: .compact) - } else if item.peer.isPremium && !premiumConfiguration.isPremiumDisabled { + } else if item.peer.isPremium && !item.context.isPremiumDisabled { credibilityIcon = .premium(color: item.presentationData.theme.list.itemAccentColor) } } @@ -799,7 +1034,7 @@ public class ItemListPeerItemNode: ItemListRevealOptionsItemNode, ItemListItemNo if let threadInfo = item.threadInfo { titleAttributedString = NSAttributedString(string: threadInfo.title, font: currentBoldFont, textColor: titleColor) - } else if item.peer.id == item.context.account.peerId, case .threatSelfAsSaved = item.aliasHandling { + } else if item.peer.id == item.context.accountPeerId, case .threatSelfAsSaved = item.aliasHandling { titleAttributedString = NSAttributedString(string: item.presentationData.strings.DialogList_SavedMessages, font: currentBoldFont, textColor: titleColor) } else if item.peer.id.isReplies { titleAttributedString = NSAttributedString(string: item.presentationData.strings.DialogList_Replies, font: currentBoldFont, textColor: titleColor) @@ -945,8 +1180,11 @@ public class ItemListPeerItemNode: ItemListRevealOptionsItemNode, ItemListItemNo let (labelLayout, labelApply) = makeLabelLayout(TextNodeLayoutArguments(attributedString: labelAttributedString, backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: params.width - leftInset - 16.0 - editingOffset - rightInset, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets())) - let (titleLayout, titleApply) = makeTitleLayout(TextNodeLayoutArguments(attributedString: titleAttributedString, backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: params.width - leftInset - 12.0 - editingOffset - rightInset - labelLayout.size.width - labelInset - titleIconsWidth, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets())) - let (statusLayout, statusApply) = makeStatusLayout(TextNodeLayoutArguments(attributedString: statusAttributedString, backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: params.width - leftInset - 8.0 - editingOffset - rightInset - labelLayout.size.width - labelInset, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets())) + let constrainedTitleSize = CGSize(width: params.width - leftInset - 12.0 - editingOffset - rightInset - labelLayout.size.width - labelInset - titleIconsWidth, height: CGFloat.greatestFiniteMagnitude) + let (titleLayout, titleApply) = makeTitleLayout(TextNodeLayoutArguments(attributedString: titleAttributedString, backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: constrainedTitleSize, alignment: .natural, cutout: nil, insets: UIEdgeInsets())) + + let constrainedStatusSize = CGSize(width: params.width - leftInset - 8.0 - editingOffset - rightInset - labelLayout.size.width - labelInset, height: CGFloat.greatestFiniteMagnitude) + let (statusLayout, statusApply) = makeStatusLayout(TextNodeLayoutArguments(attributedString: statusAttributedString, backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: constrainedStatusSize, alignment: .natural, cutout: nil, insets: UIEdgeInsets())) var insets = itemListNeighborsGroupedInsets(neighbors, params) if !item.hasTopGroupInset { @@ -1157,7 +1395,9 @@ public class ItemListPeerItemNode: ItemListRevealOptionsItemNode, ItemListItemNo } let credibilityIconComponent = EmojiStatusComponent( - context: item.context, + postbox: item.context.postbox, + energyUsageSettings: item.context.energyUsageSettings, + resolveInlineStickers: item.context.resolveInlineStickers, animationCache: animationCache, animationRenderer: animationRenderer, content: credibilityIcon, @@ -1315,7 +1555,9 @@ public class ItemListPeerItemNode: ItemListRevealOptionsItemNode, ItemListItemNo } let avatarIconComponent = EmojiStatusComponent( - context: item.context, + postbox: item.context.postbox, + energyUsageSettings: item.context.energyUsageSettings, + resolveInlineStickers: item.context.resolveInlineStickers, animationCache: item.context.animationCache, animationRenderer: item.context.animationRenderer, content: avatarIconContent, @@ -1338,10 +1580,30 @@ public class ItemListPeerItemNode: ItemListRevealOptionsItemNode, ItemListItemNo transition.updateFrame(view: avatarIconComponentView, frame: threadIconFrame) } } else { - if item.peer.id == item.context.account.peerId, case .threatSelfAsSaved = item.aliasHandling { - strongSelf.avatarNode.setPeer(context: item.context, theme: item.presentationData.theme, peer: item.peer, overrideImage: .savedMessagesIcon, emptyColor: item.presentationData.theme.list.mediaPlaceholderColor, synchronousLoad: synchronousLoad) + if item.peer.id == item.context.accountPeerId, case .threatSelfAsSaved = item.aliasHandling { + strongSelf.avatarNode.setPeer( + accountPeerId: item.context.accountPeerId, + postbox: item.context.postbox, + network: item.context.network, + contentSettings: item.context.contentSettings, + theme: item.presentationData.theme, + peer: item.peer, + overrideImage: .savedMessagesIcon, + emptyColor: item.presentationData.theme.list.mediaPlaceholderColor, + synchronousLoad: synchronousLoad + ) } else if item.peer.id.isReplies { - strongSelf.avatarNode.setPeer(context: item.context, theme: item.presentationData.theme, peer: item.peer, overrideImage: .repliesIcon, emptyColor: item.presentationData.theme.list.mediaPlaceholderColor, synchronousLoad: synchronousLoad) + strongSelf.avatarNode.setPeer( + accountPeerId: item.context.accountPeerId, + postbox: item.context.postbox, + network: item.context.network, + contentSettings: item.context.contentSettings, + theme: item.presentationData.theme, + peer: item.peer, + overrideImage: .repliesIcon, + emptyColor: item.presentationData.theme.list.mediaPlaceholderColor, + synchronousLoad: synchronousLoad + ) } else { var overrideImage: AvatarNodeImageOverride? if item.peer.isDeleted { @@ -1353,7 +1615,20 @@ public class ItemListPeerItemNode: ItemListRevealOptionsItemNode, ItemListItemNo if case let .channel(channel) = item.peer, channel.isForum { clipStyle = .roundedRect } - strongSelf.avatarNode.setPeer(context: item.context, theme: item.presentationData.theme, peer: item.peer, overrideImage: overrideImage, emptyColor: item.presentationData.theme.list.mediaPlaceholderColor, clipStyle: clipStyle, synchronousLoad: synchronousLoad) + + strongSelf.avatarNode.setPeer( + accountPeerId: item.context.accountPeerId, + postbox: item.context.postbox, + network: item.context.network, + contentSettings: item.context.contentSettings, + theme: item.presentationData.theme, + peer: item.peer, + overrideImage: overrideImage, + emptyColor: item.presentationData.theme.list.mediaPlaceholderColor, + clipStyle: clipStyle, + synchronousLoad: synchronousLoad + ) + strongSelf.avatarNode.setStoryStats(storyStats: item.storyStats.flatMap { storyStats in return AvatarNode.StoryStats( totalCount: storyStats.totalCount, diff --git a/submodules/TelegramUI/Sources/PeerInfo/ListItems/PeerInfoScreenActionItem.swift b/submodules/TelegramUI/Sources/PeerInfo/ListItems/PeerInfoScreenActionItem.swift index c129a42b4c..828a840b8e 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/ListItems/PeerInfoScreenActionItem.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/ListItems/PeerInfoScreenActionItem.swift @@ -138,7 +138,7 @@ private final class PeerInfoScreenActionItemNode: PeerInfoScreenItemNode { transition.updateFrame(node: self.iconNode, frame: iconFrame) } else if let iconSignal = item.iconSignal { self.iconDisposable.set((iconSignal - |> deliverOnMainQueue).start(next: { [weak self] image in + |> deliverOnMainQueue).startStrict(next: { [weak self] image in if let strongSelf = self, let image { strongSelf.iconNode.image = image let iconFrame = CGRect(origin: CGPoint(x: iconInset, y: floorToScreenPixels((height - image.size.height) / 2.0)), size: image.size) diff --git a/submodules/TelegramUI/Sources/PeerInfo/ListItems/PeerInfoScreenDisclosureItem.swift b/submodules/TelegramUI/Sources/PeerInfo/ListItems/PeerInfoScreenDisclosureItem.swift index 0b4a4de9c4..39d6437e45 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/ListItems/PeerInfoScreenDisclosureItem.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/ListItems/PeerInfoScreenDisclosureItem.swift @@ -170,7 +170,7 @@ private final class PeerInfoScreenDisclosureItemNode: PeerInfoScreenItemNode { if previousItem?.text != item.text { self.iconNode.image = nil self.iconDisposable = (iconSignal - |> deliverOnMainQueue).start(next: { [weak self] icon in + |> deliverOnMainQueue).startStrict(next: { [weak self] icon in if let self { self.iconNode.image = icon } diff --git a/submodules/TelegramUI/Sources/PeerInfo/ListItems/PeerInfoScreenMemberItem.swift b/submodules/TelegramUI/Sources/PeerInfo/ListItems/PeerInfoScreenMemberItem.swift index 414ea0ddf7..436a667ed9 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/ListItems/PeerInfoScreenMemberItem.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/ListItems/PeerInfoScreenMemberItem.swift @@ -19,7 +19,7 @@ enum PeerInfoScreenMemberItemAction { final class PeerInfoScreenMemberItem: PeerInfoScreenItem { let id: AnyHashable - let context: AccountContext + let context: ItemListPeerItem.Context let enclosingPeer: Peer? let member: PeerInfoMember let badge: String? @@ -30,7 +30,7 @@ final class PeerInfoScreenMemberItem: PeerInfoScreenItem { init( id: AnyHashable, - context: AccountContext, + context: ItemListPeerItem.Context, enclosingPeer: Peer?, member: PeerInfoMember, badge: String? = nil, @@ -149,7 +149,7 @@ private final class PeerInfoScreenMemberItemNode: PeerInfoScreenItemNode { } } - let actions = availableActionsForMemberOfPeer(accountPeerId: item.context.account.peerId, peer: item.enclosingPeer, member: item.member) + let actions = availableActionsForMemberOfPeer(accountPeerId: item.context.accountPeerId, peer: item.enclosingPeer, member: item.member) var options: [ItemListPeerItemRevealOption] = [] if actions.contains(.promote) && item.enclosingPeer is TelegramChannel { @@ -272,7 +272,7 @@ private final class PeerInfoScreenMemberItemNode: PeerInfoScreenItemNode { } var highlight = point != nil if case .account = item.member { - } else if item.context.account.peerId == item.member.id { + } else if item.context.accountPeerId == item.member.id { highlight = false } if let point, let itemNode = self.itemNode, let value = itemNode.view.hitTest(self.view.convert(point, to: itemNode.view), with: nil), value is UIControl { diff --git a/submodules/TelegramUI/Sources/PeerInfo/Panes/PeerInfoGroupsInCommonPaneNode.swift b/submodules/TelegramUI/Sources/PeerInfo/Panes/PeerInfoGroupsInCommonPaneNode.swift index a310357e99..7033542b75 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/Panes/PeerInfoGroupsInCommonPaneNode.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/Panes/PeerInfoGroupsInCommonPaneNode.swift @@ -118,7 +118,7 @@ final class PeerInfoGroupsInCommonPaneNode: ASDisplayNode, PeerInfoPaneNode { self.addSubnode(self.listNode) self.disposable = (groupsInCommonContext.state - |> deliverOnMainQueue).start(next: { [weak self] state in + |> deliverOnMainQueue).startStrict(next: { [weak self] state in guard let strongSelf = self else { return } diff --git a/submodules/TelegramUI/Sources/PeerInfo/Panes/PeerInfoListPaneNode.swift b/submodules/TelegramUI/Sources/PeerInfo/Panes/PeerInfoListPaneNode.swift index bc6ceffaf8..743bd62cfd 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/Panes/PeerInfoListPaneNode.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/Panes/PeerInfoListPaneNode.swift @@ -127,7 +127,7 @@ final class PeerInfoListPaneNode: ASDisplayNode, PeerInfoPaneNode { return .single(nil) } } - |> deliverOnMainQueue).start(next: { [weak self] playlistStateAndType in + |> deliverOnMainQueue).startStrict(next: { [weak self] playlistStateAndType in guard let strongSelf = self else { return } @@ -275,7 +275,7 @@ final class PeerInfoListPaneNode: ASDisplayNode, PeerInfoPaneNode { }) return rate } - |> deliverOnMainQueue).start(next: { baseRate in + |> deliverOnMainQueue).startStandalone(next: { baseRate in guard let strongSelf = self, let (_, _, _, _, type, _) = strongSelf.playlistStateAndType else { return } @@ -392,7 +392,7 @@ final class PeerInfoListPaneNode: ASDisplayNode, PeerInfoPaneNode { progressDisposable.dispose() } } - |> deliverOnMainQueue).start(next: { index in + |> deliverOnMainQueue).startStandalone(next: { index in guard let strongSelf = self else { return } @@ -409,7 +409,7 @@ final class PeerInfoListPaneNode: ASDisplayNode, PeerInfoPaneNode { } else if index.1 { if !progressStarted { progressStarted = true - progressDisposable.set(progressSignal.start()) + progressDisposable.set(progressSignal.startStandalone()) } } }, completed: { diff --git a/submodules/TelegramUI/Sources/PeerInfo/Panes/PeerInfoMembersPane.swift b/submodules/TelegramUI/Sources/PeerInfo/Panes/PeerInfoMembersPane.swift index 09b9a01d1f..3583fa2331 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/Panes/PeerInfoMembersPane.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/Panes/PeerInfoMembersPane.swift @@ -201,7 +201,7 @@ final class PeerInfoMembersPaneNode: ASDisplayNode, PeerInfoPaneNode { self.presentationDataPromise.get(), context.engine.data.subscribe(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)) ) - |> deliverOnMainQueue).start(next: { [weak self] state, presentationData, enclosingPeer in + |> deliverOnMainQueue).startStrict(next: { [weak self] state, presentationData, enclosingPeer in guard let strongSelf = self, let enclosingPeer = enclosingPeer else { return } @@ -222,6 +222,7 @@ final class PeerInfoMembersPaneNode: ASDisplayNode, PeerInfoPaneNode { } deinit { + self.disposable?.dispose() } func ensureMessageIsVisible(id: MessageId) { diff --git a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoHeaderNode.swift b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoHeaderNode.swift index 2789108ead..b57df97afc 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoHeaderNode.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoHeaderNode.swift @@ -2854,7 +2854,7 @@ final class PeerInfoHeaderNode: ASDisplayNode { } else { return .complete() } - }).start(next: { fileAndPackTitle in + }).startStrict(next: { fileAndPackTitle in guard let strongSelf = self else { return } diff --git a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoMembers.swift b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoMembers.swift index a784f89437..2654f9840f 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoMembers.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoMembers.swift @@ -188,7 +188,7 @@ private final class PeerInfoMembersContextImpl { self.channelMembersControl = control self.peerDisposable.set((context.account.postbox.peerView(id: peerId) - |> deliverOn(self.queue)).start(next: { [weak self] view in + |> deliverOn(self.queue)).startStrict(next: { [weak self] view in guard let strongSelf = self else { return } @@ -223,7 +223,7 @@ private final class PeerInfoMembersContextImpl { })) } else if peerId.namespace == Namespaces.Peer.CloudGroup { self.disposable.set((context.account.postbox.peerView(id: peerId) - |> deliverOn(self.queue)).start(next: { [weak self] view in + |> deliverOn(self.queue)).startStrict(next: { [weak self] view in guard let strongSelf = self, let cachedData = view.cachedData as? CachedGroupData, let participantsData = cachedData.participants else { return } @@ -316,7 +316,7 @@ private final class PeerInfoMembersContextImpl { self.pushState() disposable.set((signal - |> deliverOn(self.queue)).start(completed: { + |> deliverOn(self.queue)).startStrict(completed: { completed() })) } diff --git a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoPaneContainerNode.swift b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoPaneContainerNode.swift index 125ed2e209..a375e520c7 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoPaneContainerNode.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoPaneContainerNode.swift @@ -421,7 +421,7 @@ private final class PeerInfoPendingPane { self.pane = PeerInfoPaneWrapper(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) }) diff --git a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift index a088446839..880be9ab81 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift @@ -93,6 +93,7 @@ import ChatAvatarNavigationNode import PeerReportScreen import WebUI import ShareWithPeersScreen +import ItemListPeerItem enum PeerInfoAvatarEditingMode { case generic @@ -735,7 +736,7 @@ private func settingsItems(data: PeerInfoScreenData?, context: AccountContext, p } })) items[.phone]!.append(PeerInfoScreenActionItem(id: 1, text: presentationData.strings.Settings_KeepPhoneNumber(phoneNumber).string, action: { - let _ = dismissServerProvidedSuggestion(account: context.account, suggestion: .validatePhoneNumber).start() + let _ = dismissServerProvidedSuggestion(account: context.account, suggestion: .validatePhoneNumber).startStandalone() })) items[.phone]!.append(PeerInfoScreenActionItem(id: 2, text: presentationData.strings.Settings_ChangePhoneNumber, action: { interaction.openSettings(.phoneNumber) @@ -744,7 +745,7 @@ private func settingsItems(data: PeerInfoScreenData?, context: AccountContext, p items[.phone]!.append(PeerInfoScreenInfoItem(id: 0, title: presentationData.strings.Settings_CheckPasswordTitle, text: .markdown(presentationData.strings.Settings_CheckPasswordText), linkAction: { _ in })) items[.phone]!.append(PeerInfoScreenActionItem(id: 1, text: presentationData.strings.Settings_KeepPassword, action: { - let _ = dismissServerProvidedSuggestion(account: context.account, suggestion: .validatePassword).start() + let _ = dismissServerProvidedSuggestion(account: context.account, suggestion: .validatePassword).startStandalone() })) items[.phone]!.append(PeerInfoScreenActionItem(id: 2, text: presentationData.strings.Settings_TryEnterPassword, action: { interaction.openSettings(.rememberPassword) @@ -759,8 +760,19 @@ private func settingsItems(data: PeerInfoScreenData?, context: AccountContext, p if !settings.accountsAndPeers.isEmpty { for (peerAccountContext, peer, badgeCount) in settings.accountsAndPeers { + let mappedContext = ItemListPeerItem.Context.custom(ItemListPeerItem.Context.Custom( + accountPeerId: peerAccountContext.account.peerId, + postbox: peerAccountContext.account.postbox, + network: peerAccountContext.account.network, + animationCache: context.animationCache, + animationRenderer: context.animationRenderer, + isPremiumDisabled: false, + resolveInlineStickers: { fileIds in + return context.engine.stickers.resolveInlineStickers(fileIds: fileIds) + } + )) let member: PeerInfoMember = .account(peer: RenderedPeer(peer: peer._asPeer())) - items[.accounts]!.append(PeerInfoScreenMemberItem(id: member.id, context: context.sharedContext.makeTempAccountContext(account: peerAccountContext.account), enclosingPeer: nil, member: member, badge: badgeCount > 0 ? "\(compactNumericCountString(Int(badgeCount), decimalSeparator: presentationData.dateTimeFormat.decimalSeparator))" : nil, isAccount: true, action: { action in + items[.accounts]!.append(PeerInfoScreenMemberItem(id: member.id, context: mappedContext, enclosingPeer: nil, member: member, badge: badgeCount > 0 ? "\(compactNumericCountString(Int(badgeCount), decimalSeparator: presentationData.dateTimeFormat.decimalSeparator))" : nil, isAccount: true, action: { action in switch action { case .open: interaction.switchToAccount(peerAccountContext.account.id) @@ -810,7 +822,7 @@ private func settingsItems(data: PeerInfoScreenData?, context: AccountContext, p let context = generator(TransformImageArguments(corners: ImageCorners(), imageSize: size, boundingSize: size, intrinsicInsets: .zero)) return context?.generateImage() } - let _ = freeMediaFileInteractiveFetched(account: context.account, userLocation: .other, fileReference: fileReference).start() + let _ = freeMediaFileInteractiveFetched(account: context.account, userLocation: .other, fileReference: fileReference).startStandalone() } else { iconSignal = .single(UIImage(bundleImageName: "Settings/Menu/Websites")!) } @@ -1392,7 +1404,7 @@ private func infoItems(data: PeerInfoScreenData?, context: AccountContext, prese for member in memberList { let isAccountPeer = member.id == context.account.peerId - items[.peerMembers]!.append(PeerInfoScreenMemberItem(id: member.id, context: context, enclosingPeer: peer, member: member, isAccount: false, action: isAccountPeer ? nil : { action in + items[.peerMembers]!.append(PeerInfoScreenMemberItem(id: member.id, context: .account(context), enclosingPeer: peer, member: member, isAccount: false, action: isAccountPeer ? nil : { action in switch action { case .open: interaction.openPeerInfo(member.peer, true) @@ -2408,7 +2420,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro let gesture: ContextGesture? = anyRecognizer as? ContextGesture let _ = (chatAvailableMessageActionsImpl(engine: strongSelf.context.engine, accountPeerId: strongSelf.context.account.peerId, messageIds: [message.id]) - |> deliverOnMainQueue).start(next: { actions in + |> deliverOnMainQueue).startStandalone(next: { actions in guard let strongSelf = self else { return } @@ -2419,7 +2431,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro c.dismiss(completion: { if let strongSelf = self, let currentPeer = strongSelf.data?.peer, let navigationController = strongSelf.controller?.navigationController as? NavigationController { if let channel = currentPeer as? TelegramChannel, channel.flags.contains(.isForum), let threadId = message.threadId { - let _ = strongSelf.context.sharedContext.navigateToForumThread(context: strongSelf.context, peerId: currentPeer.id, threadId: threadId, messageId: message.id, navigationController: navigationController, activateInput: nil, keepStack: .default).start() + let _ = strongSelf.context.sharedContext.navigateToForumThread(context: strongSelf.context, peerId: currentPeer.id, threadId: threadId, messageId: message.id, navigationController: navigationController, activateInput: nil, keepStack: .default).startStandalone() } else { let targetLocation: NavigateToChatControllerParams.Location if case let .replyThread(message) = strongSelf.chatLocation { @@ -2509,7 +2521,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro c.dismiss(completion: { if let strongSelf = self { strongSelf.headerNode.navigationButtonContainer.performAction?(.selectionDone, nil, nil) - let _ = strongSelf.context.engine.messages.deleteMessagesInteractively(messageIds: Array(messageIds), type: .forEveryone).start() + let _ = strongSelf.context.engine.messages.deleteMessagesInteractively(messageIds: Array(messageIds), type: .forEveryone).startStandalone() } }) }))) @@ -2528,7 +2540,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro c.dismiss(completion: { if let strongSelf = self { strongSelf.headerNode.navigationButtonContainer.performAction?(.selectionDone, nil, nil) - let _ = strongSelf.context.engine.messages.deleteMessagesInteractively(messageIds: Array(messageIds), type: .forLocalPeer).start() + let _ = strongSelf.context.engine.messages.deleteMessagesInteractively(messageIds: Array(messageIds), type: .forLocalPeer).startStandalone() } }) }))) @@ -2565,7 +2577,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro } let _ = (chatMediaListPreviewControllerData(context: strongSelf.context, chatLocation: .peer(id: message.id.peerId), chatLocationContextHolder: Atomic(value: nil), message: message, standalone: false, reverseMessageGalleryOrder: false, navigationController: strongSelf.controller?.navigationController as? NavigationController) - |> deliverOnMainQueue).start(next: { previewData in + |> deliverOnMainQueue).startStandalone(next: { previewData in guard let strongSelf = self else { gesture?.cancel() return @@ -2581,7 +2593,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro c.dismiss(completion: { if let strongSelf = self, let currentPeer = strongSelf.data?.peer, let navigationController = strongSelf.controller?.navigationController as? NavigationController { if let channel = currentPeer as? TelegramChannel, channel.flags.contains(.isForum), let threadId = message.threadId { - let _ = strongSelf.context.sharedContext.navigateToForumThread(context: strongSelf.context, peerId: currentPeer.id, threadId: threadId, messageId: message.id, navigationController: navigationController, activateInput: nil, keepStack: .default).start() + let _ = strongSelf.context.sharedContext.navigateToForumThread(context: strongSelf.context, peerId: currentPeer.id, threadId: threadId, messageId: message.id, navigationController: navigationController, activateInput: nil, keepStack: .default).startStandalone() } else { let targetLocation: NavigateToChatControllerParams.Location if case let .replyThread(message) = strongSelf.chatLocation { @@ -2659,7 +2671,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro c.dismiss(completion: { if let strongSelf = self { strongSelf.headerNode.navigationButtonContainer.performAction?(.selectionDone, nil, nil) - let _ = strongSelf.context.engine.messages.deleteMessagesInteractively(messageIds: Array(messageIds), type: .forEveryone).start() + let _ = strongSelf.context.engine.messages.deleteMessagesInteractively(messageIds: Array(messageIds), type: .forEveryone).startStandalone() } }) }))) @@ -2678,7 +2690,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro c.dismiss(completion: { if let strongSelf = self { strongSelf.headerNode.navigationButtonContainer.performAction?(.selectionDone, nil, nil) - let _ = strongSelf.context.engine.messages.deleteMessagesInteractively(messageIds: Array(messageIds), type: .forLocalPeer).start() + let _ = strongSelf.context.engine.messages.deleteMessagesInteractively(messageIds: Array(messageIds), type: .forLocalPeer).startStandalone() } }) }))) @@ -2897,7 +2909,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro }, navigateToStory: { _, _ in }, automaticMediaDownloadSettings: MediaAutoDownloadSettings.defaultSettings, pollActionState: ChatInterfacePollActionState(), stickerSettings: ChatInterfaceStickerSettings(), presentationContext: ChatPresentationContext(context: context, backgroundNode: nil)) - 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 } @@ -3141,7 +3153,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro let _ = self?.headerNode.avatarListNode.listContainerNode.deleteItem(item) } } - strongSelf.hiddenAvatarRepresentationDisposable.set((galleryController.hiddenMedia |> deliverOnMainQueue).start(next: { entry in + strongSelf.hiddenAvatarRepresentationDisposable.set((galleryController.hiddenMedia |> deliverOnMainQueue).startStrict(next: { entry in self?.headerNode.updateAvatarIsHidden(entry: entry) })) strongSelf.view.endEditing(true) @@ -3226,13 +3238,13 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro let context = strongSelf.context controller.completion = { [weak controller] title, fileId, _, isHidden in let _ = (context.engine.peers.editForumChannelTopic(id: peerId, threadId: threadId, title: title, iconFileId: fileId) - |> deliverOnMainQueue).start(completed: { + |> deliverOnMainQueue).startStandalone(completed: { controller?.dismiss() }) if let isHidden = isHidden { let _ = (context.engine.peers.setForumChannelTopicHidden(id: peerId, threadId: threadId, isHidden: isHidden) - |> deliverOnMainQueue).start(completed: { + |> deliverOnMainQueue).startStandalone(completed: { controller?.dismiss() }) } @@ -3324,7 +3336,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro strongSelf.controller?.present(statusController, in: .window(.root)) } strongSelf.activeActionDisposable.set((combineLatest(updateNameSignal, updateBioSignal) |> deliverOnMainQueue - |> deliverOnMainQueue).start(completed: { + |> deliverOnMainQueue).startStrict(completed: { dismissStatus?() guard let strongSelf = self else { @@ -3381,7 +3393,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro strongSelf.controller?.present(statusController, in: .window(.root)) } strongSelf.activeActionDisposable.set((combineLatest(updateNameSignal, updateBioSignal) |> deliverOnMainQueue - |> deliverOnMainQueue).start(completed: { + |> deliverOnMainQueue).startStrict(completed: { dismissStatus?() guard let strongSelf = self else { @@ -3412,7 +3424,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro strongSelf.controller?.present(statusController, in: .window(.root)) strongSelf.activeActionDisposable.set((context.engine.contacts.updateContactName(peerId: peer.id, firstName: firstName, lastName: lastName) - |> deliverOnMainQueue).start(error: { _ in + |> deliverOnMainQueue).startStrict(error: { _ in dismissStatus?() guard let strongSelf = self else { @@ -3446,7 +3458,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro return .complete() } } - }).start() + }).startStandalone() strongSelf.headerNode.navigationButtonContainer.performAction?(.cancel, nil, nil) })) } @@ -3496,7 +3508,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro strongSelf.controller?.present(statusController, in: .window(.root)) } strongSelf.activeActionDisposable.set((combineLatest(updateDataSignals) - |> deliverOnMainQueue).start(error: { _ in + |> deliverOnMainQueue).startStrict(error: { _ in dismissStatus?() guard let strongSelf = self else { @@ -3555,7 +3567,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro strongSelf.controller?.present(statusController, in: .window(.root)) } strongSelf.activeActionDisposable.set((combineLatest(updateDataSignals) - |> deliverOnMainQueue).start(error: { _ in + |> deliverOnMainQueue).startStrict(error: { _ in dismissStatus?() guard let strongSelf = self else { @@ -3765,7 +3777,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro } let _ = (strongSelf.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: strongSelf.context.account.peerId)) - |> deliverOnMainQueue).start(next: { [weak self] _ in + |> deliverOnMainQueue).startStandalone(next: { [weak self] _ in guard let strongSelf = self else { return } @@ -3785,7 +3797,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro } let _ = (source - |> deliverOnMainQueue).start(next: { [weak self] source in + |> deliverOnMainQueue).startStandalone(next: { [weak self] source in guard let strongSelf = self else { return } @@ -3846,7 +3858,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro if let icon = threadData.info.icon, icon != 0 { let _ = (strongSelf.context.engine.stickers.resolveInlineStickers(fileIds: [icon]) - |> deliverOnMainQueue).start(next: { [weak self] files in + |> deliverOnMainQueue).startStandalone(next: { [weak self] files in if let file = files.first?.value { var stickerPackReference: StickerPackReference? for attribute in file.attributes { @@ -3858,7 +3870,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro if let stickerPackReference = stickerPackReference { let _ = (strongSelf.context.engine.stickers.loadedStickerPack(reference: stickerPackReference, forceActualized: false) - |> deliverOnMainQueue).start(next: { [weak self] stickerPack in + |> deliverOnMainQueue).startStandalone(next: { [weak self] stickerPack in if let strongSelf = self, case let .result(info, _, _) = stickerPack { strongSelf.controller?.present(UndoOverlayController(presentationData: strongSelf.presentationData, content: .sticker(context: strongSelf.context, file: file, loop: true, title: nil, text: strongSelf.presentationData.strings.PeerInfo_TopicIconInfoText(info.title).string, undoText: strongSelf.presentationData.strings.Stickers_PremiumPackView, customAction: nil), elevatedLayout: false, action: { [weak self] action in if let strongSelf = self, action == .undo { @@ -3894,7 +3906,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro queue: Queue.mainQueue(), screenData, self.forceIsContactPromise.get() - ).start(next: { [weak self] data, forceIsContact in + ).startStrict(next: { [weak self] data, forceIsContact in guard let strongSelf = self else { return } @@ -3914,7 +3926,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro } self.customStatusDisposable = (self.customStatusPromise.get() - |> deliverOnMainQueue).start(next: { [weak self] value in + |> deliverOnMainQueue).startStrict(next: { [weak self] value in guard let strongSelf = self else { return } @@ -3924,11 +3936,11 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro } }) - self.refreshMessageTagStatsDisposable = context.engine.messages.refreshMessageTagStats(peerId: peerId, threadId: chatLocation.threadId, tags: [.video, .photo, .gif, .music, .voiceOrInstantVideo, .webPage, .file]).start() + self.refreshMessageTagStatsDisposable = context.engine.messages.refreshMessageTagStats(peerId: peerId, threadId: chatLocation.threadId, tags: [.video, .photo, .gif, .music, .voiceOrInstantVideo, .webPage, .file]).startStrict() if peerId.namespace == Namespaces.Peer.CloudChannel { self.translationStateDisposable = (chatTranslationState(context: context, peerId: peerId) - |> deliverOnMainQueue).start(next: { [weak self] translationState in + |> deliverOnMainQueue).startStrict(next: { [weak self] translationState in self?.translationState = translationState }) } @@ -3941,7 +3953,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro |> map { value -> Float? in return value[peerId] } - |> distinctUntilChanged).start(next: { [weak self] value in + |> distinctUntilChanged).startStrict(next: { [weak self] value in guard let self else { return } @@ -3959,7 +3971,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro context.engine.data.subscribe(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)), expiringStoryList.state ) - |> deliverOnMainQueue).start(next: { [weak self] peer, state in + |> deliverOnMainQueue).startStrict(next: { [weak self] peer, state in guard let self, let peer else { return } @@ -4028,6 +4040,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro self.copyProtectionTooltipController?.dismiss() self.expiringStoryListDisposable?.dispose() self.postingAvailabilityDisposable?.dispose() + self.storyUploadProgressDisposable?.dispose() } override func didLoad() { @@ -4064,7 +4077,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro if let channel = data.peer as? TelegramChannel, channel.flags.contains(.isForum), self.chatLocation.threadId == nil { if self.forumTopicNotificationExceptionsDisposable == nil { self.forumTopicNotificationExceptionsDisposable = (self.context.engine.peers.forumChannelTopicNotificationExceptions(id: channel.id) - |> deliverOnMainQueue).start(next: { [weak self] list in + |> deliverOnMainQueue).startStrict(next: { [weak self] list in guard let strongSelf = self else { return } @@ -4207,7 +4220,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro let storyContent = StoryContentContextImpl(context: self.context, isHidden: false, focusedPeerId: self.peerId, singlePeer: true) let _ = (storyContent.state |> take(1) - |> deliverOnMainQueue).start(next: { [weak self] storyContentState in + |> deliverOnMainQueue).startStandalone(next: { [weak self] storyContentState in guard let self else { return } @@ -4403,14 +4416,14 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro if let timestamp = timestamp { storedState = MediaPlaybackStoredState(timestamp: timestamp, playbackRate: AudioPlaybackRate(playbackRate)) } - let _ = updateMediaPlaybackStoredStateInteractively(engine: strongSelf.context.engine, messageId: messageId, state: storedState).start() + let _ = updateMediaPlaybackStoredStateInteractively(engine: strongSelf.context.engine, messageId: messageId, state: storedState).startStandalone() }, editMedia: { [weak self] messageId, snapshots, transitionCompletion in guard let strongSelf = self else { return } let _ = (strongSelf.context.engine.data.get(TelegramEngine.EngineData.Item.Messages.Message(id: messageId)) - |> deliverOnMainQueue).start(next: { [weak self] message in + |> deliverOnMainQueue).startStandalone(next: { [weak self] message in guard let strongSelf = self, let message = message else { return } @@ -4432,9 +4445,9 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro }, sendMessagesWithSignals: { [weak self] signals, _, _ in if let strongSelf = self { strongSelf.enqueueMediaMessageDisposable.set((legacyAssetPickerEnqueueMessages(context: strongSelf.context, account: strongSelf.context.account, signals: signals!) - |> deliverOnMainQueue).start(next: { [weak self] messages in + |> deliverOnMainQueue).startStrict(next: { [weak self] messages in if let strongSelf = self { - let _ = enqueueMessages(account: strongSelf.context.account, peerId: strongSelf.peerId, messages: messages.map { $0.message }).start() + let _ = enqueueMessages(account: strongSelf.context.account, peerId: strongSelf.peerId, messages: messages.map { $0.message }).startStandalone() } })) } @@ -4528,7 +4541,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro private func openPeer(peerId: PeerId, navigation: ChatControllerInteractionNavigateToPeer) { 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 else { return } @@ -4713,12 +4726,11 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro return } if bot.flags.contains(.showInSettingsDisclaimer) { - let _ = self.context.engine.messages.acceptAttachMenuBotDisclaimer(botId: bot.peer.id).start() + let _ = self.context.engine.messages.acceptAttachMenuBotDisclaimer(botId: bot.peer.id).startStandalone() } if bot.flags.contains(.notActivated) { let _ = (self.context.engine.messages.addBotToAttachMenu(botId: bot.peer.id, allowWrite: allowWrite) - |> deliverOnMainQueue).start(error: { _ in - + |> deliverOnMainQueue).startStandalone(error: { _ in }, completed: { proceed(true) }) @@ -4755,7 +4767,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro case .discussion: if let cachedData = self.data?.cachedData as? CachedChannelData, case let .known(maybeLinkedDiscussionPeerId) = cachedData.linkedDiscussionPeerId, let linkedDiscussionPeerId = maybeLinkedDiscussionPeerId { let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: linkedDiscussionPeerId)) - |> deliverOnMainQueue).start(next: { [weak self] linkedDiscussionPeer in + |> deliverOnMainQueue).startStandalone(next: { [weak self] linkedDiscussionPeer in guard let self, let linkedDiscussionPeer else { return } @@ -4785,7 +4797,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro let peerId = self.data?.peer?.id ?? self.peerId if !displayCustomNotificationSettings { - let _ = self.context.engine.peers.updatePeerMuteSetting(peerId: peerId, threadId: self.chatLocation.threadId, muteInterval: 0).start() + let _ = self.context.engine.peers.updatePeerMuteSetting(peerId: peerId, threadId: self.chatLocation.threadId, muteInterval: 0).startStandalone() let iconColor: UIColor = .white self.controller?.present(UndoOverlayController(presentationData: self.presentationData, content: .universal(animation: "anim_profileunmute", scale: 0.075, colors: [ @@ -4831,7 +4843,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro }, action: { _, f in f(.default) - let _ = strongSelf.context.engine.peers.updatePeerMuteSetting(peerId: peerId, threadId: strongSelf.chatLocation.threadId, muteInterval: value).start() + let _ = strongSelf.context.engine.peers.updatePeerMuteSetting(peerId: peerId, threadId: strongSelf.chatLocation.threadId, muteInterval: value).startStandalone() strongSelf.controller?.present(UndoOverlayController(presentationData: strongSelf.presentationData, content: .universal(animation: "anim_mute_for", scale: 0.066, colors: [:], title: nil, text: strongSelf.presentationData.strings.PeerInfo_TooltipMutedFor(mutedForTimeIntervalString(strings: strongSelf.presentationData.strings, value: value)).string, customUndoText: nil, timeout: nil), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current) }))) @@ -4871,7 +4883,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro guard let strongSelf = self else { return } - let _ = strongSelf.context.engine.peers.updatePeerNotificationSoundInteractive(peerId: peerId, threadId: strongSelf.chatLocation.threadId, sound: .default).start() + let _ = strongSelf.context.engine.peers.updatePeerNotificationSoundInteractive(peerId: peerId, threadId: strongSelf.chatLocation.threadId, sound: .default).startStandalone() strongSelf.controller?.present(UndoOverlayController(presentationData: strongSelf.presentationData, content: .universal(animation: "anim_sound_on", scale: 0.056, colors: [:], title: nil, text: strongSelf.presentationData.strings.PeerInfo_TooltipSoundEnabled, customUndoText: nil, timeout: nil), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current) }))) @@ -4884,7 +4896,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro guard let strongSelf = self else { return } - let _ = strongSelf.context.engine.peers.updatePeerNotificationSoundInteractive(peerId: peerId, threadId: strongSelf.chatLocation.threadId, sound: .none).start() + let _ = strongSelf.context.engine.peers.updatePeerNotificationSoundInteractive(peerId: peerId, threadId: strongSelf.chatLocation.threadId, sound: .none).startStandalone() strongSelf.controller?.present(UndoOverlayController(presentationData: strongSelf.presentationData, content: .universal(animation: "anim_sound_off", scale: 0.056, colors: [:], title: nil, text: strongSelf.presentationData.strings.PeerInfo_TooltipSoundDisabled, customUndoText: nil, timeout: nil), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current) }))) @@ -4900,7 +4912,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro let _ = (context.engine.data.get( TelegramEngine.EngineData.Item.NotificationSettings.Global() ) - |> deliverOnMainQueue).start(next: { globalSettings in + |> deliverOnMainQueue).startStandalone(next: { globalSettings in guard let strongSelf = self, let peer = strongSelf.data?.peer else { return } @@ -4960,11 +4972,11 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro let exceptionController = notificationPeerExceptionController(context: context, updatedPresentationData: strongSelf.controller?.updatedPresentationData, peer: EnginePeer(peer), threadId: threadId, isStories: nil, canRemove: canRemove, defaultSound: defaultSound, defaultStoriesSound: globalSettings.privateChats.storySettings.sound, edit: true, updatePeerSound: { peerId, sound in let _ = (updatePeerSound(peer.id, 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 guard let strongSelf = self else { return } @@ -4981,18 +4993,18 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro }) }, 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(peer.id, sound) - |> deliverOnMainQueue).start() + |> deliverOnMainQueue).startStandalone() }, removePeerFromExceptions: { }, modifiedPeer: { }) @@ -5011,7 +5023,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro return } - let _ = self.context.engine.peers.updatePeerMuteSetting(peerId: peerId, threadId: self.chatLocation.threadId, muteInterval: 0).start() + let _ = self.context.engine.peers.updatePeerMuteSetting(peerId: peerId, threadId: self.chatLocation.threadId, muteInterval: 0).startStandalone() let iconColor: UIColor = .white self.controller?.present(UndoOverlayController(presentationData: self.presentationData, content: .universal(animation: "anim_profileunmute", scale: 0.075, colors: [ @@ -5032,7 +5044,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro return } - let _ = strongSelf.context.engine.peers.updatePeerMuteSetting(peerId: peerId, threadId: strongSelf.chatLocation.threadId, muteInterval: Int32.max).start() + let _ = strongSelf.context.engine.peers.updatePeerMuteSetting(peerId: peerId, threadId: strongSelf.chatLocation.threadId, muteInterval: Int32.max).startStandalone() let iconColor: UIColor = .white strongSelf.controller?.present(UndoOverlayController(presentationData: strongSelf.presentationData, content: .universal(animation: "anim_profilemute", scale: 0.075, colors: [ @@ -5248,7 +5260,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro peerIds.map(TelegramEngine.EngineData.Item.Peer.Peer.init) ) ) - |> deliverOnMainQueue).start(next: { [weak self] peerList in + |> deliverOnMainQueue).startStandalone(next: { [weak self] peerList in guard let strongSelf = self else { return } @@ -5334,11 +5346,11 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro if let strongSelf = self { let _ = updateChatTranslationStateInteractively(engine: strongSelf.context.engine, peerId: strongSelf.peerId, { current in return current?.withIsEnabled(true) - }).start() + }).startStandalone() Queue.mainQueue().after(0.2, { let _ = (strongSelf.context.engine.messages.togglePeerMessagesTranslationHidden(peerId: strongSelf.peerId, hidden: false) - |> deliverOnMainQueue).start(completed: { [weak self] in + |> deliverOnMainQueue).startStandalone(completed: { [weak self] in self?.openChatForTranslation() }) }) @@ -5498,11 +5510,11 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro if let strongSelf = self { let _ = updateChatTranslationStateInteractively(engine: strongSelf.context.engine, peerId: strongSelf.peerId, { current in return current?.withIsEnabled(true) - }).start() + }).startStandalone() Queue.mainQueue().after(0.2, { let _ = (strongSelf.context.engine.messages.togglePeerMessagesTranslationHidden(peerId: strongSelf.peerId, hidden: false) - |> deliverOnMainQueue).start(completed: { [weak self] in + |> deliverOnMainQueue).startStandalone(completed: { [weak self] in self?.openChatForTranslation() }) }) @@ -5755,11 +5767,11 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro if let strongSelf = self { let _ = updateChatTranslationStateInteractively(engine: strongSelf.context.engine, peerId: strongSelf.peerId, { current in return current?.withIsEnabled(true) - }).start() + }).startStandalone() Queue.mainQueue().after(0.2, { let _ = (strongSelf.context.engine.messages.togglePeerMessagesTranslationHidden(peerId: strongSelf.peerId, hidden: false) - |> deliverOnMainQueue).start(completed: { [weak self] in + |> deliverOnMainQueue).startStandalone(completed: { [weak self] in self?.openChatForTranslation() }) }) @@ -5866,7 +5878,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro private func openChatForReporting(_ reason: ReportReason) { if let peer = self.data?.peer, let navigationController = (self.controller?.navigationController as? NavigationController) { if let channel = peer as? TelegramChannel, channel.flags.contains(.isForum) { - let _ = self.context.engine.peers.reportPeer(peerId: peer.id, reason: reason, message: "").start() + let _ = self.context.engine.peers.reportPeer(peerId: peer.id, reason: reason, message: "").startStandalone() self.controller?.present(UndoOverlayController(presentationData: self.presentationData, content: .emoji(name: "PoliceCar", text: self.presentationData.strings.Report_Succeed), elevatedLayout: false, action: { _ in return false }), in: .current) } else { @@ -5897,7 +5909,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro } let _ = (strongSelf.context.engine.peers.setChatMessageAutoremoveTimeoutInteractively(peerId: strongSelf.peerId, timeout: value == 0 ? nil : value) - |> deliverOnMainQueue).start(completed: { + |> deliverOnMainQueue).startStandalone(completed: { guard let strongSelf = self else { return } @@ -5925,9 +5937,9 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro return } if value <= 0 { - let _ = strongSelf.context.engine.peers.updatePeerMuteSetting(peerId: peer.id, threadId: strongSelf.chatLocation.threadId, muteInterval: nil).start() + let _ = strongSelf.context.engine.peers.updatePeerMuteSetting(peerId: peer.id, threadId: strongSelf.chatLocation.threadId, muteInterval: nil).startStandalone() } else { - let _ = strongSelf.context.engine.peers.updatePeerMuteSetting(peerId: peer.id, threadId: strongSelf.chatLocation.threadId, muteInterval: value).start() + let _ = strongSelf.context.engine.peers.updatePeerMuteSetting(peerId: peer.id, threadId: strongSelf.chatLocation.threadId, muteInterval: value).startStandalone() let timeString = stringForPreciseRelativeTimestamp(strings: strongSelf.presentationData.strings, relativeTimestamp: Int32(Date().timeIntervalSince1970) + value, relativeTo: Int32(Date().timeIntervalSince1970), dateTimeFormat: strongSelf.presentationData.dateTimeFormat) @@ -5940,7 +5952,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro private func setAutoremove(timeInterval: Int32?) { let _ = (self.context.engine.peers.setChatMessageAutoremoveTimeoutInteractively(peerId: self.peerId, timeout: timeInterval) - |> deliverOnMainQueue).start(completed: { [weak self] in + |> deliverOnMainQueue).startStandalone(completed: { [weak self] in guard let strongSelf = self else { return } @@ -5965,7 +5977,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro self.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: self.peerId)), self.context.engine.peers.mostRecentSecretChat(id: self.peerId) ) - |> deliverOnMainQueue).start(next: { [weak self] peer, currentPeerId in + |> deliverOnMainQueue).startStandalone(next: { [weak self] peer, currentPeerId in guard let strongSelf = self else { return } @@ -6131,7 +6143,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro peerIds.map(TelegramEngine.EngineData.Item.Peer.Peer.init) ) ) - |> deliverOnMainQueue).start(next: { [weak self] peerList in + |> deliverOnMainQueue).startStandalone(next: { [weak self] peerList in guard let strongSelf = self else { return } @@ -6292,7 +6304,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro let _ = (combineLatest( getUserPeer(engine: self.context.engine, peerId: self.peerId), getUserPeer(engine: self.context.engine, peerId: self.context.account.peerId) - ) |> deliverOnMainQueue).start(next: { [weak self] peer, accountPeer in + ) |> deliverOnMainQueue).startStandalone(next: { [weak self] peer, accountPeer in guard let strongSelf = self else { return } @@ -6399,7 +6411,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro ), self.context.engine.peers.notificationSoundList() ) - |> deliverOnMainQueue).start(next: { [weak self] settings, notificationSoundList in + |> deliverOnMainQueue).startStandalone(next: { [weak self] settings, notificationSoundList in guard let strongSelf = self else { return } @@ -6414,7 +6426,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro guard let strongSelf = self else { return } - let _ = strongSelf.context.engine.peers.updatePeerNotificationSoundInteractive(peerId: strongSelf.peerId, threadId: strongSelf.chatLocation.threadId, sound: sound).start() + let _ = strongSelf.context.engine.peers.updatePeerNotificationSoundInteractive(peerId: strongSelf.peerId, threadId: strongSelf.chatLocation.threadId, sound: sound).startStandalone() }) soundController.navigationPresentation = .modal strongSelf.controller?.push(soundController) @@ -6422,7 +6434,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro guard let strongSelf = self else { return } - let _ = strongSelf.context.engine.peers.updatePeerMuteSetting(peerId: strongSelf.peerId, threadId: strongSelf.chatLocation.threadId, muteInterval: value).start() + let _ = strongSelf.context.engine.peers.updatePeerMuteSetting(peerId: strongSelf.peerId, threadId: strongSelf.chatLocation.threadId, muteInterval: value).startStandalone() }) strongSelf.view.endEditing(true) strongSelf.controller?.present(muteSettingsController, in: .window(.root)) @@ -6434,7 +6446,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro TelegramEngine.EngineData.Item.Peer.NotificationSettings(id: self.peerId), TelegramEngine.EngineData.Item.NotificationSettings.Global() ) - |> deliverOnMainQueue).start(next: { [weak self] peerSettings, globalSettings in + |> deliverOnMainQueue).startStandalone(next: { [weak self] peerSettings, globalSettings in guard let strongSelf = self else { return } @@ -6443,7 +6455,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro guard let strongSelf = self else { return } - let _ = strongSelf.context.engine.peers.updatePeerNotificationSoundInteractive(peerId: strongSelf.peerId, threadId: strongSelf.chatLocation.threadId, sound: sound).start() + let _ = strongSelf.context.engine.peers.updatePeerNotificationSoundInteractive(peerId: strongSelf.peerId, threadId: strongSelf.chatLocation.threadId, sound: sound).startStandalone() }) strongSelf.controller?.push(soundController) }) @@ -6451,11 +6463,11 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro private func editingToggleShowMessageText(value: Bool) { let _ = (getUserPeer(engine: self.context.engine, peerId: self.peerId) - |> deliverOnMainQueue).start(next: { [weak self] peer in + |> deliverOnMainQueue).startStandalone(next: { [weak self] peer in guard let strongSelf = self, let peer = peer else { return } - let _ = strongSelf.context.engine.peers.updatePeerDisplayPreviewsSetting(peerId: peer.id, threadId: strongSelf.chatLocation.threadId, displayPreviews: value ? .show : .hide).start() + let _ = strongSelf.context.engine.peers.updatePeerDisplayPreviewsSetting(peerId: peer.id, threadId: strongSelf.chatLocation.threadId, displayPreviews: value ? .show : .hide).startStandalone() }) } @@ -6472,7 +6484,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro return } let _ = (getUserPeer(engine: strongSelf.context.engine, peerId: strongSelf.peerId) - |> deliverOnMainQueue).start(next: { peer in + |> deliverOnMainQueue).startStandalone(next: { peer in guard let peer = peer, let strongSelf = self else { return } @@ -6511,7 +6523,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro } strongSelf.activeActionDisposable.set((deleteSignal - |> deliverOnMainQueue).start(completed: { [weak self] in + |> deliverOnMainQueue).startStrict(completed: { [weak self] in if let strongSelf = self, let peer = strongSelf.data?.peer { let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 } let controller = UndoOverlayController(presentationData: presentationData, content: .info(title: nil, text: presentationData.strings.Conversation_DeletedFromContacts(EnginePeer(peer).displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder)).string, timeout: nil), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }) @@ -6573,7 +6585,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro private func openAddContact() { let _ = (getUserPeer(engine: self.context.engine, peerId: self.peerId) - |> deliverOnMainQueue).start(next: { [weak self] peer in + |> deliverOnMainQueue).startStandalone(next: { [weak self] peer in guard let strongSelf = self, let peer = peer else { return } @@ -6592,16 +6604,16 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro private func updateBlocked(block: Bool) { let _ = (getUserPeer(engine: self.context.engine, peerId: self.peerId) |> take(1) - |> deliverOnMainQueue).start(next: { [weak self] peer in + |> deliverOnMainQueue).startStandalone(next: { [weak self] peer in guard let strongSelf = self, let peer = peer else { return } let presentationData = strongSelf.presentationData if case let .user(peer) = peer, let _ = peer.botInfo { - strongSelf.activeActionDisposable.set(strongSelf.context.engine.privacy.requestUpdatePeerIsBlocked(peerId: peer.id, isBlocked: block).start()) + strongSelf.activeActionDisposable.set(strongSelf.context.engine.privacy.requestUpdatePeerIsBlocked(peerId: peer.id, isBlocked: block).startStrict()) if !block { - let _ = enqueueMessages(account: strongSelf.context.account, peerId: peer.id, messages: [.message(text: "/start", attributes: [], inlineStickers: [:], mediaReference: nil, replyToMessageId: nil, replyToStoryId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])]).start() + let _ = enqueueMessages(account: strongSelf.context.account, peerId: peer.id, messages: [.message(text: "/start", attributes: [], inlineStickers: [:], mediaReference: nil, replyToMessageId: nil, replyToStoryId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])]).startStandalone() if let navigationController = strongSelf.controller?.navigationController as? NavigationController { strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(EnginePeer(peer)))) } @@ -6624,12 +6636,12 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro return } - strongSelf.activeActionDisposable.set(strongSelf.context.engine.privacy.requestUpdatePeerIsBlocked(peerId: peer.id, isBlocked: true).start()) + strongSelf.activeActionDisposable.set(strongSelf.context.engine.privacy.requestUpdatePeerIsBlocked(peerId: peer.id, isBlocked: true).startStrict()) if deleteChat { - let _ = strongSelf.context.engine.peers.removePeerChat(peerId: strongSelf.peerId, reportChatSpam: reportSpam).start() + let _ = strongSelf.context.engine.peers.removePeerChat(peerId: strongSelf.peerId, reportChatSpam: reportSpam).startStandalone() (strongSelf.controller?.navigationController as? NavigationController)?.popToRoot(animated: true) } else if reportSpam { - let _ = strongSelf.context.engine.peers.reportPeer(peerId: strongSelf.peerId, reason: .spam, message: "").start() + let _ = strongSelf.context.engine.peers.reportPeer(peerId: strongSelf.peerId, reason: .spam, message: "").startStandalone() } deleteSendMessageIntents(peerId: strongSelf.peerId) @@ -6650,7 +6662,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro guard let strongSelf = self else { return } - strongSelf.activeActionDisposable.set(strongSelf.context.engine.privacy.requestUpdatePeerIsBlocked(peerId: peer.id, isBlocked: block).start()) + strongSelf.activeActionDisposable.set(strongSelf.context.engine.privacy.requestUpdatePeerIsBlocked(peerId: peer.id, isBlocked: block).startStrict()) })]), in: .window(.root)) } } @@ -6697,7 +6709,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro var result = currentAccountPeer result.append(contentsOf: availablePeers) return result - }).start(next: { [weak self] peers in + }).startStandalone(next: { [weak self] peers in guard let strongSelf = self else { return } @@ -6719,7 +6731,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro } strongSelf.openVoiceChatDisplayAsPeerSelection(completion: { joinAsPeerId in - let _ = context.engine.calls.updateGroupCallJoinAsPeer(peerId: peerId, joinAs: joinAsPeerId).start() + let _ = context.engine.calls.updateGroupCallJoinAsPeer(peerId: peerId, joinAs: joinAsPeerId).startStandalone() self?.openVoiceChatOptions(defaultJoinAsPeerId: joinAsPeerId, gesture: nil, contextController: c) }, gesture: gesture, contextController: c, result: f, backAction: { [weak self] c in self?.openVoiceChatOptions(defaultJoinAsPeerId: defaultJoinAsPeerId, gesture: nil, contextController: c) @@ -6812,7 +6824,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro var result = currentAccountPeer result.append(contentsOf: availablePeers) return result - }).start(next: { [weak self] peers in + }).startStandalone(next: { [weak self] peers in guard let strongSelf = self else { return } @@ -6907,7 +6919,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro switch type { case let .reaction(sourceMessageId): let _ = (self.context.engine.peers.reportPeerReaction(authorId: self.peerId, messageId: sourceMessageId) - |> deliverOnMainQueue).start(completed: { [weak self] in + |> deliverOnMainQueue).startStandalone(completed: { [weak self] in guard let strongSelf = self else { return } @@ -6940,7 +6952,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro private func openShareBot() { let _ = (getUserPeer(engine: self.context.engine, peerId: self.peerId) - |> deliverOnMainQueue).start(next: { [weak self] peer in + |> deliverOnMainQueue).startStandalone(next: { [weak self] peer in guard let strongSelf = self else { return } @@ -6955,7 +6967,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro peerIds.map(TelegramEngine.EngineData.Item.Peer.Peer.init) ) ) - |> deliverOnMainQueue).start(next: { [weak self] peerList in + |> deliverOnMainQueue).startStandalone(next: { [weak self] peerList in guard let strongSelf = self else { return } @@ -7017,7 +7029,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro private func performBotCommand(command: PeerInfoBotCommand) { let _ = (self.context.account.postbox.loadedPeerWithId(peerId) - |> deliverOnMainQueue).start(next: { [weak self] peer in + |> deliverOnMainQueue).startStandalone(next: { [weak self] peer in guard let strongSelf = self else { return } @@ -7030,7 +7042,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro case .help: text = "/help" } - let _ = enqueueMessages(account: strongSelf.context.account, peerId: peer.id, messages: [.message(text: text, attributes: [], inlineStickers: [:], mediaReference: nil, replyToMessageId: nil, replyToStoryId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])]).start() + let _ = enqueueMessages(account: strongSelf.context.account, peerId: peer.id, messages: [.message(text: text, attributes: [], inlineStickers: [:], mediaReference: nil, replyToMessageId: nil, replyToStoryId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])]).startStandalone() if let peer = strongSelf.data?.peer, let navigationController = strongSelf.controller?.navigationController as? NavigationController { strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(EnginePeer(peer)))) @@ -7106,7 +7118,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro } |> deliverOnMainQueue - let _ = signal.start(next: { [weak self] resultPeerId in + let _ = signal.startStandalone(next: { [weak self] resultPeerId in guard let self else { return } @@ -7115,7 +7127,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro } let _ = (self.context.engine.peers.setChannelForumMode(id: resultPeerId, isForum: isEnabled) - |> deliverOnMainQueue).start(completed: { [weak self] in + |> deliverOnMainQueue).startStandalone(completed: { [weak self] in guard let self, let controller = self.controller else { return } @@ -7127,12 +7139,12 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro }) } } else { - let _ = self.context.engine.peers.setChannelForumMode(id: self.peerId, isForum: isEnabled).start() + let _ = self.context.engine.peers.setChannelForumMode(id: self.peerId, isForum: isEnabled).startStandalone() } } private func editingToggleMessageSignatures(value: Bool) { - self.toggleShouldChannelMessagesSignaturesDisposable.set(self.context.engine.peers.toggleShouldChannelMessagesSignatures(peerId: self.peerId, enabled: value).start()) + self.toggleShouldChannelMessagesSignaturesDisposable.set(self.context.engine.peers.toggleShouldChannelMessagesSignatures(peerId: self.peerId, enabled: value).startStrict()) } private func openParticipantsSection(section: PeerInfoParticipantsSection) { @@ -7253,7 +7265,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro |> mapToSignal { address -> Signal in return updateChannelGeoLocation(postbox: context.account.postbox, network: context.account.network, channelId: peer.id, coordinate: (location.latitude, location.longitude), address: address) } - |> deliverOnMainQueue).start() + |> deliverOnMainQueue).startStandalone() }) self.controller?.push(controller) } @@ -7404,7 +7416,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro let presentationData = context.sharedContext.currentPresentationData.with { $0 } let _ = (self.context.sharedContext.accountManager.sharedData(keys: [ApplicationSpecificSharedDataKeys.translationSettings]) |> take(1) - |> deliverOnMainQueue).start(next: { [weak self] sharedData in + |> deliverOnMainQueue).startStandalone(next: { [weak self] sharedData in let translationSettings: TranslationSettings if let current = sharedData.entries[ApplicationSpecificSharedDataKeys.translationSettings]?.get(TranslationSettings.self) { translationSettings = current @@ -7518,7 +7530,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro private func openDeletePeer() { let _ = (self.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: self.peerId)) - |> deliverOnMainQueue).start(next: { [weak self] peer in + |> deliverOnMainQueue).startStandalone(next: { [weak self] peer in guard let strongSelf = self, let peer = peer else { return } @@ -7563,7 +7575,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro private func openLeavePeer(delete: Bool) { let _ = (self.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: self.peerId)) - |> deliverOnMainQueue).start(next: { [weak self] peer in + |> deliverOnMainQueue).startStandalone(next: { [weak self] peer in guard let strongSelf = self, let peer = peer else { return } @@ -7718,7 +7730,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro } self.updateAvatarDisposable.set((signal - |> deliverOnMainQueue).start(next: { [weak self] result in + |> deliverOnMainQueue).startStrict(next: { [weak self] result in guard let strongSelf = self else { return } @@ -7736,7 +7748,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro dismissStatus?() let _ = (strongSelf.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: strongSelf.peerId)) - |> deliverOnMainQueue).start(next: { [weak self] peer in + |> deliverOnMainQueue).startStandalone(next: { [weak self] peer in if let strongSelf = self, let peer { switch mode { case .fallback: @@ -7744,7 +7756,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro case .custom: strongSelf.controller?.present(UndoOverlayController(presentationData: strongSelf.presentationData, content: .invitedToVoiceChat(context: strongSelf.context, peer: peer, text: strongSelf.presentationData.strings.UserInfo_SetCustomPhoto_SuccessPhotoText(peer.compactDisplayTitle).string, action: nil, duration: 5), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current) - let _ = (strongSelf.context.peerChannelMemberCategoriesContextsManager.profilePhotos(postbox: strongSelf.context.account.postbox, network: strongSelf.context.account.network, peerId: strongSelf.peerId, fetch: peerInfoProfilePhotos(context: strongSelf.context, peerId: strongSelf.peerId)) |> ignoreValues).start() + let _ = (strongSelf.context.peerChannelMemberCategoriesContextsManager.profilePhotos(postbox: strongSelf.context.account.postbox, network: strongSelf.context.account.network, peerId: strongSelf.peerId, fetch: peerInfoProfilePhotos(context: strongSelf.context, peerId: strongSelf.peerId)) |> ignoreValues).startStandalone() case .suggest: if let navigationController = (strongSelf.controller?.navigationController as? NavigationController) { strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(peer), keepStack: .default, completion: { _ in @@ -7954,7 +7966,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro }) } } - |> deliverOnMainQueue).start(next: { [weak self] result in + |> deliverOnMainQueue).startStrict(next: { [weak self] result in guard let strongSelf = self else { return } @@ -7972,7 +7984,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro dismissStatus?() let _ = (strongSelf.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: strongSelf.peerId)) - |> deliverOnMainQueue).start(next: { [weak self] peer in + |> deliverOnMainQueue).startStandalone(next: { [weak self] peer in if let strongSelf = self, let peer { switch mode { case .fallback: @@ -7980,7 +7992,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro case .custom: strongSelf.controller?.present(UndoOverlayController(presentationData: strongSelf.presentationData, content: .invitedToVoiceChat(context: strongSelf.context, peer: peer, text: strongSelf.presentationData.strings.UserInfo_SetCustomPhoto_SuccessVideoText(peer.compactDisplayTitle).string, action: nil, duration: 5), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current) - let _ = (strongSelf.context.peerChannelMemberCategoriesContextsManager.profilePhotos(postbox: strongSelf.context.account.postbox, network: strongSelf.context.account.network, peerId: strongSelf.peerId, fetch: peerInfoProfilePhotos(context: strongSelf.context, peerId: strongSelf.peerId)) |> ignoreValues).start() + let _ = (strongSelf.context.peerChannelMemberCategoriesContextsManager.profilePhotos(postbox: strongSelf.context.account.postbox, network: strongSelf.context.account.network, peerId: strongSelf.peerId, fetch: peerInfoProfilePhotos(context: strongSelf.context, peerId: strongSelf.peerId)) |> ignoreValues).startStandalone() case .suggest: if let navigationController = (strongSelf.controller?.navigationController as? NavigationController) { strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(peer), keepStack: .default, completion: { _ in @@ -8020,7 +8032,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro TelegramEngine.EngineData.Item.Peer.Peer(id: peerId), TelegramEngine.EngineData.Item.Configuration.SearchBots() ) - |> deliverOnMainQueue).start(next: { [weak self] peer, searchBotsConfiguration in + |> deliverOnMainQueue).startStandalone(next: { [weak self] peer, searchBotsConfiguration in guard let strongSelf = self, let peer = peer else { return } @@ -8224,7 +8236,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro }) } strongSelf.updateAvatarDisposable.set((signal - |> deliverOnMainQueue).start(next: { result in + |> deliverOnMainQueue).startStrict(next: { result in guard let strongSelf = self else { return } @@ -8296,7 +8308,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro #endif self.postingAvailabilityDisposable = (canPostStatus - |> deliverOnMainQueue).start(next: { [weak self] status in + |> deliverOnMainQueue).startStrict(next: { [weak self] status in guard let self else { return } @@ -8322,7 +8334,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro queue: Queue.mainQueue(), self.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: self.peerId)), self.context.engine.peers.getChannelBoostStatus(peerId: self.peerId) - ).start(next: { [weak self] peer, status in + ).startStrict(next: { [weak self] peer, status in guard let self, let peer, let status else { return } @@ -8412,7 +8424,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro push(PeerInfoStoryGridScreen(context: self.context, peerId: self.context.account.peerId, scope: .saved)) case .savedMessages: let _ = (self.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: self.context.account.peerId)) - |> deliverOnMainQueue).start(next: { [weak self] peer in + |> deliverOnMainQueue).startStandalone(next: { [weak self] peer in guard let self, let peer = peer else { return } @@ -8425,7 +8437,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro case .devices: let _ = (self.activeSessionsContextAndCount.get() |> take(1) - |> deliverOnMainQueue).start(next: { [weak self] activeSessionsContextAndCount in + |> deliverOnMainQueue).startStandalone(next: { [weak self] activeSessionsContextAndCount in if let strongSelf = self, let activeSessionsContextAndCount = activeSessionsContextAndCount { let (activeSessionsContext, _, webSessionsContext) = activeSessionsContextAndCount push(recentSessionsController(context: strongSelf.context, activeSessionsContext: activeSessionsContext, webSessionsContext: webSessionsContext, websitesOnly: false)) @@ -8441,7 +8453,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro if let settings = self.data?.globalSettings { let _ = (combineLatest(self.blockedPeers.get(), self.hasTwoStepAuth.get()) |> take(1) - |> deliverOnMainQueue).start(next: { [weak self] blockedPeersContext, hasTwoStepAuth in + |> deliverOnMainQueue).startStandalone(next: { [weak self] blockedPeersContext, hasTwoStepAuth in if let strongSelf = self { let loginEmailPattern = strongSelf.twoStepAuthData.get() |> map { data -> String? in return data?.loginEmailPattern @@ -8479,7 +8491,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro guard let self else { return } - 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) @@ -8510,7 +8522,10 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro TextAlertAction(type: .genericAction, title: presentationData.strings.Settings_FAQ_Button, action: { [weak self] in self?.openFaq() }), TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: { [weak self] in - self?.supportPeerDisposable.set((supportPeer.get() |> take(1) |> deliverOnMainQueue).start(next: { [weak self] peerId in + guard let self else { + return + } + self.supportPeerDisposable.set((supportPeer.get() |> take(1) |> deliverOnMainQueue).startStrict(next: { [weak self] peerId in if let strongSelf = self, let peerId = peerId { push(strongSelf.context.sharedContext.makeChatController(context: strongSelf.context, chatLocation: .peer(id: peerId), subject: nil, botStart: nil, mode: .standard(previewing: false))) } @@ -8535,7 +8550,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro let _ = (activeAccountsAndPeers(context: context) |> take(1) |> deliverOnMainQueue - ).start(next: { [weak self] accountAndPeer, accountsAndPeers in + ).startStandalone(next: { [weak self] accountAndPeer, accountsAndPeers in guard let strongSelf = self else { return } @@ -8584,7 +8599,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro return twoStepVerificationUnlockSettingsController(context: context, mode: .access(intro: false, data: .single(TwoStepVerificationUnlockSettingsControllerData.access(configuration: TwoStepVerificationAccessConfiguration(configuration: configuration, password: nil))))) } controller.passwordRemembered = { - let _ = dismissServerProvidedSuggestion(account: context.account, suggestion: .validatePassword).start() + let _ = dismissServerProvidedSuggestion(account: context.account, suggestion: .validatePassword).startStandalone() } push(controller) case .emojiStatus: @@ -8647,7 +8662,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro let context = self.context let navigationController = self.controller?.navigationController as? NavigationController - self.tipsPeerDisposable.set((self.context.engine.peers.resolvePeerByName(name: self.presentationData.strings.Settings_TipsUsername) |> deliverOnMainQueue).start(next: { [weak controller] peer in + self.tipsPeerDisposable.set((self.context.engine.peers.resolvePeerByName(name: self.presentationData.strings.Settings_TipsUsername) |> deliverOnMainQueue).startStrict(next: { [weak controller] peer in controller?.dismiss() if let peer = peer, let navigationController = navigationController { context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peer))) @@ -8671,7 +8686,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro items.append(ActionSheetButtonItem(title: self.presentationData.strings.Settings_Logout, color: .destructive, action: { [weak self] in dismissAction() if let strongSelf = self { - let _ = logoutFromAccount(id: id, accountManager: strongSelf.context.sharedContext.accountManager, alreadyLoggedOutRemotely: false).start() + let _ = logoutFromAccount(id: id, accountManager: strongSelf.context.sharedContext.accountManager, alreadyLoggedOutRemotely: false).startStandalone() } })) controller.setItemGroups([ @@ -8690,7 +8705,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro 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: .root, filterPredicate: nil)]) - |> deliverOnMainQueue).start(completed: { + |> deliverOnMainQueue).startStandalone(completed: { f(.default) }) }))) @@ -8709,7 +8724,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro var selectedAccount: Account? let _ = (self.accountsAndPeers.get() |> take(1) - |> deliverOnMainQueue).start(next: { accountsAndPeers in + |> deliverOnMainQueue).startStandalone(next: { accountsAndPeers in for (account, _, _) in accountsAndPeers { if account.account.id == id { selectedAccount = account.account @@ -8740,7 +8755,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro private func deleteMessages(messageIds: Set?) { if let messageIds = messageIds ?? self.state.selectedMessageIds, !messageIds.isEmpty { self.activeActionDisposable.set((self.context.sharedContext.chatAvailableMessageActions(engine: self.context.engine, accountPeerId: self.context.account.peerId, messageIds: messageIds) - |> deliverOnMainQueue).start(next: { [weak self] actions in + |> deliverOnMainQueue).startStrict(next: { [weak self] actions in if let strongSelf = self, let peer = strongSelf.data?.peer, !actions.options.isEmpty { let actionSheet = ActionSheetController(presentationData: strongSelf.presentationData) var items: [ActionSheetItem] = [] @@ -8765,7 +8780,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro actionSheet?.dismissAnimated() if let strongSelf = self { strongSelf.headerNode.navigationButtonContainer.performAction?(.selectionDone, nil, nil) - let _ = strongSelf.context.engine.messages.deleteMessagesInteractively(messageIds: Array(messageIds), type: .forEveryone).start() + let _ = strongSelf.context.engine.messages.deleteMessagesInteractively(messageIds: Array(messageIds), type: .forEveryone).startStandalone() } })) } @@ -8782,7 +8797,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro actionSheet?.dismissAnimated() if let strongSelf = self { strongSelf.headerNode.navigationButtonContainer.performAction?(.selectionDone, nil, nil) - let _ = strongSelf.context.engine.messages.deleteMessagesInteractively(messageIds: Array(messageIds), type: .forLocalPeer).start() + let _ = strongSelf.context.engine.messages.deleteMessagesInteractively(messageIds: Array(messageIds), type: .forLocalPeer).startStandalone() } })) } @@ -8832,7 +8847,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro var displayPeers: [EnginePeer] = [] for peer in peers { let _ = (enqueueMessages(account: strongSelf.context.account, peerId: peer.id, messages: result) - |> deliverOnMainQueue).start(next: { messageIds in + |> deliverOnMainQueue).startStandalone(next: { messageIds in if let strongSelf = self { let signals: [Signal] = messageIds.compactMap({ id -> Signal? in guard let id = id else { @@ -8852,7 +8867,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro strongSelf.shareStatusDisposable = MetaDisposable() } strongSelf.shareStatusDisposable?.set((combineLatest(signals) - |> deliverOnMainQueue).start()) + |> deliverOnMainQueue).startStrict()) } }) @@ -8910,7 +8925,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro let _ = (enqueueMessages(account: strongSelf.context.account, peerId: peerId, messages: messageIds.map { id -> EnqueueMessage in return .forward(source: id, threadId: nil, grouping: .auto, attributes: [], correlationId: nil) }) - |> deliverOnMainQueue).start(next: { [weak self] messageIds in + |> deliverOnMainQueue).startStandalone(next: { [weak self] messageIds in if let strongSelf = self { let signals: [Signal] = messageIds.compactMap({ id -> Signal? in guard let id = id else { @@ -8927,7 +8942,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro |> take(1) }) strongSelf.activeActionDisposable.set((combineLatest(signals) - |> deliverOnMainQueue).start()) + |> deliverOnMainQueue).startStrict()) } }) if let peerSelectionController = peerSelectionController { @@ -8937,7 +8952,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro let _ = (ChatInterfaceState.update(engine: strongSelf.context.engine, peerId: peerId, threadId: threadId, { currentState in return currentState.withUpdatedForwardMessageIds(Array(messageIds)) }) - |> deliverOnMainQueue).start(completed: { + |> deliverOnMainQueue).startStandalone(completed: { if let strongSelf = self { let proceed: (ChatController) -> Void = { chatController in strongSelf.headerNode.navigationButtonContainer.performAction?(.selectionDone, nil, nil) @@ -8954,7 +8969,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro 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) })) @@ -8963,7 +8978,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro 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 { @@ -9097,7 +9112,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro TelegramEngine.EngineData.Item.Messages.MessageCount(peerId: peerId, threadId: self.chatLocation.threadId, tag: .photo), TelegramEngine.EngineData.Item.Messages.MessageCount(peerId: peerId, threadId: self.chatLocation.threadId, tag: .video) ])) - |> deliverOnMainQueue).start(next: { [weak self] messageCounts in + |> deliverOnMainQueue).startStandalone(next: { [weak self] messageCounts in guard let strongSelf = self else { return } @@ -9379,7 +9394,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro case let .remove(positionInList): strongSelf.controller?.presentInGlobalOverlay(UndoOverlayController(presentationData: presentationData, content: .stickersModified(title: isEmoji ? presentationData.strings.EmojiPackActionInfo_RemovedTitle : presentationData.strings.StickerPackActionInfo_RemovedTitle, text: isEmoji ? presentationData.strings.EmojiPackActionInfo_RemovedText(info.title).string : presentationData.strings.StickerPackActionInfo_RemovedText(info.title).string, undo: true, info: info, topItem: items.first, context: context), elevatedLayout: false, 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 })) @@ -9412,7 +9427,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro strongSelf.updateAvatarDisposable.set((strongSelf.context.engine.contacts.updateContactPhoto(peerId: strongSelf.peerId, resource: nil, videoResource: nil, videoStartTimestamp: nil, markup: nil, mode: .custom, mapResourceToAvatarSizes: { resource, representations in mapResourceToAvatarSizes(postbox: strongSelf.context.account.postbox, resource: resource, representations: representations) }) - |> deliverOnMainQueue).start(next: { [weak self] _ in + |> deliverOnMainQueue).startStrict(next: { [weak self] _ in guard let strongSelf = self else { return } @@ -9640,7 +9655,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro let _ = (strongSelf.context.engine.data.get(EngineDataMap( messageIds.map(TelegramEngine.EngineData.Item.Messages.Message.init) )) - |> deliverOnMainQueue).start(next: { messageMap in + |> deliverOnMainQueue).startStandalone(next: { messageMap in let messages = messageMap.values.compactMap { $0 } if let strongSelf = self, !messages.isEmpty { @@ -9673,7 +9688,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro let _ = (strongSelf.context.engine.data.get(EngineDataMap( messageIds.map(TelegramEngine.EngineData.Item.Messages.Message.init) )) - |> deliverOnMainQueue).start(next: { [weak self] messageMap in + |> deliverOnMainQueue).startStandalone(next: { [weak self] messageMap in guard let strongSelf = self else { return } @@ -10212,7 +10227,7 @@ public final class PeerInfoScreenImpl: ViewController, PeerInfoScreen, KeyShortc self.accountsAndPeers.set(activeAccountsAndPeers(context: context)) self.accountsAndPeersDisposable = (self.accountsAndPeers.get() - |> deliverOnMainQueue).start(next: { [weak self] value in + |> deliverOnMainQueue).startStrict(next: { [weak self] value in self?.accountsAndPeersValue = value }) @@ -10348,7 +10363,7 @@ public final class PeerInfoScreenImpl: ViewController, PeerInfoScreen, KeyShortc return (presentationData.strings.Settings_Title, accountTabBarAvatar?.0 ?? icon, accountTabBarAvatar?.1 ?? icon, notificationsWarning || phoneNumberWarning || passwordWarning ? "!" : otherAccountsBadge, accountTabBarAvatar != nil, presentationData.reduceMotion) } - self.tabBarItemDisposable = (tabBarItem |> deliverOnMainQueue).start(next: { [weak self] title, image, selectedImage, badgeValue, isAvatar, reduceMotion in + self.tabBarItemDisposable = (tabBarItem |> deliverOnMainQueue).startStrict(next: { [weak self] title, image, selectedImage, badgeValue, isAvatar, reduceMotion in if let strongSelf = self { strongSelf.tabBarItem.title = title strongSelf.tabBarItem.image = image @@ -10444,7 +10459,7 @@ public final class PeerInfoScreenImpl: ViewController, PeerInfoScreen, KeyShortc } self.presentationDataDisposable = (presentationDataSignal - |> 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 @@ -10577,7 +10592,7 @@ public final class PeerInfoScreenImpl: ViewController, PeerInfoScreen, KeyShortc peerMap, threadDataMap ) - |> deliverOnMainQueue).start(next: { [weak parentController, weak backButtonView, weak navigationController] peerMap, threadDataMap in + |> deliverOnMainQueue).startStandalone(next: { [weak parentController, weak backButtonView, weak navigationController] peerMap, threadDataMap in guard let parentController, let backButtonView else { return } @@ -11264,7 +11279,7 @@ func presentAddMembersImpl(context: AccountContext, updatedPresentationData: (in let _ = (members.get() |> take(1) - |> deliverOnMainQueue).start(next: { [weak parentController] recentIds in + |> deliverOnMainQueue).startStandalone(next: { [weak parentController] recentIds in var createInviteLinkImpl: (() -> Void)? var confirmationImpl: ((PeerId) -> Signal)? let _ = confirmationImpl @@ -11598,7 +11613,7 @@ func presentAddMembersImpl(context: AccountContext, updatedPresentationData: (in } if !mappedPeerIds.isEmpty { let _ = (context.engine.data.get(EngineDataMap(mappedPeerIds.map(TelegramEngine.EngineData.Item.Peer.Peer.init(id:)))) - |> deliverOnMainQueue).start(next: { maybePeers in + |> deliverOnMainQueue).startStandalone(next: { maybePeers in let presentationData = context.sharedContext.currentPresentationData.with { $0 } let peers = maybePeers.compactMap { $0.value } @@ -11618,7 +11633,7 @@ func presentAddMembersImpl(context: AccountContext, updatedPresentationData: (in return item.0 }.map(TelegramEngine.EngineData.Item.Peer.Peer.init(id:))) ) - |> deliverOnMainQueue).start(next: { peerItems in + |> deliverOnMainQueue).startStandalone(next: { peerItems in let peers = peerItems.compactMap { $0 } if !peers.isEmpty, let contactsController, let navigationController = contactsController.navigationController as? NavigationController { var viewControllers = navigationController.viewControllers @@ -11640,7 +11655,7 @@ func presentAddMembersImpl(context: AccountContext, updatedPresentationData: (in switch peers[0] { case let .peer(peerId): let _ = (context.account.postbox.loadedPeerWithId(peerId) - |> deliverOnMainQueue).start(next: { peer in + |> deliverOnMainQueue).startStandalone(next: { peer in parentController?.present(textAlertController(context: context, updatedPresentationData: updatedPresentationData, title: nil, text: presentationData.strings.Privacy_GroupsAndChannels_InviteToGroupError(EnginePeer(peer).compactDisplayTitle, EnginePeer(peer).compactDisplayTitle).string, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_OK, action: {})]), in: .window(.root)) }) default: