mirror of
https://github.com/twonlyapp/twonly-app.git
synced 2026-05-25 05:22: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 (_isUserCreated) {
|
||||||
if (_isTwonlyLocked) {
|
if (_isTwonlyLocked) {
|
||||||
// do not change in case twonly was already unlocked at some point
|
// 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;
|
_showDatabaseMigration = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -178,7 +178,7 @@ class _AppMainWidgetState extends State<AppMainWidget> {
|
||||||
_isTwonlyLocked = false;
|
_isTwonlyLocked = false;
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
} else if (appSession.currentUser.twonlySafeBackup == null &&
|
} else if (userService.currentUser.twonlySafeBackup == null &&
|
||||||
!_skipBackup) {
|
!_skipBackup) {
|
||||||
child = SetupBackupView(
|
child = SetupBackupView(
|
||||||
callBack: () => setState(() {
|
callBack: () => setState(() {
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,6 @@ void setupLocator() {
|
||||||
..registerLazySingleton<TwonlyDB>(TwonlyDB.new);
|
..registerLazySingleton<TwonlyDB>(TwonlyDB.new);
|
||||||
}
|
}
|
||||||
|
|
||||||
UserService get appSession => locator<UserService>();
|
UserService get userService => locator<UserService>();
|
||||||
ApiService get apiService => locator<ApiService>();
|
ApiService get apiService => locator<ApiService>();
|
||||||
TwonlyDB get twonlyDB => locator<TwonlyDB>();
|
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/log.dart';
|
||||||
import 'package:twonly/src/utils/storage.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();
|
SentryWidgetsFlutterBinding.ensureInitialized();
|
||||||
|
|
||||||
await AppEnvironment.init();
|
await AppEnvironment.init();
|
||||||
|
|
@ -46,24 +48,25 @@ void main() async {
|
||||||
dataDirectory: AppEnvironment.supportDir,
|
dataDirectory: AppEnvironment.supportDir,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() async {
|
||||||
|
await twonlyMinimumInitialization();
|
||||||
|
|
||||||
await initFCMService();
|
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');
|
final db = File('${AppEnvironment.supportDir}/twonly.sqlite');
|
||||||
if (!db.existsSync()) {
|
if (!db.existsSync()) {
|
||||||
Log.error('[twonly] IOS: App was removed and then reinstalled again...');
|
Log.error('[twonly] IOS: App was removed and then reinstalled again...');
|
||||||
await const FlutterSecureStorage().deleteAll();
|
await const FlutterSecureStorage().deleteAll();
|
||||||
user = await getUser();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (user != null) {
|
if (userExists) {
|
||||||
appSession.currentUser = user;
|
if (userService.currentUser.allowErrorTrackingViaSentry) {
|
||||||
|
|
||||||
if (user.allowErrorTrackingViaSentry) {
|
|
||||||
AppState.allowErrorTrackingViaSentry = true;
|
AppState.allowErrorTrackingViaSentry = true;
|
||||||
await SentryFlutter.init(
|
await SentryFlutter.init(
|
||||||
(options) => options
|
(options) => options
|
||||||
|
|
@ -86,33 +89,20 @@ void main() async {
|
||||||
await settingsController.loadSettings();
|
await settingsController.loadSettings();
|
||||||
await SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
|
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();
|
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(
|
runApp(
|
||||||
MultiProvider(
|
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.userDiscoveryVersion.isNotNull() &
|
||||||
t.userDiscoveryExcluded.equals(false) &
|
t.userDiscoveryExcluded.equals(false) &
|
||||||
t.mediaSendCounter.isBiggerOrEqualValue(
|
t.mediaSendCounter.isBiggerOrEqualValue(
|
||||||
appSession.currentUser.minimumRequiredImagesExchanged,
|
userService.currentUser.minimumRequiredImagesExchanged,
|
||||||
),
|
),
|
||||||
))
|
))
|
||||||
.watch();
|
.watch();
|
||||||
|
|
|
||||||
|
|
@ -113,7 +113,10 @@ class GroupsDao extends DatabaseAccessor<TwonlyDB> with _$GroupsDaoMixin {
|
||||||
int contactId,
|
int contactId,
|
||||||
GroupsCompanion group,
|
GroupsCompanion group,
|
||||||
) async {
|
) async {
|
||||||
final groupIdDirectChat = getUUIDforDirectChat(contactId, appSession.currentUser.userId);
|
final groupIdDirectChat = getUUIDforDirectChat(
|
||||||
|
contactId,
|
||||||
|
userService.currentUser.userId,
|
||||||
|
);
|
||||||
final insertGroup = group.copyWith(
|
final insertGroup = group.copyWith(
|
||||||
groupId: Value(groupIdDirectChat),
|
groupId: Value(groupIdDirectChat),
|
||||||
isDirectChat: const Value(true),
|
isDirectChat: const Value(true),
|
||||||
|
|
@ -209,7 +212,10 @@ class GroupsDao extends DatabaseAccessor<TwonlyDB> with _$GroupsDaoMixin {
|
||||||
}
|
}
|
||||||
|
|
||||||
Stream<Group?> watchDirectChat(int contactId) {
|
Stream<Group?> watchDirectChat(int contactId) {
|
||||||
final groupId = getUUIDforDirectChat(contactId, appSession.currentUser.userId);
|
final groupId = getUUIDforDirectChat(
|
||||||
|
contactId,
|
||||||
|
userService.currentUser.userId,
|
||||||
|
);
|
||||||
return (select(
|
return (select(
|
||||||
groups,
|
groups,
|
||||||
)..where((t) => t.groupId.equals(groupId))).watchSingleOrNull();
|
)..where((t) => t.groupId.equals(groupId))).watchSingleOrNull();
|
||||||
|
|
|
||||||
|
|
@ -127,7 +127,7 @@ class ApiService {
|
||||||
|
|
||||||
unawaited(UserDiscoveryService.checkForNewAnnouncedUsers());
|
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
|
// In case the user participates in the user study, call the handler after authenticated, to be sure there is a internet connection
|
||||||
unawaited(handleUserStudyUpload());
|
unawaited(handleUserStudyUpload());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -162,7 +162,7 @@ Future<void> handleGroupUpdate(
|
||||||
case GroupActionType.demoteToMember:
|
case GroupActionType.demoteToMember:
|
||||||
int? affectedContactId = update.affectedContactId.toInt();
|
int? affectedContactId = update.affectedContactId.toInt();
|
||||||
|
|
||||||
if (affectedContactId == appSession.currentUser.userId) {
|
if (affectedContactId == userService.currentUser.userId) {
|
||||||
affectedContactId = null;
|
affectedContactId = null;
|
||||||
if (actionType == GroupActionType.removedMember) {
|
if (actionType == GroupActionType.removedMember) {
|
||||||
// Oh no, I just got removed from the group...
|
// Oh no, I just got removed from the group...
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ Future<void> handleUserDiscoveryRequest(
|
||||||
) async {
|
) async {
|
||||||
Log.info('Got a user discovery request');
|
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');
|
Log.warn('Got a user discovery request while it is disabled');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -42,10 +42,10 @@ Future<void> handleUserDiscoveryRequest(
|
||||||
if (contact == null) return;
|
if (contact == null) return;
|
||||||
|
|
||||||
if (contact.mediaSendCounter <
|
if (contact.mediaSendCounter <
|
||||||
appSession.currentUser.minimumRequiredImagesExchanged ||
|
userService.currentUser.minimumRequiredImagesExchanged ||
|
||||||
contact.userDiscoveryExcluded) {
|
contact.userDiscoveryExcluded) {
|
||||||
Log.warn(
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -73,7 +73,7 @@ Future<void> handleUserDiscoveryUpdate(
|
||||||
int fromUserId,
|
int fromUserId,
|
||||||
EncryptedContent_UserDiscoveryUpdate update,
|
EncryptedContent_UserDiscoveryUpdate update,
|
||||||
) async {
|
) async {
|
||||||
if (!appSession.currentUser.isUserDiscoveryEnabled) {
|
if (!userService.currentUser.isUserDiscoveryEnabled) {
|
||||||
Log.warn('Got a user discovery update while it is disabled');
|
Log.warn('Got a user discovery update while it is disabled');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -98,7 +98,7 @@ Future<bool> isAllowedToDownload(MediaType type) async {
|
||||||
final connectivityResult = await Connectivity().checkConnectivity();
|
final connectivityResult = await Connectivity().checkConnectivity();
|
||||||
|
|
||||||
final options =
|
final options =
|
||||||
appSession.currentUser.autoDownloadOptions ?? defaultAutoDownloadOptions;
|
userService.currentUser.autoDownloadOptions ?? defaultAutoDownloadOptions;
|
||||||
|
|
||||||
if (connectivityResult.contains(ConnectivityResult.mobile)) {
|
if (connectivityResult.contains(ConnectivityResult.mobile)) {
|
||||||
if (type == MediaType.video) {
|
if (type == MediaType.video) {
|
||||||
|
|
|
||||||
|
|
@ -359,7 +359,7 @@ Future<void> startBackgroundMediaUpload(MediaFileService mediaService) async {
|
||||||
|
|
||||||
// if the user has enabled auto storing and the file
|
// if the user has enabled auto storing and the file
|
||||||
// was send with unlimited counter not in twonly-Mode then store 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.mediaFile.requiresAuthentication &&
|
||||||
!mediaService.storedPath.existsSync() &&
|
!mediaService.storedPath.existsSync() &&
|
||||||
mediaService.mediaFile.displayLimitInMilliseconds == null) {
|
mediaService.mediaFile.displayLimitInMilliseconds == null) {
|
||||||
|
|
|
||||||
|
|
@ -346,12 +346,15 @@ Future<(Uint8List, Uint8List?)?> sendCipherText(
|
||||||
return null;
|
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);
|
final contact = await twonlyDB.contactsDao.getContactById(contactId);
|
||||||
if (contact != null &&
|
if (contact != null &&
|
||||||
contact.mediaSendCounter >= appSession.currentUser.minimumRequiredImagesExchanged &&
|
contact.mediaSendCounter >=
|
||||||
|
userService.currentUser.minimumRequiredImagesExchanged &&
|
||||||
!contact.userDiscoveryExcluded) {
|
!contact.userDiscoveryExcluded) {
|
||||||
final version = await UserDiscoveryService.getCurrentVersion();
|
final version = await UserDiscoveryService.getCurrentVersion();
|
||||||
if (version != null) {
|
if (version != null) {
|
||||||
|
|
@ -407,7 +410,7 @@ Future<(Uint8List, Uint8List?)?> sendCipherText(
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> sendTypingIndication(String groupId, bool isTyping) async {
|
Future<void> sendTypingIndication(String groupId, bool isTyping) async {
|
||||||
if (!appSession.currentUser.typingIndicators) return;
|
if (!userService.currentUser.typingIndicators) return;
|
||||||
await sendCipherTextToGroup(
|
await sendCipherTextToGroup(
|
||||||
groupId,
|
groupId,
|
||||||
pb.EncryptedContent(
|
pb.EncryptedContent(
|
||||||
|
|
@ -463,15 +466,17 @@ Future<void> notifyContactAboutOpeningMessage(
|
||||||
|
|
||||||
Future<void> sendContactMyProfileData(int contactId) async {
|
Future<void> sendContactMyProfileData(int contactId) async {
|
||||||
List<int>? avatarSvgCompressed;
|
List<int>? avatarSvgCompressed;
|
||||||
if (appSession.currentUser.avatarSvg != null) {
|
if (userService.currentUser.avatarSvg != null) {
|
||||||
avatarSvgCompressed = gzip.encode(utf8.encode(appSession.currentUser.avatarSvg!));
|
avatarSvgCompressed = gzip.encode(
|
||||||
|
utf8.encode(userService.currentUser.avatarSvg!),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
final encryptedContent = pb.EncryptedContent(
|
final encryptedContent = pb.EncryptedContent(
|
||||||
contactUpdate: pb.EncryptedContent_ContactUpdate(
|
contactUpdate: pb.EncryptedContent_ContactUpdate(
|
||||||
type: pb.EncryptedContent_ContactUpdate_Type.UPDATE,
|
type: pb.EncryptedContent_ContactUpdate_Type.UPDATE,
|
||||||
avatarSvgCompressed: avatarSvgCompressed,
|
avatarSvgCompressed: avatarSvgCompressed,
|
||||||
displayName: appSession.currentUser.displayName,
|
displayName: userService.currentUser.displayName,
|
||||||
username: appSession.currentUser.username,
|
username: userService.currentUser.username,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
await sendCipherText(contactId, encryptedContent);
|
await sendCipherText(contactId, encryptedContent);
|
||||||
|
|
|
||||||
|
|
@ -265,7 +265,7 @@ Future<(EncryptedContent?, PlaintextContent?)> handleEncryptedMessage(
|
||||||
await twonlyDB.receiptsDao.markMessagesForRetry(fromUserId);
|
await twonlyDB.receiptsDao.markMessagesForRetry(fromUserId);
|
||||||
|
|
||||||
final senderProfileCounter = await checkForProfileUpdate(fromUserId, content);
|
final senderProfileCounter = await checkForProfileUpdate(fromUserId, content);
|
||||||
if (appSession.currentUser.isUserDiscoveryEnabled &&
|
if (userService.currentUser.isUserDiscoveryEnabled &&
|
||||||
content.hasSenderUserDiscoveryVersion()) {
|
content.hasSenderUserDiscoveryVersion()) {
|
||||||
await checkForUserDiscoveryChanges(
|
await checkForUserDiscoveryChanges(
|
||||||
fromUserId,
|
fromUserId,
|
||||||
|
|
@ -354,7 +354,7 @@ Future<(EncryptedContent?, PlaintextContent?)> handleEncryptedMessage(
|
||||||
|
|
||||||
/// Verify that the user is (still) in that group...
|
/// Verify that the user is (still) in that group...
|
||||||
if (!await twonlyDB.groupsDao.isContactInGroup(fromUserId, content.groupId)) {
|
if (!await twonlyDB.groupsDao.isContactInGroup(fromUserId, content.groupId)) {
|
||||||
if (getUUIDforDirectChat(appSession.currentUser.userId, fromUserId) ==
|
if (getUUIDforDirectChat(userService.currentUser.userId, fromUserId) ==
|
||||||
content.groupId) {
|
content.groupId) {
|
||||||
final contact = await twonlyDB.contactsDao
|
final contact = await twonlyDB.contactsDao
|
||||||
.getContactByUserId(fromUserId)
|
.getContactByUserId(fromUserId)
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,11 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:mutex/mutex.dart';
|
import 'package:mutex/mutex.dart';
|
||||||
import 'package:sentry_flutter/sentry_flutter.dart';
|
|
||||||
import 'package:twonly/globals.dart';
|
import 'package:twonly/globals.dart';
|
||||||
import 'package:twonly/locator.dart';
|
import 'package:twonly/locator.dart';
|
||||||
|
import 'package:twonly/main.dart';
|
||||||
import 'package:twonly/src/constants/keyvalue.keys.dart';
|
import 'package:twonly/src/constants/keyvalue.keys.dart';
|
||||||
import 'package:twonly/src/services/api/mediafiles/upload.api.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/exclusive_access.dart';
|
||||||
import 'package:twonly/src/utils/keyvalue.dart';
|
import 'package:twonly/src/utils/keyvalue.dart';
|
||||||
import 'package:twonly/src/utils/log.dart';
|
import 'package:twonly/src/utils/log.dart';
|
||||||
|
|
@ -54,21 +53,15 @@ Future<bool> initBackgroundExecution() async {
|
||||||
if (_isInitialized) {
|
if (_isInitialized) {
|
||||||
// Reload the users, as on Android the background isolate can
|
// Reload the users, as on Android the background isolate can
|
||||||
// stay alive for multiple hours between task executions
|
// stay alive for multiple hours between task executions
|
||||||
final user = await getUser();
|
return userService.tryInit();
|
||||||
if (user == null) return false;
|
|
||||||
appSession.currentUser = user;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SentryWidgetsFlutterBinding.ensureInitialized();
|
await twonlyMinimumInitialization();
|
||||||
await AppEnvironment.init();
|
|
||||||
Log.init();
|
|
||||||
|
|
||||||
final user = await getUser();
|
if (!await userService.tryInit()) {
|
||||||
if (user == null) return false;
|
Log.info('Early return as user is not registered yet.');
|
||||||
|
return false;
|
||||||
setupLocator();
|
}
|
||||||
appSession.currentUser = user;
|
|
||||||
|
|
||||||
AppState.isInBackgroundTask = true;
|
AppState.isInBackgroundTask = true;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ import 'package:twonly/src/utils/misc.dart';
|
||||||
Future<void> enableTwonlySafe(String password) async {
|
Future<void> enableTwonlySafe(String password) async {
|
||||||
final (backupId, encryptionKey) = await getMasterKey(
|
final (backupId, encryptionKey) = await getMasterKey(
|
||||||
password,
|
password,
|
||||||
appSession.currentUser.username,
|
userService.currentUser.username,
|
||||||
);
|
);
|
||||||
|
|
||||||
await updateUser((user) {
|
await updateUser((user) {
|
||||||
|
|
@ -66,10 +66,10 @@ Future<(Uint8List, Uint8List)> getMasterKey(
|
||||||
}
|
}
|
||||||
|
|
||||||
String? getTwonlySafeBackupUrl() {
|
String? getTwonlySafeBackupUrl() {
|
||||||
if (appSession.currentUser.twonlySafeBackup == null) return null;
|
if (userService.currentUser.twonlySafeBackup == null) return null;
|
||||||
return getTwonlySafeBackupUrlFromServer(
|
return getTwonlySafeBackupUrlFromServer(
|
||||||
appSession.currentUser.twonlySafeBackup!.backupId,
|
userService.currentUser.twonlySafeBackup!.backupId,
|
||||||
appSession.currentUser.backupServer,
|
userService.currentUser.backupServer,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,18 +23,18 @@ import 'package:twonly/src/utils/log.dart';
|
||||||
import 'package:twonly/src/utils/misc.dart';
|
import 'package:twonly/src/utils/misc.dart';
|
||||||
|
|
||||||
Future<void> performTwonlySafeBackup({bool force = false}) async {
|
Future<void> performTwonlySafeBackup({bool force = false}) async {
|
||||||
if (appSession.currentUser.twonlySafeBackup == null) {
|
if (userService.currentUser.twonlySafeBackup == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (appSession.currentUser.twonlySafeBackup!.backupUploadState ==
|
if (userService.currentUser.twonlySafeBackup!.backupUploadState ==
|
||||||
LastBackupUploadState.pending) {
|
LastBackupUploadState.pending) {
|
||||||
Log.warn('Backup upload is already pending.');
|
Log.warn('Backup upload is already pending.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final lastUpdateTime =
|
final lastUpdateTime =
|
||||||
appSession.currentUser.twonlySafeBackup!.lastBackupDone;
|
userService.currentUser.twonlySafeBackup!.lastBackupDone;
|
||||||
if (!force && lastUpdateTime != null) {
|
if (!force && lastUpdateTime != null) {
|
||||||
if (lastUpdateTime.isAfter(clock.now().subtract(const Duration(days: 1)))) {
|
if (lastUpdateTime.isAfter(clock.now().subtract(const Duration(days: 1)))) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -122,8 +122,8 @@ Future<void> performTwonlySafeBackup({bool force = false}) async {
|
||||||
|
|
||||||
final backupHash = uint8ListToHex((await Sha256().hash(backupBytes)).bytes);
|
final backupHash = uint8ListToHex((await Sha256().hash(backupBytes)).bytes);
|
||||||
|
|
||||||
if (appSession.currentUser.twonlySafeBackup!.lastBackupDone == null ||
|
if (userService.currentUser.twonlySafeBackup!.lastBackupDone == null ||
|
||||||
appSession.currentUser.twonlySafeBackup!.lastBackupDone!.isAfter(
|
userService.currentUser.twonlySafeBackup!.lastBackupDone!.isAfter(
|
||||||
clock.now().subtract(const Duration(days: 90)),
|
clock.now().subtract(const Duration(days: 90)),
|
||||||
)) {
|
)) {
|
||||||
force = true;
|
force = true;
|
||||||
|
|
@ -152,7 +152,7 @@ Future<void> performTwonlySafeBackup({bool force = false}) async {
|
||||||
final secretBox = await chacha20.encrypt(
|
final secretBox = await chacha20.encrypt(
|
||||||
backupBytes,
|
backupBytes,
|
||||||
secretKey: SecretKey(
|
secretKey: SecretKey(
|
||||||
appSession.currentUser.twonlySafeBackup!.encryptionKey,
|
userService.currentUser.twonlySafeBackup!.encryptionKey,
|
||||||
),
|
),
|
||||||
nonce: nonce,
|
nonce: nonce,
|
||||||
);
|
);
|
||||||
|
|
@ -175,9 +175,9 @@ Future<void> performTwonlySafeBackup({bool force = false}) async {
|
||||||
'Create twonly Backup with a size of ${encryptedBackupBytes.length} bytes.',
|
'Create twonly Backup with a size of ${encryptedBackupBytes.length} bytes.',
|
||||||
);
|
);
|
||||||
|
|
||||||
if (appSession.currentUser.backupServer != null) {
|
if (userService.currentUser.backupServer != null) {
|
||||||
if (encryptedBackupBytes.length >
|
if (encryptedBackupBytes.length >
|
||||||
appSession.currentUser.backupServer!.maxBackupBytes) {
|
userService.currentUser.backupServer!.maxBackupBytes) {
|
||||||
Log.error('Backup is to big for the alternative backup server.');
|
Log.error('Backup is to big for the alternative backup server.');
|
||||||
await updateUser((user) {
|
await updateUser((user) {
|
||||||
user.twonlySafeBackup!.backupUploadState = LastBackupUploadState.failed;
|
user.twonlySafeBackup!.backupUploadState = LastBackupUploadState.failed;
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ Future<void> syncFlameCounters({String? forceForGroup}) async {
|
||||||
(x) => x.totalMediaCounter == maxMessageCounter,
|
(x) => x.totalMediaCounter == maxMessageCounter,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (appSession.currentUser.myBestFriendGroupId != bestFriend.groupId) {
|
if (userService.currentUser.myBestFriendGroupId != bestFriend.groupId) {
|
||||||
await updateUser((user) {
|
await updateUser((user) {
|
||||||
user.myBestFriendGroupId = bestFriend.groupId;
|
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 memberIds = members.map((x) => Int64(x.userId)).toList();
|
||||||
|
|
||||||
final groupState = EncryptedGroupState(
|
final groupState = EncryptedGroupState(
|
||||||
memberIds: [Int64(appSession.currentUser.userId)] + memberIds,
|
memberIds: [Int64(userService.currentUser.userId)] + memberIds,
|
||||||
adminIds: [Int64(appSession.currentUser.userId)],
|
adminIds: [Int64(userService.currentUser.userId)],
|
||||||
groupName: groupName,
|
groupName: groupName,
|
||||||
deleteMessagesAfterMilliseconds: Int64(
|
deleteMessagesAfterMilliseconds: Int64(
|
||||||
defaultDeleteMessagesAfterMilliseconds,
|
defaultDeleteMessagesAfterMilliseconds,
|
||||||
|
|
@ -284,9 +284,9 @@ Future<(int, EncryptedGroupState)?> fetchGroupState(Group group) async {
|
||||||
final myPubKey = keyPair.getPublicKey().serialize().toList();
|
final myPubKey = keyPair.getPublicKey().serialize().toList();
|
||||||
|
|
||||||
if (listEquals(appendedPubKey, myPubKey)) {
|
if (listEquals(appendedPubKey, myPubKey)) {
|
||||||
adminIds.remove(Int64(appSession.currentUser.userId));
|
adminIds.remove(Int64(userService.currentUser.userId));
|
||||||
memberIds.remove(
|
memberIds.remove(
|
||||||
Int64(appSession.currentUser.userId),
|
Int64(userService.currentUser.userId),
|
||||||
); // -> Will remove the user later...
|
); // -> Will remove the user later...
|
||||||
} else {
|
} else {
|
||||||
Log.info('A non admin left the group!!!');
|
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...
|
// OH no, I am no longer a member of this group...
|
||||||
// Return from the group...
|
// Return from the group...
|
||||||
await twonlyDB.groupsDao.updateGroup(
|
await twonlyDB.groupsDao.updateGroup(
|
||||||
|
|
@ -318,7 +318,7 @@ Future<(int, EncryptedGroupState)?> fetchGroupState(Group group) async {
|
||||||
|
|
||||||
final isGroupAdmin =
|
final isGroupAdmin =
|
||||||
adminIds.firstWhereOrNull(
|
adminIds.firstWhereOrNull(
|
||||||
(t) => t.toInt() == appSession.currentUser.userId,
|
(t) => t.toInt() == userService.currentUser.userId,
|
||||||
) !=
|
) !=
|
||||||
null;
|
null;
|
||||||
|
|
||||||
|
|
@ -372,7 +372,7 @@ Future<(int, EncryptedGroupState)?> fetchGroupState(Group group) async {
|
||||||
|
|
||||||
// First find and insert NEW members
|
// First find and insert NEW members
|
||||||
for (final memberId in memberIds) {
|
for (final memberId in memberIds) {
|
||||||
if (memberId == Int64(appSession.currentUser.userId)) {
|
if (memberId == Int64(userService.currentUser.userId)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (currentGroupMembers.any((t) => t.contactId == memberId.toInt())) {
|
if (currentGroupMembers.any((t) => t.contactId == memberId.toInt())) {
|
||||||
|
|
@ -842,7 +842,7 @@ Future<bool> removeMemberFromGroup(
|
||||||
groupId: Value(group.groupId),
|
groupId: Value(group.groupId),
|
||||||
type: const Value(GroupActionType.removedMember),
|
type: const Value(GroupActionType.removedMember),
|
||||||
affectedContactId: Value(
|
affectedContactId: Value(
|
||||||
removeContactId == appSession.currentUser.userId
|
removeContactId == userService.currentUser.userId
|
||||||
? null
|
? null
|
||||||
: removeContactId,
|
: removeContactId,
|
||||||
),
|
),
|
||||||
|
|
@ -951,7 +951,7 @@ Future<bool> leaveAsNonAdminFromGroup(Group group) async {
|
||||||
EncryptedContent(
|
EncryptedContent(
|
||||||
groupUpdate: EncryptedContent_GroupUpdate(
|
groupUpdate: EncryptedContent_GroupUpdate(
|
||||||
groupActionType: groupActionType.name,
|
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 (!context.mounted) return false;
|
||||||
|
|
||||||
if (username == appSession.currentUser.username) {
|
if (username == userService.currentUser.username) {
|
||||||
await context.push(Routes.settingsPublicProfile);
|
await context.push(Routes.settingsPublicProfile);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -116,7 +116,7 @@ Future<void> handleIntentMediaFile(
|
||||||
|
|
||||||
final newMediaService = await initializeMediaUpload(
|
final newMediaService = await initializeMediaUpload(
|
||||||
type,
|
type,
|
||||||
appSession.currentUser.defaultShowTime,
|
userService.currentUser.defaultShowTime,
|
||||||
);
|
);
|
||||||
if (newMediaService == null) {
|
if (newMediaService == null) {
|
||||||
Log.error('Could not create new media file for intent shared file');
|
Log.error('Could not create new media file for intent shared file');
|
||||||
|
|
|
||||||
|
|
@ -239,7 +239,7 @@ class MediaFileService {
|
||||||
}
|
}
|
||||||
if (tempPath.existsSync()) {
|
if (tempPath.existsSync()) {
|
||||||
await tempPath.copy(storedPath.path);
|
await tempPath.copy(storedPath.path);
|
||||||
if (appSession.currentUser.storeMediaFilesInGallery) {
|
if (userService.currentUser.storeMediaFilesInGallery) {
|
||||||
if (mediaFile.type == MediaType.video) {
|
if (mediaFile.type == MediaType.video) {
|
||||||
await saveVideoToGallery(storedPath.path);
|
await saveVideoToGallery(storedPath.path);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,7 @@ Future<void> checkForTokenUpdates() async {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> initFCMAfterAuthenticated({bool force = false}) async {
|
Future<void> initFCMAfterAuthenticated({bool force = false}) async {
|
||||||
if (appSession.currentUser.updateFCMToken || force) {
|
if (userService.currentUser.updateFCMToken || force) {
|
||||||
const storage = FlutterSecureStorage();
|
const storage = FlutterSecureStorage();
|
||||||
final storedToken = await storage.read(key: SecureStorageKeys.googleFcm);
|
final storedToken = await storage.read(key: SecureStorageKeys.googleFcm);
|
||||||
if (storedToken != null) {
|
if (storedToken != null) {
|
||||||
|
|
|
||||||
|
|
@ -21,10 +21,10 @@ Future<IdentityKeyPair?> getSignalIdentityKeyPair() async {
|
||||||
// This function runs after the clients authenticated with the server.
|
// This function runs after the clients authenticated with the server.
|
||||||
// It then checks if it should update a new session key
|
// It then checks if it should update a new session key
|
||||||
Future<void> signalHandleNewServerConnection() async {
|
Future<void> signalHandleNewServerConnection() async {
|
||||||
if (appSession.currentUser.signalLastSignedPreKeyUpdated != null) {
|
if (userService.currentUser.signalLastSignedPreKeyUpdated != null) {
|
||||||
final fortyEightHoursAgo = clock.now().subtract(const Duration(hours: 48));
|
final fortyEightHoursAgo = clock.now().subtract(const Duration(hours: 48));
|
||||||
final isYoungerThan48Hours =
|
final isYoungerThan48Hours =
|
||||||
(appSession.currentUser.signalLastSignedPreKeyUpdated!).isAfter(
|
(userService.currentUser.signalLastSignedPreKeyUpdated!).isAfter(
|
||||||
fortyEightHoursAgo,
|
fortyEightHoursAgo,
|
||||||
);
|
);
|
||||||
if (isYoungerThan48Hours) {
|
if (isYoungerThan48Hours) {
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,13 @@ class UserService {
|
||||||
final _userDataUpdateController = StreamController<void>.broadcast();
|
final _userDataUpdateController = StreamController<void>.broadcast();
|
||||||
Stream<void> get onUserUpdated => _userDataUpdateController.stream;
|
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() {
|
void triggerUserUpdate() {
|
||||||
_userDataUpdateController.add(null);
|
_userDataUpdateController.add(null);
|
||||||
}
|
}
|
||||||
|
|
@ -32,7 +39,7 @@ Future<bool> isUserCreated() async {
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
appSession.currentUser = user;
|
userService.currentUser = user;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -84,8 +91,8 @@ Future<void> updateUser(
|
||||||
key: SecureStorageKeys.userData,
|
key: SecureStorageKeys.userData,
|
||||||
value: jsonEncode(user),
|
value: jsonEncode(user),
|
||||||
);
|
);
|
||||||
appSession.currentUser = user;
|
userService.currentUser = user;
|
||||||
});
|
});
|
||||||
|
|
||||||
appSession.triggerUserUpdate();
|
userService.triggerUserUpdate();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@ class UserDiscoveryService {
|
||||||
try {
|
try {
|
||||||
await FlutterUserDiscovery.initializeOrUpdate(
|
await FlutterUserDiscovery.initializeOrUpdate(
|
||||||
threshold: threshold,
|
threshold: threshold,
|
||||||
userId: appSession.currentUser.userId,
|
userId: userService.currentUser.userId,
|
||||||
publicKey: await getUserPublicKey(),
|
publicKey: await getUserPublicKey(),
|
||||||
);
|
);
|
||||||
await updateUser(
|
await updateUser(
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ const surveyUrlBase = 'https://survey.twonly.org/upload.php';
|
||||||
|
|
||||||
Future<void> handleUserStudyUpload() async {
|
Future<void> handleUserStudyUpload() async {
|
||||||
try {
|
try {
|
||||||
final token = appSession.currentUser.userStudyParticipantsToken;
|
final token = userService.currentUser.userStudyParticipantsToken;
|
||||||
if (token == null) return;
|
if (token == null) return;
|
||||||
|
|
||||||
// in case the survey was taken offline try again
|
// in case the survey was taken offline try again
|
||||||
|
|
@ -35,8 +35,8 @@ Future<void> handleUserStudyUpload() async {
|
||||||
await KeyValueStore.delete(userStudySurveyKey);
|
await KeyValueStore.delete(userStudySurveyKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (appSession.currentUser.lastUserStudyDataUpload != null &&
|
if (userService.currentUser.lastUserStudyDataUpload != null &&
|
||||||
isToday(appSession.currentUser.lastUserStudyDataUpload!)) {
|
isToday(userService.currentUser.lastUserStudyDataUpload!)) {
|
||||||
// Only send updates once a day.
|
// Only send updates once a day.
|
||||||
// This enables to see if improvements to actually work.
|
// This enables to see if improvements to actually work.
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -53,13 +53,13 @@ File avatarPNGFile(int contactId) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Uint8List> getUserAvatar() async {
|
Future<Uint8List> getUserAvatar() async {
|
||||||
if (appSession.currentUser.avatarSvg == null) {
|
if (userService.currentUser.avatarSvg == null) {
|
||||||
final data = await rootBundle.load('assets/images/default_avatar.png');
|
final data = await rootBundle.load('assets/images/default_avatar.png');
|
||||||
return data.buffer.asUint8List();
|
return data.buffer.asUint8List();
|
||||||
}
|
}
|
||||||
|
|
||||||
final pictureInfo = await vg.loadPicture(
|
final pictureInfo = await vg.loadPicture(
|
||||||
SvgStringLoader(appSession.currentUser.avatarSvg!),
|
SvgStringLoader(userService.currentUser.avatarSvg!),
|
||||||
null,
|
null,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -68,7 +68,7 @@ Future<Uint8List> getUserAvatar() async {
|
||||||
final byteData = await image.toByteData(format: ui.ImageByteFormat.png);
|
final byteData = await image.toByteData(format: ui.ImageByteFormat.png);
|
||||||
final pngBytes = byteData!.buffer.asUint8List();
|
final pngBytes = byteData!.buffer.asUint8List();
|
||||||
|
|
||||||
final file = avatarPNGFile(appSession.currentUser.userId)
|
final file = avatarPNGFile(userService.currentUser.userId)
|
||||||
..writeAsBytesSync(pngBytes);
|
..writeAsBytesSync(pngBytes);
|
||||||
pictureInfo.picture.dispose();
|
pictureInfo.picture.dispose();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,8 @@ Future<Uint8List> getProfileQrCodeData() async {
|
||||||
final signedPreKey = (await signalStore.loadSignedPreKeys())[0];
|
final signedPreKey = (await signalStore.loadSignedPreKeys())[0];
|
||||||
|
|
||||||
final publicProfile = PublicProfile(
|
final publicProfile = PublicProfile(
|
||||||
userId: Int64(appSession.currentUser.userId),
|
userId: Int64(userService.currentUser.userId),
|
||||||
username: appSession.currentUser.username,
|
username: userService.currentUser.username,
|
||||||
publicIdentityKey: (await signalStore.getIdentityKeyPair())
|
publicIdentityKey: (await signalStore.getIdentityKeyPair())
|
||||||
.getPublicKey()
|
.getPublicKey()
|
||||||
.serialize(),
|
.serialize(),
|
||||||
|
|
|
||||||
|
|
@ -93,19 +93,19 @@ class _AvatarIconState extends State<AvatarIcon> {
|
||||||
setState(() {});
|
setState(() {});
|
||||||
});
|
});
|
||||||
} else if (widget.myAvatar) {
|
} else if (widget.myAvatar) {
|
||||||
_userSub = appSession.onUserUpdated.listen((_) {
|
_userSub = userService.onUserUpdated.listen((_) {
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
setState(() {
|
setState(() {
|
||||||
if (appSession.currentUser.avatarSvg != null) {
|
if (userService.currentUser.avatarSvg != null) {
|
||||||
_avatarSvg = appSession.currentUser.avatarSvg;
|
_avatarSvg = userService.currentUser.avatarSvg;
|
||||||
} else {
|
} else {
|
||||||
_avatarContacts = [];
|
_avatarContacts = [];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (appSession.currentUser.avatarSvg != null) {
|
if (userService.currentUser.avatarSvg != null) {
|
||||||
_avatarSvg = appSession.currentUser.avatarSvg;
|
_avatarSvg = userService.currentUser.avatarSvg;
|
||||||
}
|
}
|
||||||
} else if (widget.contactId != null) {
|
} else if (widget.contactId != null) {
|
||||||
contactStream = twonlyDB.contactsDao
|
contactStream = twonlyDB.contactsDao
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ class _FlameCounterWidgetState extends State<FlameCounterWidget> {
|
||||||
}
|
}
|
||||||
if (groupId != null && group != null) {
|
if (groupId != null && group != null) {
|
||||||
isBestFriend =
|
isBestFriend =
|
||||||
appSession.currentUser.myBestFriendGroupId == groupId &&
|
userService.currentUser.myBestFriendGroupId == groupId &&
|
||||||
group.alsoBestFriend;
|
group.alsoBestFriend;
|
||||||
final stream = twonlyDB.groupsDao.watchFlameCounter(groupId);
|
final stream = twonlyDB.groupsDao.watchFlameCounter(groupId);
|
||||||
flameCounterSub = stream.listen((counter) {
|
flameCounterSub = stream.listen((counter) {
|
||||||
|
|
|
||||||
|
|
@ -210,7 +210,7 @@ class _CameraPreviewViewState extends State<CameraPreviewView> {
|
||||||
_hasAudioPermission = await Permission.microphone.isGranted;
|
_hasAudioPermission = await Permission.microphone.isGranted;
|
||||||
|
|
||||||
if (!_hasAudioPermission &&
|
if (!_hasAudioPermission &&
|
||||||
!appSession.currentUser.requestedAudioPermission) {
|
!userService.currentUser.requestedAudioPermission) {
|
||||||
await updateUser((u) {
|
await updateUser((u) {
|
||||||
u.requestedAudioPermission = true;
|
u.requestedAudioPermission = true;
|
||||||
});
|
});
|
||||||
|
|
@ -322,7 +322,7 @@ class _CameraPreviewViewState extends State<CameraPreviewView> {
|
||||||
((videoFilePath != null) ? MediaType.video : MediaType.image);
|
((videoFilePath != null) ? MediaType.video : MediaType.image);
|
||||||
final mediaFileService = await initializeMediaUpload(
|
final mediaFileService = await initializeMediaUpload(
|
||||||
type,
|
type,
|
||||||
appSession.currentUser.defaultShowTime,
|
userService.currentUser.defaultShowTime,
|
||||||
isDraftMedia: true,
|
isDraftMedia: true,
|
||||||
);
|
);
|
||||||
if (!mounted) return true;
|
if (!mounted) return true;
|
||||||
|
|
|
||||||
|
|
@ -137,7 +137,7 @@ class MainCameraController {
|
||||||
await cameraController?.initialize();
|
await cameraController?.initialize();
|
||||||
await cameraController?.startImageStream(_processCameraImage);
|
await cameraController?.startImageStream(_processCameraImage);
|
||||||
await cameraController?.setZoomLevel(selectedCameraDetails.scaleFactor);
|
await cameraController?.setZoomLevel(selectedCameraDetails.scaleFactor);
|
||||||
if (appSession.currentUser.videoStabilizationEnabled && !kDebugMode) {
|
if (userService.currentUser.videoStabilizationEnabled && !kDebugMode) {
|
||||||
await cameraController?.setVideoStabilizationMode(
|
await cameraController?.setVideoStabilizationMode(
|
||||||
VideoStabilizationMode.level1,
|
VideoStabilizationMode.level1,
|
||||||
);
|
);
|
||||||
|
|
@ -397,7 +397,7 @@ class MainCameraController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (profile.username != appSession.currentUser.username) {
|
if (profile.username != userService.currentUser.username) {
|
||||||
if (scannedNewProfiles[profile.userId.toInt()] == null) {
|
if (scannedNewProfiles[profile.userId.toInt()] == null) {
|
||||||
await HapticFeedback.heavyImpact();
|
await HapticFeedback.heavyImpact();
|
||||||
scannedNewProfiles[profile.userId.toInt()] = ScannedNewProfile(
|
scannedNewProfiles[profile.userId.toInt()] = ScannedNewProfile(
|
||||||
|
|
|
||||||
|
|
@ -256,7 +256,7 @@ class _ShareImageView extends State<ShareImageView> {
|
||||||
children: [
|
children: [
|
||||||
if (widget.mediaFileService.mediaFile.type == MediaType.image &&
|
if (widget.mediaFileService.mediaFile.type == MediaType.image &&
|
||||||
_screenshotImage?.image != null &&
|
_screenshotImage?.image != null &&
|
||||||
appSession.currentUser.showShowImagePreviewWhenSending)
|
userService.currentUser.showShowImagePreviewWhenSending)
|
||||||
SizedBox(
|
SizedBox(
|
||||||
height: 100,
|
height: 100,
|
||||||
width: 100 * 9 / 16,
|
width: 100 * 9 / 16,
|
||||||
|
|
|
||||||
|
|
@ -93,7 +93,7 @@ class _SearchUsernameView extends State<AddNewUserView> {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _requestNewUserByUsername(String username) async {
|
Future<void> _requestNewUserByUsername(String username) async {
|
||||||
if (appSession.currentUser.username == username) return;
|
if (userService.currentUser.username == username) return;
|
||||||
|
|
||||||
setState(() {
|
setState(() {
|
||||||
_isLoading = true;
|
_isLoading = true;
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@ class _ChatListViewState extends State<ChatListView> {
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
initAsync();
|
initAsync();
|
||||||
_userSub = appSession.onUserUpdated.listen((_) {
|
_userSub = userService.onUserUpdated.listen((_) {
|
||||||
if (mounted) setState(() {});
|
if (mounted) setState(() {});
|
||||||
});
|
});
|
||||||
super.initState();
|
super.initState();
|
||||||
|
|
@ -90,8 +90,8 @@ class _ChatListViewState extends State<ChatListView> {
|
||||||
Sha256().hash,
|
Sha256().hash,
|
||||||
changeLog.codeUnits,
|
changeLog.codeUnits,
|
||||||
)).bytes;
|
)).bytes;
|
||||||
if (!appSession.currentUser.hideChangeLog &&
|
if (!userService.currentUser.hideChangeLog &&
|
||||||
appSession.currentUser.lastChangeLogHash.toString() !=
|
userService.currentUser.lastChangeLogHash.toString() !=
|
||||||
changeLogHash.toString()) {
|
changeLogHash.toString()) {
|
||||||
await updateUser((u) {
|
await updateUser((u) {
|
||||||
u.lastChangeLogHash = changeLogHash;
|
u.lastChangeLogHash = changeLogHash;
|
||||||
|
|
|
||||||
|
|
@ -122,7 +122,7 @@ class _ChatMessagesViewState extends State<ChatMessagesView> {
|
||||||
_receiverDeletedAccount = groupContacts.first.accountDeleted;
|
_receiverDeletedAccount = groupContacts.first.accountDeleted;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (appSession.currentUser.typingIndicators) {
|
if (userService.currentUser.typingIndicators) {
|
||||||
unawaited(sendTypingIndication(widget.groupId, false));
|
unawaited(sendTypingIndication(widget.groupId, false));
|
||||||
_nextTypingIndicator = Timer.periodic(const Duration(seconds: 4), (
|
_nextTypingIndicator = Timer.periodic(const Duration(seconds: 4), (
|
||||||
_,
|
_,
|
||||||
|
|
@ -290,7 +290,7 @@ class _ChatMessagesViewState extends State<ChatMessagesView> {
|
||||||
itemScrollController: itemScrollController,
|
itemScrollController: itemScrollController,
|
||||||
itemBuilder: (context, i) {
|
itemBuilder: (context, i) {
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
return appSession.currentUser.typingIndicators
|
return userService.currentUser.typingIndicators
|
||||||
? TypingIndicator(group: group)
|
? TypingIndicator(group: group)
|
||||||
: Container();
|
: Container();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -102,7 +102,7 @@ class _ContactRowState extends State<_ContactRow> {
|
||||||
bool _isLoading = false;
|
bool _isLoading = false;
|
||||||
|
|
||||||
Future<void> _onContactClick(bool isAdded) async {
|
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);
|
await context.push(Routes.settingsProfile);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -162,7 +162,7 @@ class _ContactRowState extends State<_ContactRow> {
|
||||||
final contactInDb = snapshot.data;
|
final contactInDb = snapshot.data;
|
||||||
final isAdded =
|
final isAdded =
|
||||||
contactInDb != null ||
|
contactInDb != null ||
|
||||||
widget.contact.userId.toInt() == appSession.currentUser.userId;
|
widget.contact.userId.toInt() == userService.currentUser.userId;
|
||||||
|
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onTap: _isLoading ? null : () => _onContactClick(isAdded),
|
onTap: _isLoading ? null : () => _onContactClick(isAdded),
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,7 @@ class _MessageInputState extends State<MessageInput> {
|
||||||
_textFieldController.text = widget.group.draftMessage!;
|
_textFieldController.text = widget.group.draftMessage!;
|
||||||
}
|
}
|
||||||
widget.textFieldFocus.addListener(_handleTextFocusChange);
|
widget.textFieldFocus.addListener(_handleTextFocusChange);
|
||||||
if (appSession.currentUser.typingIndicators) {
|
if (userService.currentUser.typingIndicators) {
|
||||||
_nextTypingIndicator = Timer.periodic(const Duration(seconds: 1), (
|
_nextTypingIndicator = Timer.periodic(const Duration(seconds: 1), (
|
||||||
_,
|
_,
|
||||||
) async {
|
) async {
|
||||||
|
|
|
||||||
|
|
@ -50,8 +50,8 @@ class _ReactionButtonsState extends State<ReactionButtons> {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> initAsync() async {
|
Future<void> initAsync() async {
|
||||||
if (appSession.currentUser.preSelectedEmojies != null) {
|
if (userService.currentUser.preSelectedEmojies != null) {
|
||||||
selectedEmojis = appSession.currentUser.preSelectedEmojies!;
|
selectedEmojis = userService.currentUser.preSelectedEmojies!;
|
||||||
}
|
}
|
||||||
setState(() {});
|
setState(() {});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ class _RestoreFlameCompState extends State<RestoreFlameComp> {
|
||||||
void initState() {
|
void initState() {
|
||||||
_groupId = getUUIDforDirectChat(
|
_groupId = getUUIDforDirectChat(
|
||||||
widget.contactId,
|
widget.contactId,
|
||||||
appSession.currentUser.userId,
|
userService.currentUser.userId,
|
||||||
);
|
);
|
||||||
final stream = twonlyDB.groupsDao.watchGroup(_groupId);
|
final stream = twonlyDB.groupsDao.watchGroup(_groupId);
|
||||||
_groupSub = stream.listen((update) {
|
_groupSub = stream.listen((update) {
|
||||||
|
|
@ -57,7 +57,9 @@ class _RestoreFlameCompState extends State<RestoreFlameComp> {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _restoreFlames() async {
|
Future<void> _restoreFlames() async {
|
||||||
final currentPlan = planFromString(appSession.currentUser.subscriptionPlan);
|
final currentPlan = planFromString(
|
||||||
|
userService.currentUser.subscriptionPlan,
|
||||||
|
);
|
||||||
if (!isUserAllowed(currentPlan, PremiumFeatures.RestoreFlames) &&
|
if (!isUserAllowed(currentPlan, PremiumFeatures.RestoreFlames) &&
|
||||||
kReleaseMode) {
|
kReleaseMode) {
|
||||||
await context.push(Routes.settingsSubscription);
|
await context.push(Routes.settingsSubscription);
|
||||||
|
|
|
||||||
|
|
@ -207,7 +207,7 @@ class _ContactViewState extends State<ContactView> {
|
||||||
SelectChatDeletionTimeListTitle(
|
SelectChatDeletionTimeListTitle(
|
||||||
groupId: getUUIDforDirectChat(
|
groupId: getUUIDforDirectChat(
|
||||||
widget.userId,
|
widget.userId,
|
||||||
appSession.currentUser.userId,
|
userService.currentUser.userId,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const Divider(),
|
const Divider(),
|
||||||
|
|
@ -226,17 +226,17 @@ class _ContactViewState extends State<ContactView> {
|
||||||
setState(() {});
|
setState(() {});
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
if (appSession.currentUser.isUserDiscoveryEnabled)
|
if (userService.currentUser.isUserDiscoveryEnabled)
|
||||||
BetterListTile(
|
BetterListTile(
|
||||||
icon: FontAwesomeIcons.usersViewfinder,
|
icon: FontAwesomeIcons.usersViewfinder,
|
||||||
text: context.lang.userDiscoverySettingsTitle,
|
text: context.lang.userDiscoverySettingsTitle,
|
||||||
subtitle:
|
subtitle:
|
||||||
!contact.userDiscoveryExcluded &&
|
!contact.userDiscoveryExcluded &&
|
||||||
contact.mediaSendCounter <
|
contact.mediaSendCounter <
|
||||||
appSession.currentUser.minimumRequiredImagesExchanged
|
userService.currentUser.minimumRequiredImagesExchanged
|
||||||
? Text(
|
? Text(
|
||||||
context.lang.contactUserDiscoveryImagesLeft(
|
context.lang.contactUserDiscoveryImagesLeft(
|
||||||
appSession.currentUser.minimumRequiredImagesExchanged -
|
userService.currentUser.minimumRequiredImagesExchanged -
|
||||||
contact.mediaSendCounter,
|
contact.mediaSendCounter,
|
||||||
getContactDisplayName(contact),
|
getContactDisplayName(contact),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -143,7 +143,7 @@ class _GroupViewState extends State<GroupView> {
|
||||||
success = await removeMemberFromGroup(
|
success = await removeMemberFromGroup(
|
||||||
_group!,
|
_group!,
|
||||||
keyPair.getPublicKey().serialize(),
|
keyPair.getPublicKey().serialize(),
|
||||||
appSession.currentUser.userId,
|
userService.currentUser.userId,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
success = await leaveAsNonAdminFromGroup(_group!);
|
success = await leaveAsNonAdminFromGroup(_group!);
|
||||||
|
|
|
||||||
|
|
@ -137,7 +137,7 @@ class HomeViewState extends State<HomeView> {
|
||||||
);
|
);
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
if (widget.initialPage == 1 &&
|
if (widget.initialPage == 1 &&
|
||||||
!appSession.currentUser.startWithCameraOpen ||
|
!userService.currentUser.startWithCameraOpen ||
|
||||||
widget.initialPage == 0) {
|
widget.initialPage == 0) {
|
||||||
globalUpdateOfHomeViewPageIndex(0);
|
globalUpdateOfHomeViewPageIndex(0);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -143,7 +143,7 @@ class _RegisterViewState extends State<RegisterView> {
|
||||||
value: jsonEncode(userData),
|
value: jsonEncode(userData),
|
||||||
);
|
);
|
||||||
|
|
||||||
appSession.currentUser = userData;
|
userService.currentUser = userData;
|
||||||
|
|
||||||
await apiService.authenticate();
|
await apiService.authenticate();
|
||||||
widget.callbackOnSuccess();
|
widget.callbackOnSuccess();
|
||||||
|
|
|
||||||
|
|
@ -107,7 +107,7 @@ class _PublicProfileViewState extends State<PublicProfileView> {
|
||||||
),
|
),
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
Text(
|
Text(
|
||||||
appSession.currentUser.username,
|
userService.currentUser.username,
|
||||||
style: const TextStyle(fontSize: 24),
|
style: const TextStyle(fontSize: 24),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
|
|
@ -127,12 +127,12 @@ class _PublicProfileViewState extends State<PublicProfileView> {
|
||||||
subtitle: (_publicKey == null)
|
subtitle: (_publicKey == null)
|
||||||
? null
|
? null
|
||||||
: Text(
|
: Text(
|
||||||
'https://me.twonly.eu/${appSession.currentUser.username}',
|
'https://me.twonly.eu/${userService.currentUser.username}',
|
||||||
),
|
),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
final params = ShareParams(
|
final params = ShareParams(
|
||||||
text:
|
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);
|
SharePlus.instance.share(params);
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -98,7 +98,7 @@ class _AppearanceViewState extends State<AppearanceView> {
|
||||||
title: Text(context.lang.settingsAppearance),
|
title: Text(context.lang.settingsAppearance),
|
||||||
),
|
),
|
||||||
body: StreamBuilder<void>(
|
body: StreamBuilder<void>(
|
||||||
stream: appSession.onUserUpdated,
|
stream: userService.onUserUpdated,
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
return ListView(
|
return ListView(
|
||||||
children: [
|
children: [
|
||||||
|
|
@ -116,7 +116,7 @@ class _AppearanceViewState extends State<AppearanceView> {
|
||||||
title: Text(context.lang.contactUsShortcut),
|
title: Text(context.lang.contactUsShortcut),
|
||||||
onTap: toggleShowFeedbackIcon,
|
onTap: toggleShowFeedbackIcon,
|
||||||
trailing: Switch(
|
trailing: Switch(
|
||||||
value: !appSession.currentUser.showFeedbackShortcut,
|
value: !userService.currentUser.showFeedbackShortcut,
|
||||||
onChanged: (a) => toggleShowFeedbackIcon(),
|
onChanged: (a) => toggleShowFeedbackIcon(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -124,7 +124,7 @@ class _AppearanceViewState extends State<AppearanceView> {
|
||||||
title: Text(context.lang.startWithCameraOpen),
|
title: Text(context.lang.startWithCameraOpen),
|
||||||
onTap: toggleStartWithCameraOpen,
|
onTap: toggleStartWithCameraOpen,
|
||||||
trailing: Switch(
|
trailing: Switch(
|
||||||
value: appSession.currentUser.startWithCameraOpen,
|
value: userService.currentUser.startWithCameraOpen,
|
||||||
onChanged: (a) => toggleStartWithCameraOpen(),
|
onChanged: (a) => toggleStartWithCameraOpen(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -132,7 +132,8 @@ class _AppearanceViewState extends State<AppearanceView> {
|
||||||
title: Text(context.lang.showImagePreviewWhenSending),
|
title: Text(context.lang.showImagePreviewWhenSending),
|
||||||
onTap: toggleShowImagePreviewWhenSending,
|
onTap: toggleShowImagePreviewWhenSending,
|
||||||
trailing: Switch(
|
trailing: Switch(
|
||||||
value: appSession.currentUser.showShowImagePreviewWhenSending,
|
value:
|
||||||
|
userService.currentUser.showShowImagePreviewWhenSending,
|
||||||
onChanged: (a) => toggleShowImagePreviewWhenSending(),
|
onChanged: (a) => toggleShowImagePreviewWhenSending(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -32,8 +32,8 @@ class _BackupServerViewState extends State<BackupServerView> {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> initAsync() async {
|
Future<void> initAsync() async {
|
||||||
if (appSession.currentUser.backupServer != null) {
|
if (userService.currentUser.backupServer != null) {
|
||||||
final uri = Uri.parse(appSession.currentUser.backupServer!.serverUrl);
|
final uri = Uri.parse(userService.currentUser.backupServer!.serverUrl);
|
||||||
// remove user auth data
|
// remove user auth data
|
||||||
final serverUrl = Uri(
|
final serverUrl = Uri(
|
||||||
scheme: uri.scheme,
|
scheme: uri.scheme,
|
||||||
|
|
|
||||||
|
|
@ -38,10 +38,10 @@ class _BackupViewState extends State<BackupView> {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return StreamBuilder<void>(
|
return StreamBuilder<void>(
|
||||||
stream: appSession.onUserUpdated,
|
stream: userService.onUserUpdated,
|
||||||
builder: (context, _) {
|
builder: (context, _) {
|
||||||
final backupServer =
|
final backupServer =
|
||||||
appSession.currentUser.backupServer ?? _defaultBackupServer;
|
userService.currentUser.backupServer ?? _defaultBackupServer;
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text(context.lang.settingsBackup),
|
title: Text(context.lang.settingsBackup),
|
||||||
|
|
@ -57,7 +57,7 @@ class _BackupViewState extends State<BackupView> {
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
),
|
),
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
if (appSession.currentUser.twonlySafeBackup != null)
|
if (userService.currentUser.twonlySafeBackup != null)
|
||||||
Column(
|
Column(
|
||||||
children: [
|
children: [
|
||||||
const SizedBox(height: 32),
|
const SizedBox(height: 32),
|
||||||
|
|
@ -87,7 +87,7 @@ class _BackupViewState extends State<BackupView> {
|
||||||
context.lang.backupLastBackupDate,
|
context.lang.backupLastBackupDate,
|
||||||
formatDateTime(
|
formatDateTime(
|
||||||
context,
|
context,
|
||||||
appSession
|
userService
|
||||||
.currentUser
|
.currentUser
|
||||||
.twonlySafeBackup!
|
.twonlySafeBackup!
|
||||||
.lastBackupDone,
|
.lastBackupDone,
|
||||||
|
|
@ -96,7 +96,7 @@ class _BackupViewState extends State<BackupView> {
|
||||||
(
|
(
|
||||||
context.lang.backupLastBackupSize,
|
context.lang.backupLastBackupSize,
|
||||||
formatBytes(
|
formatBytes(
|
||||||
appSession
|
userService
|
||||||
.currentUser
|
.currentUser
|
||||||
.twonlySafeBackup!
|
.twonlySafeBackup!
|
||||||
.lastBackupSize,
|
.lastBackupSize,
|
||||||
|
|
@ -105,7 +105,7 @@ class _BackupViewState extends State<BackupView> {
|
||||||
(
|
(
|
||||||
context.lang.backupLastBackupResult,
|
context.lang.backupLastBackupResult,
|
||||||
_backupStatus(
|
_backupStatus(
|
||||||
appSession
|
userService
|
||||||
.currentUser
|
.currentUser
|
||||||
.twonlySafeBackup!
|
.twonlySafeBackup!
|
||||||
.backupUploadState,
|
.backupUploadState,
|
||||||
|
|
@ -156,7 +156,7 @@ class _BackupViewState extends State<BackupView> {
|
||||||
onPressed: () =>
|
onPressed: () =>
|
||||||
context.push(Routes.settingsBackupSetup, extra: true),
|
context.push(Routes.settingsBackupSetup, extra: true),
|
||||||
child: Text(
|
child: Text(
|
||||||
appSession.currentUser.twonlySafeBackup == null
|
userService.currentUser.twonlySafeBackup == null
|
||||||
? context.lang.backupEnableBackup
|
? context.lang.backupEnableBackup
|
||||||
: context.lang.backupChangePassword,
|
: context.lang.backupChangePassword,
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -211,7 +211,7 @@ class _SetupBackupViewState extends State<SetupBackupView> {
|
||||||
)
|
)
|
||||||
: const Icon(Icons.lock_clock_rounded),
|
: const Icon(Icons.lock_clock_rounded),
|
||||||
label: Text(
|
label: Text(
|
||||||
appSession.currentUser.twonlySafeBackup == null
|
userService.currentUser.twonlySafeBackup == null
|
||||||
? context.lang.backupEnableBackup
|
? context.lang.backupEnableBackup
|
||||||
: context.lang.backupChangePassword,
|
: context.lang.backupChangePassword,
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ class _ChatReactionSelectionView extends State<ChatReactionSelectionView> {
|
||||||
List<String> _selectedEmojis = [];
|
List<String> _selectedEmojis = [];
|
||||||
|
|
||||||
List<String> _emojisFromSession() {
|
List<String> _emojisFromSession() {
|
||||||
final user = appSession.currentUser;
|
final user = userService.currentUser;
|
||||||
if (user.preSelectedEmojies != null) {
|
if (user.preSelectedEmojies != null) {
|
||||||
return user.preSelectedEmojies!;
|
return user.preSelectedEmojies!;
|
||||||
}
|
}
|
||||||
|
|
@ -53,7 +53,7 @@ class _ChatReactionSelectionView extends State<ChatReactionSelectionView> {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return StreamBuilder<void>(
|
return StreamBuilder<void>(
|
||||||
stream: appSession.onUserUpdated,
|
stream: userService.onUserUpdated,
|
||||||
builder: (context, _) {
|
builder: (context, _) {
|
||||||
_selectedEmojis = _emojisFromSession();
|
_selectedEmojis = _emojisFromSession();
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ class _DataAndStorageViewState extends State<DataAndStorageView> {
|
||||||
builder: (context) {
|
builder: (context) {
|
||||||
return AutoDownloadOptionsDialog(
|
return AutoDownloadOptionsDialog(
|
||||||
autoDownloadOptions:
|
autoDownloadOptions:
|
||||||
appSession.currentUser.autoDownloadOptions ??
|
userService.currentUser.autoDownloadOptions ??
|
||||||
defaultAutoDownloadOptions,
|
defaultAutoDownloadOptions,
|
||||||
connectionMode: connectionMode,
|
connectionMode: connectionMode,
|
||||||
onUpdate: () {},
|
onUpdate: () {},
|
||||||
|
|
@ -57,10 +57,10 @@ class _DataAndStorageViewState extends State<DataAndStorageView> {
|
||||||
title: Text(context.lang.settingsStorageData),
|
title: Text(context.lang.settingsStorageData),
|
||||||
),
|
),
|
||||||
body: StreamBuilder<void>(
|
body: StreamBuilder<void>(
|
||||||
stream: appSession.onUserUpdated,
|
stream: userService.onUserUpdated,
|
||||||
builder: (context, _) {
|
builder: (context, _) {
|
||||||
final autoDownloadOptions =
|
final autoDownloadOptions =
|
||||||
appSession.currentUser.autoDownloadOptions ??
|
userService.currentUser.autoDownloadOptions ??
|
||||||
defaultAutoDownloadOptions;
|
defaultAutoDownloadOptions;
|
||||||
return ListView(
|
return ListView(
|
||||||
children: [
|
children: [
|
||||||
|
|
@ -71,7 +71,7 @@ class _DataAndStorageViewState extends State<DataAndStorageView> {
|
||||||
),
|
),
|
||||||
onTap: toggleStoreInGallery,
|
onTap: toggleStoreInGallery,
|
||||||
trailing: Switch(
|
trailing: Switch(
|
||||||
value: appSession.currentUser.storeMediaFilesInGallery,
|
value: userService.currentUser.storeMediaFilesInGallery,
|
||||||
onChanged: (a) => toggleStoreInGallery(),
|
onChanged: (a) => toggleStoreInGallery(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -83,7 +83,7 @@ class _DataAndStorageViewState extends State<DataAndStorageView> {
|
||||||
),
|
),
|
||||||
onTap: toggleAutoStoreMediaFiles,
|
onTap: toggleAutoStoreMediaFiles,
|
||||||
trailing: Switch(
|
trailing: Switch(
|
||||||
value: appSession
|
value: userService
|
||||||
.currentUser
|
.currentUser
|
||||||
.autoStoreAllSendUnlimitedMediaFiles,
|
.autoStoreAllSendUnlimitedMediaFiles,
|
||||||
onChanged: (a) => toggleAutoStoreMediaFiles(),
|
onChanged: (a) => toggleAutoStoreMediaFiles(),
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ class _DeveloperSettingsViewState extends State<DeveloperSettingsView> {
|
||||||
title: const Text('Developer Settings'),
|
title: const Text('Developer Settings'),
|
||||||
),
|
),
|
||||||
body: StreamBuilder<void>(
|
body: StreamBuilder<void>(
|
||||||
stream: appSession.onUserUpdated,
|
stream: userService.onUserUpdated,
|
||||||
builder: (context, _) {
|
builder: (context, _) {
|
||||||
return ListView(
|
return ListView(
|
||||||
children: [
|
children: [
|
||||||
|
|
@ -52,7 +52,7 @@ class _DeveloperSettingsViewState extends State<DeveloperSettingsView> {
|
||||||
title: const Text('Show Developer Settings'),
|
title: const Text('Show Developer Settings'),
|
||||||
onTap: toggleDeveloperSettings,
|
onTap: toggleDeveloperSettings,
|
||||||
trailing: Switch(
|
trailing: Switch(
|
||||||
value: appSession.currentUser.isDeveloper,
|
value: userService.currentUser.isDeveloper,
|
||||||
onChanged: (_) => toggleDeveloperSettings(),
|
onChanged: (_) => toggleDeveloperSettings(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -66,7 +66,7 @@ class _DeveloperSettingsViewState extends State<DeveloperSettingsView> {
|
||||||
title: const Text('Toggle Video Stabilization'),
|
title: const Text('Toggle Video Stabilization'),
|
||||||
onTap: toggleVideoStabilization,
|
onTap: toggleVideoStabilization,
|
||||||
trailing: Switch(
|
trailing: Switch(
|
||||||
value: appSession.currentUser.videoStabilizationEnabled,
|
value: userService.currentUser.videoStabilizationEnabled,
|
||||||
onChanged: (a) => toggleVideoStabilization(),
|
onChanged: (a) => toggleVideoStabilization(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -93,7 +93,7 @@ class _ChangeLogViewState extends State<ChangeLogView> {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return StreamBuilder<void>(
|
return StreamBuilder<void>(
|
||||||
stream: appSession.onUserUpdated,
|
stream: userService.onUserUpdated,
|
||||||
builder: (context, _) {
|
builder: (context, _) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
|
|
@ -113,7 +113,7 @@ class _ChangeLogViewState extends State<ChangeLogView> {
|
||||||
children: [
|
children: [
|
||||||
Text(context.lang.openChangeLog),
|
Text(context.lang.openChangeLog),
|
||||||
Switch(
|
Switch(
|
||||||
value: !appSession.currentUser.hideChangeLog,
|
value: !userService.currentUser.hideChangeLog,
|
||||||
onChanged: (_) =>
|
onChanged: (_) =>
|
||||||
updateUser((u) => u.hideChangeLog = !u.hideChangeLog),
|
updateUser((u) => u.hideChangeLog = !u.hideChangeLog),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ class _HelpViewState extends State<HelpView> {
|
||||||
title: Text(context.lang.settingsHelp),
|
title: Text(context.lang.settingsHelp),
|
||||||
),
|
),
|
||||||
body: StreamBuilder<void>(
|
body: StreamBuilder<void>(
|
||||||
stream: appSession.onUserUpdated,
|
stream: userService.onUserUpdated,
|
||||||
builder: (context, _) {
|
builder: (context, _) {
|
||||||
return ListView(
|
return ListView(
|
||||||
children: [
|
children: [
|
||||||
|
|
@ -52,7 +52,7 @@ class _HelpViewState extends State<HelpView> {
|
||||||
),
|
),
|
||||||
onTap: toggleAllowErrorTrackingViaSentry,
|
onTap: toggleAllowErrorTrackingViaSentry,
|
||||||
trailing: Switch(
|
trailing: Switch(
|
||||||
value: appSession.currentUser.allowErrorTrackingViaSentry,
|
value: userService.currentUser.allowErrorTrackingViaSentry,
|
||||||
onChanged: (a) => toggleAllowErrorTrackingViaSentry(),
|
onChanged: (a) => toggleAllowErrorTrackingViaSentry(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -61,7 +61,7 @@ class _HelpViewState extends State<HelpView> {
|
||||||
onTap: () => context.push(Routes.settingsHelpDiagnostics),
|
onTap: () => context.push(Routes.settingsHelpDiagnostics),
|
||||||
),
|
),
|
||||||
const Divider(),
|
const Divider(),
|
||||||
if (appSession.currentUser.userStudyParticipantsToken == null ||
|
if (userService.currentUser.userStudyParticipantsToken == null ||
|
||||||
kDebugMode)
|
kDebugMode)
|
||||||
ListTile(
|
ListTile(
|
||||||
title: const Text('Teilnahme an Nutzerstudie'),
|
title: const Text('Teilnahme an Nutzerstudie'),
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ class _PrivacyViewState extends State<PrivacyView> {
|
||||||
|
|
||||||
Future<void> toggleAuthRequirementOnStartup() async {
|
Future<void> toggleAuthRequirementOnStartup() async {
|
||||||
final isAuth = await authenticateUser(
|
final isAuth = await authenticateUser(
|
||||||
appSession.currentUser.screenLockEnabled
|
userService.currentUser.screenLockEnabled
|
||||||
? context.lang.settingsScreenLockAuthMessageDisable
|
? context.lang.settingsScreenLockAuthMessageDisable
|
||||||
: context.lang.settingsScreenLockAuthMessageEnable,
|
: context.lang.settingsScreenLockAuthMessageEnable,
|
||||||
);
|
);
|
||||||
|
|
@ -84,7 +84,7 @@ class _PrivacyViewState extends State<PrivacyView> {
|
||||||
subtitle: Text(context.lang.settingsTypingIndicationSubtitle),
|
subtitle: Text(context.lang.settingsTypingIndicationSubtitle),
|
||||||
onTap: toggleTypingIndicators,
|
onTap: toggleTypingIndicators,
|
||||||
trailing: Switch(
|
trailing: Switch(
|
||||||
value: appSession.currentUser.typingIndicators,
|
value: userService.currentUser.typingIndicators,
|
||||||
onChanged: (a) => toggleTypingIndicators(),
|
onChanged: (a) => toggleTypingIndicators(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -94,7 +94,7 @@ class _PrivacyViewState extends State<PrivacyView> {
|
||||||
subtitle: Text(context.lang.settingsScreenLockSubtitle),
|
subtitle: Text(context.lang.settingsScreenLockSubtitle),
|
||||||
onTap: toggleAuthRequirementOnStartup,
|
onTap: toggleAuthRequirementOnStartup,
|
||||||
trailing: Switch(
|
trailing: Switch(
|
||||||
value: appSession.currentUser.screenLockEnabled,
|
value: userService.currentUser.screenLockEnabled,
|
||||||
onChanged: (a) => toggleAuthRequirementOnStartup(),
|
onChanged: (a) => toggleAuthRequirementOnStartup(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -19,9 +19,9 @@ class _UserDiscoverySettingsViewState extends State<UserDiscoverySettingsView> {
|
||||||
title: const Text('Freunde finden'),
|
title: const Text('Freunde finden'),
|
||||||
),
|
),
|
||||||
body: StreamBuilder<void>(
|
body: StreamBuilder<void>(
|
||||||
stream: appSession.onUserUpdated,
|
stream: userService.onUserUpdated,
|
||||||
builder: (context, _) {
|
builder: (context, _) {
|
||||||
return appSession.currentUser.isUserDiscoveryEnabled
|
return userService.currentUser.isUserDiscoveryEnabled
|
||||||
? const UserDiscoveryEnabledComp()
|
? const UserDiscoveryEnabledComp()
|
||||||
: const UserDiscoveryDisabledComp();
|
: const UserDiscoveryDisabledComp();
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -114,7 +114,7 @@ class _UserDiscoveryEnabledCompState extends State<UserDiscoveryEnabledComp> {
|
||||||
),
|
),
|
||||||
subtitle:
|
subtitle:
|
||||||
(version != null &&
|
(version != null &&
|
||||||
(appSession.currentUser.isDeveloper ||
|
(userService.currentUser.isDeveloper ||
|
||||||
!kReleaseMode))
|
!kReleaseMode))
|
||||||
? Text(
|
? Text(
|
||||||
context.lang.userDiscoveryEnabledVersion(
|
context.lang.userDiscoveryEnabledVersion(
|
||||||
|
|
@ -168,7 +168,7 @@ class _UserDiscoveryEnabledCompState extends State<UserDiscoveryEnabledComp> {
|
||||||
onTap: _disableUserDiscovery,
|
onTap: _disableUserDiscovery,
|
||||||
),
|
),
|
||||||
if (_version != null &&
|
if (_version != null &&
|
||||||
(appSession.currentUser.isDeveloper || !kReleaseMode))
|
(userService.currentUser.isDeveloper || !kReleaseMode))
|
||||||
ListTile(
|
ListTile(
|
||||||
title: Text(
|
title: Text(
|
||||||
context.lang.userDiscoveryEnabledYourVersion(
|
context.lang.userDiscoveryEnabledYourVersion(
|
||||||
|
|
|
||||||
|
|
@ -23,14 +23,14 @@ class _UserDiscoverySettingsViewState extends State<UserDiscoverySettingsView> {
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
_minimumRequiredImagesExchanged =
|
_minimumRequiredImagesExchanged =
|
||||||
appSession.currentUser.minimumRequiredImagesExchanged;
|
userService.currentUser.minimumRequiredImagesExchanged;
|
||||||
_userDiscoveryThreshold = appSession.currentUser.userDiscoveryThreshold;
|
_userDiscoveryThreshold = userService.currentUser.userDiscoveryThreshold;
|
||||||
super.initState();
|
super.initState();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _saveChanges() async {
|
Future<void> _saveChanges() async {
|
||||||
final requiresNewInitialization =
|
final requiresNewInitialization =
|
||||||
appSession.currentUser.userDiscoveryThreshold !=
|
userService.currentUser.userDiscoveryThreshold !=
|
||||||
_userDiscoveryThreshold;
|
_userDiscoveryThreshold;
|
||||||
|
|
||||||
await updateUser((u) {
|
await updateUser((u) {
|
||||||
|
|
@ -41,9 +41,9 @@ class _UserDiscoverySettingsViewState extends State<UserDiscoverySettingsView> {
|
||||||
|
|
||||||
if (requiresNewInitialization) {
|
if (requiresNewInitialization) {
|
||||||
await UserDiscoveryService.initializeOrUpdate(
|
await UserDiscoveryService.initializeOrUpdate(
|
||||||
threshold: appSession.currentUser.userDiscoveryThreshold,
|
threshold: userService.currentUser.userDiscoveryThreshold,
|
||||||
minimumRequiredImagesExchanged:
|
minimumRequiredImagesExchanged:
|
||||||
appSession.currentUser.minimumRequiredImagesExchanged,
|
userService.currentUser.minimumRequiredImagesExchanged,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (mounted) Navigator.pop(context);
|
if (mounted) Navigator.pop(context);
|
||||||
|
|
@ -115,9 +115,9 @@ class _UserDiscoverySettingsViewState extends State<UserDiscoverySettingsView> {
|
||||||
height: 30,
|
height: 30,
|
||||||
),
|
),
|
||||||
if (_minimumRequiredImagesExchanged !=
|
if (_minimumRequiredImagesExchanged !=
|
||||||
appSession.currentUser.minimumRequiredImagesExchanged ||
|
userService.currentUser.minimumRequiredImagesExchanged ||
|
||||||
_userDiscoveryThreshold !=
|
_userDiscoveryThreshold !=
|
||||||
appSession.currentUser.userDiscoveryThreshold)
|
userService.currentUser.userDiscoveryThreshold)
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.all(17),
|
padding: const EdgeInsets.all(17),
|
||||||
child: FilledButton(
|
child: FilledButton(
|
||||||
|
|
|
||||||
|
|
@ -122,7 +122,7 @@ class _ModifyAvatarViewState extends State<ModifyAvatarView> {
|
||||||
onPopInvokedWithResult: (didPop, result) async {
|
onPopInvokedWithResult: (didPop, result) async {
|
||||||
if (didPop) return;
|
if (didPop) return;
|
||||||
if (_avatarMakerController.getJsonOptionsSync() !=
|
if (_avatarMakerController.getJsonOptionsSync() !=
|
||||||
appSession.currentUser.avatarJson) {
|
userService.currentUser.avatarJson) {
|
||||||
// there where changes
|
// there where changes
|
||||||
final shouldPop = await _showBackDialog() ?? false;
|
final shouldPop = await _showBackDialog() ?? false;
|
||||||
if (context.mounted && shouldPop) {
|
if (context.mounted && shouldPop) {
|
||||||
|
|
|
||||||
|
|
@ -107,7 +107,7 @@ class _ProfileViewState extends State<ProfileView> {
|
||||||
title: Text(context.lang.settingsProfile),
|
title: Text(context.lang.settingsProfile),
|
||||||
),
|
),
|
||||||
body: StreamBuilder<void>(
|
body: StreamBuilder<void>(
|
||||||
stream: appSession.onUserUpdated,
|
stream: userService.onUserUpdated,
|
||||||
builder: (context, _) {
|
builder: (context, _) {
|
||||||
return ListView(
|
return ListView(
|
||||||
physics: const BouncingScrollPhysics(),
|
physics: const BouncingScrollPhysics(),
|
||||||
|
|
@ -154,11 +154,11 @@ class _ProfileViewState extends State<ProfileView> {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
text: context.lang.registerUsernameDecoration,
|
text: context.lang.registerUsernameDecoration,
|
||||||
subtitle: Text(appSession.currentUser.username),
|
subtitle: Text(userService.currentUser.username),
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
final username = await showDisplayNameChangeDialog(
|
final username = await showDisplayNameChangeDialog(
|
||||||
context,
|
context,
|
||||||
appSession.currentUser.username,
|
userService.currentUser.username,
|
||||||
context.lang.registerUsernameDecoration,
|
context.lang.registerUsernameDecoration,
|
||||||
context.lang.registerUsernameDecoration,
|
context.lang.registerUsernameDecoration,
|
||||||
maxLength: 12,
|
maxLength: 12,
|
||||||
|
|
@ -177,11 +177,11 @@ class _ProfileViewState extends State<ProfileView> {
|
||||||
BetterListTile(
|
BetterListTile(
|
||||||
icon: FontAwesomeIcons.userPen,
|
icon: FontAwesomeIcons.userPen,
|
||||||
text: context.lang.settingsProfileEditDisplayName,
|
text: context.lang.settingsProfileEditDisplayName,
|
||||||
subtitle: Text(appSession.currentUser.displayName),
|
subtitle: Text(userService.currentUser.displayName),
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
final displayName = await showDisplayNameChangeDialog(
|
final displayName = await showDisplayNameChangeDialog(
|
||||||
context,
|
context,
|
||||||
appSession.currentUser.displayName,
|
userService.currentUser.displayName,
|
||||||
context.lang.settingsProfileEditDisplayName,
|
context.lang.settingsProfileEditDisplayName,
|
||||||
context.lang.settingsProfileEditDisplayNameNew,
|
context.lang.settingsProfileEditDisplayNameNew,
|
||||||
maxLength: 30,
|
maxLength: 30,
|
||||||
|
|
|
||||||
|
|
@ -48,14 +48,14 @@ class _SettingsMainViewState extends State<SettingsMainView> {
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
substringBy(
|
substringBy(
|
||||||
appSession.currentUser.displayName,
|
userService.currentUser.displayName,
|
||||||
27,
|
27,
|
||||||
),
|
),
|
||||||
style: const TextStyle(fontSize: 20),
|
style: const TextStyle(fontSize: 20),
|
||||||
textAlign: TextAlign.left,
|
textAlign: TextAlign.left,
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
appSession.currentUser.username,
|
userService.currentUser.username,
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
),
|
),
|
||||||
|
|
@ -131,7 +131,7 @@ class _SettingsMainViewState extends State<SettingsMainView> {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
if (appSession.currentUser.isDeveloper)
|
if (userService.currentUser.isDeveloper)
|
||||||
BetterListTile(
|
BetterListTile(
|
||||||
icon: FontAwesomeIcons.code,
|
icon: FontAwesomeIcons.code,
|
||||||
text: 'Developer Settings',
|
text: 'Developer Settings',
|
||||||
|
|
|
||||||
|
|
@ -290,7 +290,7 @@ class _PlanCardState extends State<PlanCard> {
|
||||||
var url = 'https://apps.apple.com/account/subscriptions';
|
var url = 'https://apps.apple.com/account/subscriptions';
|
||||||
if (Platform.isAndroid) {
|
if (Platform.isAndroid) {
|
||||||
url =
|
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(
|
await launchUrl(
|
||||||
Uri.parse(url),
|
Uri.parse(url),
|
||||||
|
|
|
||||||
|
|
@ -98,7 +98,7 @@ class _MemoriesPhotoSliderViewState extends State<MemoriesPhotoSliderView> {
|
||||||
|
|
||||||
final newMediaService = await initializeMediaUpload(
|
final newMediaService = await initializeMediaUpload(
|
||||||
orgMediaService.mediaFile.type,
|
orgMediaService.mediaFile.type,
|
||||||
appSession.currentUser.defaultShowTime,
|
userService.currentUser.defaultShowTime,
|
||||||
);
|
);
|
||||||
if (newMediaService == null) {
|
if (newMediaService == null) {
|
||||||
Log.error('Could not create new mediaFIle');
|
Log.error('Could not create new mediaFIle');
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ void main() {
|
||||||
)
|
)
|
||||||
..registerSingleton<UserService>(UserService());
|
..registerSingleton<UserService>(UserService());
|
||||||
|
|
||||||
appSession.currentUser = UserData(
|
userService.currentUser = UserData(
|
||||||
userId: 0x133337,
|
userId: 0x133337,
|
||||||
username: 'test_user',
|
username: 'test_user',
|
||||||
displayName: 'Test User',
|
displayName: 'Test User',
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue