BASE: Create AppRouter Util.

This commit is contained in:
2025-12-04 15:20:19 +05:00
parent 841cdf8c21
commit 157545f1c0
11 changed files with 580 additions and 298 deletions

View File

@@ -120,7 +120,22 @@ class ConstTexts {
static String useCurrentLocation = "useCurrentLocation";
static String setFromMap = "setFromMap";
static String enterManuallyLocation = "enterManuallyLocation";
// static String intercity = "intercity";
static String changeLanguage = "changeLanguage";
static String selectPrefferedLanguage = "selectPrefferedLanguage";
// static String rideDetails = "rideDetails";
// static String youDoNothaveSufficientwalletBalance = "youDoNothaveSufficientwalletBalance";
// static String somethingWentWrong = "somethingWentWrong";
// static String cash = "cash";
// static String hugeSelectionOfAds = "hugeSelectionOfAds";
// static String cosmetics = "cosmetics";
// static String moreThan1000Products = "moreThan1000Products";
// static String foodProducts = "foodProducts";
// static String enableLocation = "enableLocation";
// static String allowLocation = "allowLocation";
// static String useCurrentLocation = "useCurrentLocation";
// static String setFromMap = "setFromMap";
// static String enterManuallyLocation = "enterManuallyLocation";
// static String changeLanguage = "changeLanguage";
// static String aroundTheCity = "aroundTheCity";
// static String rideDetails = "rideDetails";
// static String youDoNothaveSufficientwalletBalance = "youDoNothaveSufficientwalletBalance";

View File

@@ -7,6 +7,7 @@ import 'package:customer/screen_ui/service_home_screen/service_list_screen.dart'
import 'package:customer/utils/notification_service.dart';
import 'package:customer/utils/preferences.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart' hide Trans;
import '../screen_ui/auth_screens/login_screen.dart';
import '../screen_ui/location_enable_screens/location_permission_screen.dart';
@@ -14,9 +15,13 @@ import '../screen_ui/on_boarding_screen/on_boarding_screen.dart';
import '../service/fire_store_utils.dart';
class SplashController extends GetxController {
final BuildContext context;
SplashController({required this.context});
@override
void onInit() {
Timer(const Duration(seconds: 3), () => redirectScreen());
Timer(const Duration(seconds: 2), () => redirectScreen());
super.onInit();
}
@@ -73,4 +78,11 @@ class SplashController extends GetxController {
}
}
}
void _navigateAndRemoveAll(Widget screen) {
Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(builder: (_) => screen),
(route) => false,
);
}
}

View File

