You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

249 lines
9.8 KiB

import 'package:auto_size_text/auto_size_text.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:go_router/go_router.dart';
import 'package:hadi_hoda_flutter/common_ui/resources/my_assets.dart';
import 'package:hadi_hoda_flutter/common_ui/resources/my_colors.dart';
import 'package:hadi_hoda_flutter/common_ui/resources/my_spaces.dart';
import 'package:hadi_hoda_flutter/common_ui/resources/my_text_style.dart';
import 'package:hadi_hoda_flutter/core/constants/my_constants.dart';
import 'package:hadi_hoda_flutter/core/routers/my_routes.dart';
import 'package:hadi_hoda_flutter/core/status/base_status.dart';
import 'package:hadi_hoda_flutter/core/utils/my_localization.dart';
import 'package:hadi_hoda_flutter/core/utils/screen_size.dart';
import 'package:hadi_hoda_flutter/core/utils/set_platform_size.dart';
import 'package:hadi_hoda_flutter/core/widgets/button/my_blue_button.dart';
import 'package:hadi_hoda_flutter/core/widgets/images/my_image.dart';
import 'package:hadi_hoda_flutter/features/app/presentation/bloc/app_bloc.dart';
import 'package:hadi_hoda_flutter/features/app/presentation/bloc/app_event.dart';
import 'package:hadi_hoda_flutter/features/download/domain/entities/download_entity.dart';
import 'package:hadi_hoda_flutter/features/download/presentation/bloc/download_bloc.dart';
import 'package:hadi_hoda_flutter/features/download/presentation/bloc/download_event.dart';
import 'package:hadi_hoda_flutter/features/language/presentation/bloc/language_bloc.dart';
import 'package:hadi_hoda_flutter/features/language/presentation/bloc/language_event.dart';
import 'package:hadi_hoda_flutter/features/language/presentation/bloc/language_state.dart';
import 'package:wheel_chooser/wheel_chooser.dart';
class LanguagePage extends StatefulWidget {
const LanguagePage({super.key});
@override
State<LanguagePage> createState() => _LanguagePageState();
}
class _LanguagePageState extends State<LanguagePage> {
final controller = FixedExtentScrollController(initialItem: 50);
bool _isEnabled = false;
@override
void initState() {
super.initState();
context.read<LanguageBloc>().add(const GetLanguagesEvent());
}
@override
void dispose() {
controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
height: context.heightScreen,
width: context.widthScreen,
decoration: BoxDecoration(
gradient: const LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [Color(0XFF00154C), Color(0XFF150532)],
),
image: DecorationImage(
image: const AssetImage(MyAssets.pattern),
scale: 3,
repeat: ImageRepeat.repeat,
colorFilter: ColorFilter.mode(
Colors.white.withValues(alpha: 0.2),
BlendMode.srcIn,
),
),
),
child: BlocConsumer<LanguageBloc, LanguageState>(
listener: (context, state) async {
if (state.languages.isNotEmpty && !_isEnabled) {
int targetIndex = 0;
if (state.selectedLanguage != null) {
targetIndex = state.languages.indexWhere((l) => l.code == state.selectedLanguage!.code);
if (targetIndex == -1) targetIndex = 0;
}
await Future.delayed(const Duration(milliseconds: 50));
if (controller.hasClients) {
await controller.animateToItem(
targetIndex,
duration: const Duration(seconds: 1),
curve: Curves.easeOutCirc,
);
if (state.selectedLanguage == null && context.mounted) {
context.read<LanguageBloc>().add(
SelectLanguageEvent(state.languages[targetIndex]),
);
}
}
setState(() => _isEnabled = true);
}
},
builder: (context, state) {
if (state.getLanguagesStatus is BaseLoading) {
return const Center(child: CircularProgressIndicator());
}
final double itemSize = setSize(context: context, mobile: 45, tablet: 60) ?? 45;
return Padding(
padding: EdgeInsets.only(
left: setSize(context: context, mobile: 50, tablet: 0.3.w) ?? 0,
right: setSize(context: context, mobile: 50, tablet: 0.3.w) ?? 0,
bottom: MySpaces.s40 + MediaQuery.paddingOf(context).bottom,
top: 100,
),
child: Column(
children: [
_title(context),
const SizedBox(height: 72),
Expanded(
child: ShaderMask(
shaderCallback: (rect) {
return const LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Color(0x00FFF7FA),
Color(0x1AFFF7FA),
Color(0xFFFFFFFF),
Color(0x1AFEFCFD),
Color(0x00FEFCFD),
],
).createShader(rect);
},
child: Stack(
children: [
Center(
child: Container(
width: double.infinity,
alignment: Alignment.centerLeft,
height: itemSize,
padding: const EdgeInsets.symmetric(horizontal: 18),
decoration: BoxDecoration(
color: Colors.white.withValues(alpha: .2),
borderRadius: BorderRadius.circular(12),
),
child: const MyImage(image: MyAssets.check),
),
),
WheelChooser.choices(
controller: controller,
startPosition: null,
perspective: 0.00000001,
listWidth: double.infinity,
listHeight: double.infinity,
itemSize: itemSize,
isInfinite: true,
onChoiceChanged: (value) {
if (value != null && value is! String) {
context.read<LanguageBloc>().add(
SelectLanguageEvent(value),
);
}
},
selectTextStyle: MYTextStyle.titr1.copyWith(
fontSize: itemSize * 0.34,
color: Colors.white,
),
unSelectTextStyle: MYTextStyle.titr1.copyWith(
fontSize: itemSize * 0.34,
color: Colors.white.withOpacity(0.5),
),
choices: state.languages.map((lang) {
return WheelChoice(
value: lang,
title: lang.displayName,
);
}).toList(),
),
],
),
),
),
const SizedBox(height: 72),
_btn(context, state),
],
),
);
},
),
),
);
}
Widget _title(BuildContext context) {
return Row(
spacing: MySpaces.s10,
mainAxisAlignment: MainAxisAlignment.center,
children: [
const MyImage(image: MyAssets.lang, size: 28),
AutoSizeText(
context.translate.select_language,
minFontSize: 12,
maxFontSize: 20,
maxLines: 1,
textAlign: TextAlign.center,
style: MYTextStyle.titr0.copyWith(color: const Color(0XFF847AC4)),
),
],
);
}
Widget _btn(BuildContext context, LanguageState state) {
return MyBlueButton(
onTap: (_isEnabled && state.selectedLanguage != null)
? () async {
final downloadBloc = context.read<DownloadBloc>();
// 1. Cancel any previous downloads.
downloadBloc.add(CancelDownloadEvent());
// 2. Update App Locale
context.read<AppBloc>().add(
ChangeLocaleEvent(state.selectedLanguage!.locale),
);
await Future.delayed(const Duration(milliseconds: 80));
final lastDownloadedLevel = await downloadBloc
.lastDownloadedLevel();
if (!context.mounted) return;
if (lastDownloadedLevel >= MyConstants.firstDownloadBatchCount) {
context.goNamed(Routes.homePage);
} else {
context.read<DownloadBloc>().add(
const StartDownloadEvent(
toLevel: MyConstants.firstDownloadBatchCount,
),
);
context.goNamed(
Routes.downloadPage,
extra: const DownloadPageConfig(
downloadToLevel: MyConstants.firstDownloadBatchCount,
redirectTo: Routes.homePage,
),
);
}
}
: null,
title: context.translate.select,
);
}
}