feat: add multiaccount loading

This commit is contained in:
Sorunome 2021-09-18 12:12:47 +02:00
parent 9705bf0c01
commit 74735bbd5d
No known key found for this signature in database
GPG Key ID: B19471D07FC9BE9C
3 changed files with 85 additions and 49 deletions

View File

@ -7,10 +7,10 @@ import 'package:flutter/material.dart';
class LoadingView extends StatelessWidget {
@override
Widget build(BuildContext context) {
if (Matrix.of(context).loginState != null) {
if (Matrix.of(context).client.loginState != null) {
WidgetsBinding.instance.addPostFrameCallback(
(_) => VRouter.of(context).to(
Matrix.of(context).loginState == LoginState.loggedIn
Matrix.of(context).client.loginState == LoginState.loggedIn
? '/rooms'
: '/home',
queryParameters: VRouter.of(context).queryParameters,

View File

@ -10,7 +10,7 @@ class WaitForInitPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
if (Matrix.of(context).loginState == null) {
if (Matrix.of(context).client.loginState == null) {
return StreamBuilder<LoginState>(
stream: Matrix.of(context).client.onLoginStateChanged.stream,
builder: (context, snapshot) {

View File

@ -92,12 +92,15 @@ class MatrixState extends State<Matrix> with WidgetsBindingObserver {
.then((_) {
widget.clients.add(client);
ClientManager.addClientNameToStore(client.clientName);
// TODO: Connect streamsubscriptions
_registerSubs(client.clientName);
});
}
return client;
}
Client getClientByName(String name) => widget.clients
.firstWhere((c) => c.clientName == name, orElse: () => null);
Map<String, dynamic> get shareContent => _shareContent;
set shareContent(Map<String, dynamic> content) {
_shareContent = content;
@ -133,15 +136,15 @@ class MatrixState extends State<Matrix> with WidgetsBindingObserver {
}
}
StreamSubscription onRoomKeyRequestSub;
StreamSubscription onKeyVerificationRequestSub;
StreamSubscription onJitsiCallSub;
StreamSubscription onNotification;
StreamSubscription<LoginState> onLoginStateChanged;
StreamSubscription<UiaRequest> onUiaRequest;
final onRoomKeyRequestSub = <String, StreamSubscription>{};
final onKeyVerificationRequestSub = <String, StreamSubscription>{};
final onJitsiCallSub = <String, StreamSubscription>{};
final onNotification = <String, StreamSubscription>{};
final onLoginStateChanged = <String, StreamSubscription<LoginState>>{};
final onUiaRequest = <String, StreamSubscription<UiaRequest>>{};
StreamSubscription<html.Event> onFocusSub;
StreamSubscription<html.Event> onBlurSub;
StreamSubscription<Presence> onOwnPresence;
final onOwnPresence = <String, StreamSubscription<Presence>>{};
String _cachedPassword;
String get cachedPassword {
@ -325,21 +328,14 @@ class MatrixState extends State<Matrix> with WidgetsBindingObserver {
}
}
LoginState loginState;
void initMatrix() {
// Display the app lock
if (PlatformInfos.isMobile) {
WidgetsBinding.instance.addPostFrameCallback((_) {
FlutterSecureStorage().read(key: SettingKeys.appLockKey).then((lock) {
if (lock?.isNotEmpty ?? false) {
AppLock.of(widget.context).enable();
AppLock.of(widget.context).showLockScreen();
}
});
});
void _registerSubs(String name) {
final c = getClientByName(name);
if (c == null) {
Logs().w(
'Attempted to register subscriptions for non-existing client $name');
return;
}
onKeyVerificationRequestSub ??= client.onKeyVerificationRequest.stream
onKeyVerificationRequestSub[name] ??= c.onKeyVerificationRequest.stream
.listen((KeyVerification request) async {
var hidPopup = false;
request.onUpdate = () {
@ -370,51 +366,90 @@ class MatrixState extends State<Matrix> with WidgetsBindingObserver {
await request.rejectVerification();
}
});
_initWithStore();
if (kIsWeb) {
onFocusSub = html.window.onFocus.listen((_) => webHasFocus = true);
onBlurSub = html.window.onBlur.listen((_) => webHasFocus = false);
}
onLoginStateChanged ??= client.onLoginStateChanged.stream.listen((state) {
if (loginState != state) {
loginState = state;
onLoginStateChanged[name] ??= c.onLoginStateChanged.stream.listen((state) {
final loggedInWithMultipleClients = widget.clients.length > 1;
if (loggedInWithMultipleClients) {
// TODO: display a nicer toast
showOkAlertDialog(
useRootNavigator: false,
context: navigatorContext,
title: 'Login state of client $name changed',
message: 'New login state: $state',
okLabel: L10n.of(widget.context).ok,
);
} else {
final isInLoginRoutes = {'/home', '/login', '/signup'}
.contains(widget.router.currentState.url);
if (widget.router.currentState.url == '/' ||
(state == LoginState.loggedIn) == isInLoginRoutes) {
widget.router.currentState.to(
loginState == LoginState.loggedIn ? '/rooms' : '/home',
state == LoginState.loggedIn ? '/rooms' : '/home',
queryParameters: widget.router.currentState.queryParameters,
);
}
}
});
// Cache and resend status message
onOwnPresence ??= client.onPresence.stream.listen((presence) {
if (client.isLogged() &&
client.userID == presence.senderId &&
onOwnPresence[name] ??= c.onPresence.stream.listen((presence) {
if (c.isLogged() &&
c.userID == presence.senderId &&
presence.presence?.statusMsg != null) {
Logs().v('Update status message: "${presence.presence.statusMsg}"');
store.setItem(
SettingKeys.ownStatusMessage, presence.presence.statusMsg);
}
});
onUiaRequest ??= client.onUiaRequest.stream.listen(_onUiaRequest);
onUiaRequest[name] ??= c.onUiaRequest.stream.listen(_onUiaRequest);
if (PlatformInfos.isWeb || PlatformInfos.isLinux) {
client.onSync.stream.first.then((s) {
c.onSync.stream.first.then((s) {
html.Notification.requestPermission();
onNotification ??= client.onEvent.stream
onNotification[name] ??= c.onEvent.stream
.where((e) =>
e.type == EventUpdateType.timeline &&
[EventTypes.Message, EventTypes.Sticker, EventTypes.Encrypted]
.contains(e.content['type']) &&
e.content['sender'] != client.userID)
e.content['sender'] != c.userID)
.listen(_showLocalNotification);
});
}
}
void _cancelSubs(String name) {
onRoomKeyRequestSub[name]?.cancel();
onRoomKeyRequestSub.remove(name);
onKeyVerificationRequestSub[name]?.cancel();
onKeyVerificationRequestSub.remove(name);
onLoginStateChanged[name]?.cancel();
onLoginStateChanged.remove(name);
onOwnPresence[name]?.cancel();
onOwnPresence.remove(name);
onNotification[name]?.cancel();
onNotification.remove(name);
}
void initMatrix() {
// Display the app lock
if (PlatformInfos.isMobile) {
WidgetsBinding.instance.addPostFrameCallback((_) {
FlutterSecureStorage().read(key: SettingKeys.appLockKey).then((lock) {
if (lock?.isNotEmpty ?? false) {
AppLock.of(widget.context).enable();
AppLock.of(widget.context).showLockScreen();
}
});
});
}
_initWithStore();
for (final c in widget.clients) {
_registerSubs(c.clientName);
}
if (kIsWeb) {
onFocusSub = html.window.onFocus.listen((_) => webHasFocus = true);
onBlurSub = html.window.onBlur.listen((_) => webHasFocus = false);
}
if (PlatformInfos.isMobile) {
_backgroundPush = BackgroundPush(
@ -481,11 +516,12 @@ class MatrixState extends State<Matrix> with WidgetsBindingObserver {
void dispose() {
WidgetsBinding.instance.removeObserver(this);
onRoomKeyRequestSub?.cancel();
onKeyVerificationRequestSub?.cancel();
onLoginStateChanged?.cancel();
onOwnPresence?.cancel();
onNotification?.cancel();
onRoomKeyRequestSub.values.map((s) => s.cancel());
onKeyVerificationRequestSub.values.map((s) => s.cancel());
onLoginStateChanged.values.map((s) => s.cancel());
onOwnPresence.values.map((s) => s.cancel());
onNotification.values.map((s) => s.cancel());
onFocusSub?.cancel();
onBlurSub?.cancel();
_backgroundPush?.onLogin?.cancel();