@@ -2,11 +2,13 @@ import 'package:customer/screen_ui/splash_screen/splash_screen.dart';
import 'package:customer/service/localization_service.dart';
import 'package:customer/themes/app_them_data.dart';
import 'package:customer/themes/easy_loading_config.dart';
import 'package:customer/utils/app_router.dart';
import 'package:customer/utils/preferences.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:flutter_phoenix/flutter_phoenix.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'controllers/global_setting_controller.dart';
@@ -28,14 +30,14 @@ void main() async {
runApp(
EasyLocalization(
startLocale: Locale('en', 'US'),
startLocale: Locale('uz', 'UZ'),
supportedLocales: [
Locale('en', 'US'),
Locale('uz', 'UZ'),
Locale('ru', 'RU'),
],
path: 'assets/translations',
fallbackLocale: Locale('en', 'US'),
fallbackLocale: Locale('uz', 'UZ'),
child: MyApp(),
),
);
@@ -54,7 +56,8 @@ class MyApp extends StatelessWidget {
designSize: Size(375, 812),
minTextAdapt: true,
splitScreenMode: true,
child: GetMaterialApp(
child: MaterialApp(
navigatorKey: AppRouter.navigatorKey,
localizationsDelegates: context.localizationDelegates,
supportedLocales: context.supportedLocales,
locale: context.locale,
@@ -66,8 +69,7 @@ class MyApp extends StatelessWidget {
child: EasyLoading.init()(context, child),
);
},
translations: LocalizationService(),
fallbackLocale: LocalizationService.locale,
// fallbackLocale: LocalizationService.locale,
themeMode: themeController.themeMode,
theme: ThemeData(
scaffoldBackgroundColor: AppThemeData.surface,

View File

@@ -1,13 +1,15 @@
import 'dart:convert';
import 'package:customer/constant/constant.dart';
import 'package:customer/controllers/change_language_controller.dart';
import 'package:customer/screen_ui/splash_screen/splash_screen.dart';
import 'package:customer/themes/app_them_data.dart';
import 'package:customer/utils/network_image_widget.dart';
import 'package:customer/utils/preferences.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flag/flag_enum.dart';
import 'package:flag/flag_widget.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart' hide Trans;import '../../../controllers/theme_controller.dart';
import '../../../service/localization_service.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart' hide Trans;
import '../../../controllers/theme_controller.dart';
class ChangeLanguageScreen extends StatelessWidget {
const ChangeLanguageScreen({super.key});
@@ -20,81 +22,199 @@ class ChangeLanguageScreen extends StatelessWidget {
init: ChangeLanguageController(),
builder: (controller) {
return Scaffold(
appBar: AppBar(backgroundColor: isDark ? AppThemeData.surfaceDark : AppThemeData.surface, centerTitle: false, titleSpacing: 0),
appBar: AppBar(
backgroundColor:
isDark ? AppThemeData.surfaceDark : AppThemeData.surface,
centerTitle: false,
titleSpacing: 0,
leading: InkWell(
onTap: () {
// Get.back();
Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(builder: (context) => SplashScreen()),
(route) => false,
);
},
child: Icon(Icons.arrow_back),
),
),
body:
controller.isLoading.value
? Constant.loader()
: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Change Language".tr(),
style: TextStyle(fontSize: 24, color: isDark ? AppThemeData.grey50 : AppThemeData.grey900, fontFamily: AppThemeData.semiBold, fontWeight: FontWeight.w500),
),
Text(
"Select your preferred language for a personalized app experience.".tr(),
style: TextStyle(fontSize: 16, color: isDark ? AppThemeData.grey50 : AppThemeData.grey900, fontFamily: AppThemeData.regular, fontWeight: FontWeight.w400),
),
const SizedBox(height: 20),
Expanded(
child: GridView.count(
crossAxisCount: 2,
childAspectRatio: (1.1 / 1),
crossAxisSpacing: 5,
mainAxisSpacing: 1,
children:
controller.languageList
.map(
(data) => Obx(
() => GestureDetector(
onTap: () {
LocalizationService().changeLocale(data.slug.toString());
Preferences.setString(Preferences.languageCodeKey, jsonEncode(data));
controller.selectedLanguage.value = data;
},
child: Container(
padding: const EdgeInsets.all(16),
child: Column(
children: [
NetworkImageWidget(imageUrl: data.image.toString(), height: 80, width: 80),
// SvgPicture.network(
// data.image.toString(),
// height: 80,
// width: 80,
// fit: BoxFit.contain,
// placeholderBuilder: (context) => const Center(child: CircularProgressIndicator(strokeWidth: 1.5)),
// ),
const SizedBox(height: 5),
Text(
"${data.title}",
style: TextStyle(
fontSize: 16,
color:
controller.selectedLanguage.value.slug == data.slug
? AppThemeData.primary300
: isDark
? AppThemeData.grey400
: AppThemeData.grey500,
fontFamily: AppThemeData.medium,
fontWeight: FontWeight.w400,
),
),
],
),
),
),
),
)
.toList(),
),
),
],
),
: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Padding(
// padding: const EdgeInsets.symmetric(horizontal: 16),
// child: Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// Text(
// ConstTexts.changeLanguage.tr(),
// style: TextStyle(
// fontSize: 24,
// color:
// isDark
// ? AppThemeData.grey50
// : AppThemeData.grey900,
// fontFamily: AppThemeData.semiBold,
// fontWeight: FontWeight.w500,
// ),
// ),
// Text(
// ConstTexts.selectPrefferedLanguage.tr(),
// style: TextStyle(
// fontSize: 16,
// color:
// isDark
// ? AppThemeData.grey50
// : AppThemeData.grey900,
// fontFamily: AppThemeData.regular,
// fontWeight: FontWeight.w400,
// ),
// ),
// ],
// ),
// ),
_buildLanguageButton(
isActive: context.locale == Locale("uz", "UZ"),
flagCode: FlagsCode.UZ,
title: "O'zbekcha",
onTap: () async {
await context.setLocale(Locale("uz", "UZ"));
Get.forceAppUpdate();
},
),
_buildDivider(),
_buildLanguageButton(
isActive: context.locale == Locale("ru", "RU"),
flagCode: FlagsCode.RU,
title: "Русский",
onTap: () async {
await context.setLocale(Locale("ru", "RU"));
Get.forceAppUpdate();
},
),
_buildDivider(),
_buildLanguageButton(
isActive: context.locale == Locale("en", "US"),
flagCode: FlagsCode.US,
title: "English",
onTap: () async {
await context.setLocale(Locale("en", "US"));
Get.forceAppUpdate();
},
),
// Expanded(
// child: GridView.count(
// crossAxisCount: 2,
// childAspectRatio: (1.1 / 1),
// crossAxisSpacing: 5,
// mainAxisSpacing: 1,
// children:
// controller.languageList
// .map(
// (data) => Obx(
// () => GestureDetector(
// onTap: () {
// LocalizationService().changeLocale(data.slug.toString());
// Preferences.setString(Preferences.languageCodeKey, jsonEncode(data));
// controller.selectedLanguage.value = data;
// },
// child: Container(
// padding: const EdgeInsets.all(16),
// child: Column(
// children: [
// NetworkImageWidget(imageUrl: data.image.toString(), height: 80, width: 80),
// // SvgPicture.network(
// // data.image.toString(),
// // height: 80,
// // width: 80,
// // fit: BoxFit.contain,
// // placeholderBuilder: (context) => const Center(child: CircularProgressIndicator(strokeWidth: 1.5)),
// // ),
// const SizedBox(height: 5),
// Text(
// "${data.title}",
// style: TextStyle(
// fontSize: 16,
// color:
// controller.selectedLanguage.value.slug == data.slug
// ? AppThemeData.primary300
// : isDark
// ? AppThemeData.grey400
// : AppThemeData.grey500,
// fontFamily: AppThemeData.medium,
// fontWeight: FontWeight.w400,
// ),
// ),
// ],
// ),
// ),
// ),
// ),
// )
// .toList(),
// ),
// ),
],
),
);
},
);
}
Widget _buildDivider() => Padding(
padding: EdgeInsetsGeometry.symmetric(horizontal: 16.r),
child: Divider(thickness: 1.2.r),
);
InkWell _buildLanguageButton({
required bool isActive,
required VoidCallback onTap,
required String title,
required FlagsCode flagCode,
}) {
return InkWell(
hoverColor: Colors.transparent,
splashColor: Colors.transparent,
overlayColor: WidgetStatePropertyAll(Colors.transparent),
onTap: onTap,
child: Padding(
padding: EdgeInsets.symmetric(vertical: 15.r).copyWith(right: 16.r),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
Flag.fromCode(
flagCode,
height: 40.h,
width: 90.w,
borderRadius: 12.r,
),
Text(
title,
style: AppThemeData.mediumTextStyle(
fontSize: 16.sp,
color: AppThemeData.darkGrey,
),
),
],
),
isActive
? Icon(
Icons.circle,
color: AppThemeData.darkGrey.withValues(alpha: 0.6),
size: 15.r,
)
: SizedBox.shrink(),
],
),
),
);
}
}

