Files
be_happy_public/lib/presentation/viewmodel/verify_code_bloc.dart
Polyanka 182be1049b some fix
# Conflicts:
#	lib/presentation/navigation/app_router.dart
#	pubspec.yaml
2026-08-11 00:23:16 +03:00

143 lines
4.2 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'dart:async';
import 'package:be_happy/core/failures.dart';
import 'package:be_happy/core/result.dart';
import 'package:be_happy/presentation/viewmodel/splash_bloc.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import '../../domain/usecase/verify_code_usecase.dart';
import '../event/spalsh_event.dart';
import '../event/verify_code_event.dart';
import '../state/verify_code_state.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 '../../domain/usecase/login_usecase.dart'; // 🔹 Импортируем LoginUseCase
import '../event/verify_code_event.dart';
import '../state/verify_code_state.dart';
class VerifyCodeBloc extends Bloc<VerifyCodeEvent, VerifyCodeState> {
final VerifyCodeUseCase _verifyCodeUseCase;
final LoginUseCase _loginUseCase;
final SplashBloc _splashBloc;
Timer? _timer;
VerifyCodeBloc(this._verifyCodeUseCase, this._loginUseCase, this._splashBloc)
: 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,
error: null,
));
});
on<ResendCodePressed>((event, emit) async {
if (state.secondsLeft == 0 && !state.isSubmitting) {
emit(state.copyWith(isSubmitting: true, error: null));
try {
final newTempToken = await _loginUseCase.execute("+${state.phoneNumber}");
emit(state.copyWith(
isSubmitting: false,
tempToken: newTempToken,
secondsLeft: 60,
code: '',
error: null,
isBlocked: false,
));
_startTimer();
} catch (e) {
emit(state.copyWith(
isSubmitting: false,
error: 'Не удалось повторно отправить код. Попробуйте позже.',
));
}
}
});
on<TimerTicked>((event, emit) {
emit(state.copyWith(secondsLeft: event.secondsLeft));
});
on<VerifyCodeSubmitted>(_onVerifyCodeSubmitted);
}
void _startTimer() {
_timer?.cancel();
_timer = Timer.periodic(const Duration(seconds: 1), (timer) {
final currentSeconds = state.secondsLeft;
if (currentSeconds <= 1) {
timer.cancel();
add(TimerTicked(0));
} else {
add(TimerTicked(currentSeconds - 1));
}
});
}
Future<void> _onVerifyCodeSubmitted(VerifyCodeSubmitted event,
Emitter<VerifyCodeState> emit,) async {
if (state.isSubmitting || state.code.length != 6 || state.secondsLeft == 0) return;
emit(state.copyWith(isSubmitting: true, error: null));
final result = await _verifyCodeUseCase.execute(state.code, state.tempToken);
final newState = switch (result) {
Success() => (() {
_timer?.cancel();
_splashBloc.add(AuthCheckRequested());
return 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() => (() {
_timer?.cancel();
return state.copyWith(
isSubmitting: false,
isBlocked: true,
error: 'Вы заблокированы за слишком частые попытки',
);
})(),
_ => state.copyWith(
isSubmitting: false,
error: 'Произошла ошибка. Попробуйте позже',
),
},
};
emit(newState);
}
@override
Future<void> close() {
_timer?.cancel();
return super.close();
}
}