mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-11-07 09:20:08 +00:00
Improve greeting sticker preloading
This commit is contained in:
parent
66904581d6
commit
34ec6b2617
@ -219,17 +219,14 @@ public final class ChatPeerNearbyData: Equatable {
|
|||||||
|
|
||||||
public final class ChatGreetingData: Equatable {
|
public final class ChatGreetingData: Equatable {
|
||||||
public static func == (lhs: ChatGreetingData, rhs: ChatGreetingData) -> Bool {
|
public static func == (lhs: ChatGreetingData, rhs: ChatGreetingData) -> Bool {
|
||||||
if let lhsSticker = lhs.sticker, let rhsSticker = rhs.sticker, !lhsSticker.isEqual(to: rhsSticker) {
|
return lhs.uuid == rhs.uuid
|
||||||
return false
|
|
||||||
} else if (lhs.sticker == nil) != (rhs.sticker == nil) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public let sticker: TelegramMediaFile?
|
public let uuid: UUID
|
||||||
|
public let sticker: Signal<TelegramMediaFile?, NoError>
|
||||||
|
|
||||||
public init(sticker: TelegramMediaFile?) {
|
public init(uuid: UUID, sticker: Signal<TelegramMediaFile?, NoError>) {
|
||||||
|
self.uuid = uuid
|
||||||
self.sticker = sticker
|
self.sticker = sticker
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -285,14 +282,13 @@ public final class NavigateToChatControllerParams {
|
|||||||
public let activateMessageSearch: (ChatSearchDomain, String)?
|
public let activateMessageSearch: (ChatSearchDomain, String)?
|
||||||
public let peekData: ChatPeekTimeout?
|
public let peekData: ChatPeekTimeout?
|
||||||
public let peerNearbyData: ChatPeerNearbyData?
|
public let peerNearbyData: ChatPeerNearbyData?
|
||||||
public let greetingData: ChatGreetingData?
|
|
||||||
public let reportReason: ReportReason?
|
public let reportReason: ReportReason?
|
||||||
public let animated: Bool
|
public let animated: Bool
|
||||||
public let options: NavigationAnimationOptions
|
public let options: NavigationAnimationOptions
|
||||||
public let parentGroupId: PeerGroupId?
|
public let parentGroupId: PeerGroupId?
|
||||||
public let completion: (ChatController) -> Void
|
public let completion: (ChatController) -> Void
|
||||||
|
|
||||||
public init(navigationController: NavigationController, chatController: ChatController? = nil, context: AccountContext, chatLocation: ChatLocation, chatLocationContextHolder: Atomic<ChatLocationContextHolder?> = Atomic<ChatLocationContextHolder?>(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<ChatLocationContextHolder?> = Atomic<ChatLocationContextHolder?>(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.navigationController = navigationController
|
||||||
self.chatController = chatController
|
self.chatController = chatController
|
||||||
self.chatLocationContextHolder = chatLocationContextHolder
|
self.chatLocationContextHolder = chatLocationContextHolder
|
||||||
@ -309,7 +305,6 @@ public final class NavigateToChatControllerParams {
|
|||||||
self.activateMessageSearch = activateMessageSearch
|
self.activateMessageSearch = activateMessageSearch
|
||||||
self.peekData = peekData
|
self.peekData = peekData
|
||||||
self.peerNearbyData = peerNearbyData
|
self.peerNearbyData = peerNearbyData
|
||||||
self.greetingData = greetingData
|
|
||||||
self.reportReason = reportReason
|
self.reportReason = reportReason
|
||||||
self.animated = animated
|
self.animated = animated
|
||||||
self.options = options
|
self.options = options
|
||||||
@ -719,6 +714,7 @@ public protocol AccountContext: class {
|
|||||||
var liveLocationManager: LiveLocationManager? { get }
|
var liveLocationManager: LiveLocationManager? { get }
|
||||||
var peersNearbyManager: PeersNearbyManager? { get }
|
var peersNearbyManager: PeersNearbyManager? { get }
|
||||||
var fetchManager: FetchManager { get }
|
var fetchManager: FetchManager { get }
|
||||||
|
var prefetchManager: PrefetchManager? { get }
|
||||||
var downloadedMediaStoreManager: DownloadedMediaStoreManager { get }
|
var downloadedMediaStoreManager: DownloadedMediaStoreManager { get }
|
||||||
var peerChannelMemberCategoriesContextsManager: PeerChannelMemberCategoriesContextsManager { get }
|
var peerChannelMemberCategoriesContextsManager: PeerChannelMemberCategoriesContextsManager { get }
|
||||||
var wallpaperUploadManager: WallpaperUploadManager? { get }
|
var wallpaperUploadManager: WallpaperUploadManager? { get }
|
||||||
|
|||||||
@ -158,3 +158,8 @@ public protocol FetchManager {
|
|||||||
func cancelInteractiveFetches(category: FetchManagerCategory, location: FetchManagerLocation, locationKey: FetchManagerLocationKey, resource: MediaResource)
|
func cancelInteractiveFetches(category: FetchManagerCategory, location: FetchManagerLocation, locationKey: FetchManagerLocationKey, resource: MediaResource)
|
||||||
func fetchStatus(category: FetchManagerCategory, location: FetchManagerLocation, locationKey: FetchManagerLocationKey, resource: MediaResource) -> Signal<MediaResourceStatus, NoError>
|
func fetchStatus(category: FetchManagerCategory, location: FetchManagerLocation, locationKey: FetchManagerLocationKey, resource: MediaResource) -> Signal<MediaResourceStatus, NoError>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public protocol PrefetchManager {
|
||||||
|
var preloadedGreetingSticker: ChatGreetingData { get }
|
||||||
|
func prepareNextGreetingSticker()
|
||||||
|
}
|
||||||
|
|||||||
@ -144,9 +144,6 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
|||||||
private let featuredFiltersDisposable = MetaDisposable()
|
private let featuredFiltersDisposable = MetaDisposable()
|
||||||
private var processedFeaturedFilters = false
|
private var processedFeaturedFilters = false
|
||||||
|
|
||||||
private let preloadedSticker = Promise<TelegramMediaFile?>(nil)
|
|
||||||
private let preloadStickerDisposable = MetaDisposable()
|
|
||||||
|
|
||||||
private let isReorderingTabsValue = ValuePromise<Bool>(false)
|
private let isReorderingTabsValue = ValuePromise<Bool>(false)
|
||||||
|
|
||||||
private var searchContentNode: NavigationBarSearchContentNode?
|
private var searchContentNode: NavigationBarSearchContentNode?
|
||||||
@ -613,53 +610,43 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
|||||||
scrollToEndIfExists = true
|
scrollToEndIfExists = true
|
||||||
}
|
}
|
||||||
|
|
||||||
let _ = (strongSelf.preloadedSticker.get()
|
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
|
||||||
|> take(1)
|
self?.chatListDisplayNode.containerNode.currentItemNode.clearHighlightAnimated(true)
|
||||||
|> deliverOnMainQueue).start(next: { [weak self] greetingSticker in
|
if let promoInfo = promoInfo {
|
||||||
if let strongSelf = self {
|
switch promoInfo {
|
||||||
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
|
case .proxy:
|
||||||
self?.chatListDisplayNode.containerNode.currentItemNode.clearHighlightAnimated(true)
|
let _ = (ApplicationSpecificNotice.getProxyAdsAcknowledgment(accountManager: strongSelf.context.sharedContext.accountManager)
|
||||||
if let promoInfo = promoInfo {
|
|> deliverOnMainQueue).start(next: { value in
|
||||||
switch promoInfo {
|
guard let strongSelf = self else {
|
||||||
case .proxy:
|
return
|
||||||
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()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
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
|
||||||
|
}
|
||||||
|
|
||||||
if activateInput {
|
controller.displayPromoAnnouncement(text: text)
|
||||||
strongSelf.prepareRandomGreetingSticker()
|
let _ = ApplicationSpecificNotice.setPsaAcknowledgment(accountManager: strongSelf.context.sharedContext.accountManager, peerId: peer.id).start()
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1126,7 +1113,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
|||||||
super.displayNodeDidLoad()
|
super.displayNodeDidLoad()
|
||||||
|
|
||||||
Queue.mainQueue().after(1.0) {
|
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<Void, NoError> 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<Void, NoError> in
|
|
||||||
return .complete()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return .complete()
|
|
||||||
}
|
|
||||||
}).start())
|
|
||||||
}
|
|
||||||
|
|
||||||
override public func tabBarDisabledAction() {
|
override public func tabBarDisabledAction() {
|
||||||
self.donePressed()
|
self.donePressed()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -89,9 +89,6 @@ public class ContactsController: ViewController {
|
|||||||
|
|
||||||
public var switchToChatsController: (() -> Void)?
|
public var switchToChatsController: (() -> Void)?
|
||||||
|
|
||||||
private let preloadedSticker = Promise<TelegramMediaFile?>(nil)
|
|
||||||
private let preloadStickerDisposable = MetaDisposable()
|
|
||||||
|
|
||||||
public override func updateNavigationCustomData(_ data: Any?, progress: CGFloat, transition: ContainedViewLayoutTransition) {
|
public override func updateNavigationCustomData(_ data: Any?, progress: CGFloat, transition: ContainedViewLayoutTransition) {
|
||||||
if self.isNodeLoaded {
|
if self.isNodeLoaded {
|
||||||
self.contactsNode.contactListNode.updateSelectedChatLocation(data as? ChatLocation, progress: progress, transition: transition)
|
self.contactsNode.contactListNode.updateSelectedChatLocation(data as? ChatLocation, progress: progress, transition: transition)
|
||||||
@ -235,24 +232,16 @@ public class ContactsController: ViewController {
|
|||||||
scrollToEndIfExists = true
|
scrollToEndIfExists = true
|
||||||
}
|
}
|
||||||
|
|
||||||
let _ = (strongSelf.preloadedSticker.get()
|
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(peer.id), purposefulAction: { [weak self] in
|
||||||
|> take(1)
|
if fromSearch {
|
||||||
|> deliverOnMainQueue).start(next: { [weak self] greetingSticker in
|
self?.deactivateSearch(animated: false)
|
||||||
if let strongSelf = self {
|
self?.switchToChatsController?()
|
||||||
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()
|
|
||||||
}
|
}
|
||||||
})
|
}, scrollToEndIfExists: scrollToEndIfExists, options: [.removeOnMasterDetails], completion: { [weak self] _ in
|
||||||
|
if let strongSelf = self {
|
||||||
|
strongSelf.contactsNode.contactListNode.listNode.clearHighlightAnimated(true)
|
||||||
|
}
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
case let .deviceContact(id, _):
|
case let .deviceContact(id, _):
|
||||||
let _ = ((strongSelf.context.sharedContext.contactDataManager?.extendedData(stableId: id) ?? .single(nil))
|
let _ = ((strongSelf.context.sharedContext.contactDataManager?.extendedData(stableId: id) ?? .single(nil))
|
||||||
@ -423,14 +412,6 @@ public class ContactsController: ViewController {
|
|||||||
self.contactsNode.contactListNode.enableUpdates = false
|
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) {
|
override public func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
|
||||||
super.containerLayoutUpdated(layout, transition: transition)
|
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<Void, NoError> 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<Void, NoError> in
|
|
||||||
return .complete()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return .complete()
|
|
||||||
}
|
|
||||||
}).start())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -112,7 +112,7 @@ public final class AccountContextImpl: AccountContext {
|
|||||||
public let engine: TelegramEngine
|
public let engine: TelegramEngine
|
||||||
|
|
||||||
public let fetchManager: FetchManager
|
public let fetchManager: FetchManager
|
||||||
private let prefetchManager: PrefetchManager?
|
public let prefetchManager: PrefetchManager?
|
||||||
|
|
||||||
public var keyShortcutsController: KeyShortcutsController?
|
public var keyShortcutsController: KeyShortcutsController?
|
||||||
|
|
||||||
@ -172,7 +172,7 @@ public final class AccountContextImpl: AccountContext {
|
|||||||
}
|
}
|
||||||
self.fetchManager = FetchManagerImpl(postbox: account.postbox, storeManager: self.downloadedMediaStoreManager)
|
self.fetchManager = FetchManagerImpl(postbox: account.postbox, storeManager: self.downloadedMediaStoreManager)
|
||||||
if sharedContext.applicationBindings.isMainApp && !temp {
|
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.wallpaperUploadManager = WallpaperUploadManagerImpl(sharedContext: sharedContext, account: account, presentationData: sharedContext.presentationData)
|
||||||
self.themeUpdateManager = ThemeUpdateManagerImpl(sharedContext: sharedContext, account: account)
|
self.themeUpdateManager = ThemeUpdateManagerImpl(sharedContext: sharedContext, account: account)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -418,7 +418,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
|
|
||||||
private var importStateDisposable: Disposable?
|
private var importStateDisposable: Disposable?
|
||||||
|
|
||||||
public init(context: AccountContext, chatLocation: ChatLocation, chatLocationContextHolder: Atomic<ChatLocationContextHolder?> = Atomic<ChatLocationContextHolder?>(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<ChatLocationContextHolder?> = Atomic<ChatLocationContextHolder?>(value: nil), subject: ChatControllerSubject? = nil, botStart: ChatControllerInitialBotStart? = nil, mode: ChatControllerPresentationMode = .standard(previewing: false), peekData: ChatPeekTimeout? = nil, peerNearbyData: ChatPeerNearbyData? = nil) {
|
||||||
let _ = ChatControllerCount.modify { value in
|
let _ = ChatControllerCount.modify { value in
|
||||||
return value + 1
|
return value + 1
|
||||||
}
|
}
|
||||||
@ -463,7 +463,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
|
|
||||||
self.stickerSettings = ChatInterfaceStickerSettings(loopAnimatedStickers: false)
|
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)
|
self.presentationInterfaceStatePromise = ValuePromise(self.presentationInterfaceState)
|
||||||
|
|
||||||
var mediaAccessoryPanelVisibility = MediaAccessoryPanelVisibility.none
|
var mediaAccessoryPanelVisibility = MediaAccessoryPanelVisibility.none
|
||||||
|
|||||||
@ -161,7 +161,7 @@ private final class ChatEmptyNodeGreetingChatContent: ASDisplayNode, ChatEmptyNo
|
|||||||
} else if !self.didSetupSticker {
|
} else if !self.didSetupSticker {
|
||||||
let sticker: Signal<TelegramMediaFile?, NoError>
|
let sticker: Signal<TelegramMediaFile?, NoError>
|
||||||
if let preloadedSticker = interfaceState.greetingData?.sticker {
|
if let preloadedSticker = interfaceState.greetingData?.sticker {
|
||||||
sticker = .single(preloadedSticker)
|
sticker = preloadedSticker
|
||||||
} else {
|
} else {
|
||||||
sticker = self.context.engine.stickers.randomGreetingSticker()
|
sticker = self.context.engine.stickers.randomGreetingSticker()
|
||||||
|> map { item -> TelegramMediaFile? in
|
|> map { item -> TelegramMediaFile? in
|
||||||
@ -338,7 +338,7 @@ private final class ChatEmptyNodeNearbyChatContent: ASDisplayNode, ChatEmptyNode
|
|||||||
} else if !self.didSetupSticker {
|
} else if !self.didSetupSticker {
|
||||||
let sticker: Signal<TelegramMediaFile?, NoError>
|
let sticker: Signal<TelegramMediaFile?, NoError>
|
||||||
if let preloadedSticker = interfaceState.greetingData?.sticker {
|
if let preloadedSticker = interfaceState.greetingData?.sticker {
|
||||||
sticker = .single(preloadedSticker)
|
sticker = preloadedSticker
|
||||||
} else {
|
} else {
|
||||||
sticker = self.context.engine.stickers.randomGreetingSticker()
|
sticker = self.context.engine.stickers.randomGreetingSticker()
|
||||||
|> map { item -> TelegramMediaFile? in
|
|> map { item -> TelegramMediaFile? in
|
||||||
@ -876,6 +876,7 @@ final class ChatEmptyNode: ASDisplayNode {
|
|||||||
node = ChatEmptyNodeNearbyChatContent(context: self.context, interaction: self.interaction)
|
node = ChatEmptyNodeNearbyChatContent(context: self.context, interaction: self.interaction)
|
||||||
case .greeting:
|
case .greeting:
|
||||||
node = ChatEmptyNodeGreetingChatContent(context: self.context, interaction: self.interaction)
|
node = ChatEmptyNodeGreetingChatContent(context: self.context, interaction: self.interaction)
|
||||||
|
self.context.prefetchManager?.prepareNextGreetingSticker()
|
||||||
}
|
}
|
||||||
self.content = (contentType, node)
|
self.content = (contentType, node)
|
||||||
self.addSubnode(node)
|
self.addSubnode(node)
|
||||||
|
|||||||
@ -71,7 +71,7 @@ public func navigateToChatControllerImpl(_ params: NavigateToChatControllerParam
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
} else {
|
} 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
|
controller.purposefulAction = params.purposefulAction
|
||||||
if let search = params.activateMessageSearch {
|
if let search = params.activateMessageSearch {
|
||||||
|
|||||||
@ -1532,9 +1532,6 @@ private final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewD
|
|||||||
|
|
||||||
private var groupMembersSearchContext: GroupMembersSearchContext?
|
private var groupMembersSearchContext: GroupMembersSearchContext?
|
||||||
|
|
||||||
private let preloadedSticker = Promise<TelegramMediaFile?>(nil)
|
|
||||||
private let preloadStickerDisposable = MetaDisposable()
|
|
||||||
|
|
||||||
private let displayAsPeersPromise = Promise<[FoundPeer]>([])
|
private let displayAsPeersPromise = Promise<[FoundPeer]>([])
|
||||||
|
|
||||||
fileprivate let accountsAndPeers = Promise<[(Account, Peer, Int32)]>()
|
fileprivate let accountsAndPeers = Promise<[(Account, Peer, Int32)]>()
|
||||||
@ -2838,24 +2835,7 @@ private final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewD
|
|||||||
if let _ = nearbyPeerDistance {
|
if let _ = nearbyPeerDistance {
|
||||||
self.preloadHistoryDisposable.set(self.context.account.addAdditionalPreloadHistoryPeerId(peerId: peerId))
|
self.preloadHistoryDisposable.set(self.context.account.addAdditionalPreloadHistoryPeerId(peerId: peerId))
|
||||||
|
|
||||||
self.preloadedSticker.set(.single(nil)
|
self.context.prefetchManager?.prepareNextGreetingSticker()
|
||||||
|> then(context.engine.stickers.randomGreetingSticker()
|
|
||||||
|> map { item in
|
|
||||||
return item?.file
|
|
||||||
}))
|
|
||||||
|
|
||||||
self.preloadStickerDisposable.set((self.preloadedSticker.get()
|
|
||||||
|> mapToSignal { sticker -> Signal<Void, NoError> 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<Void, NoError> in
|
|
||||||
return .complete()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return .complete()
|
|
||||||
}
|
|
||||||
}).start())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2870,7 +2850,6 @@ private final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewD
|
|||||||
self.selectAddMemberDisposable.dispose()
|
self.selectAddMemberDisposable.dispose()
|
||||||
self.addMemberDisposable.dispose()
|
self.addMemberDisposable.dispose()
|
||||||
self.preloadHistoryDisposable.dispose()
|
self.preloadHistoryDisposable.dispose()
|
||||||
self.preloadStickerDisposable.dispose()
|
|
||||||
self.resolvePeerByNameDisposable?.dispose()
|
self.resolvePeerByNameDisposable?.dispose()
|
||||||
self.navigationActionDisposable.dispose()
|
self.navigationActionDisposable.dispose()
|
||||||
self.enqueueMediaMessageDisposable.dispose()
|
self.enqueueMediaMessageDisposable.dispose()
|
||||||
@ -3356,24 +3335,18 @@ private final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewD
|
|||||||
switch key {
|
switch key {
|
||||||
case .message:
|
case .message:
|
||||||
if let navigationController = controller.navigationController as? NavigationController {
|
if let navigationController = controller.navigationController as? NavigationController {
|
||||||
let _ = (self.preloadedSticker.get()
|
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
|
||||||
|> take(1)
|
if let strongSelf = self, strongSelf.nearbyPeerDistance != nil {
|
||||||
|> deliverOnMainQueue).start(next: { [weak self] sticker in
|
var viewControllers = navigationController.viewControllers
|
||||||
if let strongSelf = self {
|
viewControllers = viewControllers.filter { controller in
|
||||||
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 controller is PeerInfoScreen {
|
||||||
if strongSelf.nearbyPeerDistance != nil {
|
return false
|
||||||
var viewControllers = navigationController.viewControllers
|
|
||||||
viewControllers = viewControllers.filter { controller in
|
|
||||||
if controller is PeerInfoScreen {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
navigationController.setViewControllers(viewControllers, animated: false)
|
|
||||||
}
|
}
|
||||||
}))
|
return true
|
||||||
|
}
|
||||||
|
navigationController.setViewControllers(viewControllers, animated: false)
|
||||||
}
|
}
|
||||||
})
|
}))
|
||||||
}
|
}
|
||||||
case .discussion:
|
case .discussion:
|
||||||
if let cachedData = self.data?.cachedData as? CachedChannelData, case let .known(maybeLinkedDiscussionPeerId) = cachedData.linkedDiscussionPeerId, let linkedDiscussionPeerId = maybeLinkedDiscussionPeerId {
|
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() {
|
private func openChatWithMessageSearch() {
|
||||||
if let navigationController = (self.controller?.navigationController as? NavigationController) {
|
if let navigationController = (self.controller?.navigationController as? NavigationController) {
|
||||||
let _ = (self.preloadedSticker.get()
|
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
|
||||||
|> take(1)
|
if let strongSelf = self, strongSelf.nearbyPeerDistance != nil {
|
||||||
|> deliverOnMainQueue).start(next: { [weak self] sticker in
|
var viewControllers = navigationController.viewControllers
|
||||||
if let strongSelf = self {
|
viewControllers = viewControllers.filter { controller in
|
||||||
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 controller is PeerInfoScreen {
|
||||||
if strongSelf.nearbyPeerDistance != nil {
|
return false
|
||||||
var viewControllers = navigationController.viewControllers
|
|
||||||
viewControllers = viewControllers.filter { controller in
|
|
||||||
if controller is PeerInfoScreen {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
navigationController.setViewControllers(viewControllers, animated: false)
|
|
||||||
}
|
}
|
||||||
}))
|
return true
|
||||||
|
}
|
||||||
|
navigationController.setViewControllers(viewControllers, animated: false)
|
||||||
}
|
}
|
||||||
})
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4233,24 +4200,18 @@ private final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewD
|
|||||||
|
|
||||||
private func openChat() {
|
private func openChat() {
|
||||||
if let navigationController = self.controller?.navigationController as? NavigationController {
|
if let navigationController = self.controller?.navigationController as? NavigationController {
|
||||||
let _ = (self.preloadedSticker.get()
|
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
|
||||||
|> take(1)
|
if let strongSelf = self, strongSelf.nearbyPeerDistance != nil {
|
||||||
|> deliverOnMainQueue).start(next: { [weak self] sticker in
|
var viewControllers = navigationController.viewControllers
|
||||||
if let strongSelf = self {
|
viewControllers = viewControllers.filter { controller in
|
||||||
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 controller is PeerInfoScreen {
|
||||||
if strongSelf.nearbyPeerDistance != nil {
|
return false
|
||||||
var viewControllers = navigationController.viewControllers
|
|
||||||
viewControllers = viewControllers.filter { controller in
|
|
||||||
if controller is PeerInfoScreen {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
navigationController.setViewControllers(viewControllers, animated: false)
|
|
||||||
}
|
}
|
||||||
}))
|
return true
|
||||||
|
}
|
||||||
|
navigationController.setViewControllers(viewControllers, animated: false)
|
||||||
}
|
}
|
||||||
})
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import SyncCore
|
|||||||
import TelegramUIPreferences
|
import TelegramUIPreferences
|
||||||
import AccountContext
|
import AccountContext
|
||||||
import PhotoResources
|
import PhotoResources
|
||||||
|
import StickerResources
|
||||||
import Emoji
|
import Emoji
|
||||||
import UniversalMediaPlayer
|
import UniversalMediaPlayer
|
||||||
|
|
||||||
@ -21,18 +22,23 @@ public enum PrefetchMediaItem {
|
|||||||
case animatedEmojiSticker(TelegramMediaFile)
|
case animatedEmojiSticker(TelegramMediaFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
private final class PrefetchManagerImpl {
|
private final class PrefetchManagerInnerImpl {
|
||||||
private let queue: Queue
|
private let queue: Queue
|
||||||
private let account: Account
|
private let account: Account
|
||||||
|
private let engine: TelegramEngine
|
||||||
private let fetchManager: FetchManager
|
private let fetchManager: FetchManager
|
||||||
|
|
||||||
private var listDisposable: Disposable?
|
private var listDisposable: Disposable?
|
||||||
|
|
||||||
private var contexts: [MediaId: PrefetchMediaContext] = [:]
|
private var contexts: [MediaId: PrefetchMediaContext] = [:]
|
||||||
|
|
||||||
init(queue: Queue, sharedContext: SharedAccountContext, account: Account, fetchManager: FetchManager) {
|
private let preloadGreetingStickerDisposable = MetaDisposable()
|
||||||
|
fileprivate let preloadedGreetingStickerPromise = Promise<TelegramMediaFile?>(nil)
|
||||||
|
|
||||||
|
init(queue: Queue, sharedContext: SharedAccountContext, account: Account, engine: TelegramEngine, fetchManager: FetchManager) {
|
||||||
self.queue = queue
|
self.queue = queue
|
||||||
self.account = account
|
self.account = account
|
||||||
|
self.engine = engine
|
||||||
self.fetchManager = fetchManager
|
self.fetchManager = fetchManager
|
||||||
|
|
||||||
let networkType = account.networkType
|
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<Void, NoError> 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<Void, NoError> in
|
||||||
|
return .complete()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return .complete()
|
||||||
|
}
|
||||||
|
}).start())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final class PrefetchManager {
|
final class PrefetchManagerImpl: PrefetchManager {
|
||||||
private let queue: Queue
|
private let queue: Queue
|
||||||
|
|
||||||
private let impl: QueueLocalObject<PrefetchManagerImpl>
|
private let impl: QueueLocalObject<PrefetchManagerInnerImpl>
|
||||||
|
private let uuid = Atomic<UUID>(value: UUID())
|
||||||
|
|
||||||
init(sharedContext: SharedAccountContext, account: Account, fetchManager: FetchManager) {
|
init(sharedContext: SharedAccountContext, account: Account, engine: TelegramEngine, fetchManager: FetchManager) {
|
||||||
let queue = Queue.mainQueue()
|
let queue = Queue.mainQueue()
|
||||||
self.queue = queue
|
self.queue = queue
|
||||||
self.impl = QueueLocalObject(queue: queue, generate: {
|
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<TelegramMediaFile?, NoError> = 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()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user