mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00

Added ability to download music without streaming Added progress indicators for various blocking tasks Fixed image gallery swipe to dismiss after zooming Added online member count indication in supergroups Fixed contact statuses in contact search
120 lines
6.2 KiB
Swift
120 lines
6.2 KiB
Swift
import Foundation
|
|
import AsyncDisplayKit
|
|
import Display
|
|
import SwiftSignalKit
|
|
import Postbox
|
|
import TelegramCore
|
|
|
|
class ChatMessageFileBubbleContentNode: ChatMessageBubbleContentNode {
|
|
private let interactiveFileNode: ChatMessageInteractiveFileNode
|
|
|
|
required init() {
|
|
self.interactiveFileNode = ChatMessageInteractiveFileNode()
|
|
|
|
super.init()
|
|
|
|
self.addSubnode(self.interactiveFileNode)
|
|
|
|
self.interactiveFileNode.activateLocalContent = { [weak self] in
|
|
if let strongSelf = self {
|
|
if let item = strongSelf.item {
|
|
let _ = item.controllerInteraction.openMessage(item.message)
|
|
}
|
|
}
|
|
}
|
|
|
|
self.interactiveFileNode.requestUpdateLayout = { [weak self] _ in
|
|
if let strongSelf = self {
|
|
if let item = strongSelf.item {
|
|
let _ = item.controllerInteraction.requestMessageUpdate(item.message.id)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
required init?(coder aDecoder: NSCoder) {
|
|
fatalError("init(coder:) has not been implemented")
|
|
}
|
|
|
|
override func asyncLayoutContent() -> (_ item: ChatMessageBubbleContentItem, _ layoutConstants: ChatMessageItemLayoutConstants, _ preparePosition: ChatMessageBubblePreparePosition, _ messageSelection: Bool?, _ constrainedSize: CGSize) -> (ChatMessageBubbleContentProperties, CGSize?, CGFloat, (CGSize, ChatMessageBubbleContentPosition) -> (CGFloat, (CGFloat) -> (CGSize, (ListViewItemUpdateAnimation) -> Void))) {
|
|
let interactiveFileLayout = self.interactiveFileNode.asyncLayout()
|
|
|
|
return { item, layoutConstants, preparePosition, _, constrainedSize in
|
|
var selectedFile: TelegramMediaFile?
|
|
for media in item.message.media {
|
|
if let telegramFile = media as? TelegramMediaFile {
|
|
selectedFile = telegramFile
|
|
}
|
|
}
|
|
|
|
let incoming = item.message.effectivelyIncoming(item.account.peerId)
|
|
let statusType: ChatMessageDateAndStatusType?
|
|
switch preparePosition {
|
|
case .linear(_, .None):
|
|
if incoming {
|
|
statusType = .BubbleIncoming
|
|
} else {
|
|
if item.message.flags.contains(.Failed) {
|
|
statusType = .BubbleOutgoing(.Failed)
|
|
} else if item.message.flags.isSending && !item.message.isSentOrAcknowledged {
|
|
statusType = .BubbleOutgoing(.Sending)
|
|
} else {
|
|
statusType = .BubbleOutgoing(.Sent(read: item.read))
|
|
}
|
|
}
|
|
default:
|
|
statusType = nil
|
|
}
|
|
|
|
var automaticDownload = false
|
|
automaticDownload = shouldDownloadMediaAutomatically(settings: item.controllerInteraction.automaticMediaDownloadSettings, peerType: item.associatedData.automaticDownloadPeerType, networkType: item.associatedData.automaticDownloadNetworkType, media: selectedFile!)
|
|
|
|
let (initialWidth, refineLayout) = interactiveFileLayout(item.account, item.presentationData, item.message, selectedFile!, automaticDownload, item.message.effectivelyIncoming(item.account.peerId), item.associatedData.isRecentActions, statusType, CGSize(width: constrainedSize.width - layoutConstants.file.bubbleInsets.left - layoutConstants.file.bubbleInsets.right, height: constrainedSize.height))
|
|
|
|
let contentProperties = ChatMessageBubbleContentProperties(hidesSimpleAuthorHeader: false, headerSpacing: 0.0, hidesBackground: .never, forceFullCorners: false, forceAlignment: .none)
|
|
|
|
return (contentProperties, nil, initialWidth + layoutConstants.file.bubbleInsets.left + layoutConstants.file.bubbleInsets.right, { constrainedSize, position in
|
|
let (refinedWidth, finishLayout) = refineLayout(CGSize(width: constrainedSize.width - layoutConstants.file.bubbleInsets.left - layoutConstants.file.bubbleInsets.right, height: constrainedSize.height))
|
|
|
|
return (refinedWidth + layoutConstants.file.bubbleInsets.left + layoutConstants.file.bubbleInsets.right, { boundingWidth in
|
|
let (fileSize, fileApply) = finishLayout(boundingWidth - layoutConstants.file.bubbleInsets.left - layoutConstants.file.bubbleInsets.right)
|
|
|
|
return (CGSize(width: fileSize.width + layoutConstants.file.bubbleInsets.left + layoutConstants.file.bubbleInsets.right, height: fileSize.height + layoutConstants.file.bubbleInsets.top + layoutConstants.file.bubbleInsets.bottom), { [weak self] _ in
|
|
if let strongSelf = self {
|
|
strongSelf.item = item
|
|
|
|
strongSelf.interactiveFileNode.frame = CGRect(origin: CGPoint(x: layoutConstants.file.bubbleInsets.left, y: layoutConstants.file.bubbleInsets.top), size: fileSize)
|
|
|
|
fileApply()
|
|
}
|
|
})
|
|
})
|
|
})
|
|
}
|
|
}
|
|
|
|
override func transitionNode(messageId: MessageId, media: Media) -> (ASDisplayNode, () -> UIView?)? {
|
|
if self.item?.message.id == messageId {
|
|
return self.interactiveFileNode.transitionNode(media: media)
|
|
} else {
|
|
return nil
|
|
}
|
|
}
|
|
|
|
override func updateHiddenMedia(_ media: [Media]?) -> Bool {
|
|
return self.interactiveFileNode.updateHiddenMedia(media)
|
|
}
|
|
|
|
override func animateInsertion(_ currentTimestamp: Double, duration: Double) {
|
|
self.interactiveFileNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
|
|
}
|
|
|
|
override func animateAdded(_ currentTimestamp: Double, duration: Double) {
|
|
self.interactiveFileNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
|
|
}
|
|
|
|
override func animateRemoved(_ currentTimestamp: Double, duration: Double) {
|
|
self.interactiveFileNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, removeOnCompletion: false)
|
|
}
|
|
}
|