diff --git a/assets/l10n/intl_en.arb b/assets/l10n/intl_en.arb index de915e2ae..6398500f7 100644 --- a/assets/l10n/intl_en.arb +++ b/assets/l10n/intl_en.arb @@ -3208,6 +3208,18 @@ } } }, + "sentVoiceMessage": "\uD83C\uDF99\uFE0F {duration} - {sender}", + "@sentVoiceMessage": { + "type": "String", + "placeholders": { + "sender": { + "type": "String" + }, + "duration": { + "type": "String" + } + } + }, "deletePushRuleCanNotBeUndone": "If you delete this notification setting, this can not be undone.", "more": "More", "shareKeysWith": "Share keys with...", diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 4557f1a4b..02b5406b4 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -327,10 +327,14 @@ inputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist", ); + inputPaths = ( + ); name = "[CP] Copy Pods Resources"; outputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist", ); + outputPaths = ( + ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n"; diff --git a/lib/utils/client_manager.dart b/lib/utils/client_manager.dart index 523f9c416..8362d4a64 100644 --- a/lib/utils/client_manager.dart +++ b/lib/utils/client_manager.dart @@ -132,9 +132,6 @@ abstract class ClientManager { }, logLevel: kReleaseMode ? Level.warning : Level.verbose, databaseBuilder: flutterMatrixSdkDatabaseBuilder, - // #Pangea - // legacyDatabaseBuilder: FlutterHiveCollectionsDatabase.databaseBuilder, - // Pangea# supportedLoginTypes: { AuthenticationTypes.password, AuthenticationTypes.sso, diff --git a/lib/utils/matrix_sdk_extensions/flutter_hive_collections_database.dart b/lib/utils/matrix_sdk_extensions/flutter_hive_collections_database.dart deleted file mode 100644 index 9ad5ce5c0..000000000 --- a/lib/utils/matrix_sdk_extensions/flutter_hive_collections_database.dart +++ /dev/null @@ -1,149 +0,0 @@ -import 'dart:convert'; -import 'dart:io'; - -import 'package:flutter/foundation.dart' hide Key; -import 'package:flutter/services.dart'; - -import 'package:flutter_secure_storage/flutter_secure_storage.dart'; -import 'package:hive/hive.dart'; -import 'package:matrix/matrix.dart'; -import 'package:path_provider/path_provider.dart'; -import 'package:universal_html/html.dart' as html; - -// ignore: deprecated_member_use -class FlutterHiveCollectionsDatabase extends HiveCollectionsDatabase { - FlutterHiveCollectionsDatabase( - super.name, - String super.path, { - super.key, - }); - - static const String _cipherStorageKey = 'hive_encryption_key'; - - static Future databaseBuilder( - Client client, - ) async { - Logs().d('Open Hive...'); - HiveAesCipher? hiverCipher; - try { - // Workaround for secure storage is calling Platform.operatingSystem on web - if (kIsWeb) { - // ignore: unawaited_futures - html.window.navigator.storage?.persist(); - throw MissingPluginException(); - } - - const secureStorage = FlutterSecureStorage(); - final containsEncryptionKey = - await secureStorage.read(key: _cipherStorageKey) != null; - if (!containsEncryptionKey) { - // do not try to create a buggy secure storage for new Linux users - if (Platform.isLinux) throw MissingPluginException(); - final key = Hive.generateSecureKey(); - await secureStorage.write( - key: _cipherStorageKey, - value: base64UrlEncode(key), - ); - } - - // workaround for if we just wrote to the key and it still doesn't exist - final rawEncryptionKey = await secureStorage.read(key: _cipherStorageKey); - if (rawEncryptionKey == null) throw MissingPluginException(); - - hiverCipher = HiveAesCipher(base64Url.decode(rawEncryptionKey)); - } on MissingPluginException catch (_) { - const FlutterSecureStorage() - .delete(key: _cipherStorageKey) - .catchError((_) {}); - Logs().i('Hive encryption is not supported on this platform'); - } catch (e, s) { - const FlutterSecureStorage() - .delete(key: _cipherStorageKey) - .catchError((_) {}); - Logs().w('Unable to init Hive encryption', e, s); - } - - final db = FlutterHiveCollectionsDatabase( - 'hive_collections_${client.clientName.replaceAll(' ', '_').toLowerCase()}', - await findDatabasePath(client), - key: hiverCipher, - ); - try { - await db.open(); - } catch (e, s) { - Logs().w('Unable to open Hive. Delete database and storage key...', e, s); - const FlutterSecureStorage().delete(key: _cipherStorageKey); - await db.clear().catchError((_) {}); - await Hive.deleteFromDisk(); - rethrow; - } - Logs().d('Hive is ready'); - return db; - } - - static Future findDatabasePath(Client client) async { - var path = client.clientName; - if (!kIsWeb) { - Directory directory; - try { - if (Platform.isLinux) { - directory = await getApplicationSupportDirectory(); - } else { - directory = await getApplicationDocumentsDirectory(); - } - } catch (_) { - try { - directory = await getLibraryDirectory(); - } catch (_) { - directory = Directory.current; - } - } - // do not destroy your stable FluffyChat in debug mode - directory = Directory( - directory.uri.resolve(kDebugMode ? 'hive_debug' : 'hive').toFilePath(), - ); - directory.create(recursive: true); - path = directory.path; - } - return path; - } - - @override - int get maxFileSize => supportsFileStoring ? 100 * 1000 * 1000 : 0; - @override - bool get supportsFileStoring => !kIsWeb; - - Future _getFileStoreDirectory() async { - try { - try { - return (await getTemporaryDirectory()).path; - } catch (_) { - return (await getApplicationDocumentsDirectory()).path; - } - } catch (_) { - return (await getDownloadsDirectory())!.path; - } - } - - @override - Future getFile(Uri mxcUri) async { - if (!supportsFileStoring) return null; - final tempDirectory = await _getFileStoreDirectory(); - final file = - File('$tempDirectory/${Uri.encodeComponent(mxcUri.toString())}'); - if (await file.exists() == false) return null; - final bytes = await file.readAsBytes(); - return bytes; - } - - @override - Future storeFile(Uri mxcUri, Uint8List bytes, int time) async { - if (!supportsFileStoring) return null; - final tempDirectory = await _getFileStoreDirectory(); - final file = - File('$tempDirectory/${Uri.encodeComponent(mxcUri.toString())}'); - if (await file.exists()) return; - await file.writeAsBytes(bytes); - return; - } -} diff --git a/lib/utils/matrix_sdk_extensions/flutter_matrix_dart_sdk_database/builder.dart b/lib/utils/matrix_sdk_extensions/flutter_matrix_dart_sdk_database/builder.dart index 85bc517bc..b07f6e613 100644 --- a/lib/utils/matrix_sdk_extensions/flutter_matrix_dart_sdk_database/builder.dart +++ b/lib/utils/matrix_sdk_extensions/flutter_matrix_dart_sdk_database/builder.dart @@ -10,7 +10,6 @@ import 'package:sqflite_common_ffi/sqflite_ffi.dart'; import 'package:universal_html/html.dart' as html; import 'package:fluffychat/pangea/common/utils/error_handler.dart'; -import 'package:fluffychat/utils/matrix_sdk_extensions/flutter_hive_collections_database.dart'; import 'package:fluffychat/utils/platform_infos.dart'; import 'cipher.dart'; @@ -74,7 +73,7 @@ Future flutterMatrixSdkDatabaseBuilder(Client client) async { Logs().e('Unable to send error notification', e, s); } - return FlutterHiveCollectionsDatabase.databaseBuilder(client); + rethrow; } } diff --git a/lib/utils/matrix_sdk_extensions/matrix_locals.dart b/lib/utils/matrix_sdk_extensions/matrix_locals.dart index 83875cb43..0db2251d7 100644 --- a/lib/utils/matrix_sdk_extensions/matrix_locals.dart +++ b/lib/utils/matrix_sdk_extensions/matrix_locals.dart @@ -1,4 +1,5 @@ import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:intl/intl.dart'; import 'package:matrix/matrix.dart'; /// This is a temporary helper class until there is a proper solution to this with the new system @@ -353,4 +354,21 @@ class MatrixLocals extends MatrixLocalizations { @override String get cancelledSend => l10n.sendCanceled; + + @override + String voiceMessage(String senderName, Duration? duration) { + final dateTime = duration == null + ? null + : DateTime.fromMillisecondsSinceEpoch( + duration.inSeconds * 1000, + ); + final formattedDuration = dateTime == null + ? '' + : DateFormat( + DateFormat.MINUTE_SECOND, + l10n.localeName, + ).format(dateTime); + + return l10n.sentVoiceMessage(senderName, formattedDuration); + } } diff --git a/pubspec.yaml b/pubspec.yaml index fa7a96bde..2af6cb2d5 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -73,7 +73,7 @@ dependencies: git: url: https://github.com/pangeachat/matrix-dart-sdk.git # repo ref: disable-space-hierarchy-cache # branch - # matrix: ^0.39.4 + # matrix: ^0.40.0 # Pangea# mime: ^1.0.6 native_imaging: ^0.2.0 diff --git a/test/utils/test_client.dart b/test/utils/test_client.dart index 7cbe72f71..c27faa8f6 100644 --- a/test/utils/test_client.dart +++ b/test/utils/test_client.dart @@ -3,7 +3,7 @@ import 'package:matrix/encryption/utils/key_verification.dart'; import 'package:matrix/matrix.dart'; -import 'package:fluffychat/utils/matrix_sdk_extensions/flutter_hive_collections_database.dart'; +import 'package:fluffychat/utils/matrix_sdk_extensions/flutter_matrix_dart_sdk_database/builder.dart'; Future prepareTestClient({ bool loggedIn = false, @@ -22,7 +22,7 @@ Future prepareTestClient({ importantStateEvents: { 'im.ponies.room_emotes', // we want emotes to work properly }, - databaseBuilder: FlutterHiveCollectionsDatabase.databaseBuilder, + databaseBuilder: flutterMatrixSdkDatabaseBuilder, supportedLoginTypes: { AuthenticationTypes.password, AuthenticationTypes.sso,