import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:matrix/matrix.dart'; /// The one Matrix client, created in main() before the app starts. final clientProvider = Provider( (ref) => throw UnimplementedError('overridden in main()'), ); /// Signed in or not. Starts from the restored session. final loginStateProvider = StreamProvider((ref) async* { final client = ref.watch(clientProvider); yield client.isLogged() ? LoginState.loggedIn : LoginState.loggedOut; yield* client.onLoginStateChanged.stream; }); /// Bumps on every sync. The SDK's objects change in place, so screens that /// show rooms watch this and read the client again; that is the whole /// trick that keeps them current. final syncProvider = StreamProvider((ref) async* { final client = ref.watch(clientProvider); var n = 0; yield n; await for (final _ in client.onSync.stream) { yield ++n; } }); /// Whether the connection to the homeserver is working, from the sync /// loop's status. Null until the first sync after start finishes. final syncErrorProvider = StreamProvider((ref) async* { final client = ref.watch(clientProvider); await for (final status in client.onSyncStatus.stream) { if (status.status == SyncStatus.error) yield true; if (status.status == SyncStatus.finished) yield false; } }); /// The theme the user picked: the system's, light or dark. class ThemeModeNotifier extends Notifier { static const _key = 'warp.theme'; static const _storage = FlutterSecureStorage(); @override ThemeMode build() { _storage.read(key: _key).then((value) { final mode = ThemeMode.values.where((m) => m.name == value).firstOrNull; if (mode != null) state = mode; }); return ThemeMode.system; } void set(ThemeMode mode) { state = mode; _storage.write(key: _key, value: mode.name); } } final themeModeProvider = NotifierProvider( ThemeModeNotifier.new, ); /// The space the room list shows, or null for all chats. class SelectedSpaceNotifier extends Notifier { @override String? build() => null; void select(String? spaceId) => state = spaceId; } final selectedSpaceProvider = NotifierProvider( SelectedSpaceNotifier.new, );