diff --git a/lib/src/utils/native_implementations.dart b/lib/src/utils/native_implementations.dart index 59be73c7..5a947253 100644 --- a/lib/src/utils/native_implementations.dart +++ b/lib/src/utils/native_implementations.dart @@ -25,22 +25,37 @@ abstract class NativeImplementations { /// the UI to likely freeze static const dummy = NativeImplementationsDummy(); - FutureOr generateUploadKeys(GenerateUploadKeysArgs args); + FutureOr generateUploadKeys( + GenerateUploadKeysArgs args, { + bool retryInDummy = true, + }); - FutureOr keyFromPassphrase(KeyFromPassphraseArgs args); + FutureOr keyFromPassphrase( + KeyFromPassphraseArgs args, { + bool retryInDummy = true, + }); - FutureOr decryptFile(EncryptedFile file); + FutureOr decryptFile( + EncryptedFile file, { + bool retryInDummy = true, + }); FutureOr shrinkImage( - MatrixImageFileResizeArguments args); + MatrixImageFileResizeArguments args, { + bool retryInDummy = false, + }); - FutureOr calcImageMetadata(Uint8List bytes); + FutureOr calcImageMetadata( + Uint8List bytes, { + bool retryInDummy = false, + }); @override /// this implementation will catch any non-implemented method dynamic noSuchMethod(Invocation invocation) { final dynamic argument = invocation.positionalArguments.single; + final bool retryInDummy = invocation.namedArguments['retryInDummy'] as bool; final memberName = invocation.memberName.toString().split('"')[1]; Logs().w( @@ -50,15 +65,15 @@ abstract class NativeImplementations { ); switch (memberName) { case 'generateUploadKeys': - return dummy.generateUploadKeys(argument); + return dummy.generateUploadKeys(argument, retryInDummy: retryInDummy); case 'keyFromPassphrase': - return dummy.keyFromPassphrase(argument); + return dummy.keyFromPassphrase(argument, retryInDummy: retryInDummy); case 'decryptFile': - return dummy.decryptFile(argument); + return dummy.decryptFile(argument, retryInDummy: retryInDummy); case 'shrinkImage': - return dummy.shrinkImage(argument); + return dummy.shrinkImage(argument, retryInDummy: retryInDummy); case 'calcImageMetadata': - return dummy.calcImageMetadata(argument); + return dummy.calcImageMetadata(argument, retryInDummy: retryInDummy); default: return super.noSuchMethod(invocation); } @@ -69,28 +84,42 @@ class NativeImplementationsDummy extends NativeImplementations { const NativeImplementationsDummy(); @override - Future decryptFile(EncryptedFile file) { + Future decryptFile( + EncryptedFile file, { + bool retryInDummy = true, + }) { return decryptFileImplementation(file); } @override - Future generateUploadKeys(GenerateUploadKeysArgs args) async { + Future generateUploadKeys( + GenerateUploadKeysArgs args, { + bool retryInDummy = true, + }) async { return generateUploadKeysImplementation(args); } @override - Future keyFromPassphrase(KeyFromPassphraseArgs args) { + Future keyFromPassphrase( + KeyFromPassphraseArgs args, { + bool retryInDummy = true, + }) { return generateKeyFromPassphrase(args); } @override MatrixImageFileResizedResponse? shrinkImage( - MatrixImageFileResizeArguments args) { + MatrixImageFileResizeArguments args, { + bool retryInDummy = false, + }) { return MatrixImageFile.resizeImplementation(args); } @override - MatrixImageFileResizedResponse? calcImageMetadata(Uint8List bytes) { + MatrixImageFileResizedResponse? calcImageMetadata( + Uint8List bytes, { + bool retryInDummy = false, + }) { return MatrixImageFile.calcMetadataImplementation(bytes); } } @@ -122,7 +151,10 @@ class NativeImplementationsIsolate extends NativeImplementations { } @override - Future decryptFile(EncryptedFile file) { + Future decryptFile( + EncryptedFile file, { + bool retryInDummy = true, + }) { return runInBackground( NativeImplementations.dummy.decryptFile, file, @@ -130,7 +162,10 @@ class NativeImplementationsIsolate extends NativeImplementations { } @override - Future generateUploadKeys(GenerateUploadKeysArgs args) async { + Future generateUploadKeys( + GenerateUploadKeysArgs args, { + bool retryInDummy = true, + }) async { return runInBackground( NativeImplementations.dummy.generateUploadKeys, args, @@ -138,7 +173,10 @@ class NativeImplementationsIsolate extends NativeImplementations { } @override - Future keyFromPassphrase(KeyFromPassphraseArgs args) { + Future keyFromPassphrase( + KeyFromPassphraseArgs args, { + bool retryInDummy = true, + }) { return runInBackground( NativeImplementations.dummy.keyFromPassphrase, args, @@ -147,7 +185,9 @@ class NativeImplementationsIsolate extends NativeImplementations { @override Future shrinkImage( - MatrixImageFileResizeArguments args) { + MatrixImageFileResizeArguments args, { + bool retryInDummy = false, + }) { return runInBackground( NativeImplementations.dummy.shrinkImage, @@ -156,7 +196,10 @@ class NativeImplementationsIsolate extends NativeImplementations { } @override - FutureOr calcImageMetadata(Uint8List bytes) { + FutureOr calcImageMetadata( + Uint8List bytes, { + bool retryInDummy = false, + }) { return runInBackground( NativeImplementations.dummy.calcImageMetadata, bytes, diff --git a/lib/src/utils/web_worker/native_implementations_web_worker.dart b/lib/src/utils/web_worker/native_implementations_web_worker.dart index c4a61e8a..db9fc68f 100644 --- a/lib/src/utils/web_worker/native_implementations_web_worker.dart +++ b/lib/src/utils/web_worker/native_implementations_web_worker.dart @@ -62,7 +62,9 @@ class NativeImplementationsWebWorker extends NativeImplementations { @override Future calcImageMetadata( - Uint8List bytes) async { + Uint8List bytes, { + bool retryInDummy = false, + }) async { try { final result = await operation, Uint8List>( WebWorkerOperations.calcImageMetadata, @@ -70,6 +72,11 @@ class NativeImplementationsWebWorker extends NativeImplementations { ); return MatrixImageFileResizedResponse.fromJson(Map.from(result)); } catch (e, s) { + if (!retryInDummy) { + Logs().e( + 'Web worker computation error. Ignoring and returning null', e, s); + return null; + } Logs().e('Web worker computation error. Fallback to main thread', e, s); return NativeImplementations.dummy.calcImageMetadata(bytes); } @@ -77,7 +84,9 @@ class NativeImplementationsWebWorker extends NativeImplementations { @override Future shrinkImage( - MatrixImageFileResizeArguments args) async { + MatrixImageFileResizeArguments args, { + bool retryInDummy = false, + }) async { try { final result = await operation, Map>( @@ -86,13 +95,21 @@ class NativeImplementationsWebWorker extends NativeImplementations { ); return MatrixImageFileResizedResponse.fromJson(Map.from(result)); } catch (e, s) { + if (!retryInDummy) { + Logs().e( + 'Web worker computation error. Ignoring and returning null', e, s); + return null; + } Logs().e('Web worker computation error. Fallback to main thread', e, s); return NativeImplementations.dummy.shrinkImage(args); } } @override - Future generateUploadKeys(GenerateUploadKeysArgs args) async { + Future generateUploadKeys( + GenerateUploadKeysArgs args, { + bool retryInDummy = true, + }) async { try { final result = await operation, Map>( @@ -101,6 +118,7 @@ class NativeImplementationsWebWorker extends NativeImplementations { ); return RoomKeys.fromJson(Map.from(result)); } catch (e, s) { + if (!retryInDummy) rethrow; Logs().e('Web worker computation error. Fallback to main thread', e, s); return NativeImplementations.dummy.generateUploadKeys(args); }