93 lines
2.5 KiB
Dart
93 lines
2.5 KiB
Dart
import 'dart:async';
|
|
|
|
import 'package:be_happy/core/failures.dart';
|
|
import 'package:be_happy/core/result.dart';
|
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
|
|
|
import '../../domain/usecase/verify_code_usecase.dart';
|
|
import '../event/verify_code_event.dart';
|
|
import '../state/verify_code_state.dart';
|
|
|
|
class VerifyCodeBloc extends Bloc<VerifyCodeEvent, VerifyCodeState> {
|
|
final VerifyCodeUseCase _verifyCodeUseCase;
|
|
Timer? _timer;
|
|
|
|
VerifyCodeBloc(this._verifyCodeUseCase)
|
|
: super(VerifyCodeState.initial()) {
|
|
on<VerifyCodeStarted>((event, emit) {
|
|
emit(state.copyWith(
|
|
phoneNumber: event.phoneNumber,
|
|
tempToken: event.tempToken,
|
|
secondsLeft: 60,
|
|
));
|
|
_startTimer();
|
|
});
|
|
|
|
on<CodeChanged>((event, emit) {
|
|
emit(state.copyWith(code: event.code));
|
|
});
|
|
|
|
on<ResendCodePressed>((event, emit) {
|
|
if (state.secondsLeft == 0) {
|
|
emit(state.copyWith(secondsLeft: 60));
|
|
_startTimer();
|
|
}
|
|
});
|
|
|
|
on<VerifyCodeSubmitted>(_onVerifyCodeSubmitted);
|
|
}
|
|
|
|
void _startTimer() {
|
|
_timer?.cancel();
|
|
|
|
_timer = Timer.periodic(const Duration(seconds: 1), (timer) {
|
|
if (state.secondsLeft <= 1) {
|
|
timer.cancel();
|
|
emit(state.copyWith(secondsLeft: 0));
|
|
} else {
|
|
emit(state.copyWith(secondsLeft: state.secondsLeft - 1));
|
|
}
|
|
});
|
|
}
|
|
|
|
Future<void> _onVerifyCodeSubmitted(VerifyCodeSubmitted event,
|
|
Emitter<VerifyCodeState> emit,) async {
|
|
if (state.isSubmitting || state.code.length != 6) return;
|
|
|
|
emit(state.copyWith(isSubmitting: true, error: null));
|
|
|
|
final result = await _verifyCodeUseCase.execute(state.code, state.tempToken);
|
|
|
|
final newState = switch (result) {
|
|
Success() => state.copyWith(
|
|
isSubmitting: false,
|
|
isSuccess: true,
|
|
),
|
|
Failure(failure: final f) => switch (f) {
|
|
AuthFailure(attemptsLeft: final count) => state.copyWith(
|
|
isSubmitting: false,
|
|
attemptsLeft: count,
|
|
error: 'Неверный код. Осталось попыток: $count',
|
|
),
|
|
AuthBlockFailure() => state.copyWith(
|
|
isSubmitting: false,
|
|
isBlocked: true,
|
|
error: 'Вы заблокированы за слишком частые попытки',
|
|
),
|
|
_ => state.copyWith(
|
|
isSubmitting: false,
|
|
error: 'Произошла ошибка. Попробуйте позже',
|
|
),
|
|
},
|
|
};
|
|
|
|
emit(newState);
|
|
}
|
|
|
|
@override
|
|
Future<void> close() {
|
|
_timer?.cancel();
|
|
return super.close();
|
|
}
|
|
}
|