diff --git a/TelegramCore/MultipartUpload.swift b/TelegramCore/MultipartUpload.swift index 8c86e862e9..c79734eff9 100644 --- a/TelegramCore/MultipartUpload.swift +++ b/TelegramCore/MultipartUpload.swift @@ -167,8 +167,11 @@ func multipartUpload(network: Network, postbox: Postbox, resource: MediaResource manager.start() + let fetchedResource = postbox.mediaBox.fetchedResource(resource).start() + return ActionDisposable { manager.cancel() + fetchedResource.dispose() } } } diff --git a/TelegramCore/Namespaces.swift b/TelegramCore/Namespaces.swift index e88e467e22..8927eb59fe 100644 --- a/TelegramCore/Namespaces.swift +++ b/TelegramCore/Namespaces.swift @@ -20,6 +20,7 @@ public struct Namespaces { public static let CloudFile: Int32 = 5 public static let CloudWebpage: Int32 = 6 public static let LocalImage: Int32 = 7 + public static let LocalFile: Int32 = 8 } public struct Peer { diff --git a/TelegramCore/PendingMessageManager.swift b/TelegramCore/PendingMessageManager.swift index 859fd7841e..db942836f2 100644 --- a/TelegramCore/PendingMessageManager.swift +++ b/TelegramCore/PendingMessageManager.swift @@ -49,6 +49,8 @@ private func applyMediaResourceChanges(from: Media, to: Media, postbox: Postbox) if let fromLargestRepresentation = largestImageRepresentation(fromImage.representations), let toLargestRepresentation = largestImageRepresentation(toImage.representations) { postbox.mediaBox.moveResourceData(from: fromLargestRepresentation.resource.id, to: toLargestRepresentation.resource.id) } + } else if let fromFile = from as? TelegramMediaFile, let toFile = to as? TelegramMediaFile { + postbox.mediaBox.moveResourceData(from: fromFile.resource.id, to: toFile.resource.id) } } diff --git a/TelegramCore/PendingMessageUploadedContent.swift b/TelegramCore/PendingMessageUploadedContent.swift index e376857ac2..8ba88ad2bc 100644 --- a/TelegramCore/PendingMessageUploadedContent.swift +++ b/TelegramCore/PendingMessageUploadedContent.swift @@ -34,8 +34,12 @@ func uploadedMessageContent(network: Network, postbox: Postbox, message: Message } else if let media = message.media.first { if let image = media as? TelegramMediaImage, let largestRepresentation = largestImageRepresentation(image.representations) { return uploadedMediaImageContent(network: network, postbox: postbox, image: image, message: message) - } else if let file = media as? TelegramMediaFile, let resource = file.resource as? CloudDocumentMediaResource { - return .single(.content(message, .media(Api.InputMedia.inputMediaDocument(id: Api.InputDocument.inputDocument(id: resource.fileId, accessHash: resource.accessHash), caption: message.text)))) + } else if let file = media as? TelegramMediaFile { + if let resource = file.resource as? CloudDocumentMediaResource { + return .single(.content(message, .media(Api.InputMedia.inputMediaDocument(id: Api.InputDocument.inputDocument(id: resource.fileId, accessHash: resource.accessHash), caption: message.text)))) + } else { + return uploadedMediaFileContent(network: network, postbox: postbox, file: file, message: message) + } } else { return .single(.content(message, .text(message.text))) } @@ -59,3 +63,54 @@ private func uploadedMediaImageContent(network: Network, postbox: Postbox, image return .single(.content(message, .text(message.text))) } } + +private func inputDocumentAttributesFromFile(_ file: TelegramMediaFile) -> [Api.DocumentAttribute] { + var attributes: [Api.DocumentAttribute] = [] + for attribute in file.attributes { + switch attribute { + case .Animated: + attributes.append(.documentAttributeAnimated) + case let .FileName(fileName): + attributes.append(.documentAttributeFilename(fileName: fileName)) + case let .ImageSize(size): + attributes.append(.documentAttributeImageSize(w: Int32(size.width), h: Int32(size.height))) + case let .Sticker(displayText): + attributes.append(.documentAttributeSticker(alt: displayText, stickerset: .inputStickerSetEmpty)) + case let .Video(duration, size): + attributes.append(.documentAttributeVideo(duration: Int32(duration), w: Int32(size.width), h: Int32(size.height))) + case let .Audio(isVoice, duration, title, performer, waveform): + var flags: Int32 = 0 + if isVoice { + flags |= Int32(1 << 10) + } + if let _ = title { + flags |= Int32(1 << 0) + } + if let _ = performer { + flags |= Int32(1 << 1) + } + var waveformBuffer: Buffer? + if let waveform = waveform { + flags |= Int32(1 << 2) + waveformBuffer = Buffer(data: waveform.makeData()) + } + attributes.append(.documentAttributeAudio(flags: flags, duration: Int32(duration), title: title, performer: performer, waveform: waveformBuffer)) + break + case .Unknown: + break + } + } + return attributes +} + +private func uploadedMediaFileContent(network: Network, postbox: Postbox, file: TelegramMediaFile, message: Message) -> Signal { + return multipartUpload(network: network, postbox: postbox, resource: file.resource) + |> map { next -> PendingMessageUploadedContentResult in + switch next { + case let .progress(progress): + return .progress(progress) + case let .inputFile(inputFile): + return .content(message, .media(Api.InputMedia.inputMediaUploadedDocument(file: inputFile, mimeType: file.mimeType, attributes: inputDocumentAttributesFromFile(file), caption: message.text))) + } + } +}