Skip to content

Commit

Permalink
feat: [#17] PhoneAuthBloc, EmailDuplicateCheckBloc을 Listener로 SignUpB…
Browse files Browse the repository at this point in the history
…loc으로 값 전달
  • Loading branch information
Younggun-Kim committed Nov 23, 2024
1 parent 0b86a5c commit d0ad028
Show file tree
Hide file tree
Showing 14 changed files with 145 additions and 19 deletions.
4 changes: 4 additions & 0 deletions lib/core/types/gender_type.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,7 @@ enum GenderType with L10nKeyProvider {
)
.toList();
}

extension GenderTypeExt on GenderType {
bool get isNone => this == GenderType.none;
}
2 changes: 2 additions & 0 deletions lib/core/types/visible_type.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ enum VisibleType {
extension VisibleTypeExt on VisibleType {
bool get isVisible => this == VisibleType.visible;

bool get isInvisible => this == VisibleType.invisible;

/// Boolean -> 노출 여부
static VisibleType fromBool(bool isVisible) {
return isVisible ? VisibleType.visible : VisibleType.invisible;
Expand Down
2 changes: 1 addition & 1 deletion lib/core/utils/regex/regex_util.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class RegExUtil {

/// 이름
static RegExp namePattern = RegExp(
r'^[가-힣a-zA-Z]{2,10}\$',
r'^[ㄱ-ㅎ가-힣A-Za-z]{2,10}$',
);

/// 생년월일 패턴
Expand Down
4 changes: 3 additions & 1 deletion lib/feature/account/data/data_sources/mock/mock_api.dart
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,14 @@ class AccountMockApi extends AccountApiImpl {
FutureOr<ApiResponse<BaseResponseDto<bool>>> verifyAuthCode({
required AuthCodeVerificationRequestDto dto,
}) async {
final isAuth = '111111' == dto.authCode;

/// Mock 응답 등록
dioAdapter.onPost(
verifyAuthCodePath,
(server) => server.reply(
200,
BaseResponseDtoMock.mock(true).toJson((value) => value),
BaseResponseDtoMock.mock(isAuth).toJson((value) => value),
delay: const Duration(seconds: 1),
),
data: dto.toJson(),
Expand Down
8 changes: 4 additions & 4 deletions lib/feature/account/init_injections.dart
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,15 @@ void initAccountDomainInjections() {
}

void initAccountPresentationInjections() {
getIt.registerFactory<PhoneAuthBloc>(
getIt.registerLazySingleton<PhoneAuthBloc>(
() => PhoneAuthBloc(phoneAuthUseCase: getIt()),
);
getIt.registerLazySingleton<EmailDuplicateCheckBloc>(
() => EmailDuplicateCheckBloc(useCase: getIt()),
);
getIt.registerFactory<LoginBloc>(
() => LoginBloc(loginUseCase: getIt()),
);
getIt.registerFactory<EmailDuplicateCheckBloc>(
() => EmailDuplicateCheckBloc(useCase: getIt()),
);
getIt.registerFactory<SignUpBloc>(
() => SignUpBloc(signUpUseCase: getIt()),
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ part 'email_duplicate_check_bloc.freezed.dart';

part 'email_duplicate_check_bloc.handler.dart';

typedef EmailDuplicateCheckBlocListener
= BlocListener<EmailDuplicateCheckBloc, EmailDuplicateCheckState>;

class EmailDuplicateCheckBloc
extends BaseBloc<EmailDuplicateCheckEvent, EmailDuplicateCheckState> {
final EmailDuplicateCheckUseCase useCase;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,7 @@ class EmailDuplicateCheckState extends BaseBlocState
extension EmailDuplicateCheckStateExt on EmailDuplicateCheckState {
/// 에러 문구 노출 여부
bool get isVisibleError => errorVisible.isVisible;

/// 유니크 여부
bool get isUnique => errorVisible.isInvisible;
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ part 'phone_auth_bloc.handler.dart';

part 'phone_auth_bloc.parser.dart';

class PhoneAuthBloc
extends Bloc<PhoneAuthEvent, PhoneAuthState> {
typedef PhoneAuthBlocListener = BlocListener<PhoneAuthBloc, PhoneAuthState>;

class PhoneAuthBloc extends Bloc<PhoneAuthEvent, PhoneAuthState> {
final PhoneAuthUseCase phoneAuthUseCase;

PhoneAuthBloc({
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
part of 'phone_auth_bloc.dart';

@freezed
class PhoneAuthState extends BaseBlocState
with _$PhoneAuthState {
class PhoneAuthState extends BaseBlocState with _$PhoneAuthState {
factory PhoneAuthState({
required BaseBlocStatus status,

Expand All @@ -26,4 +25,7 @@ extension PhoneAuthStateExt on PhoneAuthState {

/// 에러 문구 노출 여부
bool get isVisibleAuthCodeError => authCodeErrorVisible.isVisible;

/// 인증 완료 여부
bool get isAuth => authCodeErrorVisible.isInvisible;
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ part 'sign_up_bloc.freezed.dart';

part 'sign_up_bloc.handler.dart';

typedef SignUpBlocBuilder = BlocBuilder<SignUpBloc, SignUpState>;

class SignUpBloc extends BaseBloc<SignUpEvent, SignUpState> {
final SignUpUseCase signUpUseCase;

Expand All @@ -22,6 +24,10 @@ class SignUpBloc extends BaseBloc<SignUpEvent, SignUpState> {
on<SignUpNameInputted>(_onNameInputted);
on<SignUpBirthDateInputted>(_onBirthDateInputted);
on<SignUpGenderSelected>(_onGenderSelected);
on<SignUpPhoneInputted>(_onPhoneInputted);
on<SignUpPhoneAuthChanged>(_onPhoneAuthChanged);
on<SignUpLoginIdInputted>(_onLoginIdInputted);
on<SignUpIsUniqueIdChanged>(_onIsUniqueIdChanged);
on<SignUpPasswordObscureToggled>(_onPasswordObscureToggled);
on<SignUpPasswordInputted>(_onPasswordInputted);
on<SignUpPasswordVerifyInputted>(_onPasswordVerifyInputted);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,34 @@ extension SignUpBlocHandler on SignUpBloc {
emit(state.copyWith(gender: event.gender));
}

void _onPhoneInputted(
SignUpPhoneInputted event,
Emitter<SignUpState> emit,
) {
emit(state.copyWith(phone: event.phone));
}

void _onPhoneAuthChanged(
SignUpPhoneAuthChanged event,
Emitter<SignUpState> emit,
) {
emit(state.copyWith(isAuthPhone: event.isAuth));
}

void _onLoginIdInputted(
SignUpLoginIdInputted event,
Emitter<SignUpState> emit,
) {
emit(state.copyWith(loginId: event.loginId));
}

void _onIsUniqueIdChanged(
SignUpIsUniqueIdChanged event,
Emitter<SignUpState> emit,
) {
emit(state.copyWith(isUniqueId: event.isUnique));
}

void _onPasswordObscureToggled(
SignUpPasswordObscureToggled event,
Emitter<SignUpState> emit,
Expand Down
28 changes: 28 additions & 0 deletions lib/feature/account/presentation/bloc/sign_up/sign_up_event.dart
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,20 @@ class SignUpGenderSelected extends SignUpEvent {
SignUpGenderSelected({required this.gender});
}

/// 휴대폰 입력 이벤트
class SignUpPhoneInputted extends SignUpEvent {
final Phone phone;

SignUpPhoneInputted({required this.phone});
}

/// 휴대폰 인증 입력 이벤트
class SignUpPhoneAuthChanged extends SignUpEvent {
final bool isAuth;

SignUpPhoneAuthChanged({required this.isAuth});
}

/// 비밀번호 입력 이벤트
class SignUpPasswordInputted extends SignUpEvent {
final String value;
Expand All @@ -39,6 +53,20 @@ class SignUpPasswordInputted extends SignUpEvent {
Password get password => Password(value);
}

/// LoginId 입력 이벤트
class SignUpLoginIdInputted extends SignUpEvent {
final Email loginId;

SignUpLoginIdInputted({required this.loginId});
}

/// LoginId 인증 여부
class SignUpIsUniqueIdChanged extends SignUpEvent {
final bool isUnique;

SignUpIsUniqueIdChanged({required this.isUnique});
}

/// 비밀번호 확인 입력 이벤트
class SignUpPasswordVerifyInputted extends SignUpEvent {
final String value;
Expand Down
17 changes: 15 additions & 2 deletions lib/feature/account/presentation/bloc/sign_up/sign_up_state.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ class SignUpState extends BaseBlocState with _$SignUpState {
@Default(BirthDate.empty) BirthDate birthDate,
@Default(GenderType.none) GenderType gender,
@Default(Phone.empty) Phone phone,
@Default(false) bool isAuthPhone,
@Default(Email.empty) LoginId loginId,
@Default(false) bool isUniqueId,
@Default(Password.empty) Password password,
@Default(Password.empty) Password passwordVerify,
@Default(true) bool isPasswordObscure,
Expand All @@ -19,10 +21,21 @@ class SignUpState extends BaseBlocState with _$SignUpState {

extension SignUpStateExt on SignUpState {
VisibleType getPasswordErrorVisible() {
return VisibleTypeExt.fromBool(!checkPasswordValid());
return VisibleTypeExt.fromBool(!_checkPasswordValid());
}

bool checkPasswordValid() {
bool _checkPasswordValid() {
return password.isValid && password.isEqual(passwordVerify);
}

bool get isEnabledSubmit => _checkSubmitEnabled();

bool _checkSubmitEnabled() {
return name.isValid &&
birthDate.isValid &&
!gender.isNone &&
isAuthPhone &&
isUniqueId &&
_checkPasswordValid();
}
}
48 changes: 41 additions & 7 deletions lib/feature/account/presentation/page/sign_up/sign_up_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,49 @@ import 'package:withu_app/shared/shared.dart';

import 'sign_up_page_key.dart';

typedef SignUpBlocBuilder = BlocBuilder<SignUpBloc, SignUpState>;

@RoutePage()
class SignUpPage extends StatelessWidget {
const SignUpPage({super.key});

@override
Widget build(BuildContext context) {
return BlocProvider<SignUpBloc>(
create: (context) => getIt(),
child: const SignUpPageContent(),
return MultiBlocProvider(
providers: [
BlocProvider<PhoneAuthBloc>(
create: (context) => getIt<PhoneAuthBloc>(),
),
BlocProvider<EmailDuplicateCheckBloc>(
create: (context) => getIt<EmailDuplicateCheckBloc>(),
),
BlocProvider<SignUpBloc>(
create: (context) => getIt<SignUpBloc>(),
),
],
child: MultiBlocListener(
listeners: [
PhoneAuthBlocListener(
listener: (context, state) {
context
.read<SignUpBloc>()
.add(SignUpPhoneInputted(phone: state.phone));
context
.read<SignUpBloc>()
.add(SignUpPhoneAuthChanged(isAuth: state.isAuth));
},
),
EmailDuplicateCheckBlocListener(
listener: (context, state) {
context
.read<SignUpBloc>()
.add(SignUpLoginIdInputted(loginId: state.email));
context
.read<SignUpBloc>()
.add(SignUpIsUniqueIdChanged(isUnique: state.isUnique));
},
),
],
child: const SignUpPageContent(),
),
);
}
}
Expand All @@ -29,7 +61,7 @@ class SignUpPageContent extends StatelessWidget {

@override
Widget build(BuildContext context) {
return BlocBuilder<SignUpBloc, SignUpState>(
return SignUpBlocBuilder(
builder: (context, state) {
return PageRoot(
isLoading: state.status.isLoading,
Expand Down Expand Up @@ -94,6 +126,7 @@ class NameInput extends StatelessWidget {
return BaseInput(
key: SignUpPageKey.name.toKey(),
hintText: StringRes.enterTwoOrMoreChars.tr,
maxLength: 10,
onChanged: (String text) {
context.read<SignUpBloc>().add(SignUpNameInputted(value: text));
},
Expand All @@ -110,6 +143,7 @@ class BirthDateInput extends StatelessWidget {
key: SignUpPageKey.birthDate.toKey(),
keyboardType: TextInputType.number,
hintText: StringRes.enterEightChars.tr,
maxLength: 8,
inputFormatters: [
FilteringTextInputFormatter.digitsOnly,
],
Expand Down Expand Up @@ -173,7 +207,7 @@ class SubmitButton extends StatelessWidget {
return EnabledButton(
key: SignUpPageKey.submitBtn.toKey(),
text: StringRes.signUp.tr,
isEnabled: true,
isEnabled: state.isEnabledSubmit,
onTap: () {
context.read<SignUpBloc>().add(SignUpSubmitPressed());
},
Expand Down

0 comments on commit d0ad028

Please sign in to comment.