feat: Matrix login flow with auth guard and client provider
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:matrix/matrix.dart';
|
||||
import 'package:pyramid/core/matrix_client.dart';
|
||||
|
||||
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<LoginState> {
|
||||
final Ref _ref;
|
||||
|
||||
LoginNotifier(this._ref) : super(const LoginState());
|
||||
|
||||
Future<void> login({
|
||||
required String userId,
|
||||
required String password,
|
||||
String? deviceName,
|
||||
}) async {
|
||||
state = state.copyWith(status: LoginStatus.loading, errorMessage: null);
|
||||
|
||||
final clientAsync = _ref.read(matrixClientProvider);
|
||||
final client = clientAsync.valueOrNull;
|
||||
if (client == null) {
|
||||
state = state.copyWith(
|
||||
status: LoginStatus.error,
|
||||
errorMessage: 'Client nicht initialisiert',
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// Auto-discover homeserver from MXID
|
||||
if (userId.isValidMatrixId) {
|
||||
final domain = Uri.https(userId.domain!, '');
|
||||
try {
|
||||
await client.checkHomeserver(domain);
|
||||
} catch (_) {
|
||||
client.homeserver = domain;
|
||||
}
|
||||
}
|
||||
|
||||
await client.login(
|
||||
LoginType.mLoginPassword,
|
||||
identifier: AuthenticationUserIdentifier(user: userId),
|
||||
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<LoginNotifier, LoginState>((ref) {
|
||||
return LoginNotifier(ref);
|
||||
});
|
||||
|
||||
final isLoggedInProvider = Provider<bool>((ref) {
|
||||
final client = ref.watch(matrixClientProvider).valueOrNull;
|
||||
return client?.isLogged() ?? false;
|
||||
});
|
||||
Reference in New Issue
Block a user