View File

@@ -9,12 +9,16 @@ class SplashScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return GetBuilder<SplashController>(
init: SplashController(),
init: SplashController(context: context),
builder: (controller) {
return Scaffold(
backgroundColor: AppThemeData.mainColor,
body: Center(
child: Image.asset("assets/images/fondex_logo_main.png", width: 120, height: 120),
child: Image.asset(
"assets/images/fondex_logo_main.png",
width: 120,
height: 120,
),
),
);
},

42
lib/utils/app_router.dart Normal file
View File

@@ -0,0 +1,42 @@
import 'package:flutter/material.dart';
class AppRouter {
static final GlobalKey<NavigatorState> navigatorKey =
GlobalKey<NavigatorState>();
static void close() {
if (navigatorKey.currentState?.canPop() ?? false) {
navigatorKey.currentState!.pop();
}
}
static void go(Widget page) {
navigatorKey.currentState?.push(_createRoute(page));
}
static void open(Widget page) {
navigatorKey.currentState?.pushAndRemoveUntil(
_createRoute(page),
(Route<dynamic> route) => false,
);
}
static PageRouteBuilder _createRoute(Widget page) {
return PageRouteBuilder(
transitionDuration: const Duration(milliseconds: 200),
reverseTransitionDuration: const Duration(milliseconds: 100),
pageBuilder: (context, animation, secondaryAnimation) => page,
transitionsBuilder: (context, animation, secondaryAnimation, child) {
final curvedAnimation = CurvedAnimation(
parent: animation,
curve: Curves.ease,
);
return ScaleTransition(
alignment: Alignment.center,
scale: Tween<double>(begin: 0.950, end: 1).animate(curvedAnimation),
child: child,
);
},
);
}
}