Improved one-time animated emoji playback

This commit is contained in:
Ilya Laktyushin 2019-08-01 12:48:28 +03:00
parent 7d434ac5c9
commit 70af4eb679
2 changed files with 67 additions and 16 deletions

View File

@ -306,9 +306,6 @@ final class AnimatedStickerNode: ASDisplayNode {
private let fetchDisposable = MetaDisposable() private let fetchDisposable = MetaDisposable()
private let eventsNode: AnimatedStickerNodeDisplayEvents private let eventsNode: AnimatedStickerNodeDisplayEvents
var shouldAutoPlay: () -> Bool = {
return true
}
var started: () -> Void = {} var started: () -> Void = {}
var reportedStarted = false var reportedStarted = false
@ -410,7 +407,7 @@ final class AnimatedStickerNode: ASDisplayNode {
} }
private func updateIsPlaying() { private func updateIsPlaying() {
let isPlaying = self.visibility && self.isDisplaying && self.shouldAutoPlay() let isPlaying = self.visibility && self.isDisplaying
if self.isPlaying != isPlaying { if self.isPlaying != isPlaying {
self.isPlaying = isPlaying self.isPlaying = isPlaying
if isPlaying { if isPlaying {
@ -481,6 +478,59 @@ final class AnimatedStickerNode: ASDisplayNode {
self.timer.swap(nil)?.invalidate() self.timer.swap(nil)?.invalidate()
} }
func seekToStart() {
self.isPlaying = false
let directData = self.directData
let cachedData = self.cachedData
let queue = self.queue
let timerHolder = self.timer
self.queue.async { [weak self] in
var maybeFrameSource: AnimatedStickerFrameSource?
if let directData = directData {
maybeFrameSource = AnimatedStickerDirectFrameSource(queue: queue, data: directData._0, width: directData._2, height: directData._3)
} else if let cachedData = cachedData {
if #available(iOS 9.0, *) {
maybeFrameSource = AnimatedStickerCachedFrameSource(queue: queue, data: cachedData)
}
}
guard let frameSource = maybeFrameSource else {
return
}
let frameQueue = QueueLocalObject<AnimatedStickerFrameQueue>(queue: queue, generate: {
return AnimatedStickerFrameQueue(queue: queue, length: 1, source: frameSource)
})
timerHolder.swap(nil)?.invalidate()
let maybeFrame = frameQueue.syncWith { frameQueue in
return frameQueue.take()
}
if let maybeFrame = maybeFrame, let frame = maybeFrame {
Queue.mainQueue().async {
guard let strongSelf = self else {
return
}
strongSelf.renderer?.render(queue: strongSelf.queue, width: frame.width, height: frame.height, bytesPerRow: frame.bytesPerRow, data: frame.data, type: frame.type, completion: {
guard let strongSelf = self else {
return
}
if !strongSelf.reportedStarted {
strongSelf.reportedStarted = true
strongSelf.started()
}
})
if case .once = strongSelf.playbackMode, frame.isLastFrame {
strongSelf.stop()
strongSelf.isPlaying = false
}
}
}
frameQueue.with { frameQueue in
frameQueue.generateFramesIfNeeded()
}
}
}
func playIfNeeded() -> Bool { func playIfNeeded() -> Bool {
if !self.isPlaying { if !self.isPlaying {
self.isPlaying = true self.isPlaying = true

View File

@ -62,17 +62,6 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
} }
} }
self.animationNode.shouldAutoPlay = { [weak self] in
if let strongSelf = self {
if let item = strongSelf.item {
if let _ = strongSelf.emojiFile {
return !item.controllerInteraction.seenOneTimeAnimatedMedia.contains(item.message.id)
}
}
}
return true
}
self.imageNode.displaysAsynchronously = false self.imageNode.displaysAsynchronously = false
self.addSubnode(self.imageNode) self.addSubnode(self.imageNode)
self.addSubnode(self.animationNode) self.addSubnode(self.animationNode)
@ -174,7 +163,19 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
let isPlaying = self.visibilityStatus let isPlaying = self.visibilityStatus
if self.isPlaying != isPlaying { if self.isPlaying != isPlaying {
self.isPlaying = isPlaying self.isPlaying = isPlaying
self.animationNode.visibility = isPlaying
var alreadySeen = false
if isPlaying, let _ = self.emojiFile {
if item.controllerInteraction.seenOneTimeAnimatedMedia.contains(item.message.id) {
alreadySeen = true
}
}
self.animationNode.visibility = isPlaying && !alreadySeen
if self.didSetUpAnimationNode && alreadySeen {
self.animationNode.seekToStart()
}
if self.isPlaying && !self.didSetUpAnimationNode { if self.isPlaying && !self.didSetUpAnimationNode {
self.didSetUpAnimationNode = true self.didSetUpAnimationNode = true