Implements KTO-01 criteria 1-4, 10 and 11 (client part). Refs #1 Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
66 lines
2.1 KiB
Dart
66 lines
2.1 KiB
Dart
import 'package:freezed_annotation/freezed_annotation.dart';
|
|
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
|
import 'package:shuffle/features/auth/domain/auth_failure.dart';
|
|
import 'package:shuffle/features/auth/domain/resend_origin.dart';
|
|
import 'package:shuffle/features/auth/domain/validation/email_format.dart';
|
|
import 'package:shuffle/features/auth/presentation/providers/auth_providers.dart';
|
|
|
|
part 'resend_controller.freezed.dart';
|
|
part 'resend_controller.g.dart';
|
|
|
|
@freezed
|
|
abstract class ResendState with _$ResendState {
|
|
const factory ResendState({
|
|
@Default(false) bool isSending,
|
|
|
|
/// The last request counts as sent (also for `emailSendLimited` from the
|
|
/// check-email screen, F12).
|
|
@Default(false) bool sent,
|
|
AuthFailure? failure,
|
|
|
|
/// Only for an address typed in by the user.
|
|
EmailError? emailError,
|
|
}) = _ResendState;
|
|
}
|
|
|
|
/// "Resend email" for the confirmation (KTO-01 Kriterium 6, F12).
|
|
///
|
|
/// The caller states where the request comes from: only there the controller
|
|
/// decides whether `emailSendLimited` is shown (login) or treated as success
|
|
/// (check-email screen).
|
|
@riverpod
|
|
class ResendController extends _$ResendController {
|
|
@override
|
|
ResendState build() => const ResendState();
|
|
|
|
void clearEmailError() {
|
|
if (state.emailError != null) {
|
|
state = state.copyWith(emailError: null);
|
|
}
|
|
}
|
|
|
|
Future<void> resend(String email, {required ResendOrigin origin}) async {
|
|
if (state.isSending) {
|
|
return;
|
|
}
|
|
final normalized = EmailFormat.normalize(email);
|
|
final emailError = EmailFormat.validate(normalized);
|
|
if (emailError != null) {
|
|
state = ResendState(emailError: emailError);
|
|
return;
|
|
}
|
|
|
|
state = const ResendState(isSending: true);
|
|
final result = await ref
|
|
.read(authRepositoryProvider)
|
|
.resendConfirmation(normalized);
|
|
if (!ref.mounted) {
|
|
return;
|
|
}
|
|
final raw = result.errorOrNull;
|
|
final failure = raw == null ? null : resendFailureFor(raw, origin);
|
|
state = failure == null
|
|
? const ResendState(sent: true)
|
|
: ResendState(failure: failure);
|
|
}
|
|
}
|