diff --git a/lib/app.dart b/lib/app.dart index a6e78d59..71ac5a04 100644 --- a/lib/app.dart +++ b/lib/app.dart @@ -11,7 +11,6 @@ import 'package:twonly/src/providers/purchases.provider.dart'; import 'package:twonly/src/providers/routing.provider.dart'; import 'package:twonly/src/providers/settings.provider.dart'; import 'package:twonly/src/services/subscription.service.dart'; -import 'package:twonly/src/services/user.service.dart'; import 'package:twonly/src/utils/log.dart'; import 'package:twonly/src/utils/pow.dart'; import 'package:twonly/src/visual/components/app_outdated.comp.dart'; @@ -45,10 +44,9 @@ class _AppState extends State with WidgetsBindingObserver { Future initAsync() async { try { - final user = await getUser(); - if (user != null && mounted) { + if (userService.isUserCreated && mounted) { context.read().updatePlan( - planFromString(user.subscriptionPlan), + planFromString(userService.currentUser.subscriptionPlan), ); } } catch (e) { @@ -142,7 +140,6 @@ class AppMainWidget extends StatefulWidget { } class _AppMainWidgetState extends State { - bool _isUserCreated = false; bool _showOnboarding = true; bool _isLoaded = false; Object? _storageError; @@ -159,9 +156,7 @@ class _AppMainWidgetState extends State { Future initAsync() async { try { - _isUserCreated = await isUserCreated(); - - if (_isUserCreated) { + if (userService.isUserCreated) { if (_isTwonlyLocked) { // do not change in case twonly was already unlocked at some point _isTwonlyLocked = userService.currentUser.screenLockEnabled; @@ -202,7 +197,7 @@ class _AppMainWidgetState extends State { late Widget child; - if (_isUserCreated) { + if (userService.isUserCreated) { if (_isTwonlyLocked) { child = UnlockTwonlyView( callbackOnSuccess: () => setState(() { diff --git a/lib/main.dart b/lib/main.dart index 8f63a19f..05ceb2fa 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -107,9 +107,8 @@ void main() async { ); } - final settingsController = SettingsChangeProvider(); + final settingsController = SettingsChangeProvider()..loadSettings(); - await settingsController.loadSettings(); await SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); await initFileDownloader(); @@ -144,13 +143,13 @@ Future runMigrations() async { if (userService.currentUser.appVersion < 90) { // BUG: Requested media files for reupload where not reuploaded because the wrong state... await twonlyDB.mediaFilesDao.updateAllRetransmissionUploadingState(); - await updateUser((u) => u.appVersion = 90); + await UserService.update((u) => u.appVersion = 90); } if (userService.currentUser.appVersion < 91) { // BUG: Requested media files for reupload where not reuploaded because the wrong state... await makeMigrationToVersion91(); - await updateUser((u) => u.appVersion = 91); + await UserService.update((u) => u.appVersion = 91); } if (userService.currentUser.appVersion < 109) { @@ -163,6 +162,6 @@ Future runMigrations() async { ); } } - await updateUser((u) => u.appVersion = 109); + await UserService.update((u) => u.appVersion = 109); } } diff --git a/lib/src/providers/purchases.provider.dart b/lib/src/providers/purchases.provider.dart index 6c839ac5..1a39e791 100644 --- a/lib/src/providers/purchases.provider.dart +++ b/lib/src/providers/purchases.provider.dart @@ -42,9 +42,8 @@ class PurchasesProvider with ChangeNotifier, DiagnosticableTreeMixin { _planSub = apiService.onPlanUpdated.listen(updatePlan); _connSub = apiService.onConnectionStateUpdated.listen((_) async { try { - final user = await getUser(); - if (user != null) { - updatePlan(planFromString(user.subscriptionPlan)); + if (userService.isUserCreated) { + updatePlan(planFromString(userService.currentUser.subscriptionPlan)); } } catch (e) { Log.error(e); @@ -95,8 +94,10 @@ class PurchasesProvider with ChangeNotifier, DiagnosticableTreeMixin { notifyListeners(); try { - final user = await getUser(); - if (user != null && isPayingUser(planFromString(user.subscriptionPlan))) { + if (userService.isUserCreated && + isPayingUser( + planFromString(userService.currentUser.subscriptionPlan), + )) { Log.info('Started IPA timer for verification.'); globalForceIpaCheck = Timer(const Duration(seconds: 5), () async { Log.info( @@ -185,7 +186,7 @@ class PurchasesProvider with ChangeNotifier, DiagnosticableTreeMixin { // an ok authenticated which is processed in the apiProvider... if (res.isSuccess) { if (Platform.isAndroid) { - await updateUser((u) { + await UserService.update((u) { u.subscriptionPlanIdStore = purchaseDetails.productID; }); } @@ -216,11 +217,10 @@ class PurchasesProvider with ChangeNotifier, DiagnosticableTreeMixin { purchaseDetails.error == null) { globalForceIpaCheck?.cancel(); - final user = await getUser(); + final currentPlan = userService.currentUser.subscriptionPlan; - if (user != null && - (user.subscriptionPlan != SubscriptionPlan.Family.name && - user.subscriptionPlan != SubscriptionPlan.Pro.name)) { + if (currentPlan != SubscriptionPlan.Family.name && + currentPlan != SubscriptionPlan.Pro.name) { for (var i = 0; i < 100; i++) { if (apiService.isAuthenticated) { Log.info( diff --git a/lib/src/providers/settings.provider.dart b/lib/src/providers/settings.provider.dart index e25645a0..f2057b3a 100644 --- a/lib/src/providers/settings.provider.dart +++ b/lib/src/providers/settings.provider.dart @@ -1,20 +1,19 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; +import 'package:twonly/locator.dart'; import 'package:twonly/src/services/user.service.dart'; -import 'package:twonly/src/utils/log.dart'; class SettingsChangeProvider with ChangeNotifier, DiagnosticableTreeMixin { late ThemeMode _themeMode; ThemeMode get themeMode => _themeMode; - Future loadSettings() async { - try { - _themeMode = (await getUser())?.themeMode ?? ThemeMode.system; + void loadSettings() { + if (userService.isUserCreated) { + _themeMode = userService.currentUser.themeMode; notifyListeners(); - } catch (e) { + } else { _themeMode = ThemeMode.system; - Log.error(e); } } @@ -27,6 +26,6 @@ class SettingsChangeProvider with ChangeNotifier, DiagnosticableTreeMixin { notifyListeners(); - await updateUser((u) => u.themeMode = newThemeMode); + await UserService.update((u) => u.themeMode = newThemeMode); } } diff --git a/lib/src/services/api.service.dart b/lib/src/services/api.service.dart index 16d32b50..e62dce92 100644 --- a/lib/src/services/api.service.dart +++ b/lib/src/services/api.service.dart @@ -354,7 +354,7 @@ class ApiService { final ok = res.value as server.Response_Ok; if (ok.hasAuthenticated()) { final authenticated = ok.authenticated; - await updateUser((user) { + await UserService.update((user) { user.subscriptionPlan = authenticated.plan; }); _planUpdateController.add(planFromString(authenticated.plan)); @@ -470,8 +470,7 @@ class ApiService { return; } - final userData = await getUser(); - if (userData == null) return; + if (userService.isUserCreated) return; if (await tryAuthenticateWithToken()) { return; @@ -501,7 +500,7 @@ class ApiService { final getAuthToken = Handshake_GetAuthToken() ..response = signature - ..userId = Int64(userData.userId); + ..userId = Int64(userService.currentUser.userId); final getauthtoken = Handshake()..getAuthToken = getAuthToken; @@ -791,7 +790,7 @@ class ApiService { Future loadPlanBalance({bool useCache = true}) async { final ballance = await getPlanBallance(); if (ballance != null) { - await updateUser((u) { + await UserService.update((u) { u.lastPlanBallance = ballance.writeToJson(); }); return ballance; diff --git a/lib/src/services/backup/common.backup.dart b/lib/src/services/backup/common.backup.dart index 50583b51..0751a0c1 100644 --- a/lib/src/services/backup/common.backup.dart +++ b/lib/src/services/backup/common.backup.dart @@ -17,7 +17,7 @@ Future enableTwonlySafe(String password) async { userService.currentUser.username, ); - await updateUser((user) { + await UserService.update((user) { user.twonlySafeBackup = TwonlySafeBackup( encryptionKey: encryptionKey, backupId: backupId, diff --git a/lib/src/services/backup/create.backup.dart b/lib/src/services/backup/create.backup.dart index fa2a4523..f633677c 100644 --- a/lib/src/services/backup/create.backup.dart +++ b/lib/src/services/backup/create.backup.dart @@ -94,7 +94,7 @@ Future performTwonlySafeBackup({bool force = false}) async { key: SecureStorageKeys.signalSignedPreKey, ); - final userBackup = await getUser(); + final userBackup = await UserService.getUser(); if (userBackup == null) return; // FILTER settings which should not be in the backup userBackup @@ -183,7 +183,7 @@ Future performTwonlySafeBackup({bool force = false}) async { if (encryptedBackupBytes.length > userService.currentUser.backupServer!.maxBackupBytes) { Log.error('Backup is to big for the alternative backup server.'); - await updateUser((user) { + await UserService.update((user) { user.twonlySafeBackup!.backupUploadState = LastBackupUploadState.failed; }); return; @@ -203,7 +203,7 @@ Future performTwonlySafeBackup({bool force = false}) async { ); if (await FileDownloader().enqueue(task)) { Log.info('Starting upload from twonly Backup.'); - await updateUser((user) { + await UserService.update((user) { user.twonlySafeBackup!.backupUploadState = LastBackupUploadState.pending; user.twonlySafeBackup!.lastBackupDone = clock.now(); user.twonlySafeBackup!.lastBackupSize = encryptedBackupBytes.length; @@ -216,7 +216,7 @@ Future performTwonlySafeBackup({bool force = false}) async { Future handleBackupStatusUpdate(TaskStatusUpdate update) async { if (update.status == TaskStatus.failed || update.status == TaskStatus.canceled) { - await updateUser((user) { + await UserService.update((user) { if (user.twonlySafeBackup != null) { user.twonlySafeBackup!.backupUploadState = LastBackupUploadState.failed; } @@ -225,7 +225,7 @@ Future handleBackupStatusUpdate(TaskStatusUpdate update) async { Log.info( 'twonly Backup uploaded with status code ${update.responseStatusCode}', ); - await updateUser((user) { + await UserService.update((user) { if (user.twonlySafeBackup != null) { user.twonlySafeBackup!.backupUploadState = LastBackupUploadState.success; diff --git a/lib/src/services/backup/restore.backup.dart b/lib/src/services/backup/restore.backup.dart index 716fff0a..3ca90187 100644 --- a/lib/src/services/backup/restore.backup.dart +++ b/lib/src/services/backup/restore.backup.dart @@ -112,7 +112,7 @@ Future handleBackupData( key: SecureStorageKeys.userData, value: secureStorage[SecureStorageKeys.userData] as String, ); - await updateUser((u) { + await UserService.update((u) { u.deviceId += 1; }); } diff --git a/lib/src/services/flame.service.dart b/lib/src/services/flame.service.dart index 3cec6396..5c5cf88d 100644 --- a/lib/src/services/flame.service.dart +++ b/lib/src/services/flame.service.dart @@ -18,7 +18,7 @@ Future syncFlameCounters({String? forceForGroup}) async { ); if (userService.currentUser.myBestFriendGroupId != bestFriend.groupId) { - await updateUser((user) { + await UserService.update((user) { user.myBestFriendGroupId = bestFriend.groupId; }); } diff --git a/lib/src/services/notifications/fcm.notifications.dart b/lib/src/services/notifications/fcm.notifications.dart index 3f928fd8..bdde5e55 100644 --- a/lib/src/services/notifications/fcm.notifications.dart +++ b/lib/src/services/notifications/fcm.notifications.dart @@ -49,7 +49,7 @@ Future checkForTokenUpdates() async { if (storedToken == null || fcmToken != storedToken) { Log.info('Got new FCM TOKEN.'); await storage.write(key: SecureStorageKeys.googleFcm, value: fcmToken); - await updateUser((u) { + await UserService.update((u) { u.updateFCMToken = true; }); } @@ -61,7 +61,7 @@ Future checkForTokenUpdates() async { key: SecureStorageKeys.googleFcm, value: fcmToken, ); - await updateUser((u) { + await UserService.update((u) { u.updateFCMToken = true; }); }) @@ -81,7 +81,7 @@ Future initFCMAfterAuthenticated({bool force = false}) async { final res = await apiService.updateFCMToken(storedToken); if (res.isSuccess) { Log.info('Uploaded new FCM token!'); - await updateUser((u) { + await UserService.update((u) { u.updateFCMToken = false; }); } else { diff --git a/lib/src/services/signal/identity.signal.dart b/lib/src/services/signal/identity.signal.dart index 6086217d..722f844c 100644 --- a/lib/src/services/signal/identity.signal.dart +++ b/lib/src/services/signal/identity.signal.dart @@ -39,7 +39,7 @@ Future signalHandleNewServerConnection() async { Log.error('could not generate a new signed pre key!'); return; } - await updateUser((user) { + await UserService.update((user) { user.signalLastSignedPreKeyUpdated = clock.now(); }); final res = await apiService.updateSignedPreKey( @@ -49,7 +49,7 @@ Future signalHandleNewServerConnection() async { ); if (res.isError) { Log.error('could not update the signed pre key: ${res.error}'); - await updateUser((user) { + await UserService.update((user) { user.signalLastSignedPreKeyUpdated = null; }); } else { @@ -59,13 +59,9 @@ Future signalHandleNewServerConnection() async { Future> signalGetPreKeys() async { return lockingSignalProtocol.protect(() async { - final user = await getUser(); - if (user == null) return []; - - final start = user.currentPreKeyIndexStart; - await updateUser((user) { - user.currentPreKeyIndexStart = - (user.currentPreKeyIndexStart + 200) % maxValue; + final start = userService.currentUser.currentPreKeyIndexStart; + await UserService.update((u) { + u.currentPreKeyIndexStart = (u.currentPreKeyIndexStart + 200) % maxValue; }); final preKeys = generatePreKeys(start, 200); final signalStore = await getSignalStore(); @@ -138,14 +134,14 @@ Future createIfNotExistsSignalIdentity() async { Future _getNewSignalSignedPreKey() async { return lockingSignalProtocol.protect(() async { var identityKeyPair = await getSignalIdentityKeyPair(); - final user = await getUser(); final signalStore = await getSignalStore(); - if (identityKeyPair == null || signalStore == null || user == null) { + if (identityKeyPair == null || signalStore == null) { return null; } - final signedPreKeyId = user.currentSignedPreKeyIndexStart; - await updateUser((user) { + final signedPreKeyId = + userService.currentUser.currentSignedPreKeyIndexStart; + await UserService.update((user) { user.currentSignedPreKeyIndexStart += 1; }); diff --git a/lib/src/services/user.service.dart b/lib/src/services/user.service.dart index c412f602..5cb4f19f 100644 --- a/lib/src/services/user.service.dart +++ b/lib/src/services/user.service.dart @@ -1,20 +1,17 @@ import 'dart:async'; import 'dart:convert'; -import 'package:flutter/material.dart'; -import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:mutex/mutex.dart'; -import 'package:provider/provider.dart'; import 'package:twonly/locator.dart'; import 'package:twonly/src/constants/secure_storage.keys.dart'; import 'package:twonly/src/model/json/userdata.model.dart'; -import 'package:twonly/src/providers/purchases.provider.dart'; -import 'package:twonly/src/services/subscription.service.dart'; import 'package:twonly/src/utils/log.dart'; import 'package:twonly/src/utils/secure_storage.dart'; class UserService { late UserData currentUser; + bool isUserCreated = false; + static final Mutex _updateProtection = Mutex(); final _userDataUpdateController = StreamController.broadcast(); Stream get onUserUpdated => _userDataUpdateController.stream; @@ -23,79 +20,53 @@ class UserService { final user = await getUser(); if (user == null) return false; userService.currentUser = user; + isUserCreated = true; return true; } + static Future getUser() async { + try { + final userDataJson = await SecureStorage.instance.read( + key: SecureStorageKeys.userData, + ); + if (userDataJson == null) { + return null; + } + return UserData.fromJson( + jsonDecode(userDataJson) as Map, + ); + } catch (e) { + Log.error('could not load user: $e'); + rethrow; // Rethrow instead of returning null to distinguish error from missing user + } + } + + static Future update( + void Function(UserData userData) updateUser, + ) async { + await _updateProtection.protect(() async { + try { + final user = await getUser(); + if (user == null) return; + if (user.defaultShowTime == 999999) { + // This was the old version for infinity -> change it to null + user.defaultShowTime = null; + } + updateUser(user); + await SecureStorage.instance.write( + key: SecureStorageKeys.userData, + value: jsonEncode(user), + ); + userService.currentUser = user; + } catch (e) { + Log.error('Could not update the user: $e'); + } + }); + + userService.triggerUserUpdate(); + } + void triggerUserUpdate() { _userDataUpdateController.add(null); } - - void dispose() { - _userDataUpdateController.close(); - } -} - -Future isUserCreated() async { - final user = await getUser(); - if (user == null) { - return false; - } - userService.currentUser = user; - return true; -} - -Future getUser() async { - try { - final userDataJson = await SecureStorage.instance.read( - key: SecureStorageKeys.userData, - ); - if (userDataJson == null) { - return null; - } - return UserData.fromJson(jsonDecode(userDataJson) as Map); - } catch (e) { - Log.error('could not load user: $e'); - rethrow; // Rethrow instead of returning null to distinguish error from missing user - } -} - -Future updateUsersPlan( - BuildContext context, - SubscriptionPlan plan, -) async { - context.read().plan = plan; - - await updateUser((user) { - user.subscriptionPlan = plan.name; - }); - - if (!context.mounted) return; - context.read().updatePlan(plan); -} - -Mutex updateProtection = Mutex(); - -Future updateUser( - void Function(UserData userData) updateUser, -) async { - await updateProtection.protect(() async { - try { - final user = await getUser(); - if (user == null) return; - if (user.defaultShowTime == 999999) { - // This was the old version for infinity -> change it to null - user.defaultShowTime = null; - } - updateUser(user); - await const FlutterSecureStorage().write( - key: SecureStorageKeys.userData, - value: jsonEncode(user), - ); - userService.currentUser = user; - } catch (e) { - Log.error('Could not update the user: $e'); - } - }); - - userService.triggerUserUpdate(); } diff --git a/lib/src/services/user_discovery.service.dart b/lib/src/services/user_discovery.service.dart index b8c430d4..00d992ce 100644 --- a/lib/src/services/user_discovery.service.dart +++ b/lib/src/services/user_discovery.service.dart @@ -56,7 +56,7 @@ class UserDiscoveryService { userId: userService.currentUser.userId, publicKey: await getUserPublicKey(), ); - await updateUser( + await UserService.update( (u) => u ..isUserDiscoveryEnabled = true ..minimumRequiredImagesExchanged = minimumRequiredImagesExchanged, @@ -168,7 +168,7 @@ class UserDiscoveryService { } static Future disable() async { - await updateUser((u) { + await UserService.update((u) { u.isUserDiscoveryEnabled = false; }); } diff --git a/lib/src/services/user_study.service.dart b/lib/src/services/user_study.service.dart index b5d96fb6..0b4e3c61 100644 --- a/lib/src/services/user_study.service.dart +++ b/lib/src/services/user_study.service.dart @@ -100,13 +100,13 @@ Future handleUserStudyUpload() async { headers: {'Content-Type': 'application/json'}, ); if (response.statusCode == 200) { - await updateUser((u) { + await UserService.update((u) { u.lastUserStudyDataUpload = DateTime.now(); }); } if (response.statusCode == 404) { // Token is unknown to the server... - await updateUser((u) { + await UserService.update((u) { u ..lastUserStudyDataUpload = null ..userStudyParticipantsToken = null; diff --git a/lib/src/visual/views/camera/camera_preview_components/camera_preview_controller_view.dart b/lib/src/visual/views/camera/camera_preview_components/camera_preview_controller_view.dart index 8dc65eb7..b4e2ff94 100644 --- a/lib/src/visual/views/camera/camera_preview_components/camera_preview_controller_view.dart +++ b/lib/src/visual/views/camera/camera_preview_components/camera_preview_controller_view.dart @@ -209,7 +209,7 @@ class _CameraPreviewViewState extends State { if (!_hasAudioPermission && !userService.currentUser.requestedAudioPermission) { - await updateUser((u) => u.requestedAudioPermission = true); + await UserService.update((u) => u.requestedAudioPermission = true); await requestMicrophonePermission(); } } diff --git a/lib/src/visual/views/camera/share_image_editor.view.dart b/lib/src/visual/views/camera/share_image_editor.view.dart index 987e1498..d2b29bc7 100644 --- a/lib/src/visual/views/camera/share_image_editor.view.dart +++ b/lib/src/visual/views/camera/share_image_editor.view.dart @@ -160,7 +160,7 @@ class _ShareImageEditorView extends State { if (!mounted) return; setState(() {}); if (storeAsDefault) { - await updateUser((user) { + await UserService.update((user) { user.defaultShowTime = maxShowTime; }); } diff --git a/lib/src/visual/views/chats/chat_list.view.dart b/lib/src/visual/views/chats/chat_list.view.dart index 45c1e281..58200324 100644 --- a/lib/src/visual/views/chats/chat_list.view.dart +++ b/lib/src/visual/views/chats/chat_list.view.dart @@ -93,7 +93,7 @@ class _ChatListViewState extends State { if (!userService.currentUser.hideChangeLog && userService.currentUser.lastChangeLogHash.toString() != changeLogHash.toString()) { - await updateUser((u) { + await UserService.update((u) { u.lastChangeLogHash = changeLogHash; }); if (!mounted) return; diff --git a/lib/src/visual/views/onboarding/register.view.dart b/lib/src/visual/views/onboarding/register.view.dart index f507b489..e687fca9 100644 --- a/lib/src/visual/views/onboarding/register.view.dart +++ b/lib/src/visual/views/onboarding/register.view.dart @@ -143,7 +143,7 @@ class _RegisterViewState extends State { value: jsonEncode(userData), ); - userService.currentUser = userData; + await userService.tryInit(); await apiService.authenticate(); widget.callbackOnSuccess(); diff --git a/lib/src/visual/views/settings/appearance.view.dart b/lib/src/visual/views/settings/appearance.view.dart index e546dbcc..84555e36 100644 --- a/lib/src/visual/views/settings/appearance.view.dart +++ b/lib/src/visual/views/settings/appearance.view.dart @@ -73,19 +73,19 @@ class _AppearanceViewState extends State { } Future toggleShowFeedbackIcon() async { - await updateUser((u) { + await UserService.update((u) { u.showFeedbackShortcut = !u.showFeedbackShortcut; }); } Future toggleStartWithCameraOpen() async { - await updateUser((u) { + await UserService.update((u) { u.startWithCameraOpen = !u.startWithCameraOpen; }); } Future toggleShowImagePreviewWhenSending() async { - await updateUser((u) { + await UserService.update((u) { u.showShowImagePreviewWhenSending = !u.showShowImagePreviewWhenSending; }); } diff --git a/lib/src/visual/views/settings/backup/backup_server.view.dart b/lib/src/visual/views/settings/backup/backup_server.view.dart index dd998db8..161ce65e 100644 --- a/lib/src/visual/views/settings/backup/backup_server.view.dart +++ b/lib/src/visual/views/settings/backup/backup_server.view.dart @@ -80,7 +80,7 @@ class _BackupServerViewState extends State { retentionDays: data['retentionDays']! as int, maxBackupBytes: data['maxBackupBytes']! as int, ); - await updateUser((user) { + await UserService.update((user) { user.backupServer = backupServer; }); if (mounted) Navigator.pop(context, backupServer); @@ -166,7 +166,7 @@ class _BackupServerViewState extends State { Center( child: OutlinedButton( onPressed: () async { - await updateUser((user) { + await UserService.update((user) { user.backupServer = null; }); if (context.mounted) Navigator.pop(context); diff --git a/lib/src/visual/views/settings/chat/chat_reactions.view.dart b/lib/src/visual/views/settings/chat/chat_reactions.view.dart index c750739d..c43dabe6 100644 --- a/lib/src/visual/views/settings/chat/chat_reactions.view.dart +++ b/lib/src/visual/views/settings/chat/chat_reactions.view.dart @@ -35,7 +35,7 @@ class _ChatReactionSelectionView extends State { } else { if (_selectedEmojis.length < 12) { _selectedEmojis.add(emoji); - await updateUser((user) { + await UserService.update((user) { user.preSelectedEmojies = _selectedEmojis; }); } else { @@ -90,7 +90,7 @@ class _ChatReactionSelectionView extends State { padding: const EdgeInsets.only(bottom: 30), child: FloatingActionButton( foregroundColor: Colors.white, - onPressed: () => updateUser( + onPressed: () => UserService.update( (u) => u.preSelectedEmojies = EmojiAnimationComp .animatedIcons .keys diff --git a/lib/src/visual/views/settings/data_and_storage.view.dart b/lib/src/visual/views/settings/data_and_storage.view.dart index c18b52e6..ce6a6b22 100644 --- a/lib/src/visual/views/settings/data_and_storage.view.dart +++ b/lib/src/visual/views/settings/data_and_storage.view.dart @@ -38,13 +38,13 @@ class _DataAndStorageViewState extends State { } Future toggleStoreInGallery() async { - await updateUser((u) { + await UserService.update((u) { u.storeMediaFilesInGallery = !u.storeMediaFilesInGallery; }); } Future toggleAutoStoreMediaFiles() async { - await updateUser((u) { + await UserService.update((u) { u.autoStoreAllSendUnlimitedMediaFiles = !u.autoStoreAllSendUnlimitedMediaFiles; }); @@ -227,7 +227,7 @@ class _AutoDownloadOptionsDialogState extends State { // Call the onUpdate callback to notify the parent widget - await updateUser((u) { + await UserService.update((u) { u.autoDownloadOptions = autoDownloadOptions; }); diff --git a/lib/src/visual/views/settings/developer/developer.view.dart b/lib/src/visual/views/settings/developer/developer.view.dart index 7b5807e4..81fa8b15 100644 --- a/lib/src/visual/views/settings/developer/developer.view.dart +++ b/lib/src/visual/views/settings/developer/developer.view.dart @@ -30,11 +30,11 @@ class _DeveloperSettingsViewState extends State { } Future toggleDeveloperSettings() async { - await updateUser((u) => u.isDeveloper = !u.isDeveloper); + await UserService.update((u) => u.isDeveloper = !u.isDeveloper); } Future toggleVideoStabilization() async { - await updateUser( + await UserService.update( (u) => u.videoStabilizationEnabled = !u.videoStabilizationEnabled, ); } diff --git a/lib/src/visual/views/settings/help/changelog.view.dart b/lib/src/visual/views/settings/help/changelog.view.dart index 43e7fe73..a8520418 100644 --- a/lib/src/visual/views/settings/help/changelog.view.dart +++ b/lib/src/visual/views/settings/help/changelog.view.dart @@ -114,8 +114,9 @@ class _ChangeLogViewState extends State { Text(context.lang.openChangeLog), Switch( value: !userService.currentUser.hideChangeLog, - onChanged: (_) => - updateUser((u) => u.hideChangeLog = !u.hideChangeLog), + onChanged: (_) => UserService.update( + (u) => u.hideChangeLog = !u.hideChangeLog, + ), ), ], ), diff --git a/lib/src/visual/views/settings/help/help.view.dart b/lib/src/visual/views/settings/help/help.view.dart index 6d3b4de5..ef09109a 100644 --- a/lib/src/visual/views/settings/help/help.view.dart +++ b/lib/src/visual/views/settings/help/help.view.dart @@ -19,7 +19,7 @@ class HelpView extends StatefulWidget { class _HelpViewState extends State { Future toggleAllowErrorTrackingViaSentry() async { - await updateUser( + await UserService.update( (u) => u.allowErrorTrackingViaSentry = !u.allowErrorTrackingViaSentry, ); } @@ -128,7 +128,7 @@ class _HelpViewState extends State { 'Do you want to enable the developer settings?', ); if (okay) { - await updateUser((u) => u.isDeveloper = true); + await UserService.update((u) => u.isDeveloper = true); } }, title: const Text( diff --git a/lib/src/visual/views/settings/privacy.view.dart b/lib/src/visual/views/settings/privacy.view.dart index 7d1295b8..2f6561f3 100644 --- a/lib/src/visual/views/settings/privacy.view.dart +++ b/lib/src/visual/views/settings/privacy.view.dart @@ -25,14 +25,14 @@ class _PrivacyViewState extends State { : context.lang.settingsScreenLockAuthMessageEnable, ); if (!isAuth) return; - await updateUser((u) { + await UserService.update((u) { u.screenLockEnabled = !u.screenLockEnabled; }); setState(() {}); } Future toggleTypingIndicators() async { - await updateUser((u) { + await UserService.update((u) { u.typingIndicators = !u.typingIndicators; }); setState(() {}); diff --git a/lib/src/visual/views/settings/privacy/user_discovery/user_discovery_settings.view.dart b/lib/src/visual/views/settings/privacy/user_discovery/user_discovery_settings.view.dart index 2dc48e9d..62906fd5 100644 --- a/lib/src/visual/views/settings/privacy/user_discovery/user_discovery_settings.view.dart +++ b/lib/src/visual/views/settings/privacy/user_discovery/user_discovery_settings.view.dart @@ -33,7 +33,7 @@ class _UserDiscoverySettingsViewState extends State { userService.currentUser.userDiscoveryThreshold != _userDiscoveryThreshold; - await updateUser((u) { + await UserService.update((u) { u ..minimumRequiredImagesExchanged = _minimumRequiredImagesExchanged ..userDiscoveryThreshold = _userDiscoveryThreshold; diff --git a/lib/src/visual/views/settings/profile/modify_avatar.view.dart b/lib/src/visual/views/settings/profile/modify_avatar.view.dart index aa8d7081..50bfdcaa 100644 --- a/lib/src/visual/views/settings/profile/modify_avatar.view.dart +++ b/lib/src/visual/views/settings/profile/modify_avatar.view.dart @@ -24,7 +24,7 @@ class _ModifyAvatarViewState extends State { } Future updateUserAvatar(String json, String svg) async { - await updateUser( + await UserService.update( (u) => u ..avatarJson = json ..avatarSvg = svg diff --git a/lib/src/visual/views/settings/profile/profile.view.dart b/lib/src/visual/views/settings/profile/profile.view.dart index 61b3bdb5..100a9811 100644 --- a/lib/src/visual/views/settings/profile/profile.view.dart +++ b/lib/src/visual/views/settings/profile/profile.view.dart @@ -48,7 +48,7 @@ class _ProfileViewState extends State { } Future updateUserDisplayName(String displayName) async { - await updateUser( + await UserService.update( (u) => u ..displayName = displayName ..avatarCounter = u.avatarCounter + 1, @@ -93,7 +93,7 @@ class _ProfileViewState extends State { await removeTwonlySafeFromServer(); unawaited(performTwonlySafeBackup(force: true)); - await updateUser( + await UserService.update( (u) => u ..username = username ..avatarCounter = u.avatarCounter + 1, diff --git a/lib/src/visual/views/user_study/user_study_questionnaire.view.dart b/lib/src/visual/views/user_study/user_study_questionnaire.view.dart index c113f34d..180c58ab 100644 --- a/lib/src/visual/views/user_study/user_study_questionnaire.view.dart +++ b/lib/src/visual/views/user_study/user_study_questionnaire.view.dart @@ -50,7 +50,7 @@ class _UserStudyQuestionnaireViewState Future _submitData() async { await KeyValueStore.put(userStudySurveyKey, _responses); - await updateUser((u) { + await UserService.update((u) { // generate a random participants id to identify data send later while keeping the user anonym u ..userStudyParticipantsToken = getRandomString(25) diff --git a/lib/src/visual/views/user_study/user_study_welcome.view.dart b/lib/src/visual/views/user_study/user_study_welcome.view.dart index dd2b9946..a1a5ce2b 100644 --- a/lib/src/visual/views/user_study/user_study_welcome.view.dart +++ b/lib/src/visual/views/user_study/user_study_welcome.view.dart @@ -86,7 +86,7 @@ class _UserStudyWelcomeViewState extends State { Center( child: GestureDetector( onTap: () async { - await updateUser( + await UserService.update( (u) => u.askedForUserStudyPermission = true, ); if (context.mounted) context.pop();