diff --git a/Riot/Modules/Room/VoiceMessages/VoiceMessageAttachmentCacheManager.swift b/Riot/Modules/Room/VoiceMessages/VoiceMessageAttachmentCacheManager.swift index 1054c8232..f1fd66efd 100644 --- a/Riot/Modules/Room/VoiceMessages/VoiceMessageAttachmentCacheManager.swift +++ b/Riot/Modules/Room/VoiceMessages/VoiceMessageAttachmentCacheManager.swift @@ -23,6 +23,7 @@ enum VoiceMessageAttachmentCacheManagerError: Error { case decryptionError(Error) case preparationError(Error) case conversionError(Error) + case invalidNumberOfSamples case samplingError } @@ -52,33 +53,32 @@ class VoiceMessageAttachmentCacheManager { } func loadAttachment(_ attachment: MXKAttachment, numberOfSamples: Int, completion: @escaping (Result<(URL, [Float]), Error>) -> Void) { - workQueue.async { - self.enqueueLoadAttachment(attachment, numberOfSamples: numberOfSamples, completion: completion) - } - } - - func enqueueLoadAttachment(_ attachment: MXKAttachment, numberOfSamples: Int, completion: @escaping (Result<(URL, [Float]), Error>) -> Void) { guard attachment.type == MXKAttachmentTypeVoiceMessage else { - DispatchQueue.main.async { - completion(Result.failure(VoiceMessageAttachmentCacheManagerError.invalidAttachmentType)) - } + completion(Result.failure(VoiceMessageAttachmentCacheManagerError.invalidAttachmentType)) return } guard let identifier = attachment.eventId else { - DispatchQueue.main.async { - completion(Result.failure(VoiceMessageAttachmentCacheManagerError.invalidEventId)) - } + completion(Result.failure(VoiceMessageAttachmentCacheManagerError.invalidEventId)) + return + } + + guard numberOfSamples > 0 else { + completion(Result.failure(VoiceMessageAttachmentCacheManagerError.invalidNumberOfSamples)) return } if let finalURL = finalURLs[identifier], let samples = samples[identifier]?[numberOfSamples] { - DispatchQueue.main.async { - completion(Result.success((finalURL, samples))) - } + completion(Result.success((finalURL, samples))) return } + workQueue.async { + self.enqueueLoadAttachment(attachment, identifier: identifier, numberOfSamples: numberOfSamples, completion: completion) + } + } + + private func enqueueLoadAttachment(_ attachment: MXKAttachment, identifier: String, numberOfSamples: Int, completion: @escaping (Result<(URL, [Float]), Error>) -> Void) { if var callbacks = completionCallbacks[identifier] { callbacks.append(CompletionWrapper(completion)) completionCallbacks[identifier] = callbacks @@ -160,13 +160,14 @@ class VoiceMessageAttachmentCacheManager { return } - for wrapper in callbacks { - DispatchQueue.main.async { + let copy = callbacks.map { $0 } + DispatchQueue.main.async { + for wrapper in copy { wrapper.completion(Result.success((url, samples))) } } - completionCallbacks[identifier] = nil + self.completionCallbacks[identifier] = nil } private func invokeFailureCallbacksForIdentifier(_ identifier: String, error: Error) { @@ -174,12 +175,13 @@ class VoiceMessageAttachmentCacheManager { return } - for wrapper in callbacks { - DispatchQueue.main.async { + let copy = callbacks.map { $0 } + DispatchQueue.main.async { + for wrapper in copy { wrapper.completion(Result.failure(error)) } } - completionCallbacks[identifier] = nil + self.completionCallbacks[identifier] = nil } } diff --git a/Riot/Modules/Room/VoiceMessages/VoiceMessageController.swift b/Riot/Modules/Room/VoiceMessages/VoiceMessageController.swift index 1b072e445..3f8a61a12 100644 --- a/Riot/Modules/Room/VoiceMessages/VoiceMessageController.swift +++ b/Riot/Modules/Room/VoiceMessages/VoiceMessageController.swift @@ -300,7 +300,7 @@ public class VoiceMessageController: NSObject, VoiceMessageToolbarViewDelegate, displayLink.isPaused = !audioPlayer.isPlaying let requiredNumberOfSamples = _voiceMessageToolbarView.getRequiredNumberOfSamples() - if audioSamples.count != requiredNumberOfSamples { + if audioSamples.count != requiredNumberOfSamples && requiredNumberOfSamples > 0 { padSamplesArrayToSize(requiredNumberOfSamples) waveformAnalyser = WaveformAnalyzer(audioAssetURL: url)