diff --git a/lib/globals.dart b/lib/globals.dart index f446d5a0..8c066fa9 100644 --- a/lib/globals.dart +++ b/lib/globals.dart @@ -1,17 +1,28 @@ import 'package:camera/camera.dart'; import 'package:flutter/material.dart'; +import 'package:path_provider/path_provider.dart'; import 'package:twonly/src/database/twonly.db.dart'; import 'package:twonly/src/model/json/userdata.dart'; import 'package:twonly/src/services/api.service.dart'; import 'package:twonly/src/services/subscription.service.dart'; +class AppEnvironment { + static late final String cacheDir; + static late final String supportDir; + static late final List cameras; + + static Future init() async { + cacheDir = (await getApplicationCacheDirectory()).path; + supportDir = (await getApplicationSupportDirectory()).path; + cameras = await availableCameras(); + } +} + late ApiService apiService; // uses for background notification late TwonlyDB twonlyDB; -List gCameras = []; - // Cached UserData in the memory. Every time the user data is changed the `updateUserdata` function is called, // which will update this global variable. The variable is set in the main.dart and after the user has registered in the register.view.dart late UserData gUser; @@ -36,8 +47,5 @@ bool globalIsInBackgroundTask = false; bool globalAllowErrorTrackingViaSentry = false; bool globalGotMessageFromServer = false; -late String globalApplicationCacheDirectory; -late String globalApplicationSupportDirectory; - final GlobalKey globalRootScaffoldMessengerKey = GlobalKey(); diff --git a/lib/main.dart b/lib/main.dart index 98ff7781..e09651bf 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,11 +1,9 @@ import 'dart:async'; import 'dart:io'; -import 'package:camera/camera.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart'; -import 'package:path_provider/path_provider.dart'; import 'package:provider/provider.dart'; import 'package:sentry_flutter/sentry_flutter.dart'; import 'package:twonly/app.dart'; @@ -35,10 +33,7 @@ void main() async { SentryWidgetsFlutterBinding.ensureInitialized(); await RustLib.init(); - - globalApplicationCacheDirectory = (await getApplicationCacheDirectory()).path; - globalApplicationSupportDirectory = - (await getApplicationSupportDirectory()).path; + await AppEnvironment.init(); initLogger(); @@ -46,8 +41,8 @@ void main() async { await bridge.initializeTwonlyFlutter( config: bridge.TwonlyConfig( - databasePath: '$globalApplicationSupportDirectory/twonly.sqlite', - dataDirectory: globalApplicationSupportDirectory, + databasePath: '${AppEnvironment.supportDir}/twonly.sqlite', + dataDirectory: AppEnvironment.supportDir, ), ); @@ -56,7 +51,7 @@ void main() async { var user = await getUser(); if (Platform.isIOS && user != null) { - final db = File('$globalApplicationSupportDirectory/twonly.sqlite'); + final db = File('${AppEnvironment.supportDir}/twonly.sqlite'); if (!db.existsSync()) { Log.error('[twonly] IOS: App was removed and then reinstalled again...'); await const FlutterSecureStorage().deleteAll(); @@ -92,8 +87,6 @@ void main() async { unawaited(setupPushNotification()); - gCameras = await availableCameras(); - apiService = ApiService(); twonlyDB = TwonlyDB(); diff --git a/lib/src/localization/translations b/lib/src/localization/translations index 0029f698..e1ac9e6c 160000 --- a/lib/src/localization/translations +++ b/lib/src/localization/translations @@ -1 +1 @@ -Subproject commit 0029f698ea3deb47dedc4ee1f37e5688d1f83f9b +Subproject commit e1ac9e6c476f82819063a8087af4d42acc1167d4 diff --git a/lib/src/services/background/callback_dispatcher.background.dart b/lib/src/services/background/callback_dispatcher.background.dart index a1460266..e3828add 100644 --- a/lib/src/services/background/callback_dispatcher.background.dart +++ b/lib/src/services/background/callback_dispatcher.background.dart @@ -62,9 +62,8 @@ Future initBackgroundExecution() async { } SentryWidgetsFlutterBinding.ensureInitialized(); - globalApplicationCacheDirectory = (await getApplicationCacheDirectory()).path; - globalApplicationSupportDirectory = - (await getApplicationSupportDirectory()).path; + AppEnvironment.cacheDir = (await getApplicationCacheDirectory()).path; + AppEnvironment.supportDir = (await getApplicationSupportDirectory()).path; initLogger(); diff --git a/lib/src/services/backup/create.backup.dart b/lib/src/services/backup/create.backup.dart index 97b74ed8..a03c7e6f 100644 --- a/lib/src/services/backup/create.backup.dart +++ b/lib/src/services/backup/create.backup.dart @@ -41,9 +41,9 @@ Future performTwonlySafeBackup({bool force = false}) async { Log.info('Starting new twonly Backup!'); - final baseDir = globalApplicationSupportDirectory; - - final backupDir = Directory(join(baseDir, 'backup_twonly_safe/')); + final backupDir = Directory( + join(AppEnvironment.supportDir, 'backup_twonly_safe/'), + ); await backupDir.create(recursive: true); final backupDatabaseFile = File(join(backupDir.path, 'twonly.backup.sqlite')); @@ -53,7 +53,9 @@ Future performTwonlySafeBackup({bool force = false}) async { ); // copy database - final originalDatabase = File(join(baseDir, 'twonly.sqlite')); + final originalDatabase = File( + join(AppEnvironment.supportDir, 'twonly.sqlite'), + ); await originalDatabase.copy(backupDatabaseFile.path); driftRuntimeOptions.dontWarnAboutMultipleDatabases = true; diff --git a/lib/src/services/backup/restore.backup.dart b/lib/src/services/backup/restore.backup.dart index 006d43fe..099bb000 100644 --- a/lib/src/services/backup/restore.backup.dart +++ b/lib/src/services/backup/restore.backup.dart @@ -90,7 +90,7 @@ Future handleBackupData( ); final originalDatabase = File( - join(globalApplicationSupportDirectory, 'twonly.sqlite'), + join(AppEnvironment.supportDir, 'twonly.sqlite'), ); await originalDatabase.writeAsBytes(backupContent.twonlyDatabase); diff --git a/lib/src/services/mediafiles/mediafile.service.dart b/lib/src/services/mediafiles/mediafile.service.dart index 6fb18271..1e5424ca 100644 --- a/lib/src/services/mediafiles/mediafile.service.dart +++ b/lib/src/services/mediafiles/mediafile.service.dart @@ -27,7 +27,7 @@ class MediaFileService { try { final tempDirectory = MediaFileService.buildDirectoryPath( 'tmp', - globalApplicationSupportDirectory, + AppEnvironment.supportDir, ); final files = tempDirectory.listSync(); @@ -307,7 +307,7 @@ class MediaFileService { } final mediaBaseDir = buildDirectoryPath( directory, - globalApplicationSupportDirectory, + AppEnvironment.supportDir, ); return File( join(mediaBaseDir.path, '${mediaFile.mediaId}$namePrefix.$extension'), diff --git a/lib/src/utils/avatars.dart b/lib/src/utils/avatars.dart index d1fcd694..a2648694 100644 --- a/lib/src/utils/avatars.dart +++ b/lib/src/utils/avatars.dart @@ -37,7 +37,7 @@ Future createPushAvatars({int? forceForUserId}) async { File avatarPNGFile(int contactId) { final avatarsDirectory = Directory( - '$globalApplicationCacheDirectory/avatars', + '${AppEnvironment.cacheDir}/avatars', ); if (!avatarsDirectory.existsSync()) { diff --git a/lib/src/utils/exclusive_access.dart b/lib/src/utils/exclusive_access.dart index d2a4253a..fb64a397 100644 --- a/lib/src/utils/exclusive_access.dart +++ b/lib/src/utils/exclusive_access.dart @@ -8,7 +8,7 @@ Future exclusiveAccess({ required Future Function() action, required Mutex mutex, }) async { - final lockFile = File('$globalApplicationSupportDirectory/$lockName.lock'); + final lockFile = File('${AppEnvironment.supportDir}/$lockName.lock'); return mutex.protect(() async { var lockAcquired = false; diff --git a/lib/src/utils/keyvalue.dart b/lib/src/utils/keyvalue.dart index 10e62f30..f970691b 100644 --- a/lib/src/utils/keyvalue.dart +++ b/lib/src/utils/keyvalue.dart @@ -5,7 +5,7 @@ import 'package:twonly/src/utils/log.dart'; class KeyValueStore { static Future _getFilePath(String key) async { - return File('$globalApplicationSupportDirectory/keyvalue/$key.json'); + return File('${AppEnvironment.supportDir}/keyvalue/$key.json'); } static Future delete(String key) async { diff --git a/lib/src/utils/log.dart b/lib/src/utils/log.dart index 29281db3..a8be4bc3 100644 --- a/lib/src/utils/log.dart +++ b/lib/src/utils/log.dart @@ -72,7 +72,7 @@ class Log { Future loadLogFile() async { return _protectFileAccess(() async { - final logFile = File('$globalApplicationSupportDirectory/app.log'); + final logFile = File('${AppEnvironment.supportDir}/app.log'); if (logFile.existsSync()) { return logFile.readAsString(); @@ -84,7 +84,7 @@ Future loadLogFile() async { Future readLast1000Lines() async { return _protectFileAccess(() async { - final file = File('$globalApplicationSupportDirectory/app.log'); + final file = File('${AppEnvironment.supportDir}/app.log'); if (!file.existsSync()) return ''; final all = await file.readAsLines(); final start = all.length > 1000 ? all.length - 1000 : 0; @@ -103,7 +103,7 @@ Future _protectFileAccess(Future Function() action) async { } Future _writeLogToFile(LogRecord record) async { - final logFile = File('$globalApplicationSupportDirectory/app.log'); + final logFile = File('${AppEnvironment.supportDir}/app.log'); final logMessage = '${clock.now().toString().split(".")[0]} ${record.level.name} [twonly] ${record.loggerName} > ${record.message}\n'; @@ -127,7 +127,7 @@ Future _writeLogToFile(LogRecord record) async { Future cleanLogFile() async { return _protectFileAccess(() async { - final logFile = File('$globalApplicationSupportDirectory/app.log'); + final logFile = File('${AppEnvironment.supportDir}/app.log'); if (!logFile.existsSync()) { return; @@ -162,7 +162,7 @@ Future cleanLogFile() async { Future deleteLogFile() async { return _protectFileAccess(() async { - final logFile = File('$globalApplicationSupportDirectory/app.log'); + final logFile = File('${AppEnvironment.supportDir}/app.log'); if (logFile.existsSync()) { await logFile.delete(); diff --git a/lib/src/views/camera/camera_preview_components/camera_preview_controller_view.dart b/lib/src/views/camera/camera_preview_components/camera_preview_controller_view.dart index bc9d0fb7..76d7ef7d 100644 --- a/lib/src/views/camera/camera_preview_components/camera_preview_controller_view.dart +++ b/lib/src/views/camera/camera_preview_components/camera_preview_controller_view.dart @@ -592,7 +592,7 @@ class _CameraPreviewViewState extends State { @override Widget build(BuildContext context) { - if (mc.selectedCameraDetails.cameraId >= gCameras.length || + if (mc.selectedCameraDetails.cameraId >= AppEnvironment.cameras.length || mc.cameraController == null) { return Container(); } diff --git a/lib/src/views/camera/camera_preview_components/main_camera_controller.dart b/lib/src/views/camera/camera_preview_components/main_camera_controller.dart index 2cc6357f..b4fc0997 100644 --- a/lib/src/views/camera/camera_preview_components/main_camera_controller.dart +++ b/lib/src/views/camera/camera_preview_components/main_camera_controller.dart @@ -105,16 +105,17 @@ class MainCameraController { initCameraStarted = true; var cameraId = sCameraId; - if (cameraId >= gCameras.length) { + if (cameraId >= AppEnvironment.cameras.length) { Log.warn( - 'Trying to select a non existing camera $cameraId >= ${gCameras.length}', + 'Trying to select a non existing camera $cameraId >= ${AppEnvironment.cameras.length}', ); return; } if (init) { - for (; cameraId < gCameras.length; cameraId++) { - if (gCameras[cameraId].lensDirection == CameraLensDirection.back) { + for (; cameraId < AppEnvironment.cameras.length; cameraId++) { + if (AppEnvironment.cameras[cameraId].lensDirection == + CameraLensDirection.back) { break; } } @@ -124,7 +125,7 @@ class MainCameraController { if (cameraController == null) { cameraController = CameraController( - gCameras[cameraId], + AppEnvironment.cameras[cameraId], ResolutionPreset.high, enableAudio: await Permission.microphone.isGranted, imageFormatGroup: Platform.isAndroid @@ -150,7 +151,7 @@ class MainCameraController { selectedCameraDetails.scaleFactor = 1; await cameraController?.setZoomLevel(1); - await cameraController?.setDescription(gCameras[cameraId]); + await cameraController?.setDescription(AppEnvironment.cameras[cameraId]); try { if (!isVideoRecording) { await cameraController?.startImageStream(_processCameraImage); diff --git a/lib/src/views/camera/camera_preview_components/zoom_selector.dart b/lib/src/views/camera/camera_preview_components/zoom_selector.dart index ab7a5eb1..07450e07 100644 --- a/lib/src/views/camera/camera_preview_components/zoom_selector.dart +++ b/lib/src/views/camera/camera_preview_components/zoom_selector.dart @@ -51,11 +51,11 @@ class _CameraZoomButtonsState extends State { Future initAsync() async { showWideAngleZoom = (await widget.controller.getMinZoomLevel()) < 1; - var index = gCameras.indexWhere( + var index = AppEnvironment.cameras.indexWhere( (t) => t.lensType == CameraLensType.ultraWide, ); if (index == -1) { - index = gCameras.indexWhere( + index = AppEnvironment.cameras.indexWhere( (t) => t.lensType == CameraLensType.wide, ); } diff --git a/lib/src/views/settings/data_and_storage/export_media.view.dart b/lib/src/views/settings/data_and_storage/export_media.view.dart index 9c3426a2..f5e3aeca 100644 --- a/lib/src/views/settings/data_and_storage/export_media.view.dart +++ b/lib/src/views/settings/data_and_storage/export_media.view.dart @@ -48,7 +48,7 @@ class _ExportMediaViewState extends State { Directory _mediaFolder() { final dir = MediaFileService.buildDirectoryPath( 'stored', - globalApplicationSupportDirectory, + AppEnvironment.supportDir, ); if (!dir.existsSync()) dir.createSync(recursive: true); return dir;