feat: Refactor code structure and optimize performance across multiple modules

This commit is contained in:
Achintha Isuru
2025-11-17 23:29:28 -05:00
parent 831570f2e0
commit a64cbd9edf
1508 changed files with 105319 additions and 0 deletions

View File

@@ -0,0 +1,105 @@
import 'dart:async';
import 'package:app_links/app_links.dart';
import 'package:auto_route/auto_route.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:gap/gap.dart';
import 'package:krow/core/presentation/styles/kw_text_styles.dart';
import 'package:krow/core/presentation/styles/theme.dart';
import 'package:krow/core/presentation/widgets/scroll_layout_helper.dart';
import 'package:krow/core/presentation/widgets/ui_kit/kw_app_bar.dart';
import 'package:krow/features/profile/email_verification/domain/bloc/email_verification_bloc.dart';
import 'package:krow/features/profile/email_verification/presentation/widgets/bottom_control_button.dart';
import 'package:krow/features/profile/email_verification/presentation/widgets/verification_actions_widget.dart';
@RoutePage()
class EmailVerificationScreen extends StatefulWidget
implements AutoRouteWrapper {
const EmailVerificationScreen({
super.key,
required this.verifiedEmail,
required this.userPhone,
});
final String verifiedEmail;
final String userPhone;
@override
State<EmailVerificationScreen> createState() =>
_EmailVerificationScreenState();
@override
Widget wrappedRoute(BuildContext context) {
return BlocProvider<EmailVerificationBloc>(
create: (context) => EmailVerificationBloc()
..add(SetVerifiedData(
verifiedEmail: verifiedEmail,
userPhone: userPhone,
)),
child: this,
);
}
}
class _EmailVerificationScreenState extends State<EmailVerificationScreen> {
StreamSubscription<Uri>? _appLinkSubscription;
@override
void initState() {
super.initState();
final context = this.context;
_appLinkSubscription = AppLinks().uriLinkStream.listen(
(link) {
if (!context.mounted) return;
context
.read<EmailVerificationBloc>()
.add(IncomingVerificationLink(verificationLink: link));
},
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: KwAppBar(
titleText: 'email_verification'.tr(),
),
body: ScrollLayoutHelper(
padding: const EdgeInsets.all(16),
upperWidget: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Gap(4),
Text(
'check_your_email'.tr(),
style: AppTextStyles.headingH1,
textAlign: TextAlign.start,
),
const Gap(8),
Text(
'verification_link_sent'
.tr(args: [widget.verifiedEmail]),
style: AppTextStyles.bodyMediumReg.copyWith(
color: AppColors.blackGray,
),
textAlign: TextAlign.start,
),
const Gap(24),
const VerificationActionsWidget(),
],
),
lowerWidget: const BottomControlButton(),
),
);
}
@override
void dispose() {
_appLinkSubscription?.cancel();
super.dispose();
}
}

View File

@@ -0,0 +1,68 @@
import 'package:auto_route/auto_route.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:krow/core/application/routing/routes.gr.dart';
import 'package:krow/core/data/enums/state_status.dart';
import 'package:krow/core/presentation/gen/assets.gen.dart';
import 'package:krow/core/presentation/widgets/ui_kit/dialogs/kw_dialog.dart';
import 'package:krow/core/presentation/widgets/ui_kit/kw_button.dart';
import 'package:krow/core/presentation/widgets/ui_kit/kw_loading_overlay.dart';
import 'package:krow/features/profile/email_verification/domain/bloc/email_verification_bloc.dart';
class BottomControlButton extends StatelessWidget {
const BottomControlButton({super.key});
void _listenHandler(BuildContext context, EmailVerificationState state) {
if (state.reAuthRequirement == ReAuthRequirement.none) return;
KwDialog.show(
context: context,
icon: Assets.images.icons.alertTriangle,
state: KwDialogState.negative,
barrierDismissible: false,
title: 'additional_action_needed'.tr(),
message: state.reAuthRequirement == ReAuthRequirement.recent
? 'email_verification_security_sensitive'.tr(args: [state.userPhone])
: 'unable_to_validate_email_status'.tr(),
primaryButtonLabel: 'Continue'.tr(),
onPrimaryButtonPressed: (dialogContext) async {
final isReAuthenticated = await dialogContext.pushRoute<bool>(
PhoneReLoginFlowRoute(userPhone: state.userPhone),
);
if (dialogContext.mounted) Navigator.maybePop(dialogContext);
if (isReAuthenticated == true &&
context.mounted &&
state.reAuthRequirement == ReAuthRequirement.recent) {
context
.read<EmailVerificationBloc>()
.add(const ResendVerificationEmail());
}
},
);
}
@override
Widget build(BuildContext context) {
return BlocConsumer<EmailVerificationBloc, EmailVerificationState>(
buildWhen: (previous, current) => previous.status != current.status,
listenWhen: (previous, current) =>
previous.reAuthRequirement != current.reAuthRequirement,
listener: _listenHandler,
builder: (context, state) {
return KwLoadingOverlay(
shouldShowLoading: state.status == StateStatus.loading,
child: KwButton.primary(
label: 'Continue'.tr(),
disabled: state.status != StateStatus.success,
onPressed: () {
context.maybePop(true);
},
),
);
},
);
}
}

View File

@@ -0,0 +1,63 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:krow/core/presentation/styles/kw_text_styles.dart';
import 'package:krow/core/presentation/styles/theme.dart';
import 'package:krow/features/profile/email_verification/domain/bloc/email_verification_bloc.dart';
class VerificationActionsWidget extends StatefulWidget {
const VerificationActionsWidget({super.key});
@override
State<VerificationActionsWidget> createState() =>
_VerificationActionsWidgetState();
}
//TODO: Finish this widget incorporating increasing timer on each code resend.
class _VerificationActionsWidgetState extends State<VerificationActionsWidget> {
double secondsToHold = 1;
bool onHold = false;
@override
Widget build(BuildContext context) {
final screenHeight = MediaQuery.sizeOf(context).height;
return Center(
child: Padding(
padding: EdgeInsets.only(top: screenHeight / 4.6),
child: RichText(
textAlign: TextAlign.center,
text: TextSpan(
text: 'didnt_receive'.tr(),
style: AppTextStyles.bodyMediumReg
.copyWith(color: AppColors.blackGray),
children: [
TextSpan(
text: 'resend'.tr(),
style: AppTextStyles.bodyMediumSmb,
recognizer: TapGestureRecognizer()
..onTap = () {
context
.read<EmailVerificationBloc>()
.add(const ResendVerificationEmail());
},
),
TextSpan(
text: ' ${'or'.tr()} ',
style: AppTextStyles.bodyMediumReg
.copyWith(color: AppColors.blackGray),
),
TextSpan(
text: 'contact_support_1'.tr(),
style: AppTextStyles.bodyMediumSmb,
recognizer: TapGestureRecognizer()..onTap = () {
//TODO: Add Contact support action.
},
),
],
),
),
),
);
}
}