Swiftgram/TelegramUI/InstantPagePlayableVideoNode.swift
2017-09-05 21:27:04 +03:00

117 lines
3.9 KiB
Swift

import Foundation
import AsyncDisplayKit
import Display
import Postbox
import TelegramCore
import SwiftSignalKit
final class InstantPagePlayableVideoNode: ASDisplayNode, InstantPageNode {
private let account: Account
let media: InstantPageMedia
private let interactive: Bool
private let openMedia: (InstantPageMedia) -> Void
private let imageNode: TransformImageNode
private let videoNode: ManagedVideoNode
private var currentSize: CGSize?
private var fetchedDisposable = MetaDisposable()
private var localIsVisible = false
init(account: Account, media: InstantPageMedia, interactive: Bool, openMedia: @escaping (InstantPageMedia) -> Void) {
self.account = account
self.media = media
self.interactive = interactive
self.openMedia = openMedia
self.imageNode = TransformImageNode()
self.videoNode = ManagedVideoNode(preferSoftwareDecoding: false, backgroundThread: false)
super.init()
self.imageNode.alphaTransitionOnFirstUpdate = true
self.addSubnode(self.imageNode)
self.addSubnode(self.videoNode)
if let file = media.media as? TelegramMediaFile {
self.imageNode.setSignal(account: account, signal: chatMessageVideo(account: account, video: file))
self.fetchedDisposable.set(chatMessageFileInteractiveFetched(account: account, file: file).start())
}
}
deinit {
self.fetchedDisposable.dispose()
}
override func didLoad() {
super.didLoad()
if self.interactive {
self.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.tapGesture(_:))))
}
}
func updateIsVisible(_ isVisible: Bool) {
if self.localIsVisible != isVisible {
self.localIsVisible = isVisible
if isVisible {
if let file = media.media as? TelegramMediaFile {
self.videoNode.acquireContext(account: self.account, mediaManager: account.telegramApplicationContext.mediaManager, id: InstantPageManagedMediaId(media: self.media), resource: file.resource, priority: 0)
}
} else {
self.videoNode.discardContext()
}
}
}
func update(strings: PresentationStrings, theme: InstantPageTheme) {
}
override func layout() {
super.layout()
let size = self.bounds.size
if self.currentSize != size {
self.currentSize = size
self.imageNode.frame = CGRect(origin: CGPoint(), size: size)
self.videoNode.frame = CGRect(origin: CGPoint(), size: size)
if let file = self.media.media as? TelegramMediaFile, let dimensions = file.dimensions {
let imageSize = dimensions.aspectFilled(size)
let boundingSize = size
let makeLayout = self.imageNode.asyncLayout()
let arguments = TransformImageArguments(corners: ImageCorners(), imageSize: imageSize, boundingSize: boundingSize, intrinsicInsets: UIEdgeInsets())
let apply = makeLayout(arguments)
apply()
self.videoNode.transformArguments = arguments
}
}
}
func transitionNode(media: InstantPageMedia) -> ASDisplayNode? {
if media == self.media {
return self.videoNode
} else {
return nil
}
}
func updateHiddenMedia(media: InstantPageMedia?) {
self.imageNode.isHidden = self.media == media
self.videoNode.isHidden = self.media == media
}
@objc func tapGesture(_ recognizer: UITapGestureRecognizer) {
if case .ended = recognizer.state {
self.openMedia(self.media)
}
}
}