diff --git a/submodules/AccountContext/Sources/AccountContext.swift b/submodules/AccountContext/Sources/AccountContext.swift index 403c739bde..4968ec27ed 100644 --- a/submodules/AccountContext/Sources/AccountContext.swift +++ b/submodules/AccountContext/Sources/AccountContext.swift @@ -219,17 +219,14 @@ public final class ChatPeerNearbyData: Equatable { public final class ChatGreetingData: Equatable { public static func == (lhs: ChatGreetingData, rhs: ChatGreetingData) -> Bool { - if let lhsSticker = lhs.sticker, let rhsSticker = rhs.sticker, !lhsSticker.isEqual(to: rhsSticker) { - return false - } else if (lhs.sticker == nil) != (rhs.sticker == nil) { - return false - } - return true + return lhs.uuid == rhs.uuid } - public let sticker: TelegramMediaFile? + public let uuid: UUID + public let sticker: Signal - public init(sticker: TelegramMediaFile?) { + public init(uuid: UUID, sticker: Signal) { + self.uuid = uuid self.sticker = sticker } } @@ -285,14 +282,13 @@ public final class NavigateToChatControllerParams { public let activateMessageSearch: (ChatSearchDomain, String)? public let peekData: ChatPeekTimeout? public let peerNearbyData: ChatPeerNearbyData? - public let greetingData: ChatGreetingData? public let reportReason: ReportReason? public let animated: Bool public let options: NavigationAnimationOptions public let parentGroupId: PeerGroupId? public let completion: (ChatController) -> Void - public init(navigationController: NavigationController, chatController: ChatController? = nil, context: AccountContext, chatLocation: ChatLocation, chatLocationContextHolder: Atomic = Atomic(value: nil), subject: ChatControllerSubject? = nil, botStart: ChatControllerInitialBotStart? = nil, updateTextInputState: ChatTextInputState? = nil, activateInput: Bool = false, keepStack: NavigateToChatKeepStack = .default, useExisting: Bool = true, purposefulAction: (() -> Void)? = nil, scrollToEndIfExists: Bool = false, activateMessageSearch: (ChatSearchDomain, String)? = nil, peekData: ChatPeekTimeout? = nil, peerNearbyData: ChatPeerNearbyData? = nil, greetingData: ChatGreetingData? = nil, reportReason: ReportReason? = nil, animated: Bool = true, options: NavigationAnimationOptions = [], parentGroupId: PeerGroupId? = nil, completion: @escaping (ChatController) -> Void = { _ in }) { + public init(navigationController: NavigationController, chatController: ChatController? = nil, context: AccountContext, chatLocation: ChatLocation, chatLocationContextHolder: Atomic = Atomic(value: nil), subject: ChatControllerSubject? = nil, botStart: ChatControllerInitialBotStart? = nil, updateTextInputState: ChatTextInputState? = nil, activateInput: Bool = false, keepStack: NavigateToChatKeepStack = .default, useExisting: Bool = true, purposefulAction: (() -> Void)? = nil, scrollToEndIfExists: Bool = false, activateMessageSearch: (ChatSearchDomain, String)? = nil, peekData: ChatPeekTimeout? = nil, peerNearbyData: ChatPeerNearbyData? = nil, reportReason: ReportReason? = nil, animated: Bool = true, options: NavigationAnimationOptions = [], parentGroupId: PeerGroupId? = nil, completion: @escaping (ChatController) -> Void = { _ in }) { self.navigationController = navigationController self.chatController = chatController self.chatLocationContextHolder = chatLocationContextHolder @@ -309,7 +305,6 @@ public final class NavigateToChatControllerParams { self.activateMessageSearch = activateMessageSearch self.peekData = peekData self.peerNearbyData = peerNearbyData - self.greetingData = greetingData self.reportReason = reportReason self.animated = animated self.options = options @@ -719,6 +714,7 @@ public protocol AccountContext: class { var liveLocationManager: LiveLocationManager? { get } var peersNearbyManager: PeersNearbyManager? { get } var fetchManager: FetchManager { get } + var prefetchManager: PrefetchManager? { get } var downloadedMediaStoreManager: DownloadedMediaStoreManager { get } var peerChannelMemberCategoriesContextsManager: PeerChannelMemberCategoriesContextsManager { get } var wallpaperUploadManager: WallpaperUploadManager? { get } diff --git a/submodules/AccountContext/Sources/FetchManager.swift b/submodules/AccountContext/Sources/FetchManager.swift index c70576facd..ad4db3b593 100644 --- a/submodules/AccountContext/Sources/FetchManager.swift +++ b/submodules/AccountContext/Sources/FetchManager.swift @@ -158,3 +158,8 @@ public protocol FetchManager { func cancelInteractiveFetches(category: FetchManagerCategory, location: FetchManagerLocation, locationKey: FetchManagerLocationKey, resource: MediaResource) func fetchStatus(category: FetchManagerCategory, location: FetchManagerLocation, locationKey: FetchManagerLocationKey, resource: MediaResource) -> Signal } + +public protocol PrefetchManager { + var preloadedGreetingSticker: ChatGreetingData { get } + func prepareNextGreetingSticker() +} diff --git a/submodules/ChatListUI/Sources/ChatListController.swift b/submodules/ChatListUI/Sources/ChatListController.swift index 113c170936..babc8ab979 100644 --- a/submodules/ChatListUI/Sources/ChatListController.swift +++ b/submodules/ChatListUI/Sources/ChatListController.swift @@ -144,9 +144,6 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController private let featuredFiltersDisposable = MetaDisposable() private var processedFeaturedFilters = false - private let preloadedSticker = Promise(nil) - private let preloadStickerDisposable = MetaDisposable() - private let isReorderingTabsValue = ValuePromise(false) private var searchContentNode: NavigationBarSearchContentNode? @@ -613,53 +610,43 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController scrollToEndIfExists = true } - let _ = (strongSelf.preloadedSticker.get() - |> take(1) - |> deliverOnMainQueue).start(next: { [weak self] greetingSticker in - if let strongSelf = self { - strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(peer.id), activateInput: activateInput && !peer.isDeleted, scrollToEndIfExists: scrollToEndIfExists, greetingData: greetingSticker.flatMap({ ChatGreetingData(sticker: $0) }), animated: !scrollToEndIfExists, options: strongSelf.groupId == PeerGroupId.root ? [.removeOnMasterDetails] : [], parentGroupId: strongSelf.groupId, completion: { [weak self] controller in - self?.chatListDisplayNode.containerNode.currentItemNode.clearHighlightAnimated(true) - if let promoInfo = promoInfo { - switch promoInfo { - case .proxy: - let _ = (ApplicationSpecificNotice.getProxyAdsAcknowledgment(accountManager: strongSelf.context.sharedContext.accountManager) - |> deliverOnMainQueue).start(next: { value in - guard let strongSelf = self else { - return - } - if !value { - controller.displayPromoAnnouncement(text: strongSelf.presentationData.strings.DialogList_AdNoticeAlert) - let _ = ApplicationSpecificNotice.setProxyAdsAcknowledgment(accountManager: strongSelf.context.sharedContext.accountManager).start() - } - }) - case let .psa(type, _): - let _ = (ApplicationSpecificNotice.getPsaAcknowledgment(accountManager: strongSelf.context.sharedContext.accountManager, peerId: peer.id) - |> deliverOnMainQueue).start(next: { value in - guard let strongSelf = self else { - return - } - if !value { - var text = strongSelf.presentationData.strings.ChatList_GenericPsaAlert - let key = "ChatList.PsaAlert.\(type)" - if let string = strongSelf.presentationData.strings.primaryComponent.dict[key] { - text = string - } else if let string = strongSelf.presentationData.strings.secondaryComponent?.dict[key] { - text = string - } - - controller.displayPromoAnnouncement(text: text) - let _ = ApplicationSpecificNotice.setPsaAcknowledgment(accountManager: strongSelf.context.sharedContext.accountManager, peerId: peer.id).start() - } - }) + strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(peer.id), activateInput: activateInput && !peer.isDeleted, scrollToEndIfExists: scrollToEndIfExists, animated: !scrollToEndIfExists, options: strongSelf.groupId == PeerGroupId.root ? [.removeOnMasterDetails] : [], parentGroupId: strongSelf.groupId, completion: { [weak self] controller in + self?.chatListDisplayNode.containerNode.currentItemNode.clearHighlightAnimated(true) + if let promoInfo = promoInfo { + switch promoInfo { + case .proxy: + let _ = (ApplicationSpecificNotice.getProxyAdsAcknowledgment(accountManager: strongSelf.context.sharedContext.accountManager) + |> deliverOnMainQueue).start(next: { value in + guard let strongSelf = self else { + return } - } - })) - - if activateInput { - strongSelf.prepareRandomGreetingSticker() + if !value { + controller.displayPromoAnnouncement(text: strongSelf.presentationData.strings.DialogList_AdNoticeAlert) + let _ = ApplicationSpecificNotice.setProxyAdsAcknowledgment(accountManager: strongSelf.context.sharedContext.accountManager).start() + } + }) + case let .psa(type, _): + let _ = (ApplicationSpecificNotice.getPsaAcknowledgment(accountManager: strongSelf.context.sharedContext.accountManager, peerId: peer.id) + |> deliverOnMainQueue).start(next: { value in + guard let strongSelf = self else { + return + } + if !value { + var text = strongSelf.presentationData.strings.ChatList_GenericPsaAlert + let key = "ChatList.PsaAlert.\(type)" + if let string = strongSelf.presentationData.strings.primaryComponent.dict[key] { + text = string + } else if let string = strongSelf.presentationData.strings.secondaryComponent?.dict[key] { + text = string + } + + controller.displayPromoAnnouncement(text: text) + let _ = ApplicationSpecificNotice.setPsaAcknowledgment(accountManager: strongSelf.context.sharedContext.accountManager, peerId: peer.id).start() + } + }) } } - }) + })) } } } @@ -1126,7 +1113,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController super.displayNodeDidLoad() Queue.mainQueue().after(1.0) { - self.prepareRandomGreetingSticker() + self.context.prefetchManager?.prepareNextGreetingSticker() } } @@ -2763,28 +2750,6 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController } } - private func prepareRandomGreetingSticker() { - let context = self.context - self.preloadedSticker.set(.single(nil) - |> then(context.engine.stickers.randomGreetingSticker() - |> map { item in - return item?.file - })) - - self.preloadStickerDisposable.set((self.preloadedSticker.get() - |> mapToSignal { sticker -> Signal in - if let sticker = sticker { - let _ = freeMediaFileInteractiveFetched(account: context.account, fileReference: .standalone(media: sticker)).start() - return chatMessageAnimationData(postbox: context.account.postbox, resource: sticker.resource, fitzModifier: nil, width: 384, height: 384, synchronousLoad: false) - |> mapToSignal { _ -> Signal in - return .complete() - } - } else { - return .complete() - } - }).start()) - } - override public func tabBarDisabledAction() { self.donePressed() } diff --git a/submodules/ContactListUI/Sources/ContactsController.swift b/submodules/ContactListUI/Sources/ContactsController.swift index ddd00d0c2a..aecb825611 100644 --- a/submodules/ContactListUI/Sources/ContactsController.swift +++ b/submodules/ContactListUI/Sources/ContactsController.swift @@ -89,9 +89,6 @@ public class ContactsController: ViewController { public var switchToChatsController: (() -> Void)? - private let preloadedSticker = Promise(nil) - private let preloadStickerDisposable = MetaDisposable() - public override func updateNavigationCustomData(_ data: Any?, progress: CGFloat, transition: ContainedViewLayoutTransition) { if self.isNodeLoaded { self.contactsNode.contactListNode.updateSelectedChatLocation(data as? ChatLocation, progress: progress, transition: transition) @@ -235,24 +232,16 @@ public class ContactsController: ViewController { scrollToEndIfExists = true } - let _ = (strongSelf.preloadedSticker.get() - |> take(1) - |> deliverOnMainQueue).start(next: { [weak self] greetingSticker in - if let strongSelf = self { - strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(peer.id), purposefulAction: { [weak self] in - if fromSearch { - self?.deactivateSearch(animated: false) - self?.switchToChatsController?() - } - }, scrollToEndIfExists: scrollToEndIfExists, greetingData: greetingSticker.flatMap({ ChatGreetingData(sticker: $0) }), options: [.removeOnMasterDetails], completion: { [weak self] _ in - if let strongSelf = self { - strongSelf.contactsNode.contactListNode.listNode.clearHighlightAnimated(true) - } - })) - - strongSelf.prepareRandomGreetingSticker() + strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(peer.id), purposefulAction: { [weak self] in + if fromSearch { + self?.deactivateSearch(animated: false) + self?.switchToChatsController?() } - }) + }, scrollToEndIfExists: scrollToEndIfExists, options: [.removeOnMasterDetails], completion: { [weak self] _ in + if let strongSelf = self { + strongSelf.contactsNode.contactListNode.listNode.clearHighlightAnimated(true) + } + })) } case let .deviceContact(id, _): let _ = ((strongSelf.context.sharedContext.contactDataManager?.extendedData(stableId: id) ?? .single(nil)) @@ -423,14 +412,6 @@ public class ContactsController: ViewController { self.contactsNode.contactListNode.enableUpdates = false } - public override func displayNodeDidLoad() { - super.displayNodeDidLoad() - - Queue.mainQueue().after(1.0) { - self.prepareRandomGreetingSticker() - } - } - override public func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) { super.containerLayoutUpdated(layout, transition: transition) @@ -525,26 +506,4 @@ public class ContactsController: ViewController { } }) } - - private func prepareRandomGreetingSticker() { - let context = self.context - self.preloadedSticker.set(.single(nil) - |> then(context.engine.stickers.randomGreetingSticker() - |> map { item in - return item?.file - })) - - self.preloadStickerDisposable.set((self.preloadedSticker.get() - |> mapToSignal { sticker -> Signal in - if let sticker = sticker { - let _ = freeMediaFileInteractiveFetched(account: context.account, fileReference: .standalone(media: sticker)).start() - return chatMessageAnimationData(postbox: context.account.postbox, resource: sticker.resource, fitzModifier: nil, width: 384, height: 384, synchronousLoad: false) - |> mapToSignal { _ -> Signal in - return .complete() - } - } else { - return .complete() - } - }).start()) - } } diff --git a/submodules/TelegramUI/Sources/AccountContext.swift b/submodules/TelegramUI/Sources/AccountContext.swift index 5e5e1ab5c3..34ea3cd855 100644 --- a/submodules/TelegramUI/Sources/AccountContext.swift +++ b/submodules/TelegramUI/Sources/AccountContext.swift @@ -112,7 +112,7 @@ public final class AccountContextImpl: AccountContext { public let engine: TelegramEngine public let fetchManager: FetchManager - private let prefetchManager: PrefetchManager? + public let prefetchManager: PrefetchManager? public var keyShortcutsController: KeyShortcutsController? @@ -172,7 +172,7 @@ public final class AccountContextImpl: AccountContext { } self.fetchManager = FetchManagerImpl(postbox: account.postbox, storeManager: self.downloadedMediaStoreManager) if sharedContext.applicationBindings.isMainApp && !temp { - self.prefetchManager = PrefetchManager(sharedContext: sharedContext, account: account, fetchManager: self.fetchManager) + self.prefetchManager = PrefetchManagerImpl(sharedContext: sharedContext, account: account, engine: self.engine, fetchManager: self.fetchManager) self.wallpaperUploadManager = WallpaperUploadManagerImpl(sharedContext: sharedContext, account: account, presentationData: sharedContext.presentationData) self.themeUpdateManager = ThemeUpdateManagerImpl(sharedContext: sharedContext, account: account) } else { diff --git a/submodules/TelegramUI/Sources/ChatController.swift b/submodules/TelegramUI/Sources/ChatController.swift index b3a1805c55..042d093469 100644 --- a/submodules/TelegramUI/Sources/ChatController.swift +++ b/submodules/TelegramUI/Sources/ChatController.swift @@ -418,7 +418,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G private var importStateDisposable: Disposable? - public init(context: AccountContext, chatLocation: ChatLocation, chatLocationContextHolder: Atomic = Atomic(value: nil), subject: ChatControllerSubject? = nil, botStart: ChatControllerInitialBotStart? = nil, mode: ChatControllerPresentationMode = .standard(previewing: false), peekData: ChatPeekTimeout? = nil, peerNearbyData: ChatPeerNearbyData? = nil, greetingData: ChatGreetingData? = nil) { + public init(context: AccountContext, chatLocation: ChatLocation, chatLocationContextHolder: Atomic = Atomic(value: nil), subject: ChatControllerSubject? = nil, botStart: ChatControllerInitialBotStart? = nil, mode: ChatControllerPresentationMode = .standard(previewing: false), peekData: ChatPeekTimeout? = nil, peerNearbyData: ChatPeerNearbyData? = nil) { let _ = ChatControllerCount.modify { value in return value + 1 } @@ -463,7 +463,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G self.stickerSettings = ChatInterfaceStickerSettings(loopAnimatedStickers: false) - self.presentationInterfaceState = ChatPresentationInterfaceState(chatWallpaper: self.presentationData.chatWallpaper, theme: self.presentationData.theme, strings: self.presentationData.strings, dateTimeFormat: self.presentationData.dateTimeFormat, nameDisplayOrder: self.presentationData.nameDisplayOrder, limitsConfiguration: context.currentLimitsConfiguration.with { $0 }, fontSize: self.presentationData.chatFontSize, bubbleCorners: self.presentationData.chatBubbleCorners, accountPeerId: context.account.peerId, mode: mode, chatLocation: chatLocation, subject: subject, peerNearbyData: peerNearbyData, greetingData: greetingData, pendingUnpinnedAllMessages: false, activeGroupCallInfo: nil, hasActiveGroupCall: false, importState: nil) + self.presentationInterfaceState = ChatPresentationInterfaceState(chatWallpaper: self.presentationData.chatWallpaper, theme: self.presentationData.theme, strings: self.presentationData.strings, dateTimeFormat: self.presentationData.dateTimeFormat, nameDisplayOrder: self.presentationData.nameDisplayOrder, limitsConfiguration: context.currentLimitsConfiguration.with { $0 }, fontSize: self.presentationData.chatFontSize, bubbleCorners: self.presentationData.chatBubbleCorners, accountPeerId: context.account.peerId, mode: mode, chatLocation: chatLocation, subject: subject, peerNearbyData: peerNearbyData, greetingData: context.prefetchManager?.preloadedGreetingSticker, pendingUnpinnedAllMessages: false, activeGroupCallInfo: nil, hasActiveGroupCall: false, importState: nil) self.presentationInterfaceStatePromise = ValuePromise(self.presentationInterfaceState) var mediaAccessoryPanelVisibility = MediaAccessoryPanelVisibility.none diff --git a/submodules/TelegramUI/Sources/ChatEmptyNode.swift b/submodules/TelegramUI/Sources/ChatEmptyNode.swift index 18976ae21f..1baaa5ff45 100644 --- a/submodules/TelegramUI/Sources/ChatEmptyNode.swift +++ b/submodules/TelegramUI/Sources/ChatEmptyNode.swift @@ -161,7 +161,7 @@ private final class ChatEmptyNodeGreetingChatContent: ASDisplayNode, ChatEmptyNo } else if !self.didSetupSticker { let sticker: Signal if let preloadedSticker = interfaceState.greetingData?.sticker { - sticker = .single(preloadedSticker) + sticker = preloadedSticker } else { sticker = self.context.engine.stickers.randomGreetingSticker() |> map { item -> TelegramMediaFile? in @@ -338,7 +338,7 @@ private final class ChatEmptyNodeNearbyChatContent: ASDisplayNode, ChatEmptyNode } else if !self.didSetupSticker { let sticker: Signal if let preloadedSticker = interfaceState.greetingData?.sticker { - sticker = .single(preloadedSticker) + sticker = preloadedSticker } else { sticker = self.context.engine.stickers.randomGreetingSticker() |> map { item -> TelegramMediaFile? in @@ -876,6 +876,7 @@ final class ChatEmptyNode: ASDisplayNode { node = ChatEmptyNodeNearbyChatContent(context: self.context, interaction: self.interaction) case .greeting: node = ChatEmptyNodeGreetingChatContent(context: self.context, interaction: self.interaction) + self.context.prefetchManager?.prepareNextGreetingSticker() } self.content = (contentType, node) self.addSubnode(node) diff --git a/submodules/TelegramUI/Sources/NavigateToChatController.swift b/submodules/TelegramUI/Sources/NavigateToChatController.swift index 4f6e15974f..fe5d204ab5 100644 --- a/submodules/TelegramUI/Sources/NavigateToChatController.swift +++ b/submodules/TelegramUI/Sources/NavigateToChatController.swift @@ -71,7 +71,7 @@ public func navigateToChatControllerImpl(_ params: NavigateToChatControllerParam }) } } else { - controller = ChatControllerImpl(context: params.context, chatLocation: params.chatLocation, chatLocationContextHolder: params.chatLocationContextHolder, subject: params.subject, botStart: params.botStart, peekData: params.peekData, peerNearbyData: params.peerNearbyData, greetingData: params.greetingData) + controller = ChatControllerImpl(context: params.context, chatLocation: params.chatLocation, chatLocationContextHolder: params.chatLocationContextHolder, subject: params.subject, botStart: params.botStart, peekData: params.peekData, peerNearbyData: params.peerNearbyData) } controller.purposefulAction = params.purposefulAction if let search = params.activateMessageSearch { diff --git a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift index 0755dbe75a..ff14e45412 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift @@ -1532,9 +1532,6 @@ private final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewD private var groupMembersSearchContext: GroupMembersSearchContext? - private let preloadedSticker = Promise(nil) - private let preloadStickerDisposable = MetaDisposable() - private let displayAsPeersPromise = Promise<[FoundPeer]>([]) fileprivate let accountsAndPeers = Promise<[(Account, Peer, Int32)]>() @@ -2838,24 +2835,7 @@ private final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewD if let _ = nearbyPeerDistance { self.preloadHistoryDisposable.set(self.context.account.addAdditionalPreloadHistoryPeerId(peerId: peerId)) - self.preloadedSticker.set(.single(nil) - |> then(context.engine.stickers.randomGreetingSticker() - |> map { item in - return item?.file - })) - - self.preloadStickerDisposable.set((self.preloadedSticker.get() - |> mapToSignal { sticker -> Signal in - if let sticker = sticker { - let _ = freeMediaFileInteractiveFetched(account: context.account, fileReference: .standalone(media: sticker)).start() - return chatMessageAnimationData(postbox: context.account.postbox, resource: sticker.resource, fitzModifier: nil, width: 384, height: 384, synchronousLoad: false) - |> mapToSignal { _ -> Signal in - return .complete() - } - } else { - return .complete() - } - }).start()) + self.context.prefetchManager?.prepareNextGreetingSticker() } } @@ -2870,7 +2850,6 @@ private final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewD self.selectAddMemberDisposable.dispose() self.addMemberDisposable.dispose() self.preloadHistoryDisposable.dispose() - self.preloadStickerDisposable.dispose() self.resolvePeerByNameDisposable?.dispose() self.navigationActionDisposable.dispose() self.enqueueMediaMessageDisposable.dispose() @@ -3356,24 +3335,18 @@ private final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewD switch key { case .message: if let navigationController = controller.navigationController as? NavigationController { - let _ = (self.preloadedSticker.get() - |> take(1) - |> deliverOnMainQueue).start(next: { [weak self] sticker in - if let strongSelf = self { - strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(strongSelf.peerId), keepStack: strongSelf.nearbyPeerDistance != nil ? .always : .default, peerNearbyData: strongSelf.nearbyPeerDistance.flatMap({ ChatPeerNearbyData(distance: $0) }), greetingData: strongSelf.nearbyPeerDistance != nil ? sticker.flatMap({ ChatGreetingData(sticker: $0) }) : nil, completion: { _ in - if strongSelf.nearbyPeerDistance != nil { - var viewControllers = navigationController.viewControllers - viewControllers = viewControllers.filter { controller in - if controller is PeerInfoScreen { - return false - } - return true - } - navigationController.setViewControllers(viewControllers, animated: false) + self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: self.context, chatLocation: .peer(self.peerId), keepStack: self.nearbyPeerDistance != nil ? .always : .default, peerNearbyData: self.nearbyPeerDistance.flatMap({ ChatPeerNearbyData(distance: $0) }), completion: { [weak self] _ in + if let strongSelf = self, strongSelf.nearbyPeerDistance != nil { + var viewControllers = navigationController.viewControllers + viewControllers = viewControllers.filter { controller in + if controller is PeerInfoScreen { + return false } - })) + return true + } + navigationController.setViewControllers(viewControllers, animated: false) } - }) + })) } case .discussion: if let cachedData = self.data?.cachedData as? CachedChannelData, case let .known(maybeLinkedDiscussionPeerId) = cachedData.linkedDiscussionPeerId, let linkedDiscussionPeerId = maybeLinkedDiscussionPeerId { @@ -3773,24 +3746,18 @@ private final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewD private func openChatWithMessageSearch() { if let navigationController = (self.controller?.navigationController as? NavigationController) { - let _ = (self.preloadedSticker.get() - |> take(1) - |> deliverOnMainQueue).start(next: { [weak self] sticker in - if let strongSelf = self { - strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(strongSelf.peerId), keepStack: strongSelf.nearbyPeerDistance != nil ? .always : .default, activateMessageSearch: (.everything, ""), peerNearbyData: strongSelf.nearbyPeerDistance.flatMap({ ChatPeerNearbyData(distance: $0) }), greetingData: strongSelf.nearbyPeerDistance != nil ? sticker.flatMap({ ChatGreetingData(sticker: $0) }) : nil, completion: { _ in - if strongSelf.nearbyPeerDistance != nil { - var viewControllers = navigationController.viewControllers - viewControllers = viewControllers.filter { controller in - if controller is PeerInfoScreen { - return false - } - return true - } - navigationController.setViewControllers(viewControllers, animated: false) + self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: self.context, chatLocation: .peer(self.peerId), keepStack: self.nearbyPeerDistance != nil ? .always : .default, activateMessageSearch: (.everything, ""), peerNearbyData: self.nearbyPeerDistance.flatMap({ ChatPeerNearbyData(distance: $0) }), completion: { [weak self] _ in + if let strongSelf = self, strongSelf.nearbyPeerDistance != nil { + var viewControllers = navigationController.viewControllers + viewControllers = viewControllers.filter { controller in + if controller is PeerInfoScreen { + return false } - })) + return true + } + navigationController.setViewControllers(viewControllers, animated: false) } - }) + })) } } @@ -4233,24 +4200,18 @@ private final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewD private func openChat() { if let navigationController = self.controller?.navigationController as? NavigationController { - let _ = (self.preloadedSticker.get() - |> take(1) - |> deliverOnMainQueue).start(next: { [weak self] sticker in - if let strongSelf = self { - strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(strongSelf.peerId), keepStack: strongSelf.nearbyPeerDistance != nil ? .always : .default, peerNearbyData: strongSelf.nearbyPeerDistance.flatMap({ ChatPeerNearbyData(distance: $0) }), greetingData: strongSelf.nearbyPeerDistance != nil ? sticker.flatMap({ ChatGreetingData(sticker: $0) }) : nil, completion: { _ in - if strongSelf.nearbyPeerDistance != nil { - var viewControllers = navigationController.viewControllers - viewControllers = viewControllers.filter { controller in - if controller is PeerInfoScreen { - return false - } - return true - } - navigationController.setViewControllers(viewControllers, animated: false) + self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: self.context, chatLocation: .peer(self.peerId), keepStack: self.nearbyPeerDistance != nil ? .always : .default, peerNearbyData: self.nearbyPeerDistance.flatMap({ ChatPeerNearbyData(distance: $0) }), completion: { [weak self] _ in + if let strongSelf = self, strongSelf.nearbyPeerDistance != nil { + var viewControllers = navigationController.viewControllers + viewControllers = viewControllers.filter { controller in + if controller is PeerInfoScreen { + return false } - })) + return true + } + navigationController.setViewControllers(viewControllers, animated: false) } - }) + })) } } diff --git a/submodules/TelegramUI/Sources/PrefetchManager.swift b/submodules/TelegramUI/Sources/PrefetchManager.swift index 9ea80fb61b..88d8f64684 100644 --- a/submodules/TelegramUI/Sources/PrefetchManager.swift +++ b/submodules/TelegramUI/Sources/PrefetchManager.swift @@ -6,6 +6,7 @@ import SyncCore import TelegramUIPreferences import AccountContext import PhotoResources +import StickerResources import Emoji import UniversalMediaPlayer @@ -21,18 +22,23 @@ public enum PrefetchMediaItem { case animatedEmojiSticker(TelegramMediaFile) } -private final class PrefetchManagerImpl { +private final class PrefetchManagerInnerImpl { private let queue: Queue private let account: Account + private let engine: TelegramEngine private let fetchManager: FetchManager private var listDisposable: Disposable? private var contexts: [MediaId: PrefetchMediaContext] = [:] - - init(queue: Queue, sharedContext: SharedAccountContext, account: Account, fetchManager: FetchManager) { + + private let preloadGreetingStickerDisposable = MetaDisposable() + fileprivate let preloadedGreetingStickerPromise = Promise(nil) + + init(queue: Queue, sharedContext: SharedAccountContext, account: Account, engine: TelegramEngine, fetchManager: FetchManager) { self.queue = queue self.account = account + self.engine = engine self.fetchManager = fetchManager let networkType = account.networkType @@ -226,18 +232,63 @@ private final class PrefetchManagerImpl { } } } + + fileprivate func prepareNextGreetingSticker() { + let account = self.account + let engine = self.engine + self.preloadedGreetingStickerPromise.set(.single(nil) + |> then(engine.stickers.randomGreetingSticker() + |> map { item in + return item?.file + })) + + self.preloadGreetingStickerDisposable.set((self.preloadedGreetingStickerPromise.get() + |> mapToSignal { sticker -> Signal in + if let sticker = sticker { + let _ = freeMediaFileInteractiveFetched(account: account, fileReference: .standalone(media: sticker)).start() + return chatMessageAnimationData(postbox: account.postbox, resource: sticker.resource, fitzModifier: nil, width: 384, height: 384, synchronousLoad: false) + |> mapToSignal { _ -> Signal in + return .complete() + } + } else { + return .complete() + } + }).start()) + } } -final class PrefetchManager { +final class PrefetchManagerImpl: PrefetchManager { private let queue: Queue - private let impl: QueueLocalObject + private let impl: QueueLocalObject + private let uuid = Atomic(value: UUID()) - init(sharedContext: SharedAccountContext, account: Account, fetchManager: FetchManager) { + init(sharedContext: SharedAccountContext, account: Account, engine: TelegramEngine, fetchManager: FetchManager) { let queue = Queue.mainQueue() self.queue = queue self.impl = QueueLocalObject(queue: queue, generate: { - return PrefetchManagerImpl(queue: queue, sharedContext: sharedContext, account: account, fetchManager: fetchManager) + return PrefetchManagerInnerImpl(queue: queue, sharedContext: sharedContext, account: account, engine: engine, fetchManager: fetchManager) }) } + + var preloadedGreetingSticker: ChatGreetingData { + let signal: Signal = Signal { subscriber in + let disposable = MetaDisposable() + self.impl.with { impl in + disposable.set((impl.preloadedGreetingStickerPromise.get() |> take(1)).start(next: { file in + subscriber.putNext(file) + subscriber.putCompletion() + })) + } + return disposable + } + return ChatGreetingData(uuid: uuid.with { $0 }, sticker: signal) + } + + func prepareNextGreetingSticker() { + let _ = uuid.swap(UUID()) + self.impl.with { impl in + impl.prepareNextGreetingSticker() + } + } }