A small cleanup
All checks were successful
ci/woodpecker/push/build Pipeline was successful

Signed-off-by: Nikolai Rodionov <allanger@posteo.de>
This commit is contained in:
Nikolai Rodionov
2026-05-29 15:45:35 +02:00
parent 84d65786bf
commit 9b8d50d3f9
2 changed files with 97 additions and 92 deletions

View File

@@ -7,20 +7,14 @@ import 'package:softplayer_web/features/authorization/application/sign_in_data.d
import 'package:softplayer_web/features/authorization/application/sign_up_data.dart'; import 'package:softplayer_web/features/authorization/application/sign_up_data.dart';
class AuthState { class AuthState {
final AuthMode mode;
final bool isAuthorized; final bool isAuthorized;
const AuthState({this.mode = AuthMode.login, this.isAuthorized = false}); const AuthState({this.isAuthorized = false});
AuthState copyWith({AuthMode? mode, String? status, bool? isAuthorized}) { AuthState copyWith({bool? isAuthorized}) {
return AuthState( return AuthState(isAuthorized: isAuthorized ?? this.isAuthorized);
mode: mode ?? this.mode,
isAuthorized: isAuthorized ?? this.isAuthorized,
);
} }
} }
enum AuthMode { login, signup }
final authorizationControllerProvider = final authorizationControllerProvider =
AsyncNotifierProvider<AuthorizationController, AuthState>( AsyncNotifierProvider<AuthorizationController, AuthState>(
AuthorizationController.new, AuthorizationController.new,
@@ -29,9 +23,6 @@ final authorizationControllerProvider =
class AuthorizationController extends AsyncNotifier<AuthState> { class AuthorizationController extends AsyncNotifier<AuthState> {
@override @override
Future<AuthState> build() async { Future<AuthState> 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); final tokenState = await ref.watch(tokensControllerProvider.future);
if (tokenState.getAccessToken().isEmpty && if (tokenState.getAccessToken().isEmpty &&
tokenState.getRefreshToken().isNotEmpty) { tokenState.getRefreshToken().isNotEmpty) {
@@ -44,18 +35,6 @@ class AuthorizationController extends AsyncNotifier<AuthState> {
return AuthState(isAuthorized: isAuthorized); 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<void> signin(SignInData form) async { Future<void> signin(SignInData form) async {
state = const AsyncLoading(); state = const AsyncLoading();

View File

@@ -49,78 +49,104 @@ class _LoginForm extends ConsumerState<LoginForm> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final controller = ref.read(authorizationControllerProvider.notifier); final state = ref.watch(authorizationControllerProvider);
return SizedBox( return LayoutBuilder(
width: 400, builder: ((context, constraints) {
child: Form( return Stack(
key: _formKey,
child: Column(
children: [ children: [
Container(
alignment: Alignment.topLeft,
child: SelectableText(
"Welcome back!",
style: Theme.of(context).textTheme.headlineLarge,
),
),
SizedBox(height: 12),
Container(
alignment: Alignment.topLeft,
child: Row(
children: [
Text(
"Don't have an account yet? ",
style: Theme.of(context).textTheme.bodyMedium,
),
TextButton(
onPressed: widget.toggleAuth,
style: TextButton.styleFrom(
padding: EdgeInsets.zero,
minimumSize: Size(0, 0),
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
),
child: const Text(
"Sign up now",
style: TextStyle(decoration: TextDecoration.underline),
),
),
],
),
),
SizedBox(height: 36),
TextFormField(
onFieldSubmitted: (_) => _submitForm(),
controller: emailCtrl,
decoration: InputDecoration(hintText: "Email address"),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Email is required';
}
return null;
},
),
SizedBox(height: 16),
TextFormField(
onFieldSubmitted: (_) => _submitForm(),
controller: passwordCtrl,
obscureText: true,
decoration: InputDecoration(hintText: "Password"),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Password is required';
}
return null;
},
),
SizedBox(height: 16),
SizedBox( SizedBox(
width: double.infinity, width: 400,
child: Text("Forgot password?", textAlign: TextAlign.left), child: Form(
key: _formKey,
child: Column(
children: [
Container(
alignment: Alignment.topLeft,
child: SelectableText(
"Welcome back!",
style: Theme.of(context).textTheme.headlineLarge,
),
),
SizedBox(height: 12),
Container(
alignment: Alignment.topLeft,
child: Row(
children: [
Text(
"Don't have an account yet? ",
style: Theme.of(context).textTheme.bodyMedium,
),
TextButton(
onPressed: widget.toggleAuth,
style: TextButton.styleFrom(
padding: EdgeInsets.zero,
minimumSize: Size(0, 0),
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
),
child: const Text(
"Sign up now",
style: TextStyle(
decoration: TextDecoration.underline,
),
),
),
],
),
),
SizedBox(height: 36),
TextFormField(
onFieldSubmitted: (_) => _submitForm(),
controller: emailCtrl,
decoration: InputDecoration(hintText: "Email address"),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Email is required';
}
return null;
},
),
SizedBox(height: 16),
TextFormField(
onFieldSubmitted: (_) => _submitForm(),
controller: passwordCtrl,
obscureText: true,
decoration: InputDecoration(hintText: "Password"),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Password is required';
}
return null;
},
),
SizedBox(height: 16),
SizedBox(
width: double.infinity,
child: Text(
"Forgot password?",
textAlign: TextAlign.left,
),
),
ElevatedButton(
onPressed: _submitForm,
child: const Text('Log in'),
),
],
),
),
), ),
ElevatedButton(onPressed: _submitForm, child: const Text('Log in')), if (state.isLoading)
Positioned.fill(
child: AbsorbPointer(
absorbing: true,
child: Container(
color: Colors.black45,
child: const Center(child: CircularProgressIndicator()),
),
),
),
], ],
), );
), }),
); );
} }
} }