mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
161 lines
6.1 KiB
Swift
161 lines
6.1 KiB
Swift
import Foundation
|
|
import Display
|
|
import AsyncDisplayKit
|
|
import TelegramCore
|
|
import Postbox
|
|
|
|
private func mediaForMessage(_ message: Message) -> Media? {
|
|
for media in message.media {
|
|
if let media = media as? TelegramMediaImage {
|
|
return media
|
|
} else if let file = media as? TelegramMediaFile {
|
|
if file.mimeType.hasPrefix("audio/") {
|
|
return nil
|
|
} else if !file.isVideo && file.mimeType.hasPrefix("video/") {
|
|
return file
|
|
} else {
|
|
return file
|
|
}
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
final class GridMessageItem: GridItem {
|
|
private let account: Account
|
|
private let message: Message
|
|
private let controllerInteraction: ChatControllerInteraction
|
|
|
|
init(account: Account, message: Message, controllerInteraction: ChatControllerInteraction) {
|
|
self.account = account
|
|
self.message = message
|
|
self.controllerInteraction = controllerInteraction
|
|
}
|
|
|
|
func node(layout: GridNodeLayout) -> GridItemNode {
|
|
let node = GridMessageItemNode()
|
|
if let media = mediaForMessage(self.message) {
|
|
node.setup(account: self.account, media: media, messageId: self.message.id, controllerInteraction: self.controllerInteraction)
|
|
}
|
|
return node
|
|
}
|
|
}
|
|
|
|
final class GridMessageItemNode: GridItemNode {
|
|
private var currentState: (Account, Media, CGSize)?
|
|
private let imageNode: TransformImageNode
|
|
private var messageId: MessageId?
|
|
private var controllerInteraction: ChatControllerInteraction?
|
|
|
|
private var selectionNode: GridMessageSelectionNode?
|
|
|
|
override init() {
|
|
self.imageNode = TransformImageNode()
|
|
|
|
super.init()
|
|
|
|
self.addSubnode(self.imageNode)
|
|
}
|
|
|
|
override func didLoad() {
|
|
super.didLoad()
|
|
|
|
self.imageNode.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.imageNodeTap(_:))))
|
|
}
|
|
|
|
func setup(account: Account, media: Media, messageId: MessageId, controllerInteraction: ChatControllerInteraction) {
|
|
if self.currentState == nil || self.currentState!.0 !== account || !self.currentState!.1.isEqual(media) {
|
|
var mediaDimensions: CGSize?
|
|
if let image = media as? TelegramMediaImage, let largestSize = largestImageRepresentation(image.representations)?.dimensions {
|
|
mediaDimensions = largestSize
|
|
self.imageNode.setSignal(account: account, signal: mediaGridMessagePhoto(account: account, photo: image), dispatchOnDisplayLink: true)
|
|
}
|
|
|
|
if let mediaDimensions = mediaDimensions {
|
|
self.currentState = (account, media, mediaDimensions)
|
|
self.setNeedsLayout()
|
|
}
|
|
}
|
|
|
|
self.messageId = messageId
|
|
self.controllerInteraction = controllerInteraction
|
|
|
|
self.updateSelectionState(animated: false)
|
|
self.updateHiddenMedia()
|
|
}
|
|
|
|
override func layout() {
|
|
super.layout()
|
|
|
|
let imageFrame = self.bounds.insetBy(dx: 1.0, dy: 1.0)
|
|
self.imageNode.frame = imageFrame
|
|
|
|
if let (_, _, mediaDimensions) = self.currentState {
|
|
let imageSize = mediaDimensions.aspectFilled(imageFrame.size)
|
|
self.imageNode.asyncLayout()(TransformImageArguments(corners: ImageCorners(), imageSize: imageSize, boundingSize: imageFrame.size, intrinsicInsets: UIEdgeInsets()))()
|
|
}
|
|
|
|
self.selectionNode?.frame = CGRect(origin: CGPoint(), size: self.bounds.size)
|
|
}
|
|
|
|
func updateSelectionState(animated: Bool) {
|
|
if let messageId = self.messageId, let controllerInteraction = self.controllerInteraction {
|
|
if let selectionState = controllerInteraction.selectionState {
|
|
var selected = selectionState.selectedIds.contains(messageId)
|
|
|
|
if let selectionNode = self.selectionNode {
|
|
selectionNode.updateSelected(selected, animated: animated)
|
|
selectionNode.frame = CGRect(origin: CGPoint(), size: self.bounds.size)
|
|
} else {
|
|
let selectionNode = GridMessageSelectionNode(toggle: { [weak self] in
|
|
if let strongSelf = self, let messageId = strongSelf.messageId {
|
|
strongSelf.controllerInteraction?.toggleMessageSelection(messageId)
|
|
}
|
|
})
|
|
|
|
selectionNode.frame = CGRect(origin: CGPoint(), size: self.bounds.size)
|
|
self.addSubnode(selectionNode)
|
|
self.selectionNode = selectionNode
|
|
selectionNode.updateSelected(selected, animated: false)
|
|
if animated {
|
|
selectionNode.animateIn()
|
|
}
|
|
}
|
|
} else {
|
|
if let selectionNode = self.selectionNode {
|
|
self.selectionNode = nil
|
|
if animated {
|
|
selectionNode.animateOut { [weak selectionNode] in
|
|
selectionNode?.removeFromSupernode()
|
|
}
|
|
} else {
|
|
selectionNode.removeFromSupernode()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func transitionNode(id: MessageId, media: Media) -> ASDisplayNode? {
|
|
if self.messageId == id {
|
|
return self.imageNode
|
|
} else {
|
|
return nil
|
|
}
|
|
}
|
|
|
|
func updateHiddenMedia() {
|
|
if let controllerInteraction = self.controllerInteraction, let messageId = self.messageId, controllerInteraction.hiddenMedia[messageId] != nil {
|
|
self.imageNode.isHidden = true
|
|
} else {
|
|
self.imageNode.isHidden = false
|
|
}
|
|
}
|
|
|
|
@objc func imageNodeTap(_ recognizer: UITapGestureRecognizer) {
|
|
if let controllerInteraction = self.controllerInteraction, let messageId = self.messageId, case .ended = recognizer.state {
|
|
controllerInteraction.openMessage(messageId)
|
|
}
|
|
}
|
|
}
|