From 33d608b8362e5e67eebd90a4c291eacfd72f116a Mon Sep 17 00:00:00 2001 From: Christian Pauly Date: Thu, 17 Feb 2022 09:43:31 +0100 Subject: [PATCH] chore: Follow up migrate old preferences --- lib/utils/famedlysdk_store.dart | 17 ++++ lib/utils/legacy_famedlysdk_store.dart | 121 +++++++++++++++++++++++++ pubspec.lock | 7 ++ pubspec.yaml | 1 + 4 files changed, 146 insertions(+) create mode 100644 lib/utils/legacy_famedlysdk_store.dart diff --git a/lib/utils/famedlysdk_store.dart b/lib/utils/famedlysdk_store.dart index 2f16b5963..b42d7f42b 100644 --- a/lib/utils/famedlysdk_store.dart +++ b/lib/utils/famedlysdk_store.dart @@ -1,7 +1,10 @@ import 'dart:core'; +import 'package:matrix/matrix.dart'; import 'package:shared_preferences/shared_preferences.dart'; +import 'legacy_famedlysdk_store.dart' as legacy; + class Store { SharedPreferences? _prefs; @@ -11,11 +14,25 @@ class Store { Future getItem(String key) async { await _setupLocalStorage(); + final legacyVal = await legacy.Store().getItem(key); + if (legacyVal != null) { + Logs().d('Found legacy preference for $key'); + await setItem(key, legacyVal); + legacy.Store().deleteItem(key); + return legacyVal; + } return _prefs!.getString(key); } Future getItemBool(String key, [bool? defaultValue]) async { await _setupLocalStorage(); + final legacyVal = await legacy.Store().getItemBool(key); + if (legacyVal != null) { + Logs().d('Found legacy preference for $key'); + await setItemBool(key, legacyVal); + legacy.Store().deleteItem(key); + return legacyVal; + } return _prefs!.getBool(key) ?? defaultValue ?? true; } diff --git a/lib/utils/legacy_famedlysdk_store.dart b/lib/utils/legacy_famedlysdk_store.dart new file mode 100644 index 000000000..ea8f5c6c9 --- /dev/null +++ b/lib/utils/legacy_famedlysdk_store.dart @@ -0,0 +1,121 @@ +import 'dart:async'; +import 'dart:core'; + +import 'package:device_info_plus/device_info_plus.dart'; +import 'package:flutter_secure_storage/flutter_secure_storage.dart'; +import 'package:localstorage/localstorage.dart'; +import 'package:path_provider/path_provider.dart'; + +import 'package:fluffychat/utils/platform_infos.dart'; + +// import 'package:flutter_secure_storage/flutter_secure_storage.dart'; + +// see https://github.com/mogol/flutter_secure_storage/issues/161#issuecomment-704578453 +class AsyncMutex { + Completer? _completer; + + Future lock() async { + while (_completer != null) { + await _completer!.future; + } + + _completer = Completer(); + } + + void unlock() { + assert(_completer != null); + final completer = _completer!; + _completer = null; + completer.complete(); + } +} + +class Store { + FlutterSecureStorage? secureStorage; + + LocalStorage? storage; + static final _mutex = AsyncMutex(); + + Future _setupLocalStorage() async { + if (PlatformInfos.isMobile) { + if (PlatformInfos.isAndroid) { + return DeviceInfoPlugin().androidInfo.then((info) { + if ((info.version.sdkInt ?? 16) >= 19) { + secureStorage = const FlutterSecureStorage(); + } + }); + } else { + secureStorage = const FlutterSecureStorage(); + } + } else { + if (storage == null) { + final directory = PlatformInfos.isBetaDesktop + ? await getApplicationSupportDirectory() + : (PlatformInfos.isWeb + ? null + : await getApplicationDocumentsDirectory()); + storage = LocalStorage('LocalStorage', directory?.path); + await storage!.ready; + } + } + } + + Future getItem(String key) async { + final storage = this.storage; + if (!PlatformInfos.isMobile && storage != null) { + await _setupLocalStorage(); + try { + return storage.getItem(key)?.toString(); + } catch (_) { + return null; + } + } + try { + await _mutex.lock(); + return await secureStorage!.read(key: key); + } catch (_) { + return null; + } finally { + _mutex.unlock(); + } + } + + Future getItemBool(String key, [bool? defaultValue]) async { + final value = await getItem(key); + if (value == null) { + return defaultValue; + } + // we also check for '1' for legacy reasons, some booleans were stored that way + return value == '1' || value.toLowerCase() == 'true'; + } + + Future setItem(String key, String? value) async { + await _setupLocalStorage(); + if (!PlatformInfos.isMobile) { + return await storage!.setItem(key, value); + } + try { + await _mutex.lock(); + return await secureStorage!.write(key: key, value: value); + } finally { + _mutex.unlock(); + } + } + + Future setItemBool(String key, bool value) async { + await setItem(key, value.toString()); + } + + Future deleteItem(String key) async { + if (!PlatformInfos.isMobile) { + await _setupLocalStorage(); + return await storage!.deleteItem(key); + } + try { + await _mutex.lock(); + return await secureStorage!.delete(key: key); + } finally { + _mutex.unlock(); + } + } +} diff --git a/pubspec.lock b/pubspec.lock index 93b7c91b0..a6f9f0355 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -903,6 +903,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.1" + localstorage: + dependency: "direct main" + description: + name: localstorage + url: "https://pub.dartlang.org" + source: hosted + version: "4.0.0+1" logging: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 189ff2a19..73b9eca22 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -54,6 +54,7 @@ dependencies: image: ^3.1.1 image_picker: ^0.8.4+8 intl: any + localstorage: ^4.0.0+1 lottie: ^1.2.2 matrix: ^0.8.9 matrix_link_text: ^1.0.2