104 lines
2.9 KiB
Dart
104 lines
2.9 KiB
Dart
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
import 'package:matrix/matrix.dart' as mx;
|
|
import 'package:pyramid/core/matrix_client.dart';
|
|
import 'package:shared_preferences/shared_preferences.dart';
|
|
|
|
const _prefHomeserver = 'homeserver_url';
|
|
|
|
final homeserverProvider = StateProvider<String?>((ref) => null);
|
|
|
|
Future<void> initHomeserver(WidgetRef ref) async {
|
|
final prefs = await SharedPreferences.getInstance();
|
|
final saved = prefs.getString(_prefHomeserver);
|
|
ref.read(homeserverProvider.notifier).state = saved;
|
|
}
|
|
|
|
Future<void> 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 LoginFormState {
|
|
final LoginStatus status;
|
|
final String? errorMessage;
|
|
|
|
const LoginFormState({this.status = LoginStatus.idle, this.errorMessage});
|
|
|
|
LoginFormState copyWith({LoginStatus? status, String? errorMessage}) =>
|
|
LoginFormState(
|
|
status: status ?? this.status,
|
|
errorMessage: errorMessage,
|
|
);
|
|
}
|
|
|
|
class LoginNotifier extends StateNotifier<LoginFormState> {
|
|
final Ref _ref;
|
|
LoginNotifier(this._ref) : super(const LoginFormState());
|
|
|
|
Future<void> 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(
|
|
mx.LoginType.mLoginPassword,
|
|
identifier: mx.AuthenticationUserIdentifier(user: username),
|
|
password: password,
|
|
initialDeviceDisplayName: deviceName ?? 'Pyramid',
|
|
);
|
|
|
|
state = state.copyWith(status: LoginStatus.idle);
|
|
} on mx.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, LoginFormState>((ref) {
|
|
return LoginNotifier(ref);
|
|
});
|
|
|
|
final isLoggedInProvider = StreamProvider<bool>((ref) async* {
|
|
final client = await ref.watch(matrixClientProvider.future);
|
|
yield client.isLogged();
|
|
await for (final loginState in client.onLoginStateChanged.stream) {
|
|
yield loginState == mx.LoginState.loggedIn;
|
|
}
|
|
});
|