diff --git a/submodules/TelegramCore/TelegramCore/EnqueueMessage.swift b/submodules/TelegramCore/TelegramCore/EnqueueMessage.swift index f1725a95b1..45ede2460d 100644 --- a/submodules/TelegramCore/TelegramCore/EnqueueMessage.swift +++ b/submodules/TelegramCore/TelegramCore/EnqueueMessage.swift @@ -42,7 +42,7 @@ func augmentMediaWithReference(_ mediaReference: AnyMediaReference) -> Media { if file.partialReference != nil { return file } else { - return file.withUpdatedPartialReference(mediaReference.partial) + return file.withUpdatedPartialReference(mediaReference.partial) } } else if let image = mediaReference.media as? TelegramMediaImage { if image.partialReference != nil { @@ -367,7 +367,7 @@ func enqueueMessages(transaction: Transaction, account: Account, peerId: PeerId, } let authorId: PeerId? - if let peer = peer as? TelegramChannel, case let .broadcast(info) = peer.info { + if let peer = peer as? TelegramChannel, case .broadcast = peer.info { authorId = peer.id } else { authorId = account.peerId @@ -388,12 +388,9 @@ func enqueueMessages(transaction: Transaction, account: Account, peerId: PeerId, if let sourceMessage = sourceMessage, let author = sourceMessage.author ?? sourceMessage.peers[sourceMessage.id.peerId] { if let peer = peer as? TelegramSecretChat { var isAction = false - var mediaDuration: Int32? for media in sourceMessage.media { if let _ = media as? TelegramMediaAction { isAction = true - } else if let file = media as? TelegramMediaFile, let duration = file.duration { - mediaDuration = duration } } if !disableAutoremove, let messageAutoremoveTimeout = peer.messageAutoremoveTimeout, !isAction { diff --git a/submodules/TelegramCore/TelegramCore/PendingMessageUploadedContent.swift b/submodules/TelegramCore/TelegramCore/PendingMessageUploadedContent.swift index c48005d56e..c2df28501e 100644 --- a/submodules/TelegramCore/TelegramCore/PendingMessageUploadedContent.swift +++ b/submodules/TelegramCore/TelegramCore/PendingMessageUploadedContent.swift @@ -476,17 +476,17 @@ private enum UploadedMediaFileAndThumbnail { private func uploadedThumbnail(network: Network, postbox: Postbox, resourceReference: MediaResourceReference) -> Signal { return multipartUpload(network: network, postbox: postbox, source: .resource(resourceReference), encrypt: false, tag: TelegramMediaResourceFetchTag(statsCategory: .image), hintFileSize: nil, hintFileIsLarge: false) - |> mapError { _ -> PendingMessageUploadError in return .generic } - |> mapToSignal { result -> Signal in - switch result { - case .progress: - return .complete() - case let .inputFile(inputFile): - return .single(inputFile) - case .inputSecretFile: - return .single(nil) - } + |> mapError { _ -> PendingMessageUploadError in return .generic } + |> mapToSignal { result -> Signal in + switch result { + case .progress: + return .complete() + case let .inputFile(inputFile): + return .single(inputFile) + case .inputSecretFile: + return .single(nil) } + } } public func statsCategoryForFileWithAttributes(_ attributes: [TelegramMediaFileAttribute]) -> MediaResourceStatsCategory { diff --git a/submodules/TelegramCore/TelegramCore/StandaloneUploadedMedia.swift b/submodules/TelegramCore/TelegramCore/StandaloneUploadedMedia.swift index 5b593a5645..955271f97e 100644 --- a/submodules/TelegramCore/TelegramCore/StandaloneUploadedMedia.swift +++ b/submodules/TelegramCore/TelegramCore/StandaloneUploadedMedia.swift @@ -21,6 +21,20 @@ public struct StandaloneUploadSecretFile { let key: SecretFileEncryptionKey } +public enum StandaloneUploadMediaThumbnailResult { + case pending + case file(Api.InputFile) + case none + + var file: Api.InputFile? { + if case let .file(file) = self { + return file + } else { + return nil + } + } +} + public enum StandaloneUploadMediaResult { case media(AnyMediaReference) } @@ -30,7 +44,22 @@ public enum StandaloneUploadMediaEvent { case result(StandaloneUploadMediaResult) } -public func standaloneUploadedImage(account: Account, peerId: PeerId, text: String, data: Data, dimensions: CGSize) -> Signal { +private func uploadedThumbnail(network: Network, postbox: Postbox, data: Data) -> Signal { + return multipartUpload(network: network, postbox: postbox, source: .data(data), encrypt: false, tag: TelegramMediaResourceFetchTag(statsCategory: .image), hintFileSize: nil, hintFileIsLarge: false) + |> mapError { _ -> StandaloneUploadMediaError in return .generic } + |> mapToSignal { result -> Signal in + switch result { + case .progress: + return .complete() + case let .inputFile(inputFile): + return .single(inputFile) + case .inputSecretFile: + return .single(nil) + } + } +} + +public func standaloneUploadedImage(account: Account, peerId: PeerId, text: String, data: Data, thumbnailData: Data? = nil, dimensions: CGSize) -> Signal { return multipartUpload(network: account.network, postbox: account.postbox, source: .data(data), encrypt: peerId.namespace == Namespaces.Peer.SecretChat, tag: TelegramMediaResourceFetchTag(statsCategory: .image), hintFileSize: nil, hintFileIsLarge: false) |> mapError { _ -> StandaloneUploadMediaError in return .generic } |> mapToSignal { next -> Signal in @@ -91,65 +120,99 @@ public func standaloneUploadedImage(account: Account, peerId: PeerId, text: Stri } } -public func standaloneUploadedFile(account: Account, peerId: PeerId, text: String, source: MultipartUploadSource, mimeType: String, attributes: [TelegramMediaFileAttribute], hintFileIsLarge: Bool) -> Signal { - return multipartUpload(network: account.network, postbox: account.postbox, source: source, encrypt: peerId.namespace == Namespaces.Peer.SecretChat, tag: TelegramMediaResourceFetchTag(statsCategory: statsCategoryForFileWithAttributes(attributes)), hintFileSize: nil, hintFileIsLarge: hintFileIsLarge) - |> mapError { _ -> StandaloneUploadMediaError in return .generic } - |> mapToSignal { next -> Signal in - switch next { - case let .inputFile(inputFile): - return account.postbox.transaction { transaction -> Api.InputPeer? in - return transaction.getPeer(peerId).flatMap(apiInputPeer) - } - |> mapError { _ -> StandaloneUploadMediaError in return .generic } - |> mapToSignal { inputPeer -> Signal in - if let inputPeer = inputPeer { - return account.network.request(Api.functions.messages.uploadMedia(peer: inputPeer, media: Api.InputMedia.inputMediaUploadedDocument(flags: 0, file: inputFile, thumb: nil, mimeType: mimeType, attributes: inputDocumentAttributesFromFileAttributes(attributes), stickers: nil, ttlSeconds: nil))) - |> mapError { _ -> StandaloneUploadMediaError in return .generic } - |> mapToSignal { media -> Signal in - switch media { - case let .messageMediaDocument(_, document, _): - if let document = document { - if let mediaFile = telegramMediaFileFromApiDocument(document) { - return .single(.result(.media(.standalone(media: mediaFile)))) - } - } - default: - break - } - return .fail(.generic) - } - } else { - return .fail(.generic) - } - } - case let .inputSecretFile(file, size, key): - return account.postbox.transaction { transaction -> Api.InputEncryptedChat? in - if let peer = transaction.getPeer(peerId) as? TelegramSecretChat { - return Api.InputEncryptedChat.inputEncryptedChat(chatId: peer.id.id, accessHash: peer.accessHash) - } - return nil - } - |> introduceError(StandaloneUploadMediaError.self) - |> mapToSignal { inputChat -> Signal in - guard let inputChat = inputChat else { - return .fail(.generic) - } - return account.network.request(Api.functions.messages.uploadEncryptedFile(peer: inputChat, file: file)) - |> mapError { _ -> StandaloneUploadMediaError in return .generic - } - |> mapToSignal { result -> Signal in - switch result { - case let .encryptedFile(id, accessHash, size, dcId, _): - let media = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: arc4random64()), partialReference: nil, resource: SecretFileMediaResource(fileId: id, accessHash: accessHash, containerSize: size, decryptedSize: size, datacenterId: Int(dcId), key: key), previewRepresentations: [], immediateThumbnailData: nil, mimeType: mimeType, size: Int(size), attributes: attributes) - - return .single(.result(.media(.standalone(media: media)))) - case .encryptedFileEmpty: - return .fail(.generic) - } - } +public func standaloneUploadedFile(account: Account, peerId: PeerId, text: String, source: MultipartUploadSource, thumbnailData: Data? = nil, mimeType: String, attributes: [TelegramMediaFileAttribute], hintFileIsLarge: Bool) -> Signal { + let upload = multipartUpload(network: account.network, postbox: account.postbox, source: source, encrypt: peerId.namespace == Namespaces.Peer.SecretChat, tag: TelegramMediaResourceFetchTag(statsCategory: statsCategoryForFileWithAttributes(attributes)), hintFileSize: nil, hintFileIsLarge: hintFileIsLarge) + |> mapError { _ -> StandaloneUploadMediaError in return .generic } + + let uploadThumbnail: Signal + if let thumbnailData = thumbnailData { + uploadThumbnail = .single(.pending) + |> then( + uploadedThumbnail(network: account.network, postbox: account.postbox, data: thumbnailData) + |> mapError { _ -> StandaloneUploadMediaError in return .generic } + |> map { result in + if let result = result { + return .file(result) + } else { + return .none } + } + ) + } else { + uploadThumbnail = .single(.none) + } + + return combineLatest(upload, uploadThumbnail) + |> mapToSignal { result, thumbnail in + switch result { case let .progress(progress): return .single(.progress(progress)) - } + default: + switch thumbnail { + case .pending: + return .complete() + default: + switch result { + case let .inputFile(inputFile): + return account.postbox.transaction { transaction -> Api.InputPeer? in + return transaction.getPeer(peerId).flatMap(apiInputPeer) + } + |> mapError { _ -> StandaloneUploadMediaError in return .generic } + |> mapToSignal { inputPeer -> Signal in + if let inputPeer = inputPeer { + var flags: Int32 = 0 + let thumbnailFile = thumbnail.file + if let _ = thumbnailFile { + flags |= 1 << 2 + } + return account.network.request(Api.functions.messages.uploadMedia(peer: inputPeer, media: Api.InputMedia.inputMediaUploadedDocument(flags: flags, file: inputFile, thumb: thumbnailFile, mimeType: mimeType, attributes: inputDocumentAttributesFromFileAttributes(attributes), stickers: nil, ttlSeconds: nil))) + |> mapError { _ -> StandaloneUploadMediaError in return .generic } + |> mapToSignal { media -> Signal in + switch media { + case let .messageMediaDocument(_, document, _): + if let document = document { + if let mediaFile = telegramMediaFileFromApiDocument(document) { + return .single(.result(.media(.standalone(media: mediaFile)))) + } + } + default: + break + } + return .fail(.generic) + } + } else { + return .fail(.generic) + } + } + case let .inputSecretFile(file, _, key): + return account.postbox.transaction { transaction -> Api.InputEncryptedChat? in + if let peer = transaction.getPeer(peerId) as? TelegramSecretChat { + return Api.InputEncryptedChat.inputEncryptedChat(chatId: peer.id.id, accessHash: peer.accessHash) + } + return nil + } + |> introduceError(StandaloneUploadMediaError.self) + |> mapToSignal { inputChat -> Signal in + guard let inputChat = inputChat else { + return .fail(.generic) + } + return account.network.request(Api.functions.messages.uploadEncryptedFile(peer: inputChat, file: file)) + |> mapError { _ -> StandaloneUploadMediaError in return .generic } + |> mapToSignal { result -> Signal in + switch result { + case let .encryptedFile(id, accessHash, size, dcId, _): + let media = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: arc4random64()), partialReference: nil, resource: SecretFileMediaResource(fileId: id, accessHash: accessHash, containerSize: size, decryptedSize: size, datacenterId: Int(dcId), key: key), previewRepresentations: [], immediateThumbnailData: nil, mimeType: mimeType, size: Int(size), attributes: attributes) + + return .single(.result(.media(.standalone(media: media)))) + case .encryptedFileEmpty: + return .fail(.generic) + } + } + } + case .progress: + return .never() + } + } + } } }