// ignore_for_file: use_build_context_synchronously import 'dart:developer'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:persistent_bottom_nav_bar_v2/persistent-tab-view.dart'; import 'package:badges/badges.dart' as badges; import '../home/home_bloc.dart'; import '../../product/constant/app/app_constants.dart'; import '../../product/constant/enums/app_route_enums.dart'; import '../../product/permission/location_permission.dart'; import '../../product/services/theme_services.dart'; import '../devices/devices_manager_bloc.dart'; import '../devices/devices_manager_screen.dart'; import '../home/home_screen.dart'; import '../inter_family/inter_family_bloc.dart'; import '../inter_family/inter_family_screen.dart'; import '../device_log/device_logs_bloc.dart'; import '../device_log/device_logs_screen.dart'; import 'main_bloc.dart'; import '../map/map_bloc.dart'; import '../map/map_screen.dart'; import '../../product/base/bloc/base_bloc.dart'; import '../../product/constant/enums/app_theme_enums.dart'; import '../../product/services/api_services.dart'; import '../../main.dart'; import '../../product/constant/icon/icon_constants.dart'; import '../../product/constant/lang/language_constants.dart'; import '../../product/services/language_services.dart'; import '../bell/bell_model.dart'; class MainScreen extends StatefulWidget { const MainScreen({super.key}); @override State createState() => _MainScreenState(); } class _MainScreenState extends State with WidgetsBindingObserver { APIServices apiServices = APIServices(); late MainBloc mainBloc; bool isVN = true; bool isLight = true; String role = 'Unknown'; String titlePage = "Page Title"; int currentPageIndex = 0; final _badgeKey = GlobalKey(); Bell bell = Bell(); void initialCheck() async { String language = await apiServices.checkLanguage(); String theme = await apiServices.checkTheme(); if (language == LanguageConstants.VIETNAM) { isVN = true; } else { isVN = false; } if (theme == AppThemes.LIGHT.name) { isLight = true; } else { isLight = false; } mainBloc.sinkIsVNIcon.add(isVN); mainBloc.sinkThemeMode.add(isLight); LocationPermissionRequest.instance.checkLocationPermission(context); } @override void initState() { super.initState(); mainBloc = BlocProvider.of(context); WidgetsBinding.instance.addObserver(this); initialCheck(); getBellNotification(); } @override void didChangeAppLifecycleState(AppLifecycleState state) { super.didChangeAppLifecycleState(state); if (state == AppLifecycleState.inactive) { log("App Inactive"); } else if (state == AppLifecycleState.resumed) { log("App Resumed"); LocationPermissionRequest.instance.checkLocationPermission(context); } else if (state == AppLifecycleState.paused) { log("App paused"); } else if (state == AppLifecycleState.detached) { log("App detached"); } } @override void dispose() { super.dispose(); WidgetsBinding.instance.removeObserver(this); } PersistentTabController controller = PersistentTabController(initialIndex: 0); List _navBarsItems() { return [ PersistentBottomNavBarItem( icon: IconConstants.instance.getMaterialIcon(Icons.home), title: appLocalization(context).home_page_destination, activeColorPrimary: Colors.blue, inactiveColorPrimary: Colors.grey, inactiveIcon: IconConstants.instance.getMaterialIcon(Icons.home_outlined), ), PersistentBottomNavBarItem( icon: IconConstants.instance.getMaterialIcon(Icons.settings), title: appLocalization(context).manager_page_destination, activeColorPrimary: Colors.blue, inactiveColorPrimary: Colors.grey, inactiveIcon: IconConstants.instance.getMaterialIcon(Icons.settings_outlined), ), PersistentBottomNavBarItem( icon: IconConstants.instance.getMaterialIcon(Icons.location_on), title: appLocalization(context).map_page_destination, activeColorPrimary: Colors.blue, inactiveColorPrimary: Colors.grey, inactiveIcon: IconConstants.instance.getMaterialIcon(Icons.location_on_outlined), ), PersistentBottomNavBarItem( icon: IconConstants.instance.getMaterialIcon(Icons.history), title: appLocalization(context).history_page_destination, activeColorPrimary: Colors.blue, inactiveColorPrimary: Colors.grey, inactiveIcon: IconConstants.instance.getMaterialIcon(Icons.history_outlined), ), PersistentBottomNavBarItem( icon: IconConstants.instance.getMaterialIcon(Icons.group), title: appLocalization(context).group_page_destination, activeColorPrimary: Colors.blue, inactiveColorPrimary: Colors.grey, inactiveIcon: IconConstants.instance.getMaterialIcon(Icons.group_outlined), ), ]; } List _buildScreens() { return [ BlocProvider( child: const HomeScreen(), blocBuilder: () => HomeBloc(), ), BlocProvider( child: const DevicesManagerScreen(), blocBuilder: () => DevicesManagerBloc()), BlocProvider( child: const MapScreen(), blocBuilder: () => MapBloc(), ), BlocProvider( child: const DeviceLogsScreen(), blocBuilder: () => DeviceLogsBloc(), ), BlocProvider( child: const InterFamilyScreen(), blocBuilder: () => InterFamilyBloc(), ), ]; } @override Widget build(BuildContext context) { return StreamBuilder( stream: mainBloc.streamThemeMode, initialData: isLight, builder: (context, themeModeSnapshot) { return Scaffold( appBar: AppBar( backgroundColor: Colors.transparent, actions: [ // LightDarkSwitch( // value: !isLight, // onChanged: (value) { // themeNotifier.changeTheme(); // isLight = !isLight; // }, // ), // SizedBox( // width: context.lowValue, // ), // StreamBuilder( // stream: mainBloc.streamIsVNIcon, // builder: (context, isVNSnapshot) { // return LanguageSwitch( // value: isVNSnapshot.data ?? isVN, // onChanged: (value) async { // Locale locale = await LanguageServices().setLocale(isVN // ? LanguageConstants.ENGLISH // : LanguageConstants.VIETNAM); // MyApp.setLocale(context, locale); // isVN = !isVN; // mainBloc.sinkIsVNIcon.add(isVN); // }, // ); // }), // SizedBox( // width: context.lowValue, // ), IconButton( onPressed: () async { ThemeData newTheme = await ThemeServices().changeTheme( isLight ? AppThemes.DARK.name : AppThemes.LIGHT.name); MyApp.setTheme(context, newTheme); isLight = !isLight; mainBloc.sinkThemeMode.add(isLight); }, icon: Icon( themeModeSnapshot.data ?? isLight ? Icons.dark_mode_outlined : Icons.light_mode_outlined, ), ), StreamBuilder( stream: mainBloc.streamIsVNIcon, initialData: isVN, builder: (context, isVnSnapshot) { return IconButton( onPressed: () async { log("Locale: ${LanguageServices().getLocale()}"); Locale locale = await LanguageServices().setLocale(isVN ? LanguageConstants.ENGLISH : LanguageConstants.VIETNAM); MyApp.setLocale(context, locale); isVN = !isVN; mainBloc.sinkIsVNIcon.add(isVN); }, icon: Image.asset( IconConstants.instance.getIcon( isVnSnapshot.data ?? isVN ? 'vi_icon' : 'en_icon'), height: 24, width: 24, ), ); }, ), StreamBuilder( stream: mainBloc.streamBellBloc, builder: (context, bellSnapshot) { return checkStatus(bellSnapshot.data?.items ?? []) ? IconButton( onPressed: () { context.pushNamed(AppRoutes.BELL.name); }, icon: const Icon( Icons.notifications, ), ) : GestureDetector( child: badges.Badge( badgeStyle: const badges.BadgeStyle( shape: badges.BadgeShape.twitter, ), key: _badgeKey, badgeContent: const Icon( CupertinoIcons.circle_filled, color: Colors.red, size: 5, ), badgeAnimation: const badges.BadgeAnimation.slide( animationDuration: Duration(milliseconds: 200), colorChangeAnimationDuration: Duration(seconds: 1), loopAnimation: false, curve: Curves.decelerate, colorChangeAnimationCurve: Curves.easeInCirc, ), showBadge: true, // ignorePointer: false, child: const Icon( Icons.notifications, size: 30, ), ), onTap: () { context.pushNamed(AppRoutes.BELL.name); }, ); }, ), PopupMenuButton( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8.0), ), icon: const Icon(Icons.more_vert), itemBuilder: (context) { return [ PopupMenuItem( value: ApplicationConstants.SETTINGS_PATH, onTap: () { context.pushNamed(AppRoutes.SETTINGS.name); }, child: Row( children: [ const Icon(Icons.person), const SizedBox(width: 5), Text(appLocalization(context).profile_icon_title) ], ), ), PopupMenuItem( value: ApplicationConstants.LOGOUT_PATH, onTap: () { Future.delayed( const Duration(milliseconds: 200), () async { await apiServices.logOut(context); }, ); }, child: Row( children: [ const Icon(Icons.logout), const SizedBox(width: 5), Text( appLocalization(context).log_out, ), ], ), ), ]; }, ) ], ), body: PersistentTabView( context, controller: controller, screens: _buildScreens(), items: _navBarsItems(), confineInSafeArea: true, handleAndroidBackButtonPress: true, resizeToAvoidBottomInset: true, stateManagement: true, hideNavigationBarWhenKeyboardShows: true, backgroundColor: themeModeSnapshot.data! ? Colors.white : Colors.black, decoration: NavBarDecoration( borderRadius: BorderRadius.circular(30.0), colorBehindNavBar: themeModeSnapshot.data! ? Colors.white : Colors.black, ), popAllScreensOnTapOfSelectedTab: true, itemAnimationProperties: const ItemAnimationProperties( duration: Duration(milliseconds: 200), curve: Curves.bounceInOut, ), screenTransitionAnimation: const ScreenTransitionAnimation( animateTabTransition: true, curve: Curves.linear, duration: Duration(milliseconds: 200), ), navBarStyle: NavBarStyle.style4, ), ); }, ); } Future getBellNotification() async { bell = await apiServices.getBellNotifications("0", "20"); mainBloc.bellBloc.add(bell); } bool checkStatus(List bells) { if (bells.isEmpty) { return true; } return !bells.any((bell) => bell.status == 0); } }