mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
175 lines
6.7 KiB
Swift
175 lines
6.7 KiB
Swift
import UIKit
|
|
import Display
|
|
import SyncCore
|
|
import TelegramCore
|
|
import AccountContext
|
|
import SwiftSignalKit
|
|
import AnimatedStickerNode
|
|
import TelegramAnimatedStickerNode
|
|
import StickerResources
|
|
import LegacyComponents
|
|
|
|
class LegacyPaintStickerView: UIView, TGPhotoPaintStickerRenderView {
|
|
var started: ((Double) -> Void)?
|
|
|
|
private let context: AccountContext
|
|
private let file: TelegramMediaFile
|
|
private var currentSize: CGSize?
|
|
private var dimensions: CGSize?
|
|
|
|
private let imageNode: TransformImageNode
|
|
private var animationNode: AnimatedStickerNode?
|
|
|
|
private var didSetUpAnimationNode = false
|
|
private let stickerFetchedDisposable = MetaDisposable()
|
|
|
|
private let cachedDisposable = MetaDisposable()
|
|
|
|
init(context: AccountContext, file: TelegramMediaFile) {
|
|
self.context = context
|
|
self.file = file
|
|
|
|
self.imageNode = TransformImageNode()
|
|
|
|
super.init(frame: CGRect())
|
|
|
|
self.addSubnode(self.imageNode)
|
|
|
|
self.setup()
|
|
}
|
|
|
|
required init?(coder: NSCoder) {
|
|
fatalError("init(coder:) has not been implemented")
|
|
}
|
|
|
|
deinit {
|
|
self.stickerFetchedDisposable.dispose()
|
|
self.cachedDisposable.dispose()
|
|
}
|
|
|
|
func image() -> UIImage! {
|
|
if self.imageNode.contents != nil {
|
|
return UIImage(cgImage: self.imageNode.contents as! CGImage)
|
|
} else {
|
|
return nil
|
|
}
|
|
}
|
|
|
|
func documentId() -> Int64 {
|
|
return self.file.fileId.id
|
|
}
|
|
|
|
private func setup() {
|
|
if let dimensions = self.file.dimensions {
|
|
if self.file.isAnimatedSticker {
|
|
if self.animationNode == nil {
|
|
let animationNode = AnimatedStickerNode()
|
|
self.animationNode = animationNode
|
|
animationNode.started = { [weak self, weak animationNode] in
|
|
self?.imageNode.isHidden = true
|
|
|
|
if let animationNode = animationNode {
|
|
let _ = (animationNode.status
|
|
|> take(1)
|
|
|> deliverOnMainQueue).start(next: { [weak self] status in
|
|
self?.started?(status.duration)
|
|
})
|
|
}
|
|
}
|
|
self.addSubnode(animationNode)
|
|
}
|
|
let dimensions = self.file.dimensions ?? PixelDimensions(width: 512, height: 512)
|
|
self.imageNode.setSignal(chatMessageAnimatedSticker(postbox: self.context.account.postbox, file: self.file, small: false, size: dimensions.cgSize.aspectFitted(CGSize(width: 256.0, height: 256.0))))
|
|
self.updateVisibility()
|
|
self.stickerFetchedDisposable.set(freeMediaFileResourceInteractiveFetched(account: self.context.account, fileReference: stickerPackFileReference(self.file), resource: self.file.resource).start())
|
|
} else {
|
|
if let animationNode = self.animationNode {
|
|
animationNode.visibility = false
|
|
self.animationNode = nil
|
|
animationNode.removeFromSupernode()
|
|
self.imageNode.isHidden = false
|
|
self.didSetUpAnimationNode = false
|
|
}
|
|
self.imageNode.setSignal(chatMessageSticker(account: self.context.account, file: self.file, small: false, synchronousLoad: false))
|
|
self.stickerFetchedDisposable.set(freeMediaFileResourceInteractiveFetched(account: self.context.account, fileReference: stickerPackFileReference(self.file), resource: chatMessageStickerResource(file: self.file, small: false)).start())
|
|
}
|
|
|
|
self.dimensions = dimensions.cgSize
|
|
self.setNeedsLayout()
|
|
}
|
|
}
|
|
|
|
var isVisible: Bool = true
|
|
func setIsVisible(_ visible: Bool) {
|
|
self.isVisible = visible
|
|
self.updateVisibility()
|
|
}
|
|
|
|
var isPlaying = false
|
|
func updateVisibility() {
|
|
let isPlaying = self.isVisible
|
|
if self.isPlaying != isPlaying {
|
|
self.isPlaying = isPlaying
|
|
|
|
self.animationNode?.visibility = isPlaying
|
|
if isPlaying && !self.didSetUpAnimationNode {
|
|
self.didSetUpAnimationNode = true
|
|
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)
|
|
self.animationNode?.setup(source: source, width: Int(fittedDimensions.width), height: Int(fittedDimensions.height), mode: .direct)
|
|
|
|
self.cachedDisposable.set((source.cachedDataPath(width: 384, height: 384)
|
|
|> deliverOn(Queue.concurrentDefaultQueue())).start())
|
|
}
|
|
}
|
|
}
|
|
|
|
func seek(to timestamp: Double) {
|
|
self.isVisible = false
|
|
self.isPlaying = false
|
|
self.animationNode?.seekTo(.timestamp(timestamp))
|
|
}
|
|
|
|
func play() {
|
|
self.isVisible = true
|
|
self.isPlaying = true
|
|
self.animationNode?.play()
|
|
}
|
|
|
|
func pause() {
|
|
self.isVisible = false
|
|
self.isPlaying = false
|
|
self.animationNode?.pause()
|
|
}
|
|
|
|
func resetToStart() {
|
|
self.isVisible = false
|
|
self.isPlaying = false
|
|
self.animationNode?.seekTo(.timestamp(0.0))
|
|
}
|
|
|
|
override func layoutSubviews() {
|
|
super.layoutSubviews()
|
|
|
|
let size = self.bounds.size
|
|
|
|
if size.width > 0 && self.currentSize != size {
|
|
self.currentSize = size
|
|
|
|
let sideSize: CGFloat = size.width
|
|
let boundingSize = CGSize(width: sideSize, height: sideSize)
|
|
|
|
if let dimensions = self.dimensions {
|
|
let imageSize = dimensions.aspectFitted(boundingSize)
|
|
self.imageNode.asyncLayout()(TransformImageArguments(corners: ImageCorners(), imageSize: imageSize, boundingSize: imageSize, intrinsicInsets: UIEdgeInsets()))()
|
|
self.imageNode.frame = CGRect(origin: CGPoint(x: floor((size.width - imageSize.width) / 2.0), y: (size.height - imageSize.height) / 2.0), size: imageSize)
|
|
if let animationNode = self.animationNode {
|
|
animationNode.frame = CGRect(origin: CGPoint(x: floor((size.width - imageSize.width) / 2.0), y: (size.height - imageSize.height) / 2.0), size: imageSize)
|
|
animationNode.updateLayout(size: imageSize)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|