AttachmentTransport: per-attachment транспортный сервер и тег, backward-compat Codable, download parity
This commit is contained in:
@@ -233,7 +233,7 @@ struct MessageAvatarView: View {
|
||||
private func downloadAvatar() {
|
||||
guard !isDownloading else { return }
|
||||
|
||||
let tag = extractTag(from: attachment.preview)
|
||||
let tag = attachment.effectiveDownloadTag
|
||||
guard !tag.isEmpty else {
|
||||
downloadError = true
|
||||
return
|
||||
@@ -247,9 +247,10 @@ struct MessageAvatarView: View {
|
||||
isDownloading = true
|
||||
downloadError = false
|
||||
|
||||
let server = attachment.transportServer
|
||||
Task {
|
||||
do {
|
||||
let encryptedData = try await TransportManager.shared.downloadFile(tag: tag)
|
||||
let encryptedData = try await TransportManager.shared.downloadFile(tag: tag, server: server)
|
||||
let encryptedString = String(decoding: encryptedData, as: UTF8.self)
|
||||
|
||||
let passwords = MessageCrypto.attachmentPasswordCandidates(from: storedPassword)
|
||||
|
||||
@@ -98,7 +98,10 @@ struct MessageFileView: View {
|
||||
|
||||
private var fileName: String { fileMetadata.name }
|
||||
private var fileSize: Int { fileMetadata.size }
|
||||
private var fileTag: String { fileMetadata.tag }
|
||||
private var fileTag: String {
|
||||
let effective = attachment.effectiveDownloadTag
|
||||
return effective.isEmpty ? fileMetadata.tag : effective
|
||||
}
|
||||
|
||||
private var formattedFileSize: String {
|
||||
let bytes = fileSize
|
||||
@@ -140,7 +143,7 @@ struct MessageFileView: View {
|
||||
|
||||
Task {
|
||||
do {
|
||||
let encryptedData = try await TransportManager.shared.downloadFile(tag: fileTag)
|
||||
let encryptedData = try await TransportManager.shared.downloadFile(tag: fileTag, server: attachment.transportServer)
|
||||
let encryptedString = String(decoding: encryptedData, as: UTF8.self)
|
||||
|
||||
let passwords = MessageCrypto.attachmentPasswordCandidates(from: storedPassword)
|
||||
|
||||
@@ -251,7 +251,7 @@ struct MessageImageView: View {
|
||||
private func downloadImage() {
|
||||
guard !isDownloading, image == nil else { return }
|
||||
|
||||
let tag = extractTag(from: attachment.preview)
|
||||
let tag = attachment.effectiveDownloadTag
|
||||
guard !tag.isEmpty else {
|
||||
downloadError = true
|
||||
return
|
||||
@@ -265,9 +265,10 @@ struct MessageImageView: View {
|
||||
isDownloading = true
|
||||
downloadError = false
|
||||
|
||||
let server = attachment.transportServer
|
||||
Task {
|
||||
do {
|
||||
let encryptedData = try await TransportManager.shared.downloadFile(tag: tag)
|
||||
let encryptedData = try await TransportManager.shared.downloadFile(tag: tag, server: server)
|
||||
let encryptedString = String(decoding: encryptedData, as: UTF8.self)
|
||||
|
||||
let passwords = MessageCrypto.attachmentPasswordCandidates(from: storedPassword)
|
||||
|
||||
@@ -901,10 +901,11 @@ final class NativeMessageCell: UICollectionViewCell, UIContextMenuInteractionDel
|
||||
/// Downloads avatar from CDN, decrypts, caches to disk, and returns the image.
|
||||
/// Shared logic with `MessageAvatarView.downloadAvatar()`.
|
||||
private static func downloadAndCacheAvatar(
|
||||
tag: String, attachmentId: String, storedPassword: String, senderKey: String
|
||||
tag: String, attachmentId: String, storedPassword: String, senderKey: String,
|
||||
server: String = ""
|
||||
) async -> UIImage? {
|
||||
do {
|
||||
let encryptedData = try await TransportManager.shared.downloadFile(tag: tag)
|
||||
let encryptedData = try await TransportManager.shared.downloadFile(tag: tag, server: server)
|
||||
let encryptedString = String(decoding: encryptedData, as: UTF8.self)
|
||||
|
||||
let passwords = MessageCrypto.attachmentPasswordCandidates(from: storedPassword)
|
||||
@@ -1109,7 +1110,7 @@ final class NativeMessageCell: UICollectionViewCell, UIContextMenuInteractionDel
|
||||
// Already downloaded?
|
||||
if AttachmentCache.shared.cachedImage(forAttachmentId: id) != nil { return }
|
||||
// Download from CDN
|
||||
let tag = AttachmentPreviewCodec.downloadTag(from: avatarAtt.preview)
|
||||
let tag = avatarAtt.effectiveDownloadTag
|
||||
guard !tag.isEmpty else { return }
|
||||
guard let password = message.attachmentPassword, !password.isEmpty else { return }
|
||||
|
||||
@@ -1118,10 +1119,12 @@ final class NativeMessageCell: UICollectionViewCell, UIContextMenuInteractionDel
|
||||
|
||||
let messageId = message.id
|
||||
let senderKey = message.fromPublicKey
|
||||
let server = avatarAtt.transportServer
|
||||
Task.detached(priority: .userInitiated) {
|
||||
let downloaded = await Self.downloadAndCacheAvatar(
|
||||
tag: tag, attachmentId: id,
|
||||
storedPassword: password, senderKey: senderKey
|
||||
storedPassword: password, senderKey: senderKey,
|
||||
server: server
|
||||
)
|
||||
await MainActor.run { [weak self] in
|
||||
guard let self, self.message?.id == messageId else { return }
|
||||
@@ -1569,7 +1572,7 @@ final class NativeMessageCell: UICollectionViewCell, UIContextMenuInteractionDel
|
||||
|
||||
private func downloadPhotoAttachment(attachment: MessageAttachment, message: ChatMessage) {
|
||||
if photoDownloadTasks[attachment.id] != nil { return }
|
||||
let tag = Self.extractTag(from: attachment.preview)
|
||||
let tag = attachment.effectiveDownloadTag
|
||||
guard !tag.isEmpty,
|
||||
let storedPassword = message.attachmentPassword,
|
||||
!storedPassword.isEmpty else {
|
||||
@@ -1593,9 +1596,10 @@ final class NativeMessageCell: UICollectionViewCell, UIContextMenuInteractionDel
|
||||
photoTileDownloadArrows[tileIndex].isHidden = true
|
||||
}
|
||||
|
||||
let server = attachment.transportServer
|
||||
photoDownloadTasks[attachmentId] = Task { [weak self] in
|
||||
do {
|
||||
let encryptedData = try await TransportManager.shared.downloadFile(tag: tag)
|
||||
let encryptedData = try await TransportManager.shared.downloadFile(tag: tag, server: server)
|
||||
let encryptedString = String(decoding: encryptedData, as: UTF8.self)
|
||||
let passwords = MessageCrypto.attachmentPasswordCandidates(from: storedPassword)
|
||||
let image = Self.decryptAndParseImage(encryptedString: encryptedString, passwords: passwords)
|
||||
|
||||
Reference in New Issue
Block a user