mirror of
https://github.com/twonlyapp/twonly-app.git
synced 2026-05-25 02:12:13 +00:00
create shared initialization function
This commit is contained in:
parent
1c902bb64d
commit
1ea97d58ea
62 changed files with 222 additions and 201 deletions
|
|
@ -133,9 +133,9 @@ class _AppMainWidgetState extends State<AppMainWidget> {
|
|||
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<AppMainWidget> {
|
|||
_isTwonlyLocked = false;
|
||||
}),
|
||||
);
|
||||
} else if (appSession.currentUser.twonlySafeBackup == null &&
|
||||
} else if (userService.currentUser.twonlySafeBackup == null &&
|
||||
!_skipBackup) {
|
||||
child = SetupBackupView(
|
||||
callBack: () => setState(() {
|
||||
|
|
|
|||
|
|
@ -12,6 +12,6 @@ void setupLocator() {
|
|||
..registerLazySingleton<TwonlyDB>(TwonlyDB.new);
|
||||
}
|
||||
|
||||
UserService get appSession => locator<UserService>();
|
||||
UserService get userService => locator<UserService>();
|
||||
ApiService get apiService => locator<ApiService>();
|
||||
TwonlyDB get twonlyDB => locator<TwonlyDB>();
|
||||
|
|
|
|||
|
|
@ -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<void> 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<void> 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;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -140,7 +140,7 @@ class ContactsDao extends DatabaseAccessor<TwonlyDB> with _$ContactsDaoMixin {
|
|||
t.userDiscoveryVersion.isNotNull() &
|
||||
t.userDiscoveryExcluded.equals(false) &
|
||||
t.mediaSendCounter.isBiggerOrEqualValue(
|
||||
appSession.currentUser.minimumRequiredImagesExchanged,
|
||||
userService.currentUser.minimumRequiredImagesExchanged,
|
||||
),
|
||||
))
|
||||
.watch();
|
||||
|
|
|
|||
|
|
@ -113,7 +113,10 @@ class GroupsDao extends DatabaseAccessor<TwonlyDB> 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<TwonlyDB> with _$GroupsDaoMixin {
|
|||
}
|
||||
|
||||
Stream<Group?> 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();
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -162,7 +162,7 @@ Future<void> 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...
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ Future<void> 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<void> 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<void> 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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ Future<bool> 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) {
|
||||
|
|
|
|||
|
|
@ -359,7 +359,7 @@ Future<void> 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) {
|
||||
|
|
|
|||
|
|
@ -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<void> 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<void> notifyContactAboutOpeningMessage(
|
|||
|
||||
Future<void> sendContactMyProfileData(int contactId) async {
|
||||
List<int>? 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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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<bool> 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;
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import 'package:twonly/src/utils/misc.dart';
|
|||
Future<void> 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,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,18 +23,18 @@ import 'package:twonly/src/utils/log.dart';
|
|||
import 'package:twonly/src/utils/misc.dart';
|
||||
|
||||
Future<void> 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<void> 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<void> 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<void> 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;
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ Future<void> 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;
|
||||
});
|
||||
|
|
|
|||
|
|
@ -43,8 +43,8 @@ Future<bool> createNewGroup(String groupName, List<Contact> 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<bool> 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<bool> leaveAsNonAdminFromGroup(Group group) async {
|
|||
EncryptedContent(
|
||||
groupUpdate: EncryptedContent_GroupUpdate(
|
||||
groupActionType: groupActionType.name,
|
||||
affectedContactId: Int64(appSession.currentUser.userId),
|
||||
affectedContactId: Int64(userService.currentUser.userId),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ Future<bool> 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<void> 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');
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ Future<void> checkForTokenUpdates() async {
|
|||
}
|
||||
|
||||
Future<void> 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) {
|
||||
|
|
|
|||
|
|
@ -21,10 +21,10 @@ Future<IdentityKeyPair?> getSignalIdentityKeyPair() async {
|
|||
// This function runs after the clients authenticated with the server.
|
||||
// It then checks if it should update a new session key
|
||||
Future<void> 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) {
|
||||
|
|
|
|||
|
|
@ -18,6 +18,13 @@ class UserService {
|
|||
final _userDataUpdateController = StreamController<void>.broadcast();
|
||||
Stream<void> get onUserUpdated => _userDataUpdateController.stream;
|
||||
|
||||
Future<bool> 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<bool> isUserCreated() async {
|
|||
if (user == null) {
|
||||
return false;
|
||||
}
|
||||
appSession.currentUser = user;
|
||||
userService.currentUser = user;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -84,8 +91,8 @@ Future<void> updateUser(
|
|||
key: SecureStorageKeys.userData,
|
||||
value: jsonEncode(user),
|
||||
);
|
||||
appSession.currentUser = user;
|
||||
userService.currentUser = user;
|
||||
});
|
||||
|
||||
appSession.triggerUserUpdate();
|
||||
userService.triggerUserUpdate();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ const surveyUrlBase = 'https://survey.twonly.org/upload.php';
|
|||
|
||||
Future<void> 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<void> 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;
|
||||
|
|
|
|||
|
|
@ -53,13 +53,13 @@ File avatarPNGFile(int contactId) {
|
|||
}
|
||||
|
||||
Future<Uint8List> 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<Uint8List> 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();
|
||||
|
||||
|
|
|
|||
|
|
@ -17,8 +17,8 @@ Future<Uint8List> 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(),
|
||||
|
|
|
|||
|
|
@ -93,19 +93,19 @@ class _AvatarIconState extends State<AvatarIcon> {
|
|||
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
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ class _FlameCounterWidgetState extends State<FlameCounterWidget> {
|
|||
}
|
||||
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) {
|
||||
|
|
|
|||
|
|
@ -210,7 +210,7 @@ class _CameraPreviewViewState extends State<CameraPreviewView> {
|
|||
_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<CameraPreviewView> {
|
|||
((videoFilePath != null) ? MediaType.video : MediaType.image);
|
||||
final mediaFileService = await initializeMediaUpload(
|
||||
type,
|
||||
appSession.currentUser.defaultShowTime,
|
||||
userService.currentUser.defaultShowTime,
|
||||
isDraftMedia: true,
|
||||
);
|
||||
if (!mounted) return true;
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -256,7 +256,7 @@ class _ShareImageView extends State<ShareImageView> {
|
|||
children: [
|
||||
if (widget.mediaFileService.mediaFile.type == MediaType.image &&
|
||||
_screenshotImage?.image != null &&
|
||||
appSession.currentUser.showShowImagePreviewWhenSending)
|
||||
userService.currentUser.showShowImagePreviewWhenSending)
|
||||
SizedBox(
|
||||
height: 100,
|
||||
width: 100 * 9 / 16,
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ class _SearchUsernameView extends State<AddNewUserView> {
|
|||
}
|
||||
|
||||
Future<void> _requestNewUserByUsername(String username) async {
|
||||
if (appSession.currentUser.username == username) return;
|
||||
if (userService.currentUser.username == username) return;
|
||||
|
||||
setState(() {
|
||||
_isLoading = true;
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ class _ChatListViewState extends State<ChatListView> {
|
|||
@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<ChatListView> {
|
|||
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;
|
||||
|
|
|
|||
|
|
@ -122,7 +122,7 @@ class _ChatMessagesViewState extends State<ChatMessagesView> {
|
|||
_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<ChatMessagesView> {
|
|||
itemScrollController: itemScrollController,
|
||||
itemBuilder: (context, i) {
|
||||
if (i == 0) {
|
||||
return appSession.currentUser.typingIndicators
|
||||
return userService.currentUser.typingIndicators
|
||||
? TypingIndicator(group: group)
|
||||
: Container();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ class _ContactRowState extends State<_ContactRow> {
|
|||
bool _isLoading = false;
|
||||
|
||||
Future<void> _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),
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ class _MessageInputState extends State<MessageInput> {
|
|||
_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 {
|
||||
|
|
|
|||
|
|
@ -50,8 +50,8 @@ class _ReactionButtonsState extends State<ReactionButtons> {
|
|||
}
|
||||
|
||||
Future<void> initAsync() async {
|
||||
if (appSession.currentUser.preSelectedEmojies != null) {
|
||||
selectedEmojis = appSession.currentUser.preSelectedEmojies!;
|
||||
if (userService.currentUser.preSelectedEmojies != null) {
|
||||
selectedEmojis = userService.currentUser.preSelectedEmojies!;
|
||||
}
|
||||
setState(() {});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ class _RestoreFlameCompState extends State<RestoreFlameComp> {
|
|||
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<RestoreFlameComp> {
|
|||
}
|
||||
|
||||
Future<void> _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);
|
||||
|
|
|
|||
|
|
@ -207,7 +207,7 @@ class _ContactViewState extends State<ContactView> {
|
|||
SelectChatDeletionTimeListTitle(
|
||||
groupId: getUUIDforDirectChat(
|
||||
widget.userId,
|
||||
appSession.currentUser.userId,
|
||||
userService.currentUser.userId,
|
||||
),
|
||||
),
|
||||
const Divider(),
|
||||
|
|
@ -226,17 +226,17 @@ class _ContactViewState extends State<ContactView> {
|
|||
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),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -143,7 +143,7 @@ class _GroupViewState extends State<GroupView> {
|
|||
success = await removeMemberFromGroup(
|
||||
_group!,
|
||||
keyPair.getPublicKey().serialize(),
|
||||
appSession.currentUser.userId,
|
||||
userService.currentUser.userId,
|
||||
);
|
||||
} else {
|
||||
success = await leaveAsNonAdminFromGroup(_group!);
|
||||
|
|
|
|||
|
|
@ -137,7 +137,7 @@ class HomeViewState extends State<HomeView> {
|
|||
);
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
if (widget.initialPage == 1 &&
|
||||
!appSession.currentUser.startWithCameraOpen ||
|
||||
!userService.currentUser.startWithCameraOpen ||
|
||||
widget.initialPage == 0) {
|
||||
globalUpdateOfHomeViewPageIndex(0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -143,7 +143,7 @@ class _RegisterViewState extends State<RegisterView> {
|
|||
value: jsonEncode(userData),
|
||||
);
|
||||
|
||||
appSession.currentUser = userData;
|
||||
userService.currentUser = userData;
|
||||
|
||||
await apiService.authenticate();
|
||||
widget.callbackOnSuccess();
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ class _PublicProfileViewState extends State<PublicProfileView> {
|
|||
),
|
||||
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<PublicProfileView> {
|
|||
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);
|
||||
},
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ class _AppearanceViewState extends State<AppearanceView> {
|
|||
title: Text(context.lang.settingsAppearance),
|
||||
),
|
||||
body: StreamBuilder<void>(
|
||||
stream: appSession.onUserUpdated,
|
||||
stream: userService.onUserUpdated,
|
||||
builder: (context, snapshot) {
|
||||
return ListView(
|
||||
children: [
|
||||
|
|
@ -116,7 +116,7 @@ class _AppearanceViewState extends State<AppearanceView> {
|
|||
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<AppearanceView> {
|
|||
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<AppearanceView> {
|
|||
title: Text(context.lang.showImagePreviewWhenSending),
|
||||
onTap: toggleShowImagePreviewWhenSending,
|
||||
trailing: Switch(
|
||||
value: appSession.currentUser.showShowImagePreviewWhenSending,
|
||||
value:
|
||||
userService.currentUser.showShowImagePreviewWhenSending,
|
||||
onChanged: (a) => toggleShowImagePreviewWhenSending(),
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -32,8 +32,8 @@ class _BackupServerViewState extends State<BackupServerView> {
|
|||
}
|
||||
|
||||
Future<void> 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,
|
||||
|
|
|
|||
|
|
@ -38,10 +38,10 @@ class _BackupViewState extends State<BackupView> {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return StreamBuilder<void>(
|
||||
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<BackupView> {
|
|||
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<BackupView> {
|
|||
context.lang.backupLastBackupDate,
|
||||
formatDateTime(
|
||||
context,
|
||||
appSession
|
||||
userService
|
||||
.currentUser
|
||||
.twonlySafeBackup!
|
||||
.lastBackupDone,
|
||||
|
|
@ -96,7 +96,7 @@ class _BackupViewState extends State<BackupView> {
|
|||
(
|
||||
context.lang.backupLastBackupSize,
|
||||
formatBytes(
|
||||
appSession
|
||||
userService
|
||||
.currentUser
|
||||
.twonlySafeBackup!
|
||||
.lastBackupSize,
|
||||
|
|
@ -105,7 +105,7 @@ class _BackupViewState extends State<BackupView> {
|
|||
(
|
||||
context.lang.backupLastBackupResult,
|
||||
_backupStatus(
|
||||
appSession
|
||||
userService
|
||||
.currentUser
|
||||
.twonlySafeBackup!
|
||||
.backupUploadState,
|
||||
|
|
@ -156,7 +156,7 @@ class _BackupViewState extends State<BackupView> {
|
|||
onPressed: () =>
|
||||
context.push(Routes.settingsBackupSetup, extra: true),
|
||||
child: Text(
|
||||
appSession.currentUser.twonlySafeBackup == null
|
||||
userService.currentUser.twonlySafeBackup == null
|
||||
? context.lang.backupEnableBackup
|
||||
: context.lang.backupChangePassword,
|
||||
),
|
||||
|
|
|
|||
|
|
@ -211,7 +211,7 @@ class _SetupBackupViewState extends State<SetupBackupView> {
|
|||
)
|
||||
: const Icon(Icons.lock_clock_rounded),
|
||||
label: Text(
|
||||
appSession.currentUser.twonlySafeBackup == null
|
||||
userService.currentUser.twonlySafeBackup == null
|
||||
? context.lang.backupEnableBackup
|
||||
: context.lang.backupChangePassword,
|
||||
),
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ class _ChatReactionSelectionView extends State<ChatReactionSelectionView> {
|
|||
List<String> _selectedEmojis = [];
|
||||
|
||||
List<String> _emojisFromSession() {
|
||||
final user = appSession.currentUser;
|
||||
final user = userService.currentUser;
|
||||
if (user.preSelectedEmojies != null) {
|
||||
return user.preSelectedEmojies!;
|
||||
}
|
||||
|
|
@ -53,7 +53,7 @@ class _ChatReactionSelectionView extends State<ChatReactionSelectionView> {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return StreamBuilder<void>(
|
||||
stream: appSession.onUserUpdated,
|
||||
stream: userService.onUserUpdated,
|
||||
builder: (context, _) {
|
||||
_selectedEmojis = _emojisFromSession();
|
||||
return Scaffold(
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ class _DataAndStorageViewState extends State<DataAndStorageView> {
|
|||
builder: (context) {
|
||||
return AutoDownloadOptionsDialog(
|
||||
autoDownloadOptions:
|
||||
appSession.currentUser.autoDownloadOptions ??
|
||||
userService.currentUser.autoDownloadOptions ??
|
||||
defaultAutoDownloadOptions,
|
||||
connectionMode: connectionMode,
|
||||
onUpdate: () {},
|
||||
|
|
@ -57,10 +57,10 @@ class _DataAndStorageViewState extends State<DataAndStorageView> {
|
|||
title: Text(context.lang.settingsStorageData),
|
||||
),
|
||||
body: StreamBuilder<void>(
|
||||
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<DataAndStorageView> {
|
|||
),
|
||||
onTap: toggleStoreInGallery,
|
||||
trailing: Switch(
|
||||
value: appSession.currentUser.storeMediaFilesInGallery,
|
||||
value: userService.currentUser.storeMediaFilesInGallery,
|
||||
onChanged: (a) => toggleStoreInGallery(),
|
||||
),
|
||||
),
|
||||
|
|
@ -83,7 +83,7 @@ class _DataAndStorageViewState extends State<DataAndStorageView> {
|
|||
),
|
||||
onTap: toggleAutoStoreMediaFiles,
|
||||
trailing: Switch(
|
||||
value: appSession
|
||||
value: userService
|
||||
.currentUser
|
||||
.autoStoreAllSendUnlimitedMediaFiles,
|
||||
onChanged: (a) => toggleAutoStoreMediaFiles(),
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ class _DeveloperSettingsViewState extends State<DeveloperSettingsView> {
|
|||
title: const Text('Developer Settings'),
|
||||
),
|
||||
body: StreamBuilder<void>(
|
||||
stream: appSession.onUserUpdated,
|
||||
stream: userService.onUserUpdated,
|
||||
builder: (context, _) {
|
||||
return ListView(
|
||||
children: [
|
||||
|
|
@ -52,7 +52,7 @@ class _DeveloperSettingsViewState extends State<DeveloperSettingsView> {
|
|||
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<DeveloperSettingsView> {
|
|||
title: const Text('Toggle Video Stabilization'),
|
||||
onTap: toggleVideoStabilization,
|
||||
trailing: Switch(
|
||||
value: appSession.currentUser.videoStabilizationEnabled,
|
||||
value: userService.currentUser.videoStabilizationEnabled,
|
||||
onChanged: (a) => toggleVideoStabilization(),
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ class _ChangeLogViewState extends State<ChangeLogView> {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return StreamBuilder<void>(
|
||||
stream: appSession.onUserUpdated,
|
||||
stream: userService.onUserUpdated,
|
||||
builder: (context, _) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
|
|
@ -113,7 +113,7 @@ class _ChangeLogViewState extends State<ChangeLogView> {
|
|||
children: [
|
||||
Text(context.lang.openChangeLog),
|
||||
Switch(
|
||||
value: !appSession.currentUser.hideChangeLog,
|
||||
value: !userService.currentUser.hideChangeLog,
|
||||
onChanged: (_) =>
|
||||
updateUser((u) => u.hideChangeLog = !u.hideChangeLog),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ class _HelpViewState extends State<HelpView> {
|
|||
title: Text(context.lang.settingsHelp),
|
||||
),
|
||||
body: StreamBuilder<void>(
|
||||
stream: appSession.onUserUpdated,
|
||||
stream: userService.onUserUpdated,
|
||||
builder: (context, _) {
|
||||
return ListView(
|
||||
children: [
|
||||
|
|
@ -52,7 +52,7 @@ class _HelpViewState extends State<HelpView> {
|
|||
),
|
||||
onTap: toggleAllowErrorTrackingViaSentry,
|
||||
trailing: Switch(
|
||||
value: appSession.currentUser.allowErrorTrackingViaSentry,
|
||||
value: userService.currentUser.allowErrorTrackingViaSentry,
|
||||
onChanged: (a) => toggleAllowErrorTrackingViaSentry(),
|
||||
),
|
||||
),
|
||||
|
|
@ -61,7 +61,7 @@ class _HelpViewState extends State<HelpView> {
|
|||
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'),
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ class _PrivacyViewState extends State<PrivacyView> {
|
|||
|
||||
Future<void> 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<PrivacyView> {
|
|||
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<PrivacyView> {
|
|||
subtitle: Text(context.lang.settingsScreenLockSubtitle),
|
||||
onTap: toggleAuthRequirementOnStartup,
|
||||
trailing: Switch(
|
||||
value: appSession.currentUser.screenLockEnabled,
|
||||
value: userService.currentUser.screenLockEnabled,
|
||||
onChanged: (a) => toggleAuthRequirementOnStartup(),
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -19,9 +19,9 @@ class _UserDiscoverySettingsViewState extends State<UserDiscoverySettingsView> {
|
|||
title: const Text('Freunde finden'),
|
||||
),
|
||||
body: StreamBuilder<void>(
|
||||
stream: appSession.onUserUpdated,
|
||||
stream: userService.onUserUpdated,
|
||||
builder: (context, _) {
|
||||
return appSession.currentUser.isUserDiscoveryEnabled
|
||||
return userService.currentUser.isUserDiscoveryEnabled
|
||||
? const UserDiscoveryEnabledComp()
|
||||
: const UserDiscoveryDisabledComp();
|
||||
},
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ class _UserDiscoveryEnabledCompState extends State<UserDiscoveryEnabledComp> {
|
|||
),
|
||||
subtitle:
|
||||
(version != null &&
|
||||
(appSession.currentUser.isDeveloper ||
|
||||
(userService.currentUser.isDeveloper ||
|
||||
!kReleaseMode))
|
||||
? Text(
|
||||
context.lang.userDiscoveryEnabledVersion(
|
||||
|
|
@ -168,7 +168,7 @@ class _UserDiscoveryEnabledCompState extends State<UserDiscoveryEnabledComp> {
|
|||
onTap: _disableUserDiscovery,
|
||||
),
|
||||
if (_version != null &&
|
||||
(appSession.currentUser.isDeveloper || !kReleaseMode))
|
||||
(userService.currentUser.isDeveloper || !kReleaseMode))
|
||||
ListTile(
|
||||
title: Text(
|
||||
context.lang.userDiscoveryEnabledYourVersion(
|
||||
|
|
|
|||
|
|
@ -23,14 +23,14 @@ class _UserDiscoverySettingsViewState extends State<UserDiscoverySettingsView> {
|
|||
@override
|
||||
void initState() {
|
||||
_minimumRequiredImagesExchanged =
|
||||
appSession.currentUser.minimumRequiredImagesExchanged;
|
||||
_userDiscoveryThreshold = appSession.currentUser.userDiscoveryThreshold;
|
||||
userService.currentUser.minimumRequiredImagesExchanged;
|
||||
_userDiscoveryThreshold = userService.currentUser.userDiscoveryThreshold;
|
||||
super.initState();
|
||||
}
|
||||
|
||||
Future<void> _saveChanges() async {
|
||||
final requiresNewInitialization =
|
||||
appSession.currentUser.userDiscoveryThreshold !=
|
||||
userService.currentUser.userDiscoveryThreshold !=
|
||||
_userDiscoveryThreshold;
|
||||
|
||||
await updateUser((u) {
|
||||
|
|
@ -41,9 +41,9 @@ class _UserDiscoverySettingsViewState extends State<UserDiscoverySettingsView> {
|
|||
|
||||
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<UserDiscoverySettingsView> {
|
|||
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(
|
||||
|
|
|
|||
|
|
@ -122,7 +122,7 @@ class _ModifyAvatarViewState extends State<ModifyAvatarView> {
|
|||
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) {
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ class _ProfileViewState extends State<ProfileView> {
|
|||
title: Text(context.lang.settingsProfile),
|
||||
),
|
||||
body: StreamBuilder<void>(
|
||||
stream: appSession.onUserUpdated,
|
||||
stream: userService.onUserUpdated,
|
||||
builder: (context, _) {
|
||||
return ListView(
|
||||
physics: const BouncingScrollPhysics(),
|
||||
|
|
@ -154,11 +154,11 @@ class _ProfileViewState extends State<ProfileView> {
|
|||
),
|
||||
),
|
||||
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<ProfileView> {
|
|||
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,
|
||||
|
|
|
|||
|
|
@ -48,14 +48,14 @@ class _SettingsMainViewState extends State<SettingsMainView> {
|
|||
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<SettingsMainView> {
|
|||
});
|
||||
},
|
||||
),
|
||||
if (appSession.currentUser.isDeveloper)
|
||||
if (userService.currentUser.isDeveloper)
|
||||
BetterListTile(
|
||||
icon: FontAwesomeIcons.code,
|
||||
text: 'Developer Settings',
|
||||
|
|
|
|||
|
|
@ -290,7 +290,7 @@ class _PlanCardState extends State<PlanCard> {
|
|||
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),
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ class _MemoriesPhotoSliderViewState extends State<MemoriesPhotoSliderView> {
|
|||
|
||||
final newMediaService = await initializeMediaUpload(
|
||||
orgMediaService.mediaFile.type,
|
||||
appSession.currentUser.defaultShowTime,
|
||||
userService.currentUser.defaultShowTime,
|
||||
);
|
||||
if (newMediaService == null) {
|
||||
Log.error('Could not create new mediaFIle');
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ void main() {
|
|||
)
|
||||
..registerSingleton<UserService>(UserService());
|
||||
|
||||
appSession.currentUser = UserData(
|
||||
userService.currentUser = UserData(
|
||||
userId: 0x133337,
|
||||
username: 'test_user',
|
||||
displayName: 'Test User',
|
||||
|
|
|
|||
Loading…
Reference in a new issue