import 'dart:developer'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:softplayer_web/core/api/v1/public_accounts.dart'; import 'package:softplayer_web/core/tokens/application/tokens_application.dart'; import 'package:softplayer_web/features/authorization/application/sign_in_data.dart'; import 'package:softplayer_web/features/authorization/application/sign_up_data.dart'; class AuthState { final AuthMode mode; final bool isAuthorized; const AuthState({this.mode = AuthMode.login, this.isAuthorized = false}); AuthState copyWith({AuthMode? mode, String? status, bool? isAuthorized}) { return AuthState( mode: mode ?? this.mode, isAuthorized: isAuthorized ?? this.isAuthorized, ); } } enum AuthMode { login, signup } final authorizationControllerProvider = AsyncNotifierProvider( AuthorizationController.new, ); class AuthorizationController extends AsyncNotifier { @override Future build() async { // Use is considered authorized if tokens are set in the memory. // In case tokens are not valid, it will be discovered by the first // api call. final tokenState = await ref.watch(tokensControllerProvider.future); if (tokenState.getAccessToken().isEmpty && tokenState.getRefreshToken().isNotEmpty) { final tokenCtrl = ref.read(tokensControllerProvider.notifier); await tokenCtrl.checkTokens(); } final isAuthorized = tokenState.getAccessToken().isNotEmpty && tokenState.getRefreshToken().isNotEmpty; return AuthState(isAuthorized: isAuthorized); } AuthMode authMode = AuthMode.login; void toggleAuthMode() { state = AsyncData( state.value!.copyWith( mode: state.value!.mode == AuthMode.login ? AuthMode.signup : AuthMode.login, ), ); } Future signin(SignInData form) async { state = const AsyncLoading(); state = await AsyncValue.guard(() async { final accountsGrpc = ref.read(publicAccountsGrpcProvider); final tokenCtrl = ref.read(tokensControllerProvider.notifier); try { final response = await accountsGrpc.signIn(form.toProto()); await tokenCtrl.writeTokenPair(Tokens.fromProto(response.tokenPair)); return state.value!.copyWith(isAuthorized: true); } catch (e) { rethrow; } }); } Future signup(SignUpData form) async { state = const AsyncLoading(); state = await AsyncValue.guard(() async { final accountsGrpc = ref.read(publicAccountsGrpcProvider); final tokenCtrl = ref.read(tokensControllerProvider.notifier); final response = await accountsGrpc.signUp(form.toProto()); await tokenCtrl.writeTokenPair(Tokens.fromProto(response.tokenPair)); return state.value!.copyWith(isAuthorized: true); }); } Future logout() async { state = await AsyncValue.guard(() async { return state.value!.copyWith(isAuthorized: false); }); } }