From 84628f4a4bd7855f2d27e84ad59eb033fb3e4c44 Mon Sep 17 00:00:00 2001 From: Flajt Date: Sun, 17 Mar 2024 22:05:55 +0100 Subject: [PATCH 1/8] Chore: Add test for consts --- test/consts_test.dart | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 test/consts_test.dart diff --git a/test/consts_test.dart b/test/consts_test.dart new file mode 100644 index 0000000..f0aeb51 --- /dev/null +++ b/test/consts_test.dart @@ -0,0 +1,33 @@ +import "package:decentproof/constants.dart"; +import "package:flutter_dotenv/flutter_dotenv.dart"; +import "package:test/test.dart"; + +// While it seems senseless at first, this is to figure out if the env vars can be accessed in the CI/CD pipeline. +void main() { + setUp(() async { + await dotenv.load(fileName: ".env"); + }); + group( + "Constants", + () { + test("SENTRY_DSN is not empty", () { + expect(SENTRY_DSN, isNotEmpty); + }); + test("SIGN_URL is not empty", () { + expect(SIGN_URL, isNotEmpty); + }); + test("VERIFY_URL is not empty", () { + expect(VERIFY_URL, isNotEmpty); + }); + test("GET_KEY_URL is not empty", () { + expect(GET_KEY_URL, isNotEmpty); + }); + test("CHECK_KEY_URL is not empty", () { + expect(CHECK_KEY_URL, isNotEmpty); + }); + test("WIKI_URL is not empty", () { + expect(WIKI_URL, isNotEmpty); + }); + }, + ); +} From 777f56eb76d783379e6905c99242f3c5e011c9d3 Mon Sep 17 00:00:00 2001 From: Flajt Date: Sun, 17 Mar 2024 23:08:58 +0100 Subject: [PATCH 2/8] Fix: Add missing hashing key --- assets/translations/ar.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/assets/translations/ar.json b/assets/translations/ar.json index a97eaff..9e9d208 100644 --- a/assets/translations/ar.json +++ b/assets/translations/ar.json @@ -78,6 +78,7 @@ }, "verificationNotification": { "title": "جارٍ التحقق", - "validatingMetaData": "التحقق من صحة البيانات الوصفية" + "validatingMetaData": "التحقق من صحة البيانات الوصفية", + "hashing": "يتم حساب قيمة التجزئة" } } \ No newline at end of file From 832fac656fab82665fbc84c2c9c317bb1344bf07 Mon Sep 17 00:00:00 2001 From: Flajt Date: Sun, 17 Mar 2024 23:09:17 +0100 Subject: [PATCH 3/8] Feat: Add locales to constants --- lib/constants.dart | 13 +++++++++++-- lib/main.dart | 11 ++--------- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/lib/constants.dart b/lib/constants.dart index aa57bb2..1683813 100644 --- a/lib/constants.dart +++ b/lib/constants.dart @@ -1,5 +1,6 @@ -// ignore_for_file: non_constant_identifier_names +// ignore_for_file: non_constant_identifier_names, constant_identifier_names +import 'dart:ui'; import 'package:flutter_dotenv/flutter_dotenv.dart'; final String GET_KEY_URL = dotenv.env["GET_KEY_URL"] ?? ""; @@ -7,6 +8,14 @@ final String CHECK_KEY_URL = dotenv.env["CHECK_KEY_URL"] ?? ""; final String SIGN_URL = dotenv.env["SIGN_URL"] ?? ""; final String VERIFY_URL = dotenv.env["VERIFY_URL"] ?? ""; final String SENTRY_DSN = dotenv.env["SENTRY_DSN"] ?? ""; +const List SUPPORTED_LOCALS = [ + Locale("en"), + Locale("de"), + Locale("sn"), + Locale("fr"), + Locale("jp"), + Locale("zn"), + Locale("ar") +]; -// ignore: constant_identifier_names const String WIKI_URL = "https://github.com/Flajt/decentproof-app/wiki/FAQ"; diff --git a/lib/main.dart b/lib/main.dart index d731ba8..a95ba87 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,5 +1,6 @@ import 'dart:async'; +import 'package:decentproof/constants.dart'; import 'package:decentproof/features/hashing/bloc/SubmissionBloc.dart'; import 'package:decentproof/features/hashing/bloc/PreparationBloc/PreparationBloc.dart'; import 'package:decentproof/features/metadata/bloc/LocationWarningBloc.dart'; @@ -44,15 +45,7 @@ void main() async { useOnlyLangCode: true, fallbackLocale: const Locale("en"), path: "assets/translations", - supportedLocales: const [ - Locale("en"), - Locale("de"), - Locale("sn"), - Locale("fr"), - Locale("jp"), - Locale("zn"), - Locale("ar") - ], + supportedLocales: SUPPORTED_LOCALS, child: const MyApp())); Bloc.observer = MetricsBlocObserver(); }, (error, stack) { From a1baff645ba591445fd9792b0ab42738e61383fa Mon Sep 17 00:00:00 2001 From: Flajt Date: Sun, 17 Mar 2024 23:10:11 +0100 Subject: [PATCH 4/8] Fix: Use tr("my.key") to get localization without context in bloc --- .../bloc/PreparationBloc/PreparationBloc.dart | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/lib/features/hashing/bloc/PreparationBloc/PreparationBloc.dart b/lib/features/hashing/bloc/PreparationBloc/PreparationBloc.dart index 5132cc1..b81900d 100644 --- a/lib/features/hashing/bloc/PreparationBloc/PreparationBloc.dart +++ b/lib/features/hashing/bloc/PreparationBloc/PreparationBloc.dart @@ -73,8 +73,8 @@ class PreparationBloc extends Bloc { "instructions", "audio::${event.filePath}"); await foregroundService.start( startPreperationForegroundService, - "perperationNotification.title".tr(), - "perperationNotification.initialDescription".tr()); + tr("perperationNotification.title"), + tr("perperationNotification.initalDescription")); ReceivePort port = await foregroundService.getReceivePort(); final stream = port.asBroadcastStream(); await emit.forEach(stream, onData: (message) { @@ -122,10 +122,11 @@ class PreparationBloc extends Bloc { try { final path = await imageSavingService.saveFile(); await foregroundService.setData("instructions", "image::$path"); - await foregroundService.start( - startPreperationForegroundService, - "perperationNotification.title".tr(), - "perperationNotification.initialDescription".tr()); + final notificationTitle = tr("perperationNotification.title"); + final notificationBody = + tr("perperationNotification.initalDescription"); + await foregroundService.start(startPreperationForegroundService, + notificationTitle, notificationBody); ReceivePort port = await foregroundService.getReceivePort(); final stream = port.asBroadcastStream(); await emit.forEach(stream, onData: (message) { @@ -177,8 +178,8 @@ class PreparationBloc extends Bloc { await foregroundService.setData("instructions", "video::$path"); await foregroundService.start( startPreperationForegroundService, - "perperationNotification.title".tr(), - "perperationNotification.initialDescription".tr()); + tr("perperationNotification.title"), + tr("perperationNotification.initalDescription")); ReceivePort port = await foregroundService.getReceivePort(); final stream = port.asBroadcastStream(); await emit.forEach(stream, onData: (message) { From 8bdbfea372c65b4c522e9e5af7032984919bccd1 Mon Sep 17 00:00:00 2001 From: Flajt Date: Sun, 17 Mar 2024 23:10:44 +0100 Subject: [PATCH 5/8] Fix: Channel name for translation --- lib/shared/foregroundService/ForegroundServiceWrapper.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/shared/foregroundService/ForegroundServiceWrapper.dart b/lib/shared/foregroundService/ForegroundServiceWrapper.dart index d716332..f635e49 100644 --- a/lib/shared/foregroundService/ForegroundServiceWrapper.dart +++ b/lib/shared/foregroundService/ForegroundServiceWrapper.dart @@ -10,7 +10,7 @@ class ForegroundServiceWrapper implements IForegroundService { androidNotificationOptions: AndroidNotificationOptions( channelId: 'decentproof_hashing_service', channelName: 'Hashing & Preperation Channel', - channelDescription: "notification.description".tr(), + channelDescription: "notificationChannel.description".tr(), channelImportance: NotificationChannelImportance.LOW, priority: NotificationPriority.MAX, visibility: NotificationVisibility.VISIBILITY_PRIVATE, From 40f6ae17d2f47622931a980112619089b70b342f Mon Sep 17 00:00:00 2001 From: Flajt Date: Sun, 17 Mar 2024 23:12:46 +0100 Subject: [PATCH 6/8] Chore+Fix: Rm useless EasyLocalization init, place dotenv.load before initSentry --- .../logic/foregroundService/PerperationTaskHandler.dart | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/features/hashing/logic/foregroundService/PerperationTaskHandler.dart b/lib/features/hashing/logic/foregroundService/PerperationTaskHandler.dart index be45a8e..e956c7c 100644 --- a/lib/features/hashing/logic/foregroundService/PerperationTaskHandler.dart +++ b/lib/features/hashing/logic/foregroundService/PerperationTaskHandler.dart @@ -10,7 +10,7 @@ import 'package:decentproof/features/metadata/interfaces/IMetaDataService.dart'; import 'package:decentproof/features/metadata/models/LocationModel.dart'; import 'package:decentproof/shared/util/initSentry.dart'; import 'package:decentproof/shared/util/register.dart'; -import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:flutter_foreground_task/flutter_foreground_task.dart'; import 'package:get_it/get_it.dart'; import 'package:sentry_flutter/sentry_flutter.dart'; @@ -21,7 +21,7 @@ class PreperationTaskHandler extends TaskHandler { void onStart(DateTime timestamp, SendPort? sendPort) async { DartPluginRegistrant.ensureInitialized(); try { - await EasyLocalization.ensureInitialized(); + await dotenv.load(); await initSentry(); await registar(); final getIt = GetIt.I; @@ -173,7 +173,6 @@ class PreperationTaskHandler extends TaskHandler { // Note that the app will only route to "/resume-route" when it is exited so // it will usually be necessary to send a message through the send port to // signal it to restore state when the app is already started. - FlutterForegroundTask.launchApp("/"); } Future sendAUpdateProgress(SendPort? sendPort, String step, From 268524f4080390ddc8addd0b1198aad586a3eb8b Mon Sep 17 00:00:00 2001 From: Flajt Date: Sun, 17 Mar 2024 23:13:22 +0100 Subject: [PATCH 7/8] Fix: Resolve using translations from foreground notifications --- .../VerificationTaskHandler.dart | 14 ++++---- lib/shared/util/loadTranslations.dart | 34 +++++++++++++++++++ 2 files changed, 42 insertions(+), 6 deletions(-) create mode 100644 lib/shared/util/loadTranslations.dart diff --git a/lib/features/verification/logic/ForegroundService/VerificationTaskHandler.dart b/lib/features/verification/logic/ForegroundService/VerificationTaskHandler.dart index 768a44a..446a154 100644 --- a/lib/features/verification/logic/ForegroundService/VerificationTaskHandler.dart +++ b/lib/features/verification/logic/ForegroundService/VerificationTaskHandler.dart @@ -9,12 +9,14 @@ import 'package:decentproof/features/verification/models/VerificationStatusModel import 'package:decentproof/shared/foregroundService/IForegroundService.dart'; import 'package:decentproof/shared/interface/IHashLogic.dart'; import 'package:decentproof/shared/util/initSentry.dart'; +import 'package:decentproof/shared/util/loadTranslations.dart'; import 'package:decentproof/shared/util/register.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:flutter_foreground_task/flutter_foreground_task.dart'; import 'package:get_it/get_it.dart'; import 'package:sentry_flutter/sentry_flutter.dart'; +import 'package:easy_localization/src/localization.dart'; class VerificationTaskHandler implements TaskHandler { @override @@ -33,10 +35,12 @@ class VerificationTaskHandler implements TaskHandler { Future onStart(DateTime timestamp, SendPort? sendPort) async { DartPluginRegistrant.ensureInitialized(); try { + await EasyLocalization.ensureInitialized(); + await loadTranslations(); + final Localization L = Localization.instance; + await dotenv.load(); await initSentry(); await registar(); - await dotenv.load(); - await EasyLocalization.ensureInitialized(); final GetIt getIt = GetIt.instance; final IForegroundService foregroundService = getIt.get(); @@ -50,8 +54,6 @@ class VerificationTaskHandler implements TaskHandler { Stream> tempStream = tempFile .openRead(); // Steams are consumed after beeing done so we need a new one sendPort?.send({"status": "Hashing", "progess": 0}); - await foregroundService.updateNotification( - body: "verificationNotification.validatingMetaData".tr()); String hash = await hashLogic.hashBytesInChunksFromStream(tempStream, (progress) async { int currentProgress = (progress / fileSize * 100).ceil(); @@ -60,7 +62,7 @@ class VerificationTaskHandler implements TaskHandler { // Should prevent to many updates await foregroundService.updateNotification( body: - "${"verificationNotification.hashing".tr()} $currentProgress%"); + "${L.tr("verificationNotification.hashing")} $currentProgress%"); } }); VerificationStatusModel model = await verificationService.verify(hash); @@ -69,7 +71,7 @@ class VerificationTaskHandler implements TaskHandler { MetaDataModel metaDataModel = await extractMetaData(fileType, tempFile, getIt); await foregroundService.updateNotification( - body: "verificationNotification.validatingMetaData".tr()); + body: L.tr("verificationNotification.validatingMetaData")); final finalModel = model.copyWith(metaDataModel: metaDataModel); sendPort?.send({"status": "Done", "model": finalModel.toJson()}); } catch (e, stack) { diff --git a/lib/shared/util/loadTranslations.dart b/lib/shared/util/loadTranslations.dart new file mode 100644 index 0000000..48d7ea2 --- /dev/null +++ b/lib/shared/util/loadTranslations.dart @@ -0,0 +1,34 @@ +import 'dart:ui'; + +import 'package:decentproof/constants.dart'; +import 'package:easy_localization/easy_localization.dart'; +import 'package:easy_localization/src/easy_localization_controller.dart'; +import 'package:easy_localization/src/localization.dart'; + +/// Load translations from assets and keep them in memory +/// Can be used to load translations in foreground services etc +/// Please also use `final Localization L = Localization.instance;` in the foreground service with `L.tr("my.key")` +/// See: https://github.com/aissat/easy_localization/issues/210#issuecomment-806089855 +Future loadTranslations() async { + //this will only set EasyLocalizationController.savedLocale + await EasyLocalizationController.initEasyLocation(); + + final controller = EasyLocalizationController( + saveLocale: true, //mandatory to use EasyLocalizationController.savedLocale + fallbackLocale: const Locale('en'), + supportedLocales: SUPPORTED_LOCALS, + assetLoader: const RootBundleAssetLoader(), + useOnlyLangCode: true, + useFallbackTranslations: true, + path: "assets/translations", + onLoadError: (e) {}, + ); + + //Load translations from assets + await controller.loadTranslations(); + + //load translations into exploitable data, kept in memory + Localization.load(controller.locale, + translations: controller.translations, + fallbackTranslations: controller.fallbackTranslations); +} From e8eb2e73ef789e4a509c8b0e714444660406707f Mon Sep 17 00:00:00 2001 From: Flajt Date: Sun, 17 Mar 2024 23:13:49 +0100 Subject: [PATCH 8/8] Chore: Update version & build number --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index f4dc09d..e563a0b 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -15,7 +15,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 2.3.1+15 +version: 2.3.2+16 environment: sdk: ">=3.0.5 <4.0.0"