2024-05-14 12:36:13 +04:00

147 lines
6.6 KiB
Swift

import Foundation
import UIKit
import AsyncDisplayKit
import TelegramPresentationData
import ChatPresentationInterfaceState
import AccountContext
import ChatSendMessageActionUI
import SwiftSignalKit
import ComponentFlow
import Display
import Postbox
import TelegramCore
import WallpaperBackgroundNode
import AudioWaveform
import ChatMessageItemView
public final class ChatSendAudioMessageContextPreview: UIView, ChatSendMessageContextScreenMediaPreview {
private let context: AccountContext
private let presentationData: PresentationData
private let wallpaperBackgroundNode: WallpaperBackgroundNode?
private let waveform: AudioWaveform
private var messageNodes: [ListViewItemNode]?
private let messagesContainer: UIView
public var isReady: Signal<Bool, NoError> {
return .single(true)
}
public var view: UIView {
return self
}
public var globalClippingRect: CGRect? {
return nil
}
public var layoutType: ChatSendMessageContextScreenMediaPreviewLayoutType {
return .message
}
public init(context: AccountContext, presentationData: PresentationData, wallpaperBackgroundNode: WallpaperBackgroundNode?, waveform: AudioWaveform) {
self.context = context
self.presentationData = presentationData
self.wallpaperBackgroundNode = wallpaperBackgroundNode
self.waveform = waveform
self.messagesContainer = UIView()
self.messagesContainer.layer.sublayerTransform = CATransform3DMakeScale(-1.0, -1.0, 1.0)
super.init(frame: CGRect())
self.addSubview(self.messagesContainer)
}
required public init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
deinit {
}
public func animateIn(transition: Transition) {
transition.animateAlpha(view: self.messagesContainer, from: 0.0, to: 1.0)
transition.animateScale(view: self.messagesContainer, from: 0.001, to: 1.0)
}
public func animateOut(transition: Transition) {
transition.setAlpha(view: self.messagesContainer, alpha: 0.0)
transition.setScale(view: self.messagesContainer, scale: 0.001)
}
public func animateOutOnSend(transition: Transition) {
transition.setAlpha(view: self.messagesContainer, alpha: 0.0)
}
public func update(containerSize: CGSize, transition: Transition) -> CGSize {
let voiceAttributes: [TelegramMediaFileAttribute] = [.Audio(isVoice: true, duration: 23, title: nil, performer: nil, waveform: self.waveform.makeBitstream())]
let voiceMedia = TelegramMediaFile(fileId: MediaId(namespace: 0, id: 0), partialReference: nil, resource: LocalFileMediaResource(fileId: 0), previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "audio/ogg", size: 0, attributes: voiceAttributes)
let message = Message(stableId: 1, stableVersion: 0, id: MessageId(peerId: self.context.account.peerId, namespace: 0, id: 1), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 0, flags: [.Incoming], tags: [], globalTags: [], localTags: [], customTags: [], forwardInfo: nil, author: nil, text: "", attributes: [], media: [voiceMedia], peers: SimpleDictionary(), associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil, associatedStories: [:])
let item = self.context.sharedContext.makeChatMessagePreviewItem(
context: self.context,
messages: [message],
theme: presentationData.theme,
strings: presentationData.strings,
wallpaper: presentationData.chatWallpaper,
fontSize: presentationData.chatFontSize,
chatBubbleCorners: presentationData.chatBubbleCorners,
dateTimeFormat: presentationData.dateTimeFormat,
nameOrder: presentationData.nameDisplayOrder,
forcedResourceStatus: FileMediaResourceStatus(mediaStatus: .fetchStatus(.Local), fetchStatus: .Local),
tapMessage: nil,
clickThroughMessage: nil,
backgroundNode: self.wallpaperBackgroundNode,
availableReactions: nil,
accountPeer: nil,
isCentered: false,
isPreview: true,
isStandalone: true
)
let items = [item]
let params = ListViewItemLayoutParams(width: containerSize.width, leftInset: 0.0, rightInset: 0.0, availableHeight: containerSize.height)
if let messageNodes = self.messageNodes {
for i in 0 ..< items.count {
let itemNode = messageNodes[i]
items[i].updateNode(async: { $0() }, node: {
return itemNode
}, params: params, previousItem: i == 0 ? nil : items[i - 1], nextItem: i == (items.count - 1) ? nil : items[i + 1], animation: .None, completion: { (layout, apply) in
let nodeFrame = CGRect(origin: itemNode.frame.origin, size: CGSize(width: containerSize.width, height: layout.size.height))
itemNode.contentSize = layout.contentSize
itemNode.insets = layout.insets
itemNode.frame = nodeFrame
itemNode.isUserInteractionEnabled = false
apply(ListViewItemApply(isOnScreen: true))
})
}
} else {
var messageNodes: [ListViewItemNode] = []
for i in 0 ..< items.count {
var itemNode: ListViewItemNode?
items[i].nodeConfiguredForParams(async: { $0() }, params: params, synchronousLoads: false, previousItem: i == 0 ? nil : items[i - 1], nextItem: i == (items.count - 1) ? nil : items[i + 1], completion: { node, apply in
itemNode = node
apply().1(ListViewItemApply(isOnScreen: true))
})
itemNode!.isUserInteractionEnabled = false
messageNodes.append(itemNode!)
self.messagesContainer.addSubview(itemNode!.view)
}
self.messageNodes = messageNodes
}
guard let messageNode = self.messageNodes?.first as? ChatMessageItemView else {
return CGSize(width: 10.0, height: 10.0)
}
let contentFrame = messageNode.contentFrame()
self.messagesContainer.frame = CGRect(origin: CGPoint(x: 6.0, y: 3.0), size: CGSize(width: contentFrame.width, height: contentFrame.height))
return CGSize(width: contentFrame.width - 4.0, height: contentFrame.height + 2.0)
}
}