Sticker refactoring

This commit is contained in:
Ali 2022-06-08 20:44:14 +04:00
parent a6292e752a
commit cff972c968
58 changed files with 162 additions and 111 deletions

View File

@ -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
}

View File

@ -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

View File

@ -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)

View File

@ -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)
}
}
}

View File

@ -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) {

View File

@ -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

View File

@ -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()

View File

@ -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):

View File

@ -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()

View File

@ -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 {

View File

@ -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
}

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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()
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
}

View File

@ -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

View File

@ -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)

View File

@ -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
})

View File

@ -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()

View File

@ -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 {

View File

@ -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)

View File

@ -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

View File

@ -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()

View File

@ -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

View File

@ -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) {

View File

@ -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
}

View File

@ -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
}

View File

@ -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

View File

@ -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()

View File

@ -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

View File

@ -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

View File

@ -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)
}
}
}

View File

@ -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)
}
}
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)
}
}
}

View File

@ -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)

View File

@ -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)
}
})
}

View File

@ -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 {

View File

@ -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

View File

@ -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

View File

@ -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
}

View File

@ -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)
}
}

View File

@ -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 {

View File

@ -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

View File

@ -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)

View File

@ -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))

View File

@ -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 {

View File

@ -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
}

View File

@ -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

View File

@ -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))

View File

@ -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))

View File

@ -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