import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:matrix/matrix.dart'; import 'package:pyramid/core/matrix_client.dart'; import 'package:shared_preferences/shared_preferences.dart'; const _prefHomeserver = 'homeserver_url'; final homeserverProvider = StateProvider((ref) => null); Future initHomeserver(WidgetRef ref) async { final prefs = await SharedPreferences.getInstance(); final saved = prefs.getString(_prefHomeserver); ref.read(homeserverProvider.notifier).state = saved; } Future saveHomeserver(WidgetRef ref, String url) async { final prefs = await SharedPreferences.getInstance(); await prefs.setString(_prefHomeserver, url); ref.read(homeserverProvider.notifier).state = url; } enum LoginStatus { idle, loading, error } class LoginState { final LoginStatus status; final String? errorMessage; const LoginState({this.status = LoginStatus.idle, this.errorMessage}); LoginState copyWith({LoginStatus? status, String? errorMessage}) => LoginState( status: status ?? this.status, errorMessage: errorMessage, ); } class LoginNotifier extends StateNotifier { final Ref _ref; LoginNotifier(this._ref) : super(const LoginState()); Future login({ required String username, required String password, required String homeserver, String? deviceName, }) async { state = state.copyWith(status: LoginStatus.loading, errorMessage: null); final client = _ref.read(matrixClientProvider).valueOrNull; if (client == null) { state = state.copyWith( status: LoginStatus.error, errorMessage: 'Client nicht initialisiert', ); return; } if (client.isLogged()) { state = state.copyWith(status: LoginStatus.idle); return; } try { final serverUri = Uri.https( homeserver.replaceAll(RegExp(r'^https?://'), ''), '', ); await client.checkHomeserver(serverUri); await client.login( LoginType.mLoginPassword, identifier: AuthenticationUserIdentifier(user: username), password: password, initialDeviceDisplayName: deviceName ?? 'Pyramid', ); state = state.copyWith(status: LoginStatus.idle); } on MatrixException catch (e) { state = state.copyWith( status: LoginStatus.error, errorMessage: e.errorMessage, ); } catch (e) { state = state.copyWith( status: LoginStatus.error, errorMessage: e.toString(), ); } } } final loginNotifierProvider = StateNotifierProvider((ref) { return LoginNotifier(ref); }); final isLoggedInProvider = Provider((ref) { final client = ref.watch(matrixClientProvider).valueOrNull; return client?.isLogged() ?? false; });