Swiftgram/submodules/InstantPageUI/Sources/InstantPageArticleNode.swift

139 lines
5.4 KiB
Swift

import Foundation
import UIKit
import AsyncDisplayKit
import Display
import Postbox
import TelegramCore
import SyncCore
import SwiftSignalKit
import TelegramPresentationData
import AccountContext
import PhotoResources
final class InstantPageArticleNode: ASDisplayNode, InstantPageNode {
let item: InstantPageArticleItem
private let highlightedBackgroundNode: ASDisplayNode
private let buttonNode: HighlightableButtonNode
private let contentTile: InstantPageTile
private let contentTileNode: InstantPageTileNode
private var imageNode: TransformImageNode?
let url: String
let webpageId: MediaId
let cover: TelegramMediaImage?
let rtl: Bool
private let openUrl: (InstantPageUrlItem) -> Void
private var fetchedDisposable = MetaDisposable()
init(context: AccountContext, item: InstantPageArticleItem, webPage: TelegramMediaWebpage, strings: PresentationStrings, theme: InstantPageTheme, contentItems: [InstantPageItem], contentSize: CGSize, cover: TelegramMediaImage?, url: String, webpageId: MediaId, rtl: Bool, openUrl: @escaping (InstantPageUrlItem) -> Void) {
self.item = item
self.url = url
self.webpageId = webpageId
self.cover = cover
self.rtl = rtl
self.openUrl = openUrl
self.highlightedBackgroundNode = ASDisplayNode()
self.highlightedBackgroundNode.isLayerBacked = true
self.highlightedBackgroundNode.alpha = 0.0
self.buttonNode = HighlightableButtonNode()
self.contentTile = InstantPageTile(frame: CGRect(x: 0.0, y: 0.0, width: contentSize.width, height: contentSize.height))
self.contentTile.items.append(contentsOf: contentItems)
self.contentTileNode = InstantPageTileNode(tile: self.contentTile, backgroundColor: .clear)
super.init()
self.addSubnode(self.highlightedBackgroundNode)
self.addSubnode(self.buttonNode)
self.addSubnode(self.contentTileNode)
if let image = cover {
let imageNode = TransformImageNode()
imageNode.isUserInteractionEnabled = false
let imageReference = ImageMediaReference.webPage(webPage: WebpageReference(webPage), media: image)
imageNode.setSignal(chatMessagePhoto(postbox: context.account.postbox, photoReference: imageReference))
self.fetchedDisposable.set(chatMessagePhotoInteractiveFetched(context: context, photoReference: imageReference, storeToDownloadsPeerType: nil).start())
self.imageNode = imageNode
self.addSubnode(imageNode)
}
self.buttonNode.addTarget(self, action: #selector(self.buttonPressed), forControlEvents: .touchUpInside)
self.buttonNode.highligthedChanged = { [weak self] highlighted in
if let strongSelf = self {
if highlighted {
strongSelf.highlightedBackgroundNode.layer.removeAnimation(forKey: "opacity")
strongSelf.highlightedBackgroundNode.alpha = 1.0
} else {
strongSelf.highlightedBackgroundNode.alpha = 0.0
strongSelf.highlightedBackgroundNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2)
}
}
}
self.update(strings: strings, theme: theme)
}
deinit {
self.fetchedDisposable.dispose()
}
@objc func buttonPressed() {
self.openUrl(InstantPageUrlItem(url: self.url, webpageId: self.webpageId))
}
override func layout() {
super.layout()
let size = self.bounds.size
let inset: CGFloat = 17.0
let imageSize = CGSize(width: 44.0, height: 44.0)
self.highlightedBackgroundNode.frame = CGRect(origin: CGPoint(x: 0.0, y: -UIScreenPixel), size: CGSize(width: size.width, height: size.height + UIScreenPixel))
self.buttonNode.frame = CGRect(origin: CGPoint(), size: size)
self.contentTileNode.frame = self.bounds
if let imageNode = self.imageNode, let image = self.cover, let largest = largestImageRepresentation(image.representations) {
let size = largest.dimensions.cgSize.aspectFilled(imageSize)
let boundingSize = imageSize
let makeLayout = imageNode.asyncLayout()
let apply = makeLayout(TransformImageArguments(corners: ImageCorners(radius: 5.0), imageSize: size, boundingSize: boundingSize, intrinsicInsets: UIEdgeInsets()))
apply()
}
if let imageNode = self.imageNode {
if self.rtl {
imageNode.frame = CGRect(origin: CGPoint(x: inset, y: 11.0), size: imageSize)
} else {
imageNode.frame = CGRect(origin: CGPoint(x: size.width - inset - imageSize.width, y: 11.0), size: imageSize)
}
}
}
func updateIsVisible(_ isVisible: Bool) {
}
func updateLayout(size: CGSize, transition: ContainedViewLayoutTransition) {
}
func transitionNode(media: InstantPageMedia) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))? {
return nil
}
func updateHiddenMedia(media: InstantPageMedia?) {
}
func update(strings: PresentationStrings, theme: InstantPageTheme) {
self.highlightedBackgroundNode.backgroundColor = theme.panelHighlightedBackgroundColor
}
}