mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-09-01 18:33:10 +00:00
Display progress when adding sticker packs
This commit is contained in:
parent
e653760a74
commit
0b5be7edad
@ -145,6 +145,8 @@ final class ChatMediaInputTrendingPane: ChatMediaInputPane {
|
||||
|
||||
var scrollingInitiated: (() -> Void)?
|
||||
|
||||
private let installDisposable = MetaDisposable()
|
||||
|
||||
init(context: AccountContext, controllerInteraction: ChatControllerInteraction, getItemIsPreviewed: @escaping (StickerPackItem) -> Bool) {
|
||||
self.context = context
|
||||
self.controllerInteraction = controllerInteraction
|
||||
@ -163,6 +165,7 @@ final class ChatMediaInputTrendingPane: ChatMediaInputPane {
|
||||
|
||||
deinit {
|
||||
self.disposable?.dispose()
|
||||
self.installDisposable.dispose()
|
||||
}
|
||||
|
||||
func activate() {
|
||||
@ -174,7 +177,7 @@ final class ChatMediaInputTrendingPane: ChatMediaInputPane {
|
||||
let interaction = TrendingPaneInteraction(installPack: { [weak self] info in
|
||||
if let strongSelf = self, let info = info as? StickerPackCollectionInfo {
|
||||
let account = strongSelf.context.account
|
||||
let _ = (loadedStickerPack(postbox: strongSelf.context.account.postbox, network: strongSelf.context.account.network, reference: .id(id: info.id.id, accessHash: info.accessHash), forceActualized: false)
|
||||
var installSignal = loadedStickerPack(postbox: strongSelf.context.account.postbox, network: strongSelf.context.account.network, reference: .id(id: info.id.id, accessHash: info.accessHash), forceActualized: false)
|
||||
|> mapToSignal { result -> Signal<(StickerPackCollectionInfo, [ItemCollectionItem]), NoError> in
|
||||
switch result {
|
||||
case let .result(info, items, installed):
|
||||
@ -200,7 +203,37 @@ final class ChatMediaInputTrendingPane: ChatMediaInputPane {
|
||||
}
|
||||
return .complete()
|
||||
}
|
||||
|> deliverOnMainQueue).start(next: { info, items in
|
||||
|> deliverOnMainQueue
|
||||
|
||||
let context = strongSelf.context
|
||||
var cancelImpl: (() -> Void)?
|
||||
let progressSignal = Signal<Never, NoError> { subscriber in
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
let controller = OverlayStatusController(theme: presentationData.theme, type: .loading(cancelled: {
|
||||
cancelImpl?()
|
||||
}))
|
||||
self?.controllerInteraction.presentController(controller, nil)
|
||||
return ActionDisposable { [weak controller] in
|
||||
Queue.mainQueue().async() {
|
||||
controller?.dismiss()
|
||||
}
|
||||
}
|
||||
}
|
||||
|> runOn(Queue.mainQueue())
|
||||
|> delay(0.12, queue: Queue.mainQueue())
|
||||
let progressDisposable = progressSignal.start()
|
||||
|
||||
installSignal = installSignal
|
||||
|> afterDisposed {
|
||||
Queue.mainQueue().async {
|
||||
progressDisposable.dispose()
|
||||
}
|
||||
}
|
||||
cancelImpl = {
|
||||
self?.installDisposable.set(nil)
|
||||
}
|
||||
|
||||
strongSelf.installDisposable.set(installSignal.start(next: { info, items in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -219,7 +252,7 @@ final class ChatMediaInputTrendingPane: ChatMediaInputPane {
|
||||
strongSelf.controllerInteraction.navigationController()?.presentOverlay(controller: UndoOverlayController(presentationData: presentationData, content: .stickersModified(title: presentationData.strings.StickerPackActionInfo_AddedTitle, text: presentationData.strings.StickerPackActionInfo_AddedText(info.title).0, undo: false, info: info, topItem: items.first, account: strongSelf.context.account), elevatedLayout: false, animateInAsReplacement: animateInAsReplacement, action: { _ in
|
||||
return true
|
||||
}))
|
||||
})
|
||||
}))
|
||||
}
|
||||
}, openPack: { [weak self] info in
|
||||
if let strongSelf = self, let info = info as? StickerPackCollectionInfo {
|
||||
|
@ -7,20 +7,23 @@ import Postbox
|
||||
import TelegramCore
|
||||
import SyncCore
|
||||
import TelegramPresentationData
|
||||
import PresentationDataUtils
|
||||
import LegacyComponents
|
||||
import MergeLists
|
||||
import AccountContext
|
||||
import StickerPackPreviewUI
|
||||
import Emoji
|
||||
import AppBundle
|
||||
import OverlayStatusController
|
||||
import UndoUI
|
||||
|
||||
final class StickerPaneSearchInteraction {
|
||||
let open: (StickerPackCollectionInfo) -> Void
|
||||
let install: (StickerPackCollectionInfo) -> Void
|
||||
let install: (StickerPackCollectionInfo, [ItemCollectionItem]) -> Void
|
||||
let sendSticker: (FileMediaReference, ASDisplayNode, CGRect) -> Void
|
||||
let getItemIsPreviewed: (StickerPackItem) -> Bool
|
||||
|
||||
init(open: @escaping (StickerPackCollectionInfo) -> Void, install: @escaping (StickerPackCollectionInfo) -> Void, sendSticker: @escaping (FileMediaReference, ASDisplayNode, CGRect) -> Void, getItemIsPreviewed: @escaping (StickerPackItem) -> Bool) {
|
||||
init(open: @escaping (StickerPackCollectionInfo) -> Void, install: @escaping (StickerPackCollectionInfo, [ItemCollectionItem]) -> Void, sendSticker: @escaping (FileMediaReference, ASDisplayNode, CGRect) -> Void, getItemIsPreviewed: @escaping (StickerPackItem) -> Bool) {
|
||||
self.open = open
|
||||
self.install = install
|
||||
self.sendSticker = sendSticker
|
||||
@ -104,7 +107,7 @@ private enum StickerSearchEntry: Identifiable, Comparable {
|
||||
return StickerPaneSearchGlobalItem(account: account, theme: theme, strings: strings, info: info, topItems: topItems, grid: false, topSeparator: topSeparator, installed: installed, unread: false, open: {
|
||||
interaction.open(info)
|
||||
}, install: {
|
||||
interaction.install(info)
|
||||
interaction.install(info, topItems)
|
||||
}, getItemIsPreviewed: { item in
|
||||
return interaction.getItemIsPreviewed(item)
|
||||
})
|
||||
@ -171,6 +174,8 @@ final class StickerPaneSearchContentNode: ASDisplayNode, PaneSearchContentNode {
|
||||
var deactivateSearchBar: (() -> Void)?
|
||||
var updateActivity: ((Bool) -> Void)?
|
||||
|
||||
private let installDisposable = MetaDisposable()
|
||||
|
||||
init(context: AccountContext, theme: PresentationTheme, strings: PresentationStrings, controllerInteraction: ChatControllerInteraction, inputNodeInteraction: ChatMediaInputNodeInteraction) {
|
||||
self.context = context
|
||||
self.controllerInteraction = controllerInteraction
|
||||
@ -227,25 +232,87 @@ final class StickerPaneSearchContentNode: ASDisplayNode, PaneSearchContentNode {
|
||||
})
|
||||
strongSelf.controllerInteraction.presentController(controller, nil)
|
||||
}
|
||||
}, install: { [weak self] info in
|
||||
if let strongSelf = self {
|
||||
let _ = (loadedStickerPack(postbox: strongSelf.context.account.postbox, network: strongSelf.context.account.network, reference: .id(id: info.id.id, accessHash: info.accessHash), forceActualized: false)
|
||||
|> mapToSignal { result -> Signal<Void, NoError> in
|
||||
switch result {
|
||||
case let .result(info, items, installed):
|
||||
if installed {
|
||||
return .complete()
|
||||
} else {
|
||||
return addStickerPackInteractively(postbox: strongSelf.context.account.postbox, info: info, items: items)
|
||||
}
|
||||
case .fetching:
|
||||
break
|
||||
case .none:
|
||||
break
|
||||
}
|
||||
return .complete()
|
||||
}).start()
|
||||
}, install: { [weak self] info, items in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
let account = strongSelf.context.account
|
||||
var installSignal = loadedStickerPack(postbox: strongSelf.context.account.postbox, network: strongSelf.context.account.network, reference: .id(id: info.id.id, accessHash: info.accessHash), forceActualized: false)
|
||||
|> mapToSignal { result -> Signal<(StickerPackCollectionInfo, [ItemCollectionItem]), NoError> in
|
||||
switch result {
|
||||
case let .result(info, items, installed):
|
||||
if installed {
|
||||
return .complete()
|
||||
} else {
|
||||
return preloadedStickerPackThumbnail(account: account, info: info, items: items)
|
||||
|> filter { $0 }
|
||||
|> ignoreValues
|
||||
|> then(
|
||||
addStickerPackInteractively(postbox: strongSelf.context.account.postbox, info: info, items: items)
|
||||
|> ignoreValues
|
||||
)
|
||||
|> mapToSignal { _ -> Signal<(StickerPackCollectionInfo, [ItemCollectionItem]), NoError> in
|
||||
return .complete()
|
||||
}
|
||||
|> then(.single((info, items)))
|
||||
}
|
||||
case .fetching:
|
||||
break
|
||||
case .none:
|
||||
break
|
||||
}
|
||||
return .complete()
|
||||
}
|
||||
|> deliverOnMainQueue
|
||||
|
||||
let context = strongSelf.context
|
||||
var cancelImpl: (() -> Void)?
|
||||
let progressSignal = Signal<Never, NoError> { subscriber in
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
let controller = OverlayStatusController(theme: presentationData.theme, type: .loading(cancelled: {
|
||||
cancelImpl?()
|
||||
}))
|
||||
self?.controllerInteraction.presentController(controller, nil)
|
||||
return ActionDisposable { [weak controller] in
|
||||
Queue.mainQueue().async() {
|
||||
controller?.dismiss()
|
||||
}
|
||||
}
|
||||
}
|
||||
|> runOn(Queue.mainQueue())
|
||||
|> delay(0.12, queue: Queue.mainQueue())
|
||||
let progressDisposable = progressSignal.start()
|
||||
|
||||
installSignal = installSignal
|
||||
|> afterDisposed {
|
||||
Queue.mainQueue().async {
|
||||
progressDisposable.dispose()
|
||||
}
|
||||
}
|
||||
cancelImpl = {
|
||||
self?.installDisposable.set(nil)
|
||||
}
|
||||
|
||||
strongSelf.installDisposable.set(installSignal.start(next: { info, items in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
|
||||
var animateInAsReplacement = false
|
||||
if let navigationController = strongSelf.controllerInteraction.navigationController() {
|
||||
for controller in navigationController.overlayControllers {
|
||||
if let controller = controller as? UndoOverlayController {
|
||||
controller.dismissWithCommitActionAndReplacementAnimation()
|
||||
animateInAsReplacement = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 }
|
||||
strongSelf.controllerInteraction.navigationController()?.presentOverlay(controller: UndoOverlayController(presentationData: presentationData, content: .stickersModified(title: presentationData.strings.StickerPackActionInfo_AddedTitle, text: presentationData.strings.StickerPackActionInfo_AddedText(info.title).0, undo: false, info: info, topItem: items.first, account: strongSelf.context.account), elevatedLayout: false, animateInAsReplacement: animateInAsReplacement, action: { _ in
|
||||
return true
|
||||
}))
|
||||
}))
|
||||
}, sendSticker: { [weak self] file, sourceNode, sourceRect in
|
||||
if let strongSelf = self {
|
||||
let _ = strongSelf.controllerInteraction.sendSticker(file, false, sourceNode, sourceRect)
|
||||
@ -262,6 +329,7 @@ final class StickerPaneSearchContentNode: ASDisplayNode, PaneSearchContentNode {
|
||||
|
||||
deinit {
|
||||
self.searchDisposable.dispose()
|
||||
self.installDisposable.dispose()
|
||||
}
|
||||
|
||||
func updateText(_ text: String, languageCode: String?) {
|
||||
|
@ -7,6 +7,7 @@ import SyncCore
|
||||
import SwiftSignalKit
|
||||
import Postbox
|
||||
import TelegramPresentationData
|
||||
import StickerPackPreviewUI
|
||||
|
||||
final class StickerPaneSearchGlobalSection: GridSection {
|
||||
let height: CGFloat = 0.0
|
||||
@ -41,6 +42,7 @@ final class StickerPaneSearchGlobalItem: GridItem {
|
||||
let grid: Bool
|
||||
let topSeparator: Bool
|
||||
let installed: Bool
|
||||
let installing: Bool
|
||||
let unread: Bool
|
||||
let open: () -> Void
|
||||
let install: () -> Void
|
||||
@ -51,7 +53,7 @@ final class StickerPaneSearchGlobalItem: GridItem {
|
||||
return self.grid ? nil : (128.0 + (self.topSeparator ? 12.0 : 0.0))
|
||||
}
|
||||
|
||||
init(account: Account, theme: PresentationTheme, strings: PresentationStrings, info: StickerPackCollectionInfo, topItems: [StickerPackItem], grid: Bool, topSeparator: Bool, installed: Bool, unread: Bool, open: @escaping () -> Void, install: @escaping () -> Void, getItemIsPreviewed: @escaping (StickerPackItem) -> Bool) {
|
||||
init(account: Account, theme: PresentationTheme, strings: PresentationStrings, info: StickerPackCollectionInfo, topItems: [StickerPackItem], grid: Bool, topSeparator: Bool, installed: Bool, installing: Bool = false, unread: Bool, open: @escaping () -> Void, install: @escaping () -> Void, getItemIsPreviewed: @escaping (StickerPackItem) -> Bool) {
|
||||
self.account = account
|
||||
self.theme = theme
|
||||
self.strings = strings
|
||||
@ -60,6 +62,7 @@ final class StickerPaneSearchGlobalItem: GridItem {
|
||||
self.grid = grid
|
||||
self.topSeparator = topSeparator
|
||||
self.installed = installed
|
||||
self.installing = installing
|
||||
self.unread = unread
|
||||
self.open = open
|
||||
self.install = install
|
||||
@ -98,6 +101,9 @@ class StickerPaneSearchGlobalItemNode: GridItemNode {
|
||||
private var item: StickerPaneSearchGlobalItem?
|
||||
private var appliedItem: StickerPaneSearchGlobalItem?
|
||||
private let preloadDisposable = MetaDisposable()
|
||||
private let preloadedStickerPackThumbnailDisposable = MetaDisposable()
|
||||
|
||||
private var preloadedThumbnail = false
|
||||
|
||||
override var isVisibleInGrid: Bool {
|
||||
didSet {
|
||||
@ -105,6 +111,12 @@ class StickerPaneSearchGlobalItemNode: GridItemNode {
|
||||
for node in self.itemNodes {
|
||||
node.visibility = self.isVisibleInGrid
|
||||
}
|
||||
|
||||
if let item = self.item, self.isVisibleInGrid, !self.preloadedThumbnail {
|
||||
self.preloadedThumbnail = true
|
||||
|
||||
self.preloadedStickerPackThumbnailDisposable.set(preloadedStickerPackThumbnail(account: item.account, info: item.info, items: item.topItems).start())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -173,6 +185,7 @@ class StickerPaneSearchGlobalItemNode: GridItemNode {
|
||||
|
||||
deinit {
|
||||
self.preloadDisposable.dispose()
|
||||
self.preloadedStickerPackThumbnailDisposable.dispose()
|
||||
}
|
||||
|
||||
override func didLoad() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user