diff --git a/lib/app.dart b/lib/app.dart index 637fa8c2..b0825594 100644 --- a/lib/app.dart +++ b/lib/app.dart @@ -133,9 +133,9 @@ class _AppMainWidgetState extends State { if (_isUserCreated) { if (_isTwonlyLocked) { // do not change in case twonly was already unlocked at some point - _isTwonlyLocked = appSession.currentUser.screenLockEnabled; + _isTwonlyLocked = userService.currentUser.screenLockEnabled; } - if (appSession.currentUser.appVersion < 62) { + if (userService.currentUser.appVersion < 62) { _showDatabaseMigration = true; } } @@ -178,7 +178,7 @@ class _AppMainWidgetState extends State { _isTwonlyLocked = false; }), ); - } else if (appSession.currentUser.twonlySafeBackup == null && + } else if (userService.currentUser.twonlySafeBackup == null && !_skipBackup) { child = SetupBackupView( callBack: () => setState(() { diff --git a/lib/locator.dart b/lib/locator.dart index 36879ae6..a9333733 100644 --- a/lib/locator.dart +++ b/lib/locator.dart @@ -12,6 +12,6 @@ void setupLocator() { ..registerLazySingleton(TwonlyDB.new); } -UserService get appSession => locator(); +UserService get userService => locator(); ApiService get apiService => locator(); TwonlyDB get twonlyDB => locator(); diff --git a/lib/main.dart b/lib/main.dart index 91e2d502..426fadbe 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -29,7 +29,9 @@ import 'package:twonly/src/utils/avatars.dart'; import 'package:twonly/src/utils/log.dart'; import 'package:twonly/src/utils/storage.dart'; -void main() async { +/// This function is used to initialized the absolute minimum so it +/// can also be used by the backend without the UI was loaded. +Future twonlyMinimumInitialization() async { SentryWidgetsFlutterBinding.ensureInitialized(); await AppEnvironment.init(); @@ -46,24 +48,25 @@ void main() async { dataDirectory: AppEnvironment.supportDir, ), ); +} + +void main() async { + await twonlyMinimumInitialization(); await initFCMService(); - var user = await getUser(); + final userExists = await userService.tryInit(); - if (Platform.isIOS && user != null) { + if (Platform.isIOS && userExists) { 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(); - user = await getUser(); } } - if (user != null) { - appSession.currentUser = user; - - if (user.allowErrorTrackingViaSentry) { + if (userExists) { + if (userService.currentUser.allowErrorTrackingViaSentry) { AppState.allowErrorTrackingViaSentry = true; await SentryFlutter.init( (options) => options @@ -86,33 +89,20 @@ void main() async { await settingsController.loadSettings(); await SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); - unawaited(setupPushNotification()); - - if (user != null) { - if (appSession.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; - }); - } - if (appSession.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 twonlyDB.messagesDao.purgeMessageTable(); - await twonlyDB.receiptsDao.purgeReceivedReceipts(); - unawaited(MediaFileService.purgeTempFolder()); - await initFileDownloader(); - unawaited(finishStartedPreprocessing()); - unawaited(createPushAvatars()); + if (userExists) { + await runMigrations(); + + await twonlyDB.messagesDao.purgeMessageTable(); + await twonlyDB.receiptsDao.purgeReceivedReceipts(); + + unawaited(MediaFileService.purgeTempFolder()); + + unawaited(setupPushNotification()); + unawaited(finishStartedPreprocessing()); + unawaited(createPushAvatars()); + } runApp( MultiProvider( @@ -126,3 +116,20 @@ void main() async { ), ); } + +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; + }); + } + 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; + }); + } +} diff --git a/lib/src/database/daos/contacts.dao.dart b/lib/src/database/daos/contacts.dao.dart index 7acf9e1c..c0baab18 100644 --- a/lib/src/database/daos/contacts.dao.dart +++ b/lib/src/database/daos/contacts.dao.dart @@ -140,7 +140,7 @@ class ContactsDao extends DatabaseAccessor with _$ContactsDaoMixin { t.userDiscoveryVersion.isNotNull() & t.userDiscoveryExcluded.equals(false) & t.mediaSendCounter.isBiggerOrEqualValue( - appSession.currentUser.minimumRequiredImagesExchanged, + userService.currentUser.minimumRequiredImagesExchanged, ), )) .watch(); diff --git a/lib/src/database/daos/groups.dao.dart b/lib/src/database/daos/groups.dao.dart index 0092be9d..82319226 100644 --- a/lib/src/database/daos/groups.dao.dart +++ b/lib/src/database/daos/groups.dao.dart @@ -113,7 +113,10 @@ class GroupsDao extends DatabaseAccessor with _$GroupsDaoMixin { int contactId, GroupsCompanion group, ) async { - final groupIdDirectChat = getUUIDforDirectChat(contactId, appSession.currentUser.userId); + final groupIdDirectChat = getUUIDforDirectChat( + contactId, + userService.currentUser.userId, + ); final insertGroup = group.copyWith( groupId: Value(groupIdDirectChat), isDirectChat: const Value(true), @@ -209,7 +212,10 @@ class GroupsDao extends DatabaseAccessor with _$GroupsDaoMixin { } Stream watchDirectChat(int contactId) { - final groupId = getUUIDforDirectChat(contactId, appSession.currentUser.userId); + final groupId = getUUIDforDirectChat( + contactId, + userService.currentUser.userId, + ); return (select( groups, )..where((t) => t.groupId.equals(groupId))).watchSingleOrNull(); diff --git a/lib/src/services/api.service.dart b/lib/src/services/api.service.dart index ad0d20a7..08a23c20 100644 --- a/lib/src/services/api.service.dart +++ b/lib/src/services/api.service.dart @@ -127,7 +127,7 @@ class ApiService { unawaited(UserDiscoveryService.checkForNewAnnouncedUsers()); - if (appSession.currentUser.userStudyParticipantsToken != null) { + if (userService.currentUser.userStudyParticipantsToken != null) { // In case the user participates in the user study, call the handler after authenticated, to be sure there is a internet connection unawaited(handleUserStudyUpload()); } diff --git a/lib/src/services/api/client2client/groups.c2c.dart b/lib/src/services/api/client2client/groups.c2c.dart index 073336c4..a6a1c463 100644 --- a/lib/src/services/api/client2client/groups.c2c.dart +++ b/lib/src/services/api/client2client/groups.c2c.dart @@ -162,7 +162,7 @@ Future handleGroupUpdate( case GroupActionType.demoteToMember: int? affectedContactId = update.affectedContactId.toInt(); - if (affectedContactId == appSession.currentUser.userId) { + if (affectedContactId == userService.currentUser.userId) { affectedContactId = null; if (actionType == GroupActionType.removedMember) { // Oh no, I just got removed from the group... diff --git a/lib/src/services/api/client2client/user_discovery.c2c.dart b/lib/src/services/api/client2client/user_discovery.c2c.dart index 3ed36027..c9ac4850 100644 --- a/lib/src/services/api/client2client/user_discovery.c2c.dart +++ b/lib/src/services/api/client2client/user_discovery.c2c.dart @@ -34,7 +34,7 @@ Future handleUserDiscoveryRequest( ) async { Log.info('Got a user discovery request'); - if (!appSession.currentUser.isUserDiscoveryEnabled) { + if (!userService.currentUser.isUserDiscoveryEnabled) { Log.warn('Got a user discovery request while it is disabled'); return; } @@ -42,10 +42,10 @@ Future handleUserDiscoveryRequest( if (contact == null) return; if (contact.mediaSendCounter < - appSession.currentUser.minimumRequiredImagesExchanged || + userService.currentUser.minimumRequiredImagesExchanged || contact.userDiscoveryExcluded) { Log.warn( - 'Got a request to update user discovery, but mediaSendCounter (${contact.mediaSendCounter}) < ${appSession.currentUser.minimumRequiredImagesExchanged} or user is excluded ${contact.userDiscoveryExcluded}', + 'Got a request to update user discovery, but mediaSendCounter (${contact.mediaSendCounter}) < ${userService.currentUser.minimumRequiredImagesExchanged} or user is excluded ${contact.userDiscoveryExcluded}', ); return; } @@ -73,7 +73,7 @@ Future handleUserDiscoveryUpdate( int fromUserId, EncryptedContent_UserDiscoveryUpdate update, ) async { - if (!appSession.currentUser.isUserDiscoveryEnabled) { + if (!userService.currentUser.isUserDiscoveryEnabled) { Log.warn('Got a user discovery update while it is disabled'); return; } diff --git a/lib/src/services/api/mediafiles/download.api.dart b/lib/src/services/api/mediafiles/download.api.dart index 537816fa..dac06e9f 100644 --- a/lib/src/services/api/mediafiles/download.api.dart +++ b/lib/src/services/api/mediafiles/download.api.dart @@ -98,7 +98,7 @@ Future isAllowedToDownload(MediaType type) async { final connectivityResult = await Connectivity().checkConnectivity(); final options = - appSession.currentUser.autoDownloadOptions ?? defaultAutoDownloadOptions; + userService.currentUser.autoDownloadOptions ?? defaultAutoDownloadOptions; if (connectivityResult.contains(ConnectivityResult.mobile)) { if (type == MediaType.video) { diff --git a/lib/src/services/api/mediafiles/upload.api.dart b/lib/src/services/api/mediafiles/upload.api.dart index 9a4c5e28..b3191669 100644 --- a/lib/src/services/api/mediafiles/upload.api.dart +++ b/lib/src/services/api/mediafiles/upload.api.dart @@ -359,7 +359,7 @@ Future startBackgroundMediaUpload(MediaFileService mediaService) async { // if the user has enabled auto storing and the file // was send with unlimited counter not in twonly-Mode then store the file - if (appSession.currentUser.autoStoreAllSendUnlimitedMediaFiles && + if (userService.currentUser.autoStoreAllSendUnlimitedMediaFiles && !mediaService.mediaFile.requiresAuthentication && !mediaService.storedPath.existsSync() && mediaService.mediaFile.displayLimitInMilliseconds == null) { diff --git a/lib/src/services/api/messages.api.dart b/lib/src/services/api/messages.api.dart index 17a530f7..fbd5b43a 100644 --- a/lib/src/services/api/messages.api.dart +++ b/lib/src/services/api/messages.api.dart @@ -346,12 +346,15 @@ Future<(Uint8List, Uint8List?)?> sendCipherText( return null; } } - encryptedContent.senderProfileCounter = Int64(appSession.currentUser.avatarCounter); + encryptedContent.senderProfileCounter = Int64( + userService.currentUser.avatarCounter, + ); - if (appSession.currentUser.isUserDiscoveryEnabled && messageId != null) { + if (userService.currentUser.isUserDiscoveryEnabled && messageId != null) { final contact = await twonlyDB.contactsDao.getContactById(contactId); if (contact != null && - contact.mediaSendCounter >= appSession.currentUser.minimumRequiredImagesExchanged && + contact.mediaSendCounter >= + userService.currentUser.minimumRequiredImagesExchanged && !contact.userDiscoveryExcluded) { final version = await UserDiscoveryService.getCurrentVersion(); if (version != null) { @@ -407,7 +410,7 @@ Future<(Uint8List, Uint8List?)?> sendCipherText( } Future sendTypingIndication(String groupId, bool isTyping) async { - if (!appSession.currentUser.typingIndicators) return; + if (!userService.currentUser.typingIndicators) return; await sendCipherTextToGroup( groupId, pb.EncryptedContent( @@ -463,15 +466,17 @@ Future notifyContactAboutOpeningMessage( Future sendContactMyProfileData(int contactId) async { List? avatarSvgCompressed; - if (appSession.currentUser.avatarSvg != null) { - avatarSvgCompressed = gzip.encode(utf8.encode(appSession.currentUser.avatarSvg!)); + if (userService.currentUser.avatarSvg != null) { + avatarSvgCompressed = gzip.encode( + utf8.encode(userService.currentUser.avatarSvg!), + ); } final encryptedContent = pb.EncryptedContent( contactUpdate: pb.EncryptedContent_ContactUpdate( type: pb.EncryptedContent_ContactUpdate_Type.UPDATE, avatarSvgCompressed: avatarSvgCompressed, - displayName: appSession.currentUser.displayName, - username: appSession.currentUser.username, + displayName: userService.currentUser.displayName, + username: userService.currentUser.username, ), ); await sendCipherText(contactId, encryptedContent); diff --git a/lib/src/services/api/server_messages.api.dart b/lib/src/services/api/server_messages.api.dart index fbf3bf7f..4e7b92b3 100644 --- a/lib/src/services/api/server_messages.api.dart +++ b/lib/src/services/api/server_messages.api.dart @@ -265,7 +265,7 @@ Future<(EncryptedContent?, PlaintextContent?)> handleEncryptedMessage( await twonlyDB.receiptsDao.markMessagesForRetry(fromUserId); final senderProfileCounter = await checkForProfileUpdate(fromUserId, content); - if (appSession.currentUser.isUserDiscoveryEnabled && + if (userService.currentUser.isUserDiscoveryEnabled && content.hasSenderUserDiscoveryVersion()) { await checkForUserDiscoveryChanges( fromUserId, @@ -354,7 +354,7 @@ Future<(EncryptedContent?, PlaintextContent?)> handleEncryptedMessage( /// Verify that the user is (still) in that group... if (!await twonlyDB.groupsDao.isContactInGroup(fromUserId, content.groupId)) { - if (getUUIDforDirectChat(appSession.currentUser.userId, fromUserId) == + if (getUUIDforDirectChat(userService.currentUser.userId, fromUserId) == content.groupId) { final contact = await twonlyDB.contactsDao .getContactByUserId(fromUserId) diff --git a/lib/src/services/background/callback_dispatcher.background.dart b/lib/src/services/background/callback_dispatcher.background.dart index 65e1b8fc..f0e8d4ae 100644 --- a/lib/src/services/background/callback_dispatcher.background.dart +++ b/lib/src/services/background/callback_dispatcher.background.dart @@ -1,12 +1,11 @@ import 'dart:async'; import 'package:mutex/mutex.dart'; -import 'package:sentry_flutter/sentry_flutter.dart'; import 'package:twonly/globals.dart'; import 'package:twonly/locator.dart'; +import 'package:twonly/main.dart'; import 'package:twonly/src/constants/keyvalue.keys.dart'; import 'package:twonly/src/services/api/mediafiles/upload.api.dart'; -import 'package:twonly/src/services/user.service.dart'; import 'package:twonly/src/utils/exclusive_access.dart'; import 'package:twonly/src/utils/keyvalue.dart'; import 'package:twonly/src/utils/log.dart'; @@ -54,21 +53,15 @@ Future initBackgroundExecution() async { if (_isInitialized) { // Reload the users, as on Android the background isolate can // stay alive for multiple hours between task executions - final user = await getUser(); - if (user == null) return false; - appSession.currentUser = user; - return true; + return userService.tryInit(); } - SentryWidgetsFlutterBinding.ensureInitialized(); - await AppEnvironment.init(); - Log.init(); + await twonlyMinimumInitialization(); - final user = await getUser(); - if (user == null) return false; - - setupLocator(); - appSession.currentUser = user; + if (!await userService.tryInit()) { + Log.info('Early return as user is not registered yet.'); + return false; + } AppState.isInBackgroundTask = true; diff --git a/lib/src/services/backup/common.backup.dart b/lib/src/services/backup/common.backup.dart index 692a8220..50583b51 100644 --- a/lib/src/services/backup/common.backup.dart +++ b/lib/src/services/backup/common.backup.dart @@ -14,7 +14,7 @@ import 'package:twonly/src/utils/misc.dart'; Future enableTwonlySafe(String password) async { final (backupId, encryptionKey) = await getMasterKey( password, - appSession.currentUser.username, + userService.currentUser.username, ); await updateUser((user) { @@ -66,10 +66,10 @@ Future<(Uint8List, Uint8List)> getMasterKey( } String? getTwonlySafeBackupUrl() { - if (appSession.currentUser.twonlySafeBackup == null) return null; + if (userService.currentUser.twonlySafeBackup == null) return null; return getTwonlySafeBackupUrlFromServer( - appSession.currentUser.twonlySafeBackup!.backupId, - appSession.currentUser.backupServer, + userService.currentUser.twonlySafeBackup!.backupId, + userService.currentUser.backupServer, ); } diff --git a/lib/src/services/backup/create.backup.dart b/lib/src/services/backup/create.backup.dart index 6038021b..5bb70f03 100644 --- a/lib/src/services/backup/create.backup.dart +++ b/lib/src/services/backup/create.backup.dart @@ -23,18 +23,18 @@ import 'package:twonly/src/utils/log.dart'; import 'package:twonly/src/utils/misc.dart'; Future performTwonlySafeBackup({bool force = false}) async { - if (appSession.currentUser.twonlySafeBackup == null) { + if (userService.currentUser.twonlySafeBackup == null) { return; } - if (appSession.currentUser.twonlySafeBackup!.backupUploadState == + if (userService.currentUser.twonlySafeBackup!.backupUploadState == LastBackupUploadState.pending) { Log.warn('Backup upload is already pending.'); return; } final lastUpdateTime = - appSession.currentUser.twonlySafeBackup!.lastBackupDone; + userService.currentUser.twonlySafeBackup!.lastBackupDone; if (!force && lastUpdateTime != null) { if (lastUpdateTime.isAfter(clock.now().subtract(const Duration(days: 1)))) { return; @@ -122,8 +122,8 @@ Future performTwonlySafeBackup({bool force = false}) async { final backupHash = uint8ListToHex((await Sha256().hash(backupBytes)).bytes); - if (appSession.currentUser.twonlySafeBackup!.lastBackupDone == null || - appSession.currentUser.twonlySafeBackup!.lastBackupDone!.isAfter( + if (userService.currentUser.twonlySafeBackup!.lastBackupDone == null || + userService.currentUser.twonlySafeBackup!.lastBackupDone!.isAfter( clock.now().subtract(const Duration(days: 90)), )) { force = true; @@ -152,7 +152,7 @@ Future performTwonlySafeBackup({bool force = false}) async { final secretBox = await chacha20.encrypt( backupBytes, secretKey: SecretKey( - appSession.currentUser.twonlySafeBackup!.encryptionKey, + userService.currentUser.twonlySafeBackup!.encryptionKey, ), nonce: nonce, ); @@ -175,9 +175,9 @@ Future performTwonlySafeBackup({bool force = false}) async { 'Create twonly Backup with a size of ${encryptedBackupBytes.length} bytes.', ); - if (appSession.currentUser.backupServer != null) { + if (userService.currentUser.backupServer != null) { if (encryptedBackupBytes.length > - appSession.currentUser.backupServer!.maxBackupBytes) { + userService.currentUser.backupServer!.maxBackupBytes) { Log.error('Backup is to big for the alternative backup server.'); await updateUser((user) { user.twonlySafeBackup!.backupUploadState = LastBackupUploadState.failed; diff --git a/lib/src/services/flame.service.dart b/lib/src/services/flame.service.dart index 353c6a16..3cec6396 100644 --- a/lib/src/services/flame.service.dart +++ b/lib/src/services/flame.service.dart @@ -17,7 +17,7 @@ Future syncFlameCounters({String? forceForGroup}) async { (x) => x.totalMediaCounter == maxMessageCounter, ); - if (appSession.currentUser.myBestFriendGroupId != bestFriend.groupId) { + if (userService.currentUser.myBestFriendGroupId != bestFriend.groupId) { await updateUser((user) { user.myBestFriendGroupId = bestFriend.groupId; }); diff --git a/lib/src/services/group.services.dart b/lib/src/services/group.services.dart index a474dbd1..5df5828d 100644 --- a/lib/src/services/group.services.dart +++ b/lib/src/services/group.services.dart @@ -43,8 +43,8 @@ Future createNewGroup(String groupName, List members) async { final memberIds = members.map((x) => Int64(x.userId)).toList(); final groupState = EncryptedGroupState( - memberIds: [Int64(appSession.currentUser.userId)] + memberIds, - adminIds: [Int64(appSession.currentUser.userId)], + memberIds: [Int64(userService.currentUser.userId)] + memberIds, + adminIds: [Int64(userService.currentUser.userId)], groupName: groupName, deleteMessagesAfterMilliseconds: Int64( defaultDeleteMessagesAfterMilliseconds, @@ -284,9 +284,9 @@ Future<(int, EncryptedGroupState)?> fetchGroupState(Group group) async { final myPubKey = keyPair.getPublicKey().serialize().toList(); if (listEquals(appendedPubKey, myPubKey)) { - adminIds.remove(Int64(appSession.currentUser.userId)); + adminIds.remove(Int64(userService.currentUser.userId)); memberIds.remove( - Int64(appSession.currentUser.userId), + Int64(userService.currentUser.userId), ); // -> Will remove the user later... } else { Log.info('A non admin left the group!!!'); @@ -304,7 +304,7 @@ Future<(int, EncryptedGroupState)?> fetchGroupState(Group group) async { } } - if (!memberIds.contains(Int64(appSession.currentUser.userId))) { + if (!memberIds.contains(Int64(userService.currentUser.userId))) { // OH no, I am no longer a member of this group... // Return from the group... await twonlyDB.groupsDao.updateGroup( @@ -318,7 +318,7 @@ Future<(int, EncryptedGroupState)?> fetchGroupState(Group group) async { final isGroupAdmin = adminIds.firstWhereOrNull( - (t) => t.toInt() == appSession.currentUser.userId, + (t) => t.toInt() == userService.currentUser.userId, ) != null; @@ -372,7 +372,7 @@ Future<(int, EncryptedGroupState)?> fetchGroupState(Group group) async { // First find and insert NEW members for (final memberId in memberIds) { - if (memberId == Int64(appSession.currentUser.userId)) { + if (memberId == Int64(userService.currentUser.userId)) { continue; } if (currentGroupMembers.any((t) => t.contactId == memberId.toInt())) { @@ -842,7 +842,7 @@ Future removeMemberFromGroup( groupId: Value(group.groupId), type: const Value(GroupActionType.removedMember), affectedContactId: Value( - removeContactId == appSession.currentUser.userId + removeContactId == userService.currentUser.userId ? null : removeContactId, ), @@ -951,7 +951,7 @@ Future leaveAsNonAdminFromGroup(Group group) async { EncryptedContent( groupUpdate: EncryptedContent_GroupUpdate( groupActionType: groupActionType.name, - affectedContactId: Int64(appSession.currentUser.userId), + affectedContactId: Int64(userService.currentUser.userId), ), ), ); diff --git a/lib/src/services/intent/links.intent.dart b/lib/src/services/intent/links.intent.dart index ebc6e8ea..42a50f0f 100644 --- a/lib/src/services/intent/links.intent.dart +++ b/lib/src/services/intent/links.intent.dart @@ -33,7 +33,7 @@ Future handleIntentUrl(BuildContext context, Uri uri) async { if (!context.mounted) return false; - if (username == appSession.currentUser.username) { + if (username == userService.currentUser.username) { await context.push(Routes.settingsPublicProfile); return true; } @@ -116,7 +116,7 @@ Future handleIntentMediaFile( final newMediaService = await initializeMediaUpload( type, - appSession.currentUser.defaultShowTime, + userService.currentUser.defaultShowTime, ); if (newMediaService == null) { Log.error('Could not create new media file for intent shared file'); diff --git a/lib/src/services/mediafiles/mediafile.service.dart b/lib/src/services/mediafiles/mediafile.service.dart index 4c0ba7ac..daffe410 100644 --- a/lib/src/services/mediafiles/mediafile.service.dart +++ b/lib/src/services/mediafiles/mediafile.service.dart @@ -239,7 +239,7 @@ class MediaFileService { } if (tempPath.existsSync()) { await tempPath.copy(storedPath.path); - if (appSession.currentUser.storeMediaFilesInGallery) { + if (userService.currentUser.storeMediaFilesInGallery) { if (mediaFile.type == MediaType.video) { await saveVideoToGallery(storedPath.path); } else { diff --git a/lib/src/services/notifications/fcm.notifications.dart b/lib/src/services/notifications/fcm.notifications.dart index 27056aa2..3f928fd8 100644 --- a/lib/src/services/notifications/fcm.notifications.dart +++ b/lib/src/services/notifications/fcm.notifications.dart @@ -74,7 +74,7 @@ Future checkForTokenUpdates() async { } Future initFCMAfterAuthenticated({bool force = false}) async { - if (appSession.currentUser.updateFCMToken || force) { + if (userService.currentUser.updateFCMToken || force) { const storage = FlutterSecureStorage(); final storedToken = await storage.read(key: SecureStorageKeys.googleFcm); if (storedToken != null) { diff --git a/lib/src/services/signal/identity.signal.dart b/lib/src/services/signal/identity.signal.dart index 65737607..693a23c7 100644 --- a/lib/src/services/signal/identity.signal.dart +++ b/lib/src/services/signal/identity.signal.dart @@ -21,10 +21,10 @@ Future getSignalIdentityKeyPair() async { // This function runs after the clients authenticated with the server. // It then checks if it should update a new session key Future signalHandleNewServerConnection() async { - if (appSession.currentUser.signalLastSignedPreKeyUpdated != null) { + if (userService.currentUser.signalLastSignedPreKeyUpdated != null) { final fortyEightHoursAgo = clock.now().subtract(const Duration(hours: 48)); final isYoungerThan48Hours = - (appSession.currentUser.signalLastSignedPreKeyUpdated!).isAfter( + (userService.currentUser.signalLastSignedPreKeyUpdated!).isAfter( fortyEightHoursAgo, ); if (isYoungerThan48Hours) { diff --git a/lib/src/services/user.service.dart b/lib/src/services/user.service.dart index d9518a40..37c8c146 100644 --- a/lib/src/services/user.service.dart +++ b/lib/src/services/user.service.dart @@ -18,6 +18,13 @@ class UserService { final _userDataUpdateController = StreamController.broadcast(); Stream get onUserUpdated => _userDataUpdateController.stream; + Future tryInit() async { + final user = await getUser(); + if (user == null) return false; + userService.currentUser = user; + return true; + } + void triggerUserUpdate() { _userDataUpdateController.add(null); } @@ -32,7 +39,7 @@ Future isUserCreated() async { if (user == null) { return false; } - appSession.currentUser = user; + userService.currentUser = user; return true; } @@ -84,8 +91,8 @@ Future updateUser( key: SecureStorageKeys.userData, value: jsonEncode(user), ); - appSession.currentUser = user; + userService.currentUser = user; }); - appSession.triggerUserUpdate(); + userService.triggerUserUpdate(); } diff --git a/lib/src/services/user_discovery.service.dart b/lib/src/services/user_discovery.service.dart index 1f1eea9c..5a17881f 100644 --- a/lib/src/services/user_discovery.service.dart +++ b/lib/src/services/user_discovery.service.dart @@ -54,7 +54,7 @@ class UserDiscoveryService { try { await FlutterUserDiscovery.initializeOrUpdate( threshold: threshold, - userId: appSession.currentUser.userId, + userId: userService.currentUser.userId, publicKey: await getUserPublicKey(), ); await updateUser( diff --git a/lib/src/services/user_study.service.dart b/lib/src/services/user_study.service.dart index 30d06220..15deffab 100644 --- a/lib/src/services/user_study.service.dart +++ b/lib/src/services/user_study.service.dart @@ -15,7 +15,7 @@ const surveyUrlBase = 'https://survey.twonly.org/upload.php'; Future handleUserStudyUpload() async { try { - final token = appSession.currentUser.userStudyParticipantsToken; + final token = userService.currentUser.userStudyParticipantsToken; if (token == null) return; // in case the survey was taken offline try again @@ -35,8 +35,8 @@ Future handleUserStudyUpload() async { await KeyValueStore.delete(userStudySurveyKey); } - if (appSession.currentUser.lastUserStudyDataUpload != null && - isToday(appSession.currentUser.lastUserStudyDataUpload!)) { + if (userService.currentUser.lastUserStudyDataUpload != null && + isToday(userService.currentUser.lastUserStudyDataUpload!)) { // Only send updates once a day. // This enables to see if improvements to actually work. return; diff --git a/lib/src/utils/avatars.dart b/lib/src/utils/avatars.dart index ba5bdd51..4aaefa48 100644 --- a/lib/src/utils/avatars.dart +++ b/lib/src/utils/avatars.dart @@ -53,13 +53,13 @@ File avatarPNGFile(int contactId) { } Future getUserAvatar() async { - if (appSession.currentUser.avatarSvg == null) { + if (userService.currentUser.avatarSvg == null) { final data = await rootBundle.load('assets/images/default_avatar.png'); return data.buffer.asUint8List(); } final pictureInfo = await vg.loadPicture( - SvgStringLoader(appSession.currentUser.avatarSvg!), + SvgStringLoader(userService.currentUser.avatarSvg!), null, ); @@ -68,7 +68,7 @@ Future getUserAvatar() async { final byteData = await image.toByteData(format: ui.ImageByteFormat.png); final pngBytes = byteData!.buffer.asUint8List(); - final file = avatarPNGFile(appSession.currentUser.userId) + final file = avatarPNGFile(userService.currentUser.userId) ..writeAsBytesSync(pngBytes); pictureInfo.picture.dispose(); diff --git a/lib/src/utils/qr.dart b/lib/src/utils/qr.dart index c3b4d47b..9650207c 100644 --- a/lib/src/utils/qr.dart +++ b/lib/src/utils/qr.dart @@ -17,8 +17,8 @@ Future getProfileQrCodeData() async { final signedPreKey = (await signalStore.loadSignedPreKeys())[0]; final publicProfile = PublicProfile( - userId: Int64(appSession.currentUser.userId), - username: appSession.currentUser.username, + userId: Int64(userService.currentUser.userId), + username: userService.currentUser.username, publicIdentityKey: (await signalStore.getIdentityKeyPair()) .getPublicKey() .serialize(), diff --git a/lib/src/visual/components/avatar_icon.comp.dart b/lib/src/visual/components/avatar_icon.comp.dart index 5580e369..e057ab37 100644 --- a/lib/src/visual/components/avatar_icon.comp.dart +++ b/lib/src/visual/components/avatar_icon.comp.dart @@ -93,19 +93,19 @@ class _AvatarIconState extends State { setState(() {}); }); } else if (widget.myAvatar) { - _userSub = appSession.onUserUpdated.listen((_) { + _userSub = userService.onUserUpdated.listen((_) { if (mounted) { setState(() { - if (appSession.currentUser.avatarSvg != null) { - _avatarSvg = appSession.currentUser.avatarSvg; + if (userService.currentUser.avatarSvg != null) { + _avatarSvg = userService.currentUser.avatarSvg; } else { _avatarContacts = []; } }); } }); - if (appSession.currentUser.avatarSvg != null) { - _avatarSvg = appSession.currentUser.avatarSvg; + if (userService.currentUser.avatarSvg != null) { + _avatarSvg = userService.currentUser.avatarSvg; } } else if (widget.contactId != null) { contactStream = twonlyDB.contactsDao diff --git a/lib/src/visual/components/flame_counter.comp.dart b/lib/src/visual/components/flame_counter.comp.dart index 5a629e31..aded260d 100644 --- a/lib/src/visual/components/flame_counter.comp.dart +++ b/lib/src/visual/components/flame_counter.comp.dart @@ -49,7 +49,7 @@ class _FlameCounterWidgetState extends State { } if (groupId != null && group != null) { isBestFriend = - appSession.currentUser.myBestFriendGroupId == groupId && + userService.currentUser.myBestFriendGroupId == groupId && group.alsoBestFriend; final stream = twonlyDB.groupsDao.watchFlameCounter(groupId); flameCounterSub = stream.listen((counter) { 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 9bf92347..32f59a8f 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 @@ -210,7 +210,7 @@ class _CameraPreviewViewState extends State { _hasAudioPermission = await Permission.microphone.isGranted; if (!_hasAudioPermission && - !appSession.currentUser.requestedAudioPermission) { + !userService.currentUser.requestedAudioPermission) { await updateUser((u) { u.requestedAudioPermission = true; }); @@ -322,7 +322,7 @@ class _CameraPreviewViewState extends State { ((videoFilePath != null) ? MediaType.video : MediaType.image); final mediaFileService = await initializeMediaUpload( type, - appSession.currentUser.defaultShowTime, + userService.currentUser.defaultShowTime, isDraftMedia: true, ); if (!mounted) return true; diff --git a/lib/src/visual/views/camera/camera_preview_components/main_camera_controller.dart b/lib/src/visual/views/camera/camera_preview_components/main_camera_controller.dart index 25e40b80..f7bd197e 100644 --- a/lib/src/visual/views/camera/camera_preview_components/main_camera_controller.dart +++ b/lib/src/visual/views/camera/camera_preview_components/main_camera_controller.dart @@ -137,7 +137,7 @@ class MainCameraController { await cameraController?.initialize(); await cameraController?.startImageStream(_processCameraImage); await cameraController?.setZoomLevel(selectedCameraDetails.scaleFactor); - if (appSession.currentUser.videoStabilizationEnabled && !kDebugMode) { + if (userService.currentUser.videoStabilizationEnabled && !kDebugMode) { await cameraController?.setVideoStabilizationMode( VideoStabilizationMode.level1, ); @@ -397,7 +397,7 @@ class MainCameraController { } } } else { - if (profile.username != appSession.currentUser.username) { + if (profile.username != userService.currentUser.username) { if (scannedNewProfiles[profile.userId.toInt()] == null) { await HapticFeedback.heavyImpact(); scannedNewProfiles[profile.userId.toInt()] = ScannedNewProfile( diff --git a/lib/src/visual/views/camera/share_image_contact_selection.view.dart b/lib/src/visual/views/camera/share_image_contact_selection.view.dart index f30beef7..9f28bc70 100644 --- a/lib/src/visual/views/camera/share_image_contact_selection.view.dart +++ b/lib/src/visual/views/camera/share_image_contact_selection.view.dart @@ -256,7 +256,7 @@ class _ShareImageView extends State { children: [ if (widget.mediaFileService.mediaFile.type == MediaType.image && _screenshotImage?.image != null && - appSession.currentUser.showShowImagePreviewWhenSending) + userService.currentUser.showShowImagePreviewWhenSending) SizedBox( height: 100, width: 100 * 9 / 16, diff --git a/lib/src/visual/views/chats/add_new_user.view.dart b/lib/src/visual/views/chats/add_new_user.view.dart index 3d97450c..3c8eb10a 100644 --- a/lib/src/visual/views/chats/add_new_user.view.dart +++ b/lib/src/visual/views/chats/add_new_user.view.dart @@ -93,7 +93,7 @@ class _SearchUsernameView extends State { } Future _requestNewUserByUsername(String username) async { - if (appSession.currentUser.username == username) return; + if (userService.currentUser.username == username) return; setState(() { _isLoading = true; diff --git a/lib/src/visual/views/chats/chat_list.view.dart b/lib/src/visual/views/chats/chat_list.view.dart index af63ed32..c6a02e33 100644 --- a/lib/src/visual/views/chats/chat_list.view.dart +++ b/lib/src/visual/views/chats/chat_list.view.dart @@ -45,7 +45,7 @@ class _ChatListViewState extends State { @override void initState() { initAsync(); - _userSub = appSession.onUserUpdated.listen((_) { + _userSub = userService.onUserUpdated.listen((_) { if (mounted) setState(() {}); }); super.initState(); @@ -90,8 +90,8 @@ class _ChatListViewState extends State { Sha256().hash, changeLog.codeUnits, )).bytes; - if (!appSession.currentUser.hideChangeLog && - appSession.currentUser.lastChangeLogHash.toString() != + if (!userService.currentUser.hideChangeLog && + userService.currentUser.lastChangeLogHash.toString() != changeLogHash.toString()) { await updateUser((u) { u.lastChangeLogHash = changeLogHash; diff --git a/lib/src/visual/views/chats/chat_messages.view.dart b/lib/src/visual/views/chats/chat_messages.view.dart index 321196d1..1e27634b 100644 --- a/lib/src/visual/views/chats/chat_messages.view.dart +++ b/lib/src/visual/views/chats/chat_messages.view.dart @@ -122,7 +122,7 @@ class _ChatMessagesViewState extends State { _receiverDeletedAccount = groupContacts.first.accountDeleted; } - if (appSession.currentUser.typingIndicators) { + if (userService.currentUser.typingIndicators) { unawaited(sendTypingIndication(widget.groupId, false)); _nextTypingIndicator = Timer.periodic(const Duration(seconds: 4), ( _, @@ -290,7 +290,7 @@ class _ChatMessagesViewState extends State { itemScrollController: itemScrollController, itemBuilder: (context, i) { if (i == 0) { - return appSession.currentUser.typingIndicators + return userService.currentUser.typingIndicators ? TypingIndicator(group: group) : Container(); } diff --git a/lib/src/visual/views/chats/chat_messages_components/entries/chat_contacts.entry.dart b/lib/src/visual/views/chats/chat_messages_components/entries/chat_contacts.entry.dart index aa4e769e..4cc9a919 100644 --- a/lib/src/visual/views/chats/chat_messages_components/entries/chat_contacts.entry.dart +++ b/lib/src/visual/views/chats/chat_messages_components/entries/chat_contacts.entry.dart @@ -102,7 +102,7 @@ class _ContactRowState extends State<_ContactRow> { bool _isLoading = false; Future _onContactClick(bool isAdded) async { - if (widget.contact.userId.toInt() == appSession.currentUser.userId) { + if (widget.contact.userId.toInt() == userService.currentUser.userId) { await context.push(Routes.settingsProfile); return; } @@ -162,7 +162,7 @@ class _ContactRowState extends State<_ContactRow> { final contactInDb = snapshot.data; final isAdded = contactInDb != null || - widget.contact.userId.toInt() == appSession.currentUser.userId; + widget.contact.userId.toInt() == userService.currentUser.userId; return GestureDetector( onTap: _isLoading ? null : () => _onContactClick(isAdded), diff --git a/lib/src/visual/views/chats/chat_messages_components/message_input.dart b/lib/src/visual/views/chats/chat_messages_components/message_input.dart index df76c323..9cc45bd1 100644 --- a/lib/src/visual/views/chats/chat_messages_components/message_input.dart +++ b/lib/src/visual/views/chats/chat_messages_components/message_input.dart @@ -73,7 +73,7 @@ class _MessageInputState extends State { _textFieldController.text = widget.group.draftMessage!; } widget.textFieldFocus.addListener(_handleTextFocusChange); - if (appSession.currentUser.typingIndicators) { + if (userService.currentUser.typingIndicators) { _nextTypingIndicator = Timer.periodic(const Duration(seconds: 1), ( _, ) async { diff --git a/lib/src/visual/views/chats/media_viewer_components/reaction_buttons.comp.dart b/lib/src/visual/views/chats/media_viewer_components/reaction_buttons.comp.dart index a8840dd6..4e88e842 100644 --- a/lib/src/visual/views/chats/media_viewer_components/reaction_buttons.comp.dart +++ b/lib/src/visual/views/chats/media_viewer_components/reaction_buttons.comp.dart @@ -50,8 +50,8 @@ class _ReactionButtonsState extends State { } Future initAsync() async { - if (appSession.currentUser.preSelectedEmojies != null) { - selectedEmojis = appSession.currentUser.preSelectedEmojies!; + if (userService.currentUser.preSelectedEmojies != null) { + selectedEmojis = userService.currentUser.preSelectedEmojies!; } setState(() {}); } diff --git a/lib/src/visual/views/contact/components/restore_flame.comp.dart b/lib/src/visual/views/contact/components/restore_flame.comp.dart index 2018fe0b..f6291d8e 100644 --- a/lib/src/visual/views/contact/components/restore_flame.comp.dart +++ b/lib/src/visual/views/contact/components/restore_flame.comp.dart @@ -41,7 +41,7 @@ class _RestoreFlameCompState extends State { void initState() { _groupId = getUUIDforDirectChat( widget.contactId, - appSession.currentUser.userId, + userService.currentUser.userId, ); final stream = twonlyDB.groupsDao.watchGroup(_groupId); _groupSub = stream.listen((update) { @@ -57,7 +57,9 @@ class _RestoreFlameCompState extends State { } Future _restoreFlames() async { - final currentPlan = planFromString(appSession.currentUser.subscriptionPlan); + final currentPlan = planFromString( + userService.currentUser.subscriptionPlan, + ); if (!isUserAllowed(currentPlan, PremiumFeatures.RestoreFlames) && kReleaseMode) { await context.push(Routes.settingsSubscription); diff --git a/lib/src/visual/views/contact/contact.view.dart b/lib/src/visual/views/contact/contact.view.dart index 7294893f..e9748665 100644 --- a/lib/src/visual/views/contact/contact.view.dart +++ b/lib/src/visual/views/contact/contact.view.dart @@ -207,7 +207,7 @@ class _ContactViewState extends State { SelectChatDeletionTimeListTitle( groupId: getUUIDforDirectChat( widget.userId, - appSession.currentUser.userId, + userService.currentUser.userId, ), ), const Divider(), @@ -226,17 +226,17 @@ class _ContactViewState extends State { setState(() {}); }, ), - if (appSession.currentUser.isUserDiscoveryEnabled) + if (userService.currentUser.isUserDiscoveryEnabled) BetterListTile( icon: FontAwesomeIcons.usersViewfinder, text: context.lang.userDiscoverySettingsTitle, subtitle: !contact.userDiscoveryExcluded && contact.mediaSendCounter < - appSession.currentUser.minimumRequiredImagesExchanged + userService.currentUser.minimumRequiredImagesExchanged ? Text( context.lang.contactUserDiscoveryImagesLeft( - appSession.currentUser.minimumRequiredImagesExchanged - + userService.currentUser.minimumRequiredImagesExchanged - contact.mediaSendCounter, getContactDisplayName(contact), ), diff --git a/lib/src/visual/views/groups/group.view.dart b/lib/src/visual/views/groups/group.view.dart index 023e5ee4..1edca94b 100644 --- a/lib/src/visual/views/groups/group.view.dart +++ b/lib/src/visual/views/groups/group.view.dart @@ -143,7 +143,7 @@ class _GroupViewState extends State { success = await removeMemberFromGroup( _group!, keyPair.getPublicKey().serialize(), - appSession.currentUser.userId, + userService.currentUser.userId, ); } else { success = await leaveAsNonAdminFromGroup(_group!); diff --git a/lib/src/visual/views/home.view.dart b/lib/src/visual/views/home.view.dart index a353c0e3..d569f4d9 100644 --- a/lib/src/visual/views/home.view.dart +++ b/lib/src/visual/views/home.view.dart @@ -137,7 +137,7 @@ class HomeViewState extends State { ); WidgetsBinding.instance.addPostFrameCallback((_) { if (widget.initialPage == 1 && - !appSession.currentUser.startWithCameraOpen || + !userService.currentUser.startWithCameraOpen || widget.initialPage == 0) { globalUpdateOfHomeViewPageIndex(0); } diff --git a/lib/src/visual/views/onboarding/register.view.dart b/lib/src/visual/views/onboarding/register.view.dart index 8bb7a994..98394411 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), ); - appSession.currentUser = userData; + userService.currentUser = userData; await apiService.authenticate(); widget.callbackOnSuccess(); diff --git a/lib/src/visual/views/public_profile.view.dart b/lib/src/visual/views/public_profile.view.dart index a0b3f9a1..05aa2e0e 100644 --- a/lib/src/visual/views/public_profile.view.dart +++ b/lib/src/visual/views/public_profile.view.dart @@ -107,7 +107,7 @@ class _PublicProfileViewState extends State { ), const SizedBox(height: 20), Text( - appSession.currentUser.username, + userService.currentUser.username, style: const TextStyle(fontSize: 24), ), const SizedBox(height: 20), @@ -127,12 +127,12 @@ class _PublicProfileViewState extends State { subtitle: (_publicKey == null) ? null : Text( - 'https://me.twonly.eu/${appSession.currentUser.username}', + 'https://me.twonly.eu/${userService.currentUser.username}', ), onTap: () { final params = ShareParams( text: - 'https://me.twonly.eu/${appSession.currentUser.username}#${base64Url.encode(_publicKey!)}', + 'https://me.twonly.eu/${userService.currentUser.username}#${base64Url.encode(_publicKey!)}', ); SharePlus.instance.share(params); }, diff --git a/lib/src/visual/views/settings/appearance.view.dart b/lib/src/visual/views/settings/appearance.view.dart index 1c0e728f..e546dbcc 100644 --- a/lib/src/visual/views/settings/appearance.view.dart +++ b/lib/src/visual/views/settings/appearance.view.dart @@ -98,7 +98,7 @@ class _AppearanceViewState extends State { title: Text(context.lang.settingsAppearance), ), body: StreamBuilder( - stream: appSession.onUserUpdated, + stream: userService.onUserUpdated, builder: (context, snapshot) { return ListView( children: [ @@ -116,7 +116,7 @@ class _AppearanceViewState extends State { title: Text(context.lang.contactUsShortcut), onTap: toggleShowFeedbackIcon, trailing: Switch( - value: !appSession.currentUser.showFeedbackShortcut, + value: !userService.currentUser.showFeedbackShortcut, onChanged: (a) => toggleShowFeedbackIcon(), ), ), @@ -124,7 +124,7 @@ class _AppearanceViewState extends State { title: Text(context.lang.startWithCameraOpen), onTap: toggleStartWithCameraOpen, trailing: Switch( - value: appSession.currentUser.startWithCameraOpen, + value: userService.currentUser.startWithCameraOpen, onChanged: (a) => toggleStartWithCameraOpen(), ), ), @@ -132,7 +132,8 @@ class _AppearanceViewState extends State { title: Text(context.lang.showImagePreviewWhenSending), onTap: toggleShowImagePreviewWhenSending, trailing: Switch( - value: appSession.currentUser.showShowImagePreviewWhenSending, + value: + userService.currentUser.showShowImagePreviewWhenSending, onChanged: (a) => toggleShowImagePreviewWhenSending(), ), ), 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 0ec4cfb2..bb9c4976 100644 --- a/lib/src/visual/views/settings/backup/backup_server.view.dart +++ b/lib/src/visual/views/settings/backup/backup_server.view.dart @@ -32,8 +32,8 @@ class _BackupServerViewState extends State { } Future initAsync() async { - if (appSession.currentUser.backupServer != null) { - final uri = Uri.parse(appSession.currentUser.backupServer!.serverUrl); + if (userService.currentUser.backupServer != null) { + final uri = Uri.parse(userService.currentUser.backupServer!.serverUrl); // remove user auth data final serverUrl = Uri( scheme: uri.scheme, diff --git a/lib/src/visual/views/settings/backup/backup_settings.view.dart b/lib/src/visual/views/settings/backup/backup_settings.view.dart index e4214e33..e321debf 100644 --- a/lib/src/visual/views/settings/backup/backup_settings.view.dart +++ b/lib/src/visual/views/settings/backup/backup_settings.view.dart @@ -38,10 +38,10 @@ class _BackupViewState extends State { @override Widget build(BuildContext context) { return StreamBuilder( - stream: appSession.onUserUpdated, + stream: userService.onUserUpdated, builder: (context, _) { final backupServer = - appSession.currentUser.backupServer ?? _defaultBackupServer; + userService.currentUser.backupServer ?? _defaultBackupServer; return Scaffold( appBar: AppBar( title: Text(context.lang.settingsBackup), @@ -57,7 +57,7 @@ class _BackupViewState extends State { textAlign: TextAlign.center, ), const SizedBox(height: 8), - if (appSession.currentUser.twonlySafeBackup != null) + if (userService.currentUser.twonlySafeBackup != null) Column( children: [ const SizedBox(height: 32), @@ -87,7 +87,7 @@ class _BackupViewState extends State { context.lang.backupLastBackupDate, formatDateTime( context, - appSession + userService .currentUser .twonlySafeBackup! .lastBackupDone, @@ -96,7 +96,7 @@ class _BackupViewState extends State { ( context.lang.backupLastBackupSize, formatBytes( - appSession + userService .currentUser .twonlySafeBackup! .lastBackupSize, @@ -105,7 +105,7 @@ class _BackupViewState extends State { ( context.lang.backupLastBackupResult, _backupStatus( - appSession + userService .currentUser .twonlySafeBackup! .backupUploadState, @@ -156,7 +156,7 @@ class _BackupViewState extends State { onPressed: () => context.push(Routes.settingsBackupSetup, extra: true), child: Text( - appSession.currentUser.twonlySafeBackup == null + userService.currentUser.twonlySafeBackup == null ? context.lang.backupEnableBackup : context.lang.backupChangePassword, ), diff --git a/lib/src/visual/views/settings/backup/backup_setup.view.dart b/lib/src/visual/views/settings/backup/backup_setup.view.dart index 347cfdce..25d94181 100644 --- a/lib/src/visual/views/settings/backup/backup_setup.view.dart +++ b/lib/src/visual/views/settings/backup/backup_setup.view.dart @@ -211,7 +211,7 @@ class _SetupBackupViewState extends State { ) : const Icon(Icons.lock_clock_rounded), label: Text( - appSession.currentUser.twonlySafeBackup == null + userService.currentUser.twonlySafeBackup == null ? context.lang.backupEnableBackup : context.lang.backupChangePassword, ), 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 9884fe40..c750739d 100644 --- a/lib/src/visual/views/settings/chat/chat_reactions.view.dart +++ b/lib/src/visual/views/settings/chat/chat_reactions.view.dart @@ -16,7 +16,7 @@ class _ChatReactionSelectionView extends State { List _selectedEmojis = []; List _emojisFromSession() { - final user = appSession.currentUser; + final user = userService.currentUser; if (user.preSelectedEmojies != null) { return user.preSelectedEmojies!; } @@ -53,7 +53,7 @@ class _ChatReactionSelectionView extends State { @override Widget build(BuildContext context) { return StreamBuilder( - stream: appSession.onUserUpdated, + stream: userService.onUserUpdated, builder: (context, _) { _selectedEmojis = _emojisFromSession(); return Scaffold( 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 c751b9bb..c18b52e6 100644 --- a/lib/src/visual/views/settings/data_and_storage.view.dart +++ b/lib/src/visual/views/settings/data_and_storage.view.dart @@ -28,7 +28,7 @@ class _DataAndStorageViewState extends State { builder: (context) { return AutoDownloadOptionsDialog( autoDownloadOptions: - appSession.currentUser.autoDownloadOptions ?? + userService.currentUser.autoDownloadOptions ?? defaultAutoDownloadOptions, connectionMode: connectionMode, onUpdate: () {}, @@ -57,10 +57,10 @@ class _DataAndStorageViewState extends State { title: Text(context.lang.settingsStorageData), ), body: StreamBuilder( - stream: appSession.onUserUpdated, + stream: userService.onUserUpdated, builder: (context, _) { final autoDownloadOptions = - appSession.currentUser.autoDownloadOptions ?? + userService.currentUser.autoDownloadOptions ?? defaultAutoDownloadOptions; return ListView( children: [ @@ -71,7 +71,7 @@ class _DataAndStorageViewState extends State { ), onTap: toggleStoreInGallery, trailing: Switch( - value: appSession.currentUser.storeMediaFilesInGallery, + value: userService.currentUser.storeMediaFilesInGallery, onChanged: (a) => toggleStoreInGallery(), ), ), @@ -83,7 +83,7 @@ class _DataAndStorageViewState extends State { ), onTap: toggleAutoStoreMediaFiles, trailing: Switch( - value: appSession + value: userService .currentUser .autoStoreAllSendUnlimitedMediaFiles, onChanged: (a) => toggleAutoStoreMediaFiles(), diff --git a/lib/src/visual/views/settings/developer/developer.view.dart b/lib/src/visual/views/settings/developer/developer.view.dart index 5e0499c8..f8244bf9 100644 --- a/lib/src/visual/views/settings/developer/developer.view.dart +++ b/lib/src/visual/views/settings/developer/developer.view.dart @@ -44,7 +44,7 @@ class _DeveloperSettingsViewState extends State { title: const Text('Developer Settings'), ), body: StreamBuilder( - stream: appSession.onUserUpdated, + stream: userService.onUserUpdated, builder: (context, _) { return ListView( children: [ @@ -52,7 +52,7 @@ class _DeveloperSettingsViewState extends State { title: const Text('Show Developer Settings'), onTap: toggleDeveloperSettings, trailing: Switch( - value: appSession.currentUser.isDeveloper, + value: userService.currentUser.isDeveloper, onChanged: (_) => toggleDeveloperSettings(), ), ), @@ -66,7 +66,7 @@ class _DeveloperSettingsViewState extends State { title: const Text('Toggle Video Stabilization'), onTap: toggleVideoStabilization, trailing: Switch( - value: appSession.currentUser.videoStabilizationEnabled, + value: userService.currentUser.videoStabilizationEnabled, onChanged: (a) => toggleVideoStabilization(), ), ), diff --git a/lib/src/visual/views/settings/help/changelog.view.dart b/lib/src/visual/views/settings/help/changelog.view.dart index 08722d4a..43e7fe73 100644 --- a/lib/src/visual/views/settings/help/changelog.view.dart +++ b/lib/src/visual/views/settings/help/changelog.view.dart @@ -93,7 +93,7 @@ class _ChangeLogViewState extends State { @override Widget build(BuildContext context) { return StreamBuilder( - stream: appSession.onUserUpdated, + stream: userService.onUserUpdated, builder: (context, _) { return Scaffold( appBar: AppBar( @@ -113,7 +113,7 @@ class _ChangeLogViewState extends State { children: [ Text(context.lang.openChangeLog), Switch( - value: !appSession.currentUser.hideChangeLog, + value: !userService.currentUser.hideChangeLog, onChanged: (_) => updateUser((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 eb353d2e..6d3b4de5 100644 --- a/lib/src/visual/views/settings/help/help.view.dart +++ b/lib/src/visual/views/settings/help/help.view.dart @@ -31,7 +31,7 @@ class _HelpViewState extends State { title: Text(context.lang.settingsHelp), ), body: StreamBuilder( - stream: appSession.onUserUpdated, + stream: userService.onUserUpdated, builder: (context, _) { return ListView( children: [ @@ -52,7 +52,7 @@ class _HelpViewState extends State { ), onTap: toggleAllowErrorTrackingViaSentry, trailing: Switch( - value: appSession.currentUser.allowErrorTrackingViaSentry, + value: userService.currentUser.allowErrorTrackingViaSentry, onChanged: (a) => toggleAllowErrorTrackingViaSentry(), ), ), @@ -61,7 +61,7 @@ class _HelpViewState extends State { onTap: () => context.push(Routes.settingsHelpDiagnostics), ), const Divider(), - if (appSession.currentUser.userStudyParticipantsToken == null || + if (userService.currentUser.userStudyParticipantsToken == null || kDebugMode) ListTile( title: const Text('Teilnahme an Nutzerstudie'), diff --git a/lib/src/visual/views/settings/privacy.view.dart b/lib/src/visual/views/settings/privacy.view.dart index c5320d54..36099c04 100644 --- a/lib/src/visual/views/settings/privacy.view.dart +++ b/lib/src/visual/views/settings/privacy.view.dart @@ -20,7 +20,7 @@ class _PrivacyViewState extends State { Future toggleAuthRequirementOnStartup() async { final isAuth = await authenticateUser( - appSession.currentUser.screenLockEnabled + userService.currentUser.screenLockEnabled ? context.lang.settingsScreenLockAuthMessageDisable : context.lang.settingsScreenLockAuthMessageEnable, ); @@ -84,7 +84,7 @@ class _PrivacyViewState extends State { subtitle: Text(context.lang.settingsTypingIndicationSubtitle), onTap: toggleTypingIndicators, trailing: Switch( - value: appSession.currentUser.typingIndicators, + value: userService.currentUser.typingIndicators, onChanged: (a) => toggleTypingIndicators(), ), ), @@ -94,7 +94,7 @@ class _PrivacyViewState extends State { subtitle: Text(context.lang.settingsScreenLockSubtitle), onTap: toggleAuthRequirementOnStartup, trailing: Switch( - value: appSession.currentUser.screenLockEnabled, + value: userService.currentUser.screenLockEnabled, onChanged: (a) => toggleAuthRequirementOnStartup(), ), ), diff --git a/lib/src/visual/views/settings/privacy/user_discovery.view.dart b/lib/src/visual/views/settings/privacy/user_discovery.view.dart index 109eb7f5..76ec23b5 100644 --- a/lib/src/visual/views/settings/privacy/user_discovery.view.dart +++ b/lib/src/visual/views/settings/privacy/user_discovery.view.dart @@ -19,9 +19,9 @@ class _UserDiscoverySettingsViewState extends State { title: const Text('Freunde finden'), ), body: StreamBuilder( - stream: appSession.onUserUpdated, + stream: userService.onUserUpdated, builder: (context, _) { - return appSession.currentUser.isUserDiscoveryEnabled + return userService.currentUser.isUserDiscoveryEnabled ? const UserDiscoveryEnabledComp() : const UserDiscoveryDisabledComp(); }, diff --git a/lib/src/visual/views/settings/privacy/user_discovery/components/user_discovery_enabled.comp.dart b/lib/src/visual/views/settings/privacy/user_discovery/components/user_discovery_enabled.comp.dart index 9b049921..06954bce 100644 --- a/lib/src/visual/views/settings/privacy/user_discovery/components/user_discovery_enabled.comp.dart +++ b/lib/src/visual/views/settings/privacy/user_discovery/components/user_discovery_enabled.comp.dart @@ -114,7 +114,7 @@ class _UserDiscoveryEnabledCompState extends State { ), subtitle: (version != null && - (appSession.currentUser.isDeveloper || + (userService.currentUser.isDeveloper || !kReleaseMode)) ? Text( context.lang.userDiscoveryEnabledVersion( @@ -168,7 +168,7 @@ class _UserDiscoveryEnabledCompState extends State { onTap: _disableUserDiscovery, ), if (_version != null && - (appSession.currentUser.isDeveloper || !kReleaseMode)) + (userService.currentUser.isDeveloper || !kReleaseMode)) ListTile( title: Text( context.lang.userDiscoveryEnabledYourVersion( 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 89ccd6ae..350075ff 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 @@ -23,14 +23,14 @@ class _UserDiscoverySettingsViewState extends State { @override void initState() { _minimumRequiredImagesExchanged = - appSession.currentUser.minimumRequiredImagesExchanged; - _userDiscoveryThreshold = appSession.currentUser.userDiscoveryThreshold; + userService.currentUser.minimumRequiredImagesExchanged; + _userDiscoveryThreshold = userService.currentUser.userDiscoveryThreshold; super.initState(); } Future _saveChanges() async { final requiresNewInitialization = - appSession.currentUser.userDiscoveryThreshold != + userService.currentUser.userDiscoveryThreshold != _userDiscoveryThreshold; await updateUser((u) { @@ -41,9 +41,9 @@ class _UserDiscoverySettingsViewState extends State { if (requiresNewInitialization) { await UserDiscoveryService.initializeOrUpdate( - threshold: appSession.currentUser.userDiscoveryThreshold, + threshold: userService.currentUser.userDiscoveryThreshold, minimumRequiredImagesExchanged: - appSession.currentUser.minimumRequiredImagesExchanged, + userService.currentUser.minimumRequiredImagesExchanged, ); } if (mounted) Navigator.pop(context); @@ -115,9 +115,9 @@ class _UserDiscoverySettingsViewState extends State { height: 30, ), if (_minimumRequiredImagesExchanged != - appSession.currentUser.minimumRequiredImagesExchanged || + userService.currentUser.minimumRequiredImagesExchanged || _userDiscoveryThreshold != - appSession.currentUser.userDiscoveryThreshold) + userService.currentUser.userDiscoveryThreshold) Padding( padding: const EdgeInsets.all(17), child: FilledButton( 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 9c70f4f6..aa8d7081 100644 --- a/lib/src/visual/views/settings/profile/modify_avatar.view.dart +++ b/lib/src/visual/views/settings/profile/modify_avatar.view.dart @@ -122,7 +122,7 @@ class _ModifyAvatarViewState extends State { onPopInvokedWithResult: (didPop, result) async { if (didPop) return; if (_avatarMakerController.getJsonOptionsSync() != - appSession.currentUser.avatarJson) { + userService.currentUser.avatarJson) { // there where changes final shouldPop = await _showBackDialog() ?? false; if (context.mounted && shouldPop) { diff --git a/lib/src/visual/views/settings/profile/profile.view.dart b/lib/src/visual/views/settings/profile/profile.view.dart index cbd2566a..0d989c95 100644 --- a/lib/src/visual/views/settings/profile/profile.view.dart +++ b/lib/src/visual/views/settings/profile/profile.view.dart @@ -107,7 +107,7 @@ class _ProfileViewState extends State { title: Text(context.lang.settingsProfile), ), body: StreamBuilder( - stream: appSession.onUserUpdated, + stream: userService.onUserUpdated, builder: (context, _) { return ListView( physics: const BouncingScrollPhysics(), @@ -154,11 +154,11 @@ class _ProfileViewState extends State { ), ), text: context.lang.registerUsernameDecoration, - subtitle: Text(appSession.currentUser.username), + subtitle: Text(userService.currentUser.username), onTap: () async { final username = await showDisplayNameChangeDialog( context, - appSession.currentUser.username, + userService.currentUser.username, context.lang.registerUsernameDecoration, context.lang.registerUsernameDecoration, maxLength: 12, @@ -177,11 +177,11 @@ class _ProfileViewState extends State { BetterListTile( icon: FontAwesomeIcons.userPen, text: context.lang.settingsProfileEditDisplayName, - subtitle: Text(appSession.currentUser.displayName), + subtitle: Text(userService.currentUser.displayName), onTap: () async { final displayName = await showDisplayNameChangeDialog( context, - appSession.currentUser.displayName, + userService.currentUser.displayName, context.lang.settingsProfileEditDisplayName, context.lang.settingsProfileEditDisplayNameNew, maxLength: 30, diff --git a/lib/src/visual/views/settings/settings_main.view.dart b/lib/src/visual/views/settings/settings_main.view.dart index 24d33698..8d49c5b4 100644 --- a/lib/src/visual/views/settings/settings_main.view.dart +++ b/lib/src/visual/views/settings/settings_main.view.dart @@ -48,14 +48,14 @@ class _SettingsMainViewState extends State { children: [ Text( substringBy( - appSession.currentUser.displayName, + userService.currentUser.displayName, 27, ), style: const TextStyle(fontSize: 20), textAlign: TextAlign.left, ), Text( - appSession.currentUser.username, + userService.currentUser.username, style: const TextStyle( fontSize: 14, ), @@ -131,7 +131,7 @@ class _SettingsMainViewState extends State { }); }, ), - if (appSession.currentUser.isDeveloper) + if (userService.currentUser.isDeveloper) BetterListTile( icon: FontAwesomeIcons.code, text: 'Developer Settings', diff --git a/lib/src/visual/views/settings/subscription/subscription.view.dart b/lib/src/visual/views/settings/subscription/subscription.view.dart index b2bc7862..6d608643 100644 --- a/lib/src/visual/views/settings/subscription/subscription.view.dart +++ b/lib/src/visual/views/settings/subscription/subscription.view.dart @@ -290,7 +290,7 @@ class _PlanCardState extends State { var url = 'https://apps.apple.com/account/subscriptions'; if (Platform.isAndroid) { url = - 'https://play.google.com/store/account/subscriptions?sku=${appSession.currentUser.subscriptionPlanIdStore}&package=eu.twonly'; + 'https://play.google.com/store/account/subscriptions?sku=${userService.currentUser.subscriptionPlanIdStore}&package=eu.twonly'; } await launchUrl( Uri.parse(url), diff --git a/lib/src/visual/views/shared/memory_item_slider.view.dart b/lib/src/visual/views/shared/memory_item_slider.view.dart index d72a08c6..a5aa2c54 100644 --- a/lib/src/visual/views/shared/memory_item_slider.view.dart +++ b/lib/src/visual/views/shared/memory_item_slider.view.dart @@ -98,7 +98,7 @@ class _MemoriesPhotoSliderViewState extends State { final newMediaService = await initializeMediaUpload( orgMediaService.mediaFile.type, - appSession.currentUser.defaultShowTime, + userService.currentUser.defaultShowTime, ); if (newMediaService == null) { Log.error('Could not create new mediaFIle'); diff --git a/test/features/flame_counter_test.dart b/test/features/flame_counter_test.dart index 8a502e17..52cf7058 100644 --- a/test/features/flame_counter_test.dart +++ b/test/features/flame_counter_test.dart @@ -52,7 +52,7 @@ void main() { ) ..registerSingleton(UserService()); - appSession.currentUser = UserData( + userService.currentUser = UserData( userId: 0x133337, username: 'test_user', displayName: 'Test User',