fix: StreamProvider for login state, rename LoginState to avoid matrix SDK conflict

This commit is contained in:
Bernd Steckmeister
2026-04-19 20:26:28 +02:00
parent 85cf7cdf13
commit c9af913468
3 changed files with 20 additions and 20 deletions
+1 -1
View File
@@ -9,7 +9,7 @@ import 'package:pyramid/features/settings/settings_page.dart';
import 'package:pyramid/layout/shell_page.dart'; import 'package:pyramid/layout/shell_page.dart';
final routerProvider = Provider<GoRouter>((ref) { final routerProvider = Provider<GoRouter>((ref) {
final isLoggedIn = ref.watch(isLoggedInProvider); final isLoggedIn = ref.watch(isLoggedInProvider).valueOrNull ?? false;
final hasServer = ref.watch(homeserverProvider) != null; final hasServer = ref.watch(homeserverProvider) != null;
return GoRouter( return GoRouter(
+17 -14
View File
@@ -1,5 +1,5 @@
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:matrix/matrix.dart'; import 'package:matrix/matrix.dart' as mx;
import 'package:pyramid/core/matrix_client.dart'; import 'package:pyramid/core/matrix_client.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
@@ -21,22 +21,22 @@ Future<void> saveHomeserver(WidgetRef ref, String url) async {
enum LoginStatus { idle, loading, error } enum LoginStatus { idle, loading, error }
class LoginState { class LoginFormState {
final LoginStatus status; final LoginStatus status;
final String? errorMessage; final String? errorMessage;
const LoginState({this.status = LoginStatus.idle, this.errorMessage}); const LoginFormState({this.status = LoginStatus.idle, this.errorMessage});
LoginState copyWith({LoginStatus? status, String? errorMessage}) => LoginFormState copyWith({LoginStatus? status, String? errorMessage}) =>
LoginState( LoginFormState(
status: status ?? this.status, status: status ?? this.status,
errorMessage: errorMessage, errorMessage: errorMessage,
); );
} }
class LoginNotifier extends StateNotifier<LoginState> { class LoginNotifier extends StateNotifier<LoginFormState> {
final Ref _ref; final Ref _ref;
LoginNotifier(this._ref) : super(const LoginState()); LoginNotifier(this._ref) : super(const LoginFormState());
Future<void> login({ Future<void> login({
required String username, required String username,
@@ -68,14 +68,14 @@ class LoginNotifier extends StateNotifier<LoginState> {
await client.checkHomeserver(serverUri); await client.checkHomeserver(serverUri);
await client.login( await client.login(
LoginType.mLoginPassword, mx.LoginType.mLoginPassword,
identifier: AuthenticationUserIdentifier(user: username), identifier: mx.AuthenticationUserIdentifier(user: username),
password: password, password: password,
initialDeviceDisplayName: deviceName ?? 'Pyramid', initialDeviceDisplayName: deviceName ?? 'Pyramid',
); );
state = state.copyWith(status: LoginStatus.idle); state = state.copyWith(status: LoginStatus.idle);
} on MatrixException catch (e) { } on mx.MatrixException catch (e) {
state = state.copyWith( state = state.copyWith(
status: LoginStatus.error, status: LoginStatus.error,
errorMessage: e.errorMessage, errorMessage: e.errorMessage,
@@ -90,11 +90,14 @@ class LoginNotifier extends StateNotifier<LoginState> {
} }
final loginNotifierProvider = final loginNotifierProvider =
StateNotifierProvider<LoginNotifier, LoginState>((ref) { StateNotifierProvider<LoginNotifier, LoginFormState>((ref) {
return LoginNotifier(ref); return LoginNotifier(ref);
}); });
final isLoggedInProvider = Provider<bool>((ref) { final isLoggedInProvider = StreamProvider<bool>((ref) async* {
final client = ref.watch(matrixClientProvider).valueOrNull; final client = await ref.watch(matrixClientProvider.future);
return client?.isLogged() ?? false; yield client.isLogged();
await for (final loginState in client.onLoginStateChanged.stream) {
yield loginState == mx.LoginState.loggedIn;
}
}); });
+2 -5
View File
@@ -33,11 +33,7 @@ class _LoginPageState extends ConsumerState<LoginPage> {
password: _passCtrl.text, password: _passCtrl.text,
homeserver: homeserver, homeserver: homeserver,
); );
// Redirect erfolgt reaktiv über isLoggedInProvider → Router
final state = ref.read(loginNotifierProvider);
if (state.status == LoginStatus.idle && mounted) {
context.go('/rooms');
}
} }
@override @override
@@ -45,6 +41,7 @@ class _LoginPageState extends ConsumerState<LoginPage> {
final theme = Theme.of(context); final theme = Theme.of(context);
final loginState = ref.watch(loginNotifierProvider); final loginState = ref.watch(loginNotifierProvider);
final loading = loginState.status == LoginStatus.loading; final loading = loginState.status == LoginStatus.loading;
final homeserver = ref.watch(homeserverProvider) ?? 'matrix.org'; final homeserver = ref.watch(homeserverProvider) ?? 'matrix.org';
return Scaffold( return Scaffold(