mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-15 13:35:19 +00:00
Sticker refactoring
This commit is contained in:
parent
a6292e752a
commit
cff972c968
@ -147,7 +147,41 @@ public protocol AnimatedStickerNodeSource {
|
||||
func directDataPath(attemptSynchronously: Bool) -> Signal<String?, NoError>
|
||||
}
|
||||
|
||||
public final class AnimatedStickerNode: ASDisplayNode {
|
||||
public protocol AnimatedStickerNode: ASDisplayNode {
|
||||
var automaticallyLoadFirstFrame: Bool { get set }
|
||||
var automaticallyLoadLastFrame: Bool { get set }
|
||||
var playToCompletionOnStop: Bool { get set }
|
||||
var started: () -> Void { get set }
|
||||
|
||||
var completed: (Bool) -> Void { get set }
|
||||
var frameUpdated: (Int, Int) -> Void { get set }
|
||||
var currentFrameIndex: Int { get }
|
||||
var currentFrameCount: Int { get }
|
||||
var isPlaying: Bool { get }
|
||||
var stopAtNearestLoop: Bool { get set }
|
||||
|
||||
var status: Signal<AnimatedStickerStatus, NoError> { get }
|
||||
|
||||
var autoplay: Bool { get set }
|
||||
|
||||
var visibility: Bool { get set }
|
||||
|
||||
var isPlayingChanged: (Bool) -> Void { get }
|
||||
|
||||
func cloneCurrentFrame(from otherNode: AnimatedStickerNode?)
|
||||
func setup(source: AnimatedStickerNodeSource, width: Int, height: Int, playbackMode: AnimatedStickerPlaybackMode, mode: AnimatedStickerMode)
|
||||
func reset()
|
||||
func playOnce()
|
||||
func play(firstFrame: Bool, fromIndex: Int?)
|
||||
func pause()
|
||||
func stop()
|
||||
func seekTo(_ position: AnimatedStickerPlaybackPosition)
|
||||
func playIfNeeded() -> Bool
|
||||
func updateLayout(size: CGSize)
|
||||
func setOverlayColor(_ color: UIColor?, replace: Bool, animated: Bool)
|
||||
}
|
||||
|
||||
public final class DefaultAnimatedStickerNodeImpl: ASDisplayNode, AnimatedStickerNode {
|
||||
private let queue: Queue
|
||||
private let disposable = MetaDisposable()
|
||||
private let fetchDisposable = MetaDisposable()
|
||||
@ -245,14 +279,14 @@ public final class AnimatedStickerNode: ASDisplayNode {
|
||||
return SoftwareAnimationRenderer()
|
||||
})
|
||||
|
||||
private weak var nodeToCopyFrameFrom: AnimatedStickerNode?
|
||||
private weak var nodeToCopyFrameFrom: DefaultAnimatedStickerNodeImpl?
|
||||
override public func didLoad() {
|
||||
super.didLoad()
|
||||
|
||||
if #available(iOS 10.0, *), (self.useMetalCache/* || "".isEmpty*/) {
|
||||
self.renderer = AnimatedStickerNode.hardwareRendererPool.take()
|
||||
self.renderer = DefaultAnimatedStickerNodeImpl.hardwareRendererPool.take()
|
||||
} else {
|
||||
self.renderer = AnimatedStickerNode.softwareRendererPool.take()
|
||||
self.renderer = DefaultAnimatedStickerNodeImpl.softwareRendererPool.take()
|
||||
if let contents = self.nodeToCopyFrameFrom?.renderer?.renderer.contents {
|
||||
self.renderer?.renderer.contents = contents
|
||||
}
|
||||
@ -267,7 +301,12 @@ public final class AnimatedStickerNode: ASDisplayNode {
|
||||
}
|
||||
|
||||
public func cloneCurrentFrame(from otherNode: AnimatedStickerNode?) {
|
||||
if let renderer = self.renderer?.renderer as? SoftwareAnimationRenderer, let otherRenderer = otherNode?.renderer?.renderer as? SoftwareAnimationRenderer {
|
||||
guard let otherNode = otherNode as? DefaultAnimatedStickerNodeImpl else {
|
||||
self.nodeToCopyFrameFrom = nil
|
||||
return
|
||||
}
|
||||
|
||||
if let renderer = self.renderer?.renderer as? SoftwareAnimationRenderer, let otherRenderer = otherNode.renderer?.renderer as? SoftwareAnimationRenderer {
|
||||
if let contents = otherRenderer.contents {
|
||||
renderer.contents = contents
|
||||
}
|
||||
|
@ -250,7 +250,7 @@ final class CallListControllerNode: ASDisplayNode {
|
||||
self.emptyTextNode.textAlignment = .center
|
||||
self.emptyTextNode.maximumNumberOfLines = 3
|
||||
|
||||
self.emptyAnimationNode = AnimatedStickerNode()
|
||||
self.emptyAnimationNode = DefaultAnimatedStickerNodeImpl()
|
||||
self.emptyAnimationNode.alpha = 0.0
|
||||
self.emptyAnimationNode.isUserInteractionEnabled = false
|
||||
|
||||
|
@ -337,8 +337,8 @@ public final class ChatImportActivityScreen: ViewController {
|
||||
|
||||
self.presentationData = self.context.sharedContext.currentPresentationData.with { $0 }
|
||||
|
||||
self.animationNode = AnimatedStickerNode()
|
||||
self.doneAnimationNode = AnimatedStickerNode()
|
||||
self.animationNode = DefaultAnimatedStickerNodeImpl()
|
||||
self.doneAnimationNode = DefaultAnimatedStickerNodeImpl()
|
||||
self.doneAnimationNode.isHidden = true
|
||||
|
||||
self.radialStatus = RadialStatusNode(backgroundNodeColor: .clear)
|
||||
|
@ -84,7 +84,7 @@ class ChatListFilterSettingsHeaderItemNode: ListViewItemNode {
|
||||
self.titleNode.contentMode = .left
|
||||
self.titleNode.contentsScale = UIScreen.main.scale
|
||||
|
||||
self.animationNode = AnimatedStickerNode()
|
||||
self.animationNode = DefaultAnimatedStickerNodeImpl()
|
||||
|
||||
super.init(layerBacked: false, dynamicBounce: false)
|
||||
|
||||
@ -101,7 +101,7 @@ class ChatListFilterSettingsHeaderItemNode: ListViewItemNode {
|
||||
@objc private func animationTapGesture(_ recognizer: UITapGestureRecognizer) {
|
||||
if case .ended = recognizer.state {
|
||||
if !self.animationNode.isPlaying {
|
||||
self.animationNode.play()
|
||||
self.animationNode.play(firstFrame: false, fromIndex: nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ final class ChatListEmptyNode: ASDisplayNode {
|
||||
self.isFilter = isFilter
|
||||
self.isLoading = isLoading
|
||||
|
||||
self.animationNode = AnimatedStickerNode()
|
||||
self.animationNode = DefaultAnimatedStickerNodeImpl()
|
||||
|
||||
self.textNode = ImmediateTextNode()
|
||||
self.textNode.displaysAsynchronously = false
|
||||
@ -107,13 +107,13 @@ final class ChatListEmptyNode: ASDisplayNode {
|
||||
@objc private func animationTapGesture(_ recognizer: UITapGestureRecognizer) {
|
||||
if case .ended = recognizer.state {
|
||||
if !self.animationNode.isPlaying {
|
||||
self.animationNode.play()
|
||||
self.animationNode.play(firstFrame: false, fromIndex: nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func restartAnimation() {
|
||||
self.animationNode.play()
|
||||
self.animationNode.play(firstFrame: false, fromIndex: nil)
|
||||
}
|
||||
|
||||
func updateThemeAndStrings(theme: PresentationTheme, strings: PresentationStrings) {
|
||||
|
@ -1467,7 +1467,7 @@ final class ActionSheetAnimationAndTextItemNode: ActionSheetItemNode {
|
||||
self.theme = theme
|
||||
self.defaultFont = Font.regular(floor(theme.baseFontSize * 13.0 / 17.0))
|
||||
|
||||
self.animationNode = AnimatedStickerNode()
|
||||
self.animationNode = DefaultAnimatedStickerNodeImpl()
|
||||
self.animationNode.setup(source: AnimatedStickerNodeLocalFileSource(name: "ClearDownloadList"), width: 256, height: 256, playbackMode: .loop, mode: .direct(cachePathPrefix: nil))
|
||||
self.animationNode.visibility = true
|
||||
|
||||
|
@ -971,7 +971,7 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
|
||||
self.emptyResultsTextNode.textAlignment = .center
|
||||
self.emptyResultsTextNode.isHidden = true
|
||||
|
||||
self.emptyResultsAnimationNode = AnimatedStickerNode()
|
||||
self.emptyResultsAnimationNode = DefaultAnimatedStickerNodeImpl()
|
||||
self.emptyResultsAnimationNode.isHidden = true
|
||||
|
||||
super.init()
|
||||
|
@ -95,7 +95,7 @@ public final class AnimatedStickerComponent: Component {
|
||||
if self.component?.animation != component.animation {
|
||||
self.animationNode?.view.removeFromSuperview()
|
||||
|
||||
let animationNode = AnimatedStickerNode()
|
||||
let animationNode = DefaultAnimatedStickerNodeImpl()
|
||||
let source: AnimatedStickerNodeSource
|
||||
switch component.animation.source {
|
||||
case let .bundle(name):
|
||||
|
@ -261,7 +261,7 @@ public final class ContactsSearchContainerNode: SearchDisplayControllerContentNo
|
||||
self.emptyResultsTextNode.textAlignment = .center
|
||||
self.emptyResultsTextNode.isHidden = true
|
||||
|
||||
self.emptyResultsAnimationNode = AnimatedStickerNode()
|
||||
self.emptyResultsAnimationNode = DefaultAnimatedStickerNodeImpl()
|
||||
self.emptyResultsAnimationNode.isHidden = true
|
||||
|
||||
super.init()
|
||||
|
@ -123,7 +123,7 @@ final class StickerPackPreviewGridItemNode: GridItemNode {
|
||||
self.imageNode.isHidden = true
|
||||
|
||||
if isVerified {
|
||||
let animationNode = AnimatedStickerNode()
|
||||
let animationNode = DefaultAnimatedStickerNodeImpl()
|
||||
self.animationNode = animationNode
|
||||
|
||||
if let placeholderNode = self.placeholderNode {
|
||||
|
@ -75,7 +75,7 @@ private final class StickerPreviewPeekContentNode: ASDisplayNode, PeekController
|
||||
case let .image(data):
|
||||
self.imageNode.image = UIImage(data: data)
|
||||
case .animation, .video:
|
||||
let animationNode = AnimatedStickerNode()
|
||||
let animationNode = DefaultAnimatedStickerNodeImpl()
|
||||
self.animationNode = animationNode
|
||||
let dimensions = PixelDimensions(width: 512, height: 512)
|
||||
let fittedDimensions = dimensions.cgSize.aspectFitted(CGSize(width: 400.0, height: 400.0))
|
||||
@ -84,7 +84,7 @@ private final class StickerPreviewPeekContentNode: ASDisplayNode, PeekController
|
||||
if case .video = item.content {
|
||||
isVideo = true
|
||||
}
|
||||
self.animationNode?.setup(source: AnimatedStickerResourceSource(account: account, resource: resource, isVideo: isVideo), width: Int(fittedDimensions.width), height: Int(fittedDimensions.height), mode: .direct(cachePathPrefix: nil))
|
||||
self.animationNode?.setup(source: AnimatedStickerResourceSource(account: account, resource: resource, isVideo: isVideo), width: Int(fittedDimensions.width), height: Int(fittedDimensions.height), playbackMode: .loop, mode: .direct(cachePathPrefix: nil))
|
||||
}
|
||||
self.animationNode?.visibility = true
|
||||
}
|
||||
|
@ -80,7 +80,7 @@ class InviteLinkHeaderItemNode: ListViewItemNode {
|
||||
self.titleNode.contentMode = .left
|
||||
self.titleNode.contentsScale = UIScreen.main.scale
|
||||
|
||||
self.animationNode = AnimatedStickerNode()
|
||||
self.animationNode = DefaultAnimatedStickerNodeImpl()
|
||||
|
||||
super.init(layerBacked: false, dynamicBounce: false)
|
||||
|
||||
|
@ -58,7 +58,7 @@ final class InviteRequestsEmptyStateItemNode: ItemListControllerEmptyStateItemNo
|
||||
init(item: InviteRequestsEmptyStateItem) {
|
||||
self.item = item
|
||||
|
||||
self.animationNode = AnimatedStickerNode()
|
||||
self.animationNode = DefaultAnimatedStickerNodeImpl()
|
||||
self.animationNode.setup(source: AnimatedStickerNodeLocalFileSource(name: "TwoFactorSetupRememberSuccess"), width: 192, height: 192, playbackMode: .once, mode: .direct(cachePathPrefix: nil))
|
||||
self.animationNode.visibility = true
|
||||
|
||||
|
@ -761,14 +761,14 @@ class ItemListStickerPackItemNode: ItemListRevealOptionsItemNode {
|
||||
if let current = strongSelf.animationNode {
|
||||
animationNode = current
|
||||
} else {
|
||||
animationNode = AnimatedStickerNode()
|
||||
animationNode = DefaultAnimatedStickerNodeImpl()
|
||||
animationNode.started = { [weak self] in
|
||||
self?.removePlaceholder(animated: false)
|
||||
}
|
||||
strongSelf.animationNode = animationNode
|
||||
strongSelf.addSubnode(animationNode)
|
||||
|
||||
animationNode.setup(source: AnimatedStickerResourceSource(account: item.account, resource: resource, isVideo: isVideo), width: 80, height: 80, mode: .cached)
|
||||
animationNode.setup(source: AnimatedStickerResourceSource(account: item.account, resource: resource, isVideo: isVideo), width: 80, height: 80, playbackMode: .loop, mode: .cached)
|
||||
}
|
||||
animationNode.visibility = strongSelf.visibility != .none && item.playAnimatedStickers
|
||||
animationNode.isHidden = !item.playAnimatedStickers
|
||||
|
@ -62,7 +62,7 @@ class LegacyPaintStickerView: UIView, TGPhotoPaintStickerRenderView {
|
||||
if let dimensions = self.file.dimensions {
|
||||
if self.file.isAnimatedSticker || self.file.isVideoSticker {
|
||||
if self.animationNode == nil {
|
||||
let animationNode = AnimatedStickerNode()
|
||||
let animationNode = DefaultAnimatedStickerNodeImpl()
|
||||
animationNode.autoplay = false
|
||||
self.animationNode = animationNode
|
||||
animationNode.started = { [weak self, weak animationNode] in
|
||||
@ -115,7 +115,7 @@ class LegacyPaintStickerView: UIView, TGPhotoPaintStickerRenderView {
|
||||
let dimensions = self.file.dimensions ?? PixelDimensions(width: 512, height: 512)
|
||||
let fittedDimensions = dimensions.cgSize.aspectFitted(CGSize(width: 384.0, height: 384.0))
|
||||
let source = AnimatedStickerResourceSource(account: self.context.account, resource: self.file.resource, isVideo: self.file.isVideoSticker)
|
||||
self.animationNode?.setup(source: source, width: Int(fittedDimensions.width), height: Int(fittedDimensions.height), mode: .direct(cachePathPrefix: nil))
|
||||
self.animationNode?.setup(source: source, width: Int(fittedDimensions.width), height: Int(fittedDimensions.height), playbackMode: .loop, mode: .direct(cachePathPrefix: nil))
|
||||
|
||||
self.cachedDisposable.set((source.cachedDataPath(width: 384, height: 384)
|
||||
|> deliverOn(Queue.concurrentDefaultQueue())).start())
|
||||
@ -150,7 +150,7 @@ class LegacyPaintStickerView: UIView, TGPhotoPaintStickerRenderView {
|
||||
func play(fromFrame frameIndex: Int) {
|
||||
self.isVisible = true
|
||||
self.updateVisibility()
|
||||
self.animationNode?.play(fromIndex: frameIndex)
|
||||
self.animationNode?.play(firstFrame: false, fromIndex: frameIndex)
|
||||
}
|
||||
|
||||
func copyStickerView(_ view: TGPhotoPaintStickerRenderView!) {
|
||||
@ -158,7 +158,7 @@ class LegacyPaintStickerView: UIView, TGPhotoPaintStickerRenderView {
|
||||
return
|
||||
}
|
||||
self.animationNode?.cloneCurrentFrame(from: animationNode)
|
||||
self.animationNode?.play(fromIndex: animationNode.currentFrameIndex)
|
||||
self.animationNode?.play(firstFrame: false, fromIndex: animationNode.currentFrameIndex)
|
||||
self.updateVisibility()
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,7 @@ final class LocationPlaceholderNode: ASDisplayNode {
|
||||
playbackMode = .loop
|
||||
}
|
||||
|
||||
self.animationNode = AnimatedStickerNode()
|
||||
self.animationNode = DefaultAnimatedStickerNodeImpl()
|
||||
self.animationNode.setup(source: AnimatedStickerNodeLocalFileSource(name: name), width: 320, height: 320, playbackMode: playbackMode, mode: .direct(cachePathPrefix: nil))
|
||||
self.animationNode.visibility = true
|
||||
|
||||
|
@ -43,7 +43,7 @@ final class MediaPickerPlaceholderNode: ASDisplayNode {
|
||||
playbackMode = .once
|
||||
}
|
||||
|
||||
self.animationNode = AnimatedStickerNode()
|
||||
self.animationNode = DefaultAnimatedStickerNodeImpl()
|
||||
self.animationNode.setup(source: AnimatedStickerNodeLocalFileSource(name: name), width: 320, height: 320, playbackMode: playbackMode, mode: .direct(cachePathPrefix: nil))
|
||||
self.animationNode.visibility = true
|
||||
|
||||
|
@ -1269,17 +1269,17 @@ private final class TwoFactorDataInputScreenNode: ViewControllerTracingNode, UIS
|
||||
case .password, .passwordRecovery, .emailAddress, .updateEmailAddress:
|
||||
self.monkeyNode = ManagedMonkeyAnimationNode()
|
||||
case .emailConfirmation, .passwordRecoveryEmail:
|
||||
let animatedStickerNode = AnimatedStickerNode()
|
||||
let animatedStickerNode = DefaultAnimatedStickerNodeImpl()
|
||||
animatedStickerNode.setup(source: AnimatedStickerNodeLocalFileSource(name: "TwoFactorSetupMail"), width: 272, height: 272, playbackMode: .once, mode: .direct(cachePathPrefix: nil))
|
||||
animatedStickerNode.visibility = true
|
||||
self.animatedStickerNode = animatedStickerNode
|
||||
case .passwordHint:
|
||||
let animatedStickerNode = AnimatedStickerNode()
|
||||
let animatedStickerNode = DefaultAnimatedStickerNodeImpl()
|
||||
animatedStickerNode.setup(source: AnimatedStickerNodeLocalFileSource(name: "TwoFactorSetupHint"), width: 272, height: 272, playbackMode: .once, mode: .direct(cachePathPrefix: nil))
|
||||
animatedStickerNode.visibility = true
|
||||
self.animatedStickerNode = animatedStickerNode
|
||||
case .rememberPassword:
|
||||
let animatedStickerNode = AnimatedStickerNode()
|
||||
let animatedStickerNode = DefaultAnimatedStickerNodeImpl()
|
||||
animatedStickerNode.setup(source: AnimatedStickerNodeLocalFileSource(name: "TwoFactorSetupRemember"), width: 272, height: 272, playbackMode: .count(3), mode: .direct(cachePathPrefix: nil))
|
||||
animatedStickerNode.visibility = true
|
||||
self.animatedStickerNode = animatedStickerNode
|
||||
|
@ -155,7 +155,7 @@ private final class TwoFactorAuthSplashScreenNode: ViewControllerTracingNode {
|
||||
self.presentationData = presentationData
|
||||
self.mode = mode
|
||||
|
||||
self.animationNode = AnimatedStickerNode()
|
||||
self.animationNode = DefaultAnimatedStickerNodeImpl()
|
||||
|
||||
let title: String
|
||||
let texts: [NSAttributedString]
|
||||
@ -178,7 +178,7 @@ private final class TwoFactorAuthSplashScreenNode: ViewControllerTracingNode {
|
||||
texts = [NSAttributedString(string: self.presentationData.strings.TwoFactorSetup_Done_Text, font: textFont, textColor: textColor)]
|
||||
buttonText = doneText
|
||||
|
||||
self.animationNode.setup(source: AnimatedStickerNodeLocalFileSource(name: "TwoFactorSetupDone"), width: 248, height: 248, mode: .direct(cachePathPrefix: nil))
|
||||
self.animationNode.setup(source: AnimatedStickerNodeLocalFileSource(name: "TwoFactorSetupDone"), width: 248, height: 248, playbackMode: .loop, mode: .direct(cachePathPrefix: nil))
|
||||
self.animationSize = CGSize(width: 124.0, height: 124.0)
|
||||
self.animationNode.visibility = true
|
||||
case let .recoveryDone(_, _, isPasswordSet):
|
||||
@ -209,7 +209,7 @@ private final class TwoFactorAuthSplashScreenNode: ViewControllerTracingNode {
|
||||
texts = [NSAttributedString(string: self.presentationData.strings.TwoFactorRemember_Done_Text, font: textFont, textColor: textColor)]
|
||||
buttonText = self.presentationData.strings.TwoFactorRemember_Done_Action
|
||||
|
||||
self.animationNode.setup(source: AnimatedStickerNodeLocalFileSource(name: "TwoFactorSetupRememberSuccess"), width: 248, height: 248, mode: .direct(cachePathPrefix: nil))
|
||||
self.animationNode.setup(source: AnimatedStickerNodeLocalFileSource(name: "TwoFactorSetupRememberSuccess"), width: 248, height: 248, playbackMode: .loop, mode: .direct(cachePathPrefix: nil))
|
||||
self.animationSize = CGSize(width: 124.0, height: 124.0)
|
||||
self.animationNode.visibility = true
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ private final class ReportPeerHeaderActionSheetItemNode: ActionSheetItemNode {
|
||||
|
||||
let textFont = Font.regular(floor(theme.baseFontSize * 13.0 / 17.0))
|
||||
|
||||
self.animationNode = AnimatedStickerNode()
|
||||
self.animationNode = DefaultAnimatedStickerNodeImpl()
|
||||
self.animationNode.setup(source: AnimatedStickerNodeLocalFileSource(name: "Cop"), width: 192, height: 192, playbackMode: .count(2), mode: .direct(cachePathPrefix: nil))
|
||||
self.animationNode.visibility = true
|
||||
|
||||
|
@ -74,7 +74,7 @@ class PeersNearbyHeaderItemNode: ListViewItemNode {
|
||||
self.titleNode.contentMode = .left
|
||||
self.titleNode.contentsScale = UIScreen.main.scale
|
||||
|
||||
self.animationNode = AnimatedStickerNode()
|
||||
self.animationNode = DefaultAnimatedStickerNodeImpl()
|
||||
|
||||
super.init(layerBacked: false, dynamicBounce: false)
|
||||
|
||||
|
@ -104,7 +104,7 @@ private class StickerNode: ASDisplayNode {
|
||||
self.imageNode = TransformImageNode()
|
||||
|
||||
if file.isPremiumSticker || forceIsPremium {
|
||||
let animationNode = AnimatedStickerNode()
|
||||
let animationNode = DefaultAnimatedStickerNodeImpl()
|
||||
animationNode.automaticallyLoadFirstFrame = true
|
||||
self.animationNode = animationNode
|
||||
|
||||
@ -122,7 +122,7 @@ private class StickerNode: ASDisplayNode {
|
||||
self.effectDisposable.set(freeMediaFileResourceInteractiveFetched(account: self.context.account, fileReference: .standalone(media: file), resource: effect.resource).start())
|
||||
|
||||
let source = AnimatedStickerResourceSource(account: self.context.account, resource: effect.resource, fitzModifier: nil)
|
||||
let additionalAnimationNode = AnimatedStickerNode()
|
||||
let additionalAnimationNode = DefaultAnimatedStickerNodeImpl()
|
||||
|
||||
var pathPrefix: String?
|
||||
pathPrefix = context.account.postbox.mediaBox.shortLivedResourceCachePathPrefix(effect.resource.id)
|
||||
@ -232,7 +232,7 @@ private class StickerNode: ASDisplayNode {
|
||||
} else if isVisible {
|
||||
additionalAnimationNode.visibility = isVisible
|
||||
if !wasVisible {
|
||||
additionalAnimationNode.play(fromIndex: 0)
|
||||
additionalAnimationNode.play(firstFrame: false, fromIndex: 0)
|
||||
Queue.mainQueue().after(0.05, {
|
||||
additionalAnimationNode.alpha = 1.0
|
||||
})
|
||||
|
@ -255,8 +255,8 @@ public final class QrCodeScreen: ViewController {
|
||||
self.qrImageNode.clipsToBounds = true
|
||||
self.qrImageNode.cornerRadius = 16.0
|
||||
|
||||
self.qrIconNode = AnimatedStickerNode()
|
||||
self.qrIconNode.setup(source: AnimatedStickerNodeLocalFileSource(name: "PlaneLogo"), width: 240, height: 240, mode: .direct(cachePathPrefix: nil))
|
||||
self.qrIconNode = DefaultAnimatedStickerNodeImpl()
|
||||
self.qrIconNode.setup(source: AnimatedStickerNodeLocalFileSource(name: "PlaneLogo"), width: 240, height: 240, playbackMode: .loop, mode: .direct(cachePathPrefix: nil))
|
||||
self.qrIconNode.visibility = true
|
||||
|
||||
super.init()
|
||||
|
@ -656,7 +656,7 @@ public final class ReactionContextNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
transition.updateBounds(node: itemNode, bounds: CGRect(origin: CGPoint(), size: expandedFrame.size))
|
||||
itemNode.updateLayout(size: expandedFrame.size, isExpanded: true, largeExpanded: self.didTriggerExpandedReaction, isPreviewing: false, transition: transition)
|
||||
|
||||
let additionalAnimationNode = AnimatedStickerNode()
|
||||
let additionalAnimationNode = DefaultAnimatedStickerNodeImpl()
|
||||
|
||||
let additionalAnimation: TelegramMediaFile
|
||||
if self.didTriggerExpandedReaction {
|
||||
@ -1064,7 +1064,7 @@ public final class StandaloneReactionAnimation: ASDisplayNode {
|
||||
|
||||
itemNode.updateLayout(size: expandedFrame.size, isExpanded: true, largeExpanded: isLarge, isPreviewing: false, transition: .immediate)
|
||||
|
||||
let additionalAnimationNode = AnimatedStickerNode()
|
||||
let additionalAnimationNode = DefaultAnimatedStickerNodeImpl()
|
||||
|
||||
let additionalAnimation: TelegramMediaFile
|
||||
if isLarge && !forceSmallEffectAnimation {
|
||||
|
@ -72,11 +72,11 @@ public final class ReactionNode: ASDisplayNode, ReactionItemNode {
|
||||
self.item = item
|
||||
self.hasAppearAnimation = hasAppearAnimation
|
||||
|
||||
self.staticAnimationNode = AnimatedStickerNode()
|
||||
self.staticAnimationNode = DefaultAnimatedStickerNodeImpl()
|
||||
|
||||
if hasAppearAnimation {
|
||||
self.staticAnimationNode.isHidden = true
|
||||
self.animateInAnimationNode = AnimatedStickerNode()
|
||||
self.animateInAnimationNode = DefaultAnimatedStickerNodeImpl()
|
||||
}
|
||||
|
||||
super.init()
|
||||
@ -144,9 +144,9 @@ public final class ReactionNode: ASDisplayNode, ReactionItemNode {
|
||||
self.staticAnimationNode.completed = { [weak self] _ in
|
||||
self?.mainAnimationCompletion?()
|
||||
}
|
||||
self.staticAnimationNode.play(fromIndex: 0)
|
||||
self.staticAnimationNode.play(firstFrame: false, fromIndex: 0)
|
||||
} else if isExpanded, self.animationNode == nil {
|
||||
let animationNode = AnimatedStickerNode()
|
||||
let animationNode = DefaultAnimatedStickerNodeImpl()
|
||||
animationNode.automaticallyLoadFirstFrame = true
|
||||
self.animationNode = animationNode
|
||||
self.addSubnode(animationNode)
|
||||
@ -235,7 +235,7 @@ public final class ReactionNode: ASDisplayNode, ReactionItemNode {
|
||||
if self.animationNode == nil {
|
||||
if isPreviewing {
|
||||
if self.stillAnimationNode == nil {
|
||||
let stillAnimationNode = AnimatedStickerNode()
|
||||
let stillAnimationNode = DefaultAnimatedStickerNodeImpl()
|
||||
self.stillAnimationNode = stillAnimationNode
|
||||
self.addSubnode(stillAnimationNode)
|
||||
|
||||
|
@ -1015,7 +1015,7 @@ private class StorageUsageClearProgressOverlayNode: ASDisplayNode, ActionSheetGr
|
||||
init(presentationData: PresentationData) {
|
||||
self.presentationData = presentationData
|
||||
|
||||
self.animationNode = AnimatedStickerNode()
|
||||
self.animationNode = DefaultAnimatedStickerNodeImpl()
|
||||
self.animationNode.setup(source: AnimatedStickerNodeLocalFileSource(name: "ClearCache"), width: 256, height: 256, playbackMode: .loop, mode: .direct(cachePathPrefix: nil))
|
||||
self.animationNode.visibility = true
|
||||
|
||||
|
@ -58,7 +58,7 @@ final class PrivacyIntroControllerNode: ViewControllerTracingNode {
|
||||
self.proceedAction = proceedAction
|
||||
|
||||
self.iconNode = ASImageNode()
|
||||
self.animationNode = AnimatedStickerNode()
|
||||
self.animationNode = DefaultAnimatedStickerNodeImpl()
|
||||
|
||||
self.titleNode = ASTextNode()
|
||||
self.textNode = ASTextNode()
|
||||
|
@ -84,7 +84,7 @@ class RecentSessionsHeaderItemNode: ListViewItemNode {
|
||||
self.titleNode.contentMode = .left
|
||||
self.titleNode.contentsScale = UIScreen.main.scale
|
||||
|
||||
self.animationNode = AnimatedStickerNode()
|
||||
self.animationNode = DefaultAnimatedStickerNodeImpl()
|
||||
|
||||
self.buttonNode = SolidRoundedButtonNode(theme: SolidRoundedButtonTheme(backgroundColor: .black, foregroundColor: .white), fontSize: 16.0, height: 50.0, cornerRadius: 11.0)
|
||||
|
||||
@ -143,7 +143,7 @@ class RecentSessionsHeaderItemNode: ListViewItemNode {
|
||||
strongSelf.animationNode.setup(source: AnimatedStickerNodeLocalFileSource(name: item.animationName), width: 256, height: 256, playbackMode: .still(.start), mode: .direct(cachePathPrefix: nil))
|
||||
strongSelf.animationNode.visibility = true
|
||||
Queue.mainQueue().after(0.3) {
|
||||
strongSelf.animationNode.play()
|
||||
strongSelf.animationNode.play(firstFrame: false, fromIndex: nil)
|
||||
}
|
||||
}
|
||||
strongSelf.item = item
|
||||
|
@ -134,6 +134,14 @@ class ReactionChatPreviewItemNode: ListViewItemNode {
|
||||
}
|
||||
}
|
||||
|
||||
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
|
||||
if self.bounds.contains(point) {
|
||||
return self.view
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
private func beginReactionAnimation() {
|
||||
if let item = self.item, let updatedReaction = item.reaction, let availableReactions = item.availableReactions, let messageNode = self.messageNode as? ChatMessageItemNodeProtocol {
|
||||
if let targetView = messageNode.targetReactionView(value: updatedReaction) {
|
||||
|
@ -302,7 +302,7 @@ private final class ThemeCarouselThemeItemIconNode : ListViewItemNode {
|
||||
Queue.mainQueue().after(0.1) {
|
||||
if !wasSelected {
|
||||
animatedStickerNode.seekTo(.frameIndex(0))
|
||||
animatedStickerNode.play()
|
||||
animatedStickerNode.play(firstFrame: false, fromIndex: nil)
|
||||
|
||||
let scale: CGFloat = 2.6
|
||||
animatedStickerNode.transform = CATransform3DMakeScale(scale, scale, 1.0)
|
||||
@ -417,7 +417,7 @@ private final class ThemeCarouselThemeItemIconNode : ListViewItemNode {
|
||||
if let current = strongSelf.animatedStickerNode {
|
||||
animatedStickerNode = current
|
||||
} else {
|
||||
animatedStickerNode = AnimatedStickerNode()
|
||||
animatedStickerNode = DefaultAnimatedStickerNodeImpl()
|
||||
animatedStickerNode.started = { [weak self] in
|
||||
self?.emojiImageNode.isHidden = true
|
||||
}
|
||||
|
@ -258,7 +258,7 @@ private final class ThemeGridThemeItemIconNode : ASDisplayNode {
|
||||
if let current = self.animatedStickerNode {
|
||||
animatedStickerNode = current
|
||||
} else {
|
||||
animatedStickerNode = AnimatedStickerNode()
|
||||
animatedStickerNode = DefaultAnimatedStickerNodeImpl()
|
||||
animatedStickerNode.started = { [weak self] in
|
||||
self?.emojiImageNode.isHidden = true
|
||||
}
|
||||
|
@ -212,11 +212,11 @@ public final class ShareProlongedLoadingContainerNode: ASDisplayNode, ShareConte
|
||||
self.theme = theme
|
||||
self.strings = strings
|
||||
|
||||
self.animationNode = AnimatedStickerNode()
|
||||
self.animationNode = DefaultAnimatedStickerNodeImpl()
|
||||
self.animationNode.setup(source: AnimatedStickerNodeLocalFileSource(name: "ShareProgress"), width: 384, height: 384, playbackMode: .loop, mode: .direct(cachePathPrefix: nil))
|
||||
self.animationNode.visibility = true
|
||||
|
||||
self.doneAnimationNode = AnimatedStickerNode()
|
||||
self.doneAnimationNode = DefaultAnimatedStickerNodeImpl()
|
||||
self.doneAnimationNode.setup(source: AnimatedStickerNodeLocalFileSource(name: "ShareDone"), width: 384, height: 384, playbackMode: .once, mode: .direct(cachePathPrefix: nil))
|
||||
self.doneAnimationNode.visibility = false
|
||||
self.doneAnimationNode.isHidden = true
|
||||
|
@ -264,7 +264,7 @@ class DiceAnimatedStickerNode: ASDisplayNode {
|
||||
self.account = account
|
||||
self.intrinsicSize = size
|
||||
|
||||
self.animationNode = AnimatedStickerNode()
|
||||
self.animationNode = DefaultAnimatedStickerNodeImpl()
|
||||
self.animationNode.autoplay = true
|
||||
|
||||
super.init()
|
||||
|
@ -56,7 +56,7 @@ final class StatsEmptyStateItemNode: ItemListControllerEmptyStateItemNode {
|
||||
init(item: StatsEmptyStateItem) {
|
||||
self.item = item
|
||||
|
||||
self.animationNode = AnimatedStickerNode()
|
||||
self.animationNode = DefaultAnimatedStickerNodeImpl()
|
||||
self.animationNode.setup(source: AnimatedStickerNodeLocalFileSource(name: "Charts"), width: 192, height: 192, playbackMode: .loop, mode: .direct(cachePathPrefix: nil))
|
||||
self.animationNode.visibility = true
|
||||
|
||||
|
@ -223,7 +223,7 @@ final class StickerPackPreviewGridItemNode: GridItemNode {
|
||||
}
|
||||
|
||||
if self.animationNode == nil {
|
||||
let animationNode = AnimatedStickerNode()
|
||||
let animationNode = DefaultAnimatedStickerNodeImpl()
|
||||
self.animationNode = animationNode
|
||||
self.insertSubnode(animationNode, aboveSubnode: self.imageNode)
|
||||
animationNode.started = { [weak self] in
|
||||
@ -243,7 +243,7 @@ final class StickerPackPreviewGridItemNode: GridItemNode {
|
||||
}
|
||||
}
|
||||
let fittedDimensions = dimensions.cgSize.aspectFitted(CGSize(width: 160.0, height: 160.0))
|
||||
self.animationNode?.setup(source: AnimatedStickerResourceSource(account: account, resource: stickerItem.file.resource, isVideo: stickerItem.file.isVideoSticker), width: Int(fittedDimensions.width), height: Int(fittedDimensions.height), mode: .cached)
|
||||
self.animationNode?.setup(source: AnimatedStickerResourceSource(account: account, resource: stickerItem.file.resource, isVideo: stickerItem.file.isVideoSticker), width: Int(fittedDimensions.width), height: Int(fittedDimensions.height), playbackMode: .loop, mode: .cached)
|
||||
|
||||
self.animationNode?.visibility = visibility
|
||||
|
||||
|
@ -116,7 +116,7 @@ public final class StickerPreviewPeekContentNode: ASDisplayNode, PeekControllerC
|
||||
let isPremiumSticker = item.file.isPremiumSticker
|
||||
|
||||
if item.file.isAnimatedSticker || item.file.isVideoSticker {
|
||||
let animationNode = AnimatedStickerNode()
|
||||
let animationNode = DefaultAnimatedStickerNodeImpl()
|
||||
self.animationNode = animationNode
|
||||
|
||||
let dimensions = item.file.dimensions ?? PixelDimensions(width: 512, height: 512)
|
||||
@ -130,7 +130,7 @@ public final class StickerPreviewPeekContentNode: ASDisplayNode, PeekControllerC
|
||||
self.effectDisposable.set(freeMediaFileResourceInteractiveFetched(account: account, fileReference: .standalone(media: item.file), resource: effect.resource).start())
|
||||
|
||||
let source = AnimatedStickerResourceSource(account: account, resource: effect.resource, fitzModifier: nil)
|
||||
let additionalAnimationNode = AnimatedStickerNode()
|
||||
let additionalAnimationNode = DefaultAnimatedStickerNodeImpl()
|
||||
additionalAnimationNode.setup(source: source, width: Int(fittedDimensions.width * 2.0), height: Int(fittedDimensions.height * 2.0), playbackMode: .once, mode: .direct(cachePathPrefix: nil))
|
||||
additionalAnimationNode.visibility = true
|
||||
self.additionalAnimationNode = additionalAnimationNode
|
||||
@ -153,8 +153,8 @@ public final class StickerPreviewPeekContentNode: ASDisplayNode, PeekControllerC
|
||||
animationNode.completed = { [weak self] _ in
|
||||
if let strongSelf = self, let animationNode = strongSelf.animationNode, let additionalAnimationNode = strongSelf.additionalAnimationNode {
|
||||
Queue.mainQueue().async {
|
||||
animationNode.play()
|
||||
additionalAnimationNode.play()
|
||||
animationNode.play(firstFrame: false, fromIndex: nil)
|
||||
additionalAnimationNode.play(firstFrame: false, fromIndex: nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -125,7 +125,7 @@ private final class TabBarItemNode: ASDisplayNode {
|
||||
|
||||
self.animationContainerNode = ASDisplayNode()
|
||||
|
||||
self.animationNode = AnimatedStickerNode()
|
||||
self.animationNode = DefaultAnimatedStickerNodeImpl()
|
||||
self.animationNode.autoplay = true
|
||||
self.animationNode.automaticallyLoadLastFrame = true
|
||||
|
||||
@ -788,7 +788,7 @@ class TabBarNode: ASDisplayNode {
|
||||
self.itemSelected(closestNode.0, longTap, [container.imageNode.imageNode, container.imageNode.textImageNode, container.badgeContainerNode])
|
||||
if previousSelectedIndex != closestNode.0 {
|
||||
if let selectedIndex = self.selectedIndex, let _ = self.tabBarItems[selectedIndex].item.animationName {
|
||||
container.imageNode.animationNode.play()
|
||||
container.imageNode.animationNode.play(firstFrame: false, fromIndex: nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -72,7 +72,7 @@ public final class PermissionContentNode: ASDisplayNode {
|
||||
self.iconNode.displaysAsynchronously = false
|
||||
|
||||
if case let .animation(animation) = icon {
|
||||
self.animationNode = AnimatedStickerNode()
|
||||
self.animationNode = DefaultAnimatedStickerNodeImpl()
|
||||
|
||||
self.animationNode?.setup(source: AnimatedStickerNodeLocalFileSource(name: animation), width: 320, height: 320, playbackMode: .once, mode: .direct(cachePathPrefix: nil))
|
||||
self.animationNode?.visibility = true
|
||||
|
@ -62,7 +62,7 @@ final class AttachmentFileEmptyStateItemNode: ItemListControllerEmptyStateItemNo
|
||||
init(item: AttachmentFileEmptyStateItem) {
|
||||
self.item = item
|
||||
|
||||
self.animationNode = AnimatedStickerNode()
|
||||
self.animationNode = DefaultAnimatedStickerNodeImpl()
|
||||
self.animationNode.setup(source: AnimatedStickerNodeLocalFileSource(name: "Files"), width: 320, height: 320, playbackMode: .loop, mode: .direct(cachePathPrefix: nil))
|
||||
self.animationNode.visibility = true
|
||||
|
||||
|
@ -243,10 +243,10 @@ final class ChatMediaInputMetaSectionItemNode: ListViewItemNode {
|
||||
if let current = self.animatedStickerNode {
|
||||
animatedStickerNode = current
|
||||
} else {
|
||||
animatedStickerNode = AnimatedStickerNode()
|
||||
animatedStickerNode = DefaultAnimatedStickerNodeImpl()
|
||||
self.animatedStickerNode = animatedStickerNode
|
||||
self.scalingNode.addSubnode(animatedStickerNode)
|
||||
animatedStickerNode.setup(source: AnimatedStickerResourceSource(account: account, resource: file.resource), width: 128, height: 128, mode: .cached)
|
||||
animatedStickerNode.setup(source: AnimatedStickerResourceSource(account: account, resource: file.resource), width: 128, height: 128, playbackMode: .loop, mode: .cached)
|
||||
}
|
||||
animatedStickerNode.visibility = self.visibilityStatus && loopAnimatedStickers
|
||||
|
||||
|
@ -275,7 +275,7 @@ final class ChatMediaInputStickerGridItemNode: GridItemNode {
|
||||
if let dimensions = item.stickerItem.file.dimensions {
|
||||
if item.stickerItem.file.isAnimatedSticker || item.stickerItem.file.isVideoSticker {
|
||||
if self.animationNode == nil {
|
||||
let animationNode = AnimatedStickerNode()
|
||||
let animationNode = DefaultAnimatedStickerNodeImpl()
|
||||
animationNode.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.imageNodeTap(_:))))
|
||||
self.animationNode = animationNode
|
||||
animationNode.started = { [weak self] in
|
||||
@ -445,7 +445,7 @@ final class ChatMediaInputStickerGridItemNode: GridItemNode {
|
||||
let dimensions = item.stickerItem.file.dimensions ?? PixelDimensions(width: 512, height: 512)
|
||||
let fitSize = item.large ? CGSize(width: 384.0, height: 384.0) : CGSize(width: 160.0, height: 160.0)
|
||||
let fittedDimensions = dimensions.cgSize.aspectFitted(fitSize)
|
||||
animationNode.setup(source: AnimatedStickerResourceSource(account: item.account, resource: item.stickerItem.file.resource, isVideo: item.stickerItem.file.isVideoSticker), width: Int(fittedDimensions.width), height: Int(fittedDimensions.height), mode: .cached)
|
||||
animationNode.setup(source: AnimatedStickerResourceSource(account: item.account, resource: item.stickerItem.file.resource, isVideo: item.stickerItem.file.isVideoSticker), width: Int(fittedDimensions.width), height: Int(fittedDimensions.height), playbackMode: .loop, mode: .cached)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -233,7 +233,7 @@ final class ChatMediaInputStickerPackItemNode: ListViewItemNode {
|
||||
if let current = self.animatedStickerNode {
|
||||
animatedStickerNode = current
|
||||
} else {
|
||||
animatedStickerNode = AnimatedStickerNode()
|
||||
animatedStickerNode = DefaultAnimatedStickerNodeImpl()
|
||||
animatedStickerNode.started = { [weak self] in
|
||||
self?.imageNode.isHidden = true
|
||||
self?.removePlaceholder(animated: false)
|
||||
@ -244,7 +244,7 @@ final class ChatMediaInputStickerPackItemNode: ListViewItemNode {
|
||||
} else {
|
||||
self.scalingNode.addSubnode(animatedStickerNode)
|
||||
}
|
||||
animatedStickerNode.setup(source: AnimatedStickerResourceSource(account: account, resource: resource, isVideo: isVideo), width: 128, height: 128, mode: .cached)
|
||||
animatedStickerNode.setup(source: AnimatedStickerResourceSource(account: account, resource: resource, isVideo: isVideo), width: 128, height: 128, playbackMode: .loop, mode: .cached)
|
||||
}
|
||||
animatedStickerNode.visibility = self.visibilityStatus && loopAnimatedStickers
|
||||
}
|
||||
@ -367,7 +367,7 @@ final class ChatMediaInputStickerPackItemNode: ListViewItemNode {
|
||||
case let .animated(resource, dimensions, isVideo):
|
||||
imageSize = dimensions.cgSize.aspectFitted(boundingImageSize)
|
||||
|
||||
let animatedStickerNode = AnimatedStickerNode()
|
||||
let animatedStickerNode = DefaultAnimatedStickerNodeImpl()
|
||||
animatedStickerNode.setup(source: AnimatedStickerResourceSource(account: account, resource: resource, isVideo: isVideo), width: 128, height: 128, mode: .cached)
|
||||
animatedStickerNode.visibility = self.visibilityStatus && loopAnimatedStickers
|
||||
scalingNode.addSubnode(animatedStickerNode)
|
||||
|
@ -39,7 +39,7 @@ protocol GenericAnimatedStickerNode: ASDisplayNode {
|
||||
func setFrameIndex(_ frameIndex: Int)
|
||||
}
|
||||
|
||||
extension AnimatedStickerNode: GenericAnimatedStickerNode {
|
||||
extension DefaultAnimatedStickerNodeImpl: GenericAnimatedStickerNode {
|
||||
func setFrameIndex(_ frameIndex: Int) {
|
||||
self.stop()
|
||||
self.play(fromIndex: frameIndex)
|
||||
@ -440,7 +440,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
||||
self.animationNode = animationNode
|
||||
}
|
||||
} else {
|
||||
let animationNode = AnimatedStickerNode(useMetalCache: item.context.sharedContext.immediateExperimentalUISettings.acceleratedStickers)
|
||||
let animationNode = DefaultAnimatedStickerNodeImpl(useMetalCache: item.context.sharedContext.immediateExperimentalUISettings.acceleratedStickers)
|
||||
animationNode.started = { [weak self] in
|
||||
if let strongSelf = self {
|
||||
strongSelf.imageNode.alpha = 0.0
|
||||
@ -1684,7 +1684,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
||||
}
|
||||
} else {
|
||||
let pathPrefix = item.context.account.postbox.mediaBox.shortLivedResourceCachePathPrefix(resource.id)
|
||||
let additionalAnimationNode = AnimatedStickerNode()
|
||||
let additionalAnimationNode = DefaultAnimatedStickerNodeImpl()
|
||||
additionalAnimationNode.setup(source: source, width: Int(animationSize.width * 1.6), height: Int(animationSize.height * 1.6), playbackMode: .once, mode: .direct(cachePathPrefix: pathPrefix))
|
||||
var animationFrame: CGRect
|
||||
if isStickerEffect {
|
||||
@ -1941,7 +1941,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
||||
|
||||
switch status.status {
|
||||
case .playing:
|
||||
animationNode?.play()
|
||||
animationNode?.play(firstFrame: false, fromIndex: nil)
|
||||
strongSelf.mediaStatusDisposable.set(nil)
|
||||
default:
|
||||
break
|
||||
@ -1955,7 +1955,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
||||
if let haptic = haptic, !haptic.active {
|
||||
haptic.start(time: 0.0)
|
||||
}
|
||||
animationNode?.play()
|
||||
animationNode?.play(firstFrame: false, fromIndex: nil)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -981,7 +981,7 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
|
||||
}
|
||||
|
||||
if currentReplaceAnimatedStickerNode, let updatedAnimatedStickerFile = updateAnimatedStickerFile {
|
||||
let animatedStickerNode = AnimatedStickerNode()
|
||||
let animatedStickerNode = DefaultAnimatedStickerNodeImpl()
|
||||
animatedStickerNode.isUserInteractionEnabled = false
|
||||
animatedStickerNode.started = {
|
||||
guard let strongSelf = self else {
|
||||
|
@ -112,11 +112,11 @@ public final class ChatMessageTransitionNode: ASDisplayNode {
|
||||
|
||||
final class Sticker {
|
||||
let imageNode: TransformImageNode
|
||||
let animationNode: GenericAnimatedStickerNode?
|
||||
let animationNode: AnimatedStickerNode?
|
||||
let placeholderNode: ASDisplayNode?
|
||||
let relativeSourceRect: CGRect
|
||||
|
||||
init(imageNode: TransformImageNode, animationNode: GenericAnimatedStickerNode?, placeholderNode: ASDisplayNode?, relativeSourceRect: CGRect) {
|
||||
init(imageNode: TransformImageNode, animationNode: AnimatedStickerNode?, placeholderNode: ASDisplayNode?, relativeSourceRect: CGRect) {
|
||||
self.imageNode = imageNode
|
||||
self.animationNode = animationNode
|
||||
self.placeholderNode = placeholderNode
|
||||
|
@ -381,7 +381,7 @@ private final class ThemeSettingsThemeItemIconNode : ListViewItemNode {
|
||||
Queue.mainQueue().after(0.1) {
|
||||
if !wasSelected {
|
||||
animatedStickerNode.seekTo(.frameIndex(0))
|
||||
animatedStickerNode.play()
|
||||
animatedStickerNode.play(firstFrame: false, fromIndex: nil)
|
||||
|
||||
let scale: CGFloat = 1.95
|
||||
animatedStickerNode.transform = CATransform3DMakeScale(scale, scale, 1.0)
|
||||
@ -498,7 +498,7 @@ private final class ThemeSettingsThemeItemIconNode : ListViewItemNode {
|
||||
if let current = strongSelf.animatedStickerNode {
|
||||
animatedStickerNode = current
|
||||
} else {
|
||||
animatedStickerNode = AnimatedStickerNode()
|
||||
animatedStickerNode = DefaultAnimatedStickerNodeImpl()
|
||||
animatedStickerNode.started = { [weak self] in
|
||||
self?.emojiImageNode.isHidden = true
|
||||
}
|
||||
@ -1499,7 +1499,7 @@ private class QrContentNode: ASDisplayNode, ContentNode {
|
||||
self.codeStaticIconNode = codeStaticIconNode
|
||||
self.codeAnimatedIconNode = nil
|
||||
} else {
|
||||
let codeAnimatedIconNode = AnimatedStickerNode()
|
||||
let codeAnimatedIconNode = DefaultAnimatedStickerNodeImpl()
|
||||
codeAnimatedIconNode.setup(source: AnimatedStickerNodeLocalFileSource(name: "PlaneLogoPlain"), width: 120, height: 120, mode: .direct(cachePathPrefix: nil))
|
||||
codeAnimatedIconNode.visibility = true
|
||||
self.codeAnimatedIconNode = codeAnimatedIconNode
|
||||
|
@ -362,7 +362,7 @@ private final class ThemeSettingsThemeItemIconNode : ListViewItemNode {
|
||||
Queue.mainQueue().after(0.1) {
|
||||
if !wasSelected {
|
||||
animatedStickerNode.seekTo(.frameIndex(0))
|
||||
animatedStickerNode.play()
|
||||
animatedStickerNode.play(firstFrame: false, fromIndex: nil)
|
||||
|
||||
let scale: CGFloat = 2.6
|
||||
animatedStickerNode.transform = CATransform3DMakeScale(scale, scale, 1.0)
|
||||
@ -479,7 +479,7 @@ private final class ThemeSettingsThemeItemIconNode : ListViewItemNode {
|
||||
if let current = strongSelf.animatedStickerNode {
|
||||
animatedStickerNode = current
|
||||
} else {
|
||||
animatedStickerNode = AnimatedStickerNode()
|
||||
animatedStickerNode = DefaultAnimatedStickerNodeImpl()
|
||||
animatedStickerNode.started = { [weak self] in
|
||||
self?.emojiImageNode.isHidden = true
|
||||
}
|
||||
|
@ -421,7 +421,7 @@ final class HorizontalListContextResultsChatInputPanelItemNode: ListViewItemNode
|
||||
if let currentAnimationNode = strongSelf.animationNode {
|
||||
animationNode = currentAnimationNode
|
||||
} else {
|
||||
animationNode = AnimatedStickerNode()
|
||||
animationNode = DefaultAnimatedStickerNodeImpl()
|
||||
animationNode.transform = CATransform3DMakeRotation(CGFloat.pi / 2.0, 0.0, 0.0, 1.0)
|
||||
animationNode.visibility = true
|
||||
if let placeholderNode = strongSelf.placeholderNode {
|
||||
@ -437,7 +437,7 @@ final class HorizontalListContextResultsChatInputPanelItemNode: ListViewItemNode
|
||||
let dimensions = animatedStickerFile.dimensions ?? PixelDimensions(width: 512, height: 512)
|
||||
let fittedDimensions = dimensions.cgSize.aspectFitted(CGSize(width: 160.0, height: 160.0))
|
||||
strongSelf.fetchDisposable.set(freeMediaFileResourceInteractiveFetched(account: item.account, fileReference: stickerPackFileReference(animatedStickerFile), resource: animatedStickerFile.resource).start())
|
||||
animationNode.setup(source: AnimatedStickerResourceSource(account: item.account, resource: animatedStickerFile.resource, isVideo: animatedStickerFile.isVideoSticker), width: Int(fittedDimensions.width), height: Int(fittedDimensions.height), mode: .cached)
|
||||
animationNode.setup(source: AnimatedStickerResourceSource(account: item.account, resource: animatedStickerFile.resource, isVideo: animatedStickerFile.isVideoSticker), width: Int(fittedDimensions.width), height: Int(fittedDimensions.height), playbackMode: .loop, mode: .cached)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -142,7 +142,7 @@ final class HorizontalStickerGridItemNode: GridItemNode {
|
||||
if let currentAnimationNode = self.animationNode {
|
||||
animationNode = currentAnimationNode
|
||||
} else {
|
||||
animationNode = AnimatedStickerNode()
|
||||
animationNode = DefaultAnimatedStickerNodeImpl()
|
||||
animationNode.transform = self.imageNode.transform
|
||||
animationNode.visibility = self.isVisibleInGrid
|
||||
animationNode.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.imageNodeTap(_:))))
|
||||
@ -178,7 +178,7 @@ final class HorizontalStickerGridItemNode: GridItemNode {
|
||||
strongSelf.removePlaceholder(animated: false)
|
||||
}
|
||||
}
|
||||
animationNode.setup(source: AnimatedStickerResourceSource(account: account, resource: item.file.resource, isVideo: item.file.isVideoSticker), width: Int(fittedDimensions.width), height: Int(fittedDimensions.height), mode: .cached)
|
||||
animationNode.setup(source: AnimatedStickerResourceSource(account: account, resource: item.file.resource, isVideo: item.file.isVideoSticker), width: Int(fittedDimensions.width), height: Int(fittedDimensions.height), playbackMode: .loop, mode: .cached)
|
||||
|
||||
self.stickerFetchedDisposable.set(freeMediaFileResourceInteractiveFetched(account: account, fileReference: stickerPackFileReference(item.file), resource: item.file.resource).start())
|
||||
} else {
|
||||
|
@ -63,7 +63,7 @@ private final class LargeEmojiActionSheetItemNode: ActionSheetItemNode {
|
||||
if let fitz = fitz {
|
||||
fitzModifier = EmojiFitzModifier(emoji: fitz)
|
||||
}
|
||||
self.animationNode = AnimatedStickerNode()
|
||||
self.animationNode = DefaultAnimatedStickerNodeImpl()
|
||||
self.animationNode.setup(source: AnimatedStickerResourceSource(account: context.account, resource: file.resource, fitzModifier: fitzModifier), width: 192, height: 192, playbackMode: .once, mode: .direct(cachePathPrefix: nil))
|
||||
self.animationNode.visibility = true
|
||||
|
||||
|
@ -120,7 +120,7 @@ final class TrendingTopItemNode: ASDisplayNode {
|
||||
if let currentAnimationNode = self.animationNode {
|
||||
animationNode = currentAnimationNode
|
||||
} else {
|
||||
animationNode = AnimatedStickerNode()
|
||||
animationNode = DefaultAnimatedStickerNodeImpl()
|
||||
animationNode.transform = self.imageNode.transform
|
||||
animationNode.visibility = self.visibility
|
||||
self.animationNode = animationNode
|
||||
@ -141,7 +141,7 @@ final class TrendingTopItemNode: ASDisplayNode {
|
||||
animationNode.started = { [weak self] in
|
||||
self?.imageNode.alpha = 0.0
|
||||
}
|
||||
animationNode.setup(source: AnimatedStickerResourceSource(account: account, resource: item.file.resource, isVideo: item.file.isVideoSticker), width: Int(fittedDimensions.width), height: Int(fittedDimensions.height), mode: .cached)
|
||||
animationNode.setup(source: AnimatedStickerResourceSource(account: account, resource: item.file.resource, isVideo: item.file.isVideoSticker), width: Int(fittedDimensions.width), height: Int(fittedDimensions.height), playbackMode: .loop, mode: .cached)
|
||||
self.loadDisposable.set(freeMediaFileResourceInteractiveFetched(account: account, fileReference: stickerPackFileReference(item.file), resource: item.file.resource).start())
|
||||
} else {
|
||||
self.imageNode.setSignal(chatMessageSticker(account: account, file: item.file, small: true, synchronousLoad: synchronousLoads), attemptSynchronously: synchronousLoads)
|
||||
|
@ -294,7 +294,7 @@ public final class NotificationViewControllerImpl {
|
||||
if let current = strongSelf.animatedStickerNode {
|
||||
animatedStickerNode = current
|
||||
} else {
|
||||
animatedStickerNode = AnimatedStickerNode()
|
||||
animatedStickerNode = DefaultAnimatedStickerNodeImpl()
|
||||
strongSelf.animatedStickerNode = animatedStickerNode
|
||||
animatedStickerNode.started = {
|
||||
guard let strongSelf = self else {
|
||||
@ -315,7 +315,7 @@ public final class NotificationViewControllerImpl {
|
||||
} else {
|
||||
strongSelf.imageNode.setSignal(chatMessageAnimatedSticker(postbox: accountAndImage.0.postbox, file: fileReference.media, small: false, size: fittedDimensions))
|
||||
}
|
||||
animatedStickerNode.setup(source: AnimatedStickerResourceSource(account: accountAndImage.0, resource: fileReference.media.resource, isVideo: file.isVideoSticker), width: Int(fittedDimensions.width), height: Int(fittedDimensions.height), mode: .direct(cachePathPrefix: nil))
|
||||
animatedStickerNode.setup(source: AnimatedStickerResourceSource(account: accountAndImage.0, resource: fileReference.media.resource, isVideo: file.isVideoSticker), width: Int(fittedDimensions.width), height: Int(fittedDimensions.height), playbackMode: .loop, mode: .direct(cachePathPrefix: nil))
|
||||
animatedStickerNode.visibility = true
|
||||
|
||||
accountAndImage.0.network.shouldExplicitelyKeepWorkerConnections.set(.single(true))
|
||||
|
@ -158,14 +158,14 @@ final class StickerPaneSearchStickerItemNode: GridItemNode {
|
||||
if let dimensions = stickerItem.file.dimensions {
|
||||
if stickerItem.file.isAnimatedSticker || stickerItem.file.isVideoSticker {
|
||||
if self.animationNode == nil {
|
||||
let animationNode = AnimatedStickerNode()
|
||||
let animationNode = DefaultAnimatedStickerNodeImpl()
|
||||
animationNode.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.imageNodeTap(_:))))
|
||||
self.animationNode = animationNode
|
||||
self.insertSubnode(animationNode, belowSubnode: self.textNode)
|
||||
}
|
||||
let dimensions = stickerItem.file.dimensions ?? PixelDimensions(width: 512, height: 512)
|
||||
let fittedDimensions = dimensions.cgSize.aspectFitted(CGSize(width: 160.0, height: 160.0))
|
||||
self.animationNode?.setup(source: AnimatedStickerResourceSource(account: account, resource: stickerItem.file.resource, isVideo: stickerItem.file.isVideoSticker), width: Int(fittedDimensions.width), height: Int(fittedDimensions.height), mode: .cached)
|
||||
self.animationNode?.setup(source: AnimatedStickerResourceSource(account: account, resource: stickerItem.file.resource, isVideo: stickerItem.file.isVideoSticker), width: Int(fittedDimensions.width), height: Int(fittedDimensions.height), playbackMode: .loop, mode: .cached)
|
||||
self.animationNode?.visibility = self.isVisibleInGrid
|
||||
self.stickerFetchedDisposable.set(freeMediaFileResourceInteractiveFetched(account: account, fileReference: stickerPackFileReference(stickerItem.file), resource: stickerItem.file.resource).start())
|
||||
} else {
|
||||
|
@ -294,7 +294,7 @@ private final class FeaturedPackItemNode: ListViewItemNode {
|
||||
if let current = self.animatedStickerNode {
|
||||
animatedStickerNode = current
|
||||
} else {
|
||||
animatedStickerNode = AnimatedStickerNode()
|
||||
animatedStickerNode = DefaultAnimatedStickerNodeImpl()
|
||||
animatedStickerNode.started = { [weak self] in
|
||||
self?.imageNode.isHidden = true
|
||||
self?.removePlaceholder(animated: false)
|
||||
@ -305,7 +305,7 @@ private final class FeaturedPackItemNode: ListViewItemNode {
|
||||
} else {
|
||||
self.containerNode.addSubnode(animatedStickerNode)
|
||||
}
|
||||
animatedStickerNode.setup(source: AnimatedStickerResourceSource(account: account, resource: resource, isVideo: isVideo), width: 128, height: 128, mode: .cached)
|
||||
animatedStickerNode.setup(source: AnimatedStickerResourceSource(account: account, resource: resource, isVideo: isVideo), width: 128, height: 128, playbackMode: .loop, mode: .cached)
|
||||
}
|
||||
animatedStickerNode.visibility = self.visibilityStatus && loopAnimatedStickers
|
||||
}
|
||||
|
@ -194,7 +194,7 @@ private final class TooltipScreenNode: ViewControllerTracingNode {
|
||||
|
||||
self.textNode.attributedText = stringWithAppliedEntities(text, entities: textEntities, baseColor: .white, linkColor: .white, baseFont: Font.regular(fontSize), linkFont: Font.regular(fontSize), boldFont: Font.semibold(14.0), italicFont: Font.italic(fontSize), boldItalicFont: Font.semiboldItalic(fontSize), fixedFont: Font.monospace(fontSize), blockQuoteFont: Font.regular(fontSize), underlineLinks: true, external: false)
|
||||
|
||||
self.animatedStickerNode = AnimatedStickerNode()
|
||||
self.animatedStickerNode = DefaultAnimatedStickerNodeImpl()
|
||||
switch icon {
|
||||
case .none:
|
||||
break
|
||||
|
@ -319,7 +319,7 @@ final class UndoOverlayControllerNode: ViewControllerTracingNode {
|
||||
self.iconNode = nil
|
||||
self.iconCheckNode = nil
|
||||
self.animationNode = nil
|
||||
self.animatedStickerNode = AnimatedStickerNode()
|
||||
self.animatedStickerNode = DefaultAnimatedStickerNodeImpl()
|
||||
self.animatedStickerNode?.visibility = true
|
||||
self.animatedStickerNode?.setup(source: AnimatedStickerNodeLocalFileSource(name: name), width: 100, height: 100, playbackMode: .once, mode: .direct(cachePathPrefix: nil))
|
||||
|
||||
@ -429,7 +429,7 @@ final class UndoOverlayControllerNode: ViewControllerTracingNode {
|
||||
case .still:
|
||||
break
|
||||
case let .animated(resource, _, isVideo):
|
||||
let animatedStickerNode = AnimatedStickerNode()
|
||||
let animatedStickerNode = DefaultAnimatedStickerNodeImpl()
|
||||
self.animatedStickerNode = animatedStickerNode
|
||||
animatedStickerNode.setup(source: AnimatedStickerResourceSource(account: context.account, resource: resource._asResource(), isVideo: isVideo), width: 80, height: 80, mode: .direct(cachePathPrefix: nil))
|
||||
}
|
||||
@ -471,7 +471,7 @@ final class UndoOverlayControllerNode: ViewControllerTracingNode {
|
||||
slotMachineNode.setState(.value(value, true))
|
||||
}
|
||||
} else {
|
||||
let animatedStickerNode = AnimatedStickerNode()
|
||||
let animatedStickerNode = DefaultAnimatedStickerNodeImpl()
|
||||
self.animatedStickerNode = animatedStickerNode
|
||||
|
||||
let _ = (context.engine.stickers.loadedStickerPack(reference: .dice(dice.emoji), forceActualized: false)
|
||||
@ -723,7 +723,7 @@ final class UndoOverlayControllerNode: ViewControllerTracingNode {
|
||||
case .still:
|
||||
break
|
||||
case let .animated(resource):
|
||||
let animatedStickerNode = AnimatedStickerNode()
|
||||
let animatedStickerNode = DefaultAnimatedStickerNodeImpl()
|
||||
self.animatedStickerNode = animatedStickerNode
|
||||
animatedStickerNode.setup(source: AnimatedStickerResourceSource(account: context.account, resource: resource._asResource(), isVideo: file.isVideoSticker), width: 80, height: 80, mode: .cached)
|
||||
}
|
||||
@ -749,7 +749,7 @@ final class UndoOverlayControllerNode: ViewControllerTracingNode {
|
||||
self.iconCheckNode = nil
|
||||
self.animationNode = nil
|
||||
|
||||
let animatedStickerNode = AnimatedStickerNode()
|
||||
let animatedStickerNode = DefaultAnimatedStickerNodeImpl()
|
||||
self.animatedStickerNode = animatedStickerNode
|
||||
|
||||
animatedStickerNode.setup(source: AnimatedStickerNodeLocalFileSource(name: "anim_savemedia"), width: 80, height: 80, playbackMode: .once, mode: .direct(cachePathPrefix: nil))
|
||||
|
@ -467,7 +467,7 @@ final class WallpaperBackgroundNodeImpl: ASDisplayNode, WallpaperBackgroundNode
|
||||
("ptrnSLON_0906_1033", CGPoint(x: 906 - 256, y: 1033 - 256))
|
||||
]
|
||||
for (animation, relativePosition) in animationList {
|
||||
let animationNode = AnimatedStickerNode()
|
||||
let animationNode = DefaultAnimatedStickerNodeImpl()
|
||||
animationNode.automaticallyLoadFirstFrame = true
|
||||
animationNode.autoplay = true
|
||||
//self.inlineAnimationNodes.append((animationNode, relativePosition))
|
||||
|
@ -4,7 +4,9 @@
|
||||
// enable threading
|
||||
//#define LOTTIE_THREAD_SUPPORT
|
||||
|
||||
#ifndef LOTTIE_THREAD_SAFE
|
||||
#define LOTTIE_THREAD_SAFE
|
||||
#endif
|
||||
|
||||
//enable logging
|
||||
//#define LOTTIE_LOGGING_SUPPORT
|
||||
@ -16,6 +18,8 @@
|
||||
//#define LOTTIE_CACHE_SUPPORT
|
||||
|
||||
// disable image loader
|
||||
#ifndef LOTTIE_IMAGE_MODULE_DISABLED
|
||||
#define LOTTIE_IMAGE_MODULE_DISABLED
|
||||
#endif
|
||||
|
||||
#endif // CONFIG_H
|
||||
|
Loading…
x
Reference in New Issue
Block a user