// 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:provider/provider.dart'; import 'package:badges/badges.dart' as badges; import 'package:sfm_app/feature/home/home_bloc.dart'; import 'package:sfm_app/product/constant/app/app_constants.dart'; import 'package:sfm_app/product/constant/enums/app_route_enums.dart'; import 'package:sfm_app/product/constant/enums/role_enums.dart'; import 'package:sfm_app/product/permission/location_permission.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 '../log/device_logs_bloc.dart'; import '../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/extention/context_extention.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 '../../product/theme/theme_notifier.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 { role = await apiServices.getUserRole(); mainBloc.sinkRole.add(role); 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); log("role: $role"); 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); } @override Widget build(BuildContext context) { ThemeNotifier themeNotifier = context.watch(); checkSelectedIndex(currentPageIndex); List userDestinations = [ NavigationDestination( selectedIcon: IconConstants.instance.getMaterialIcon(Icons.home), icon: IconConstants.instance.getMaterialIcon(Icons.home_outlined), label: appLocalization(context).home_page_destination, tooltip: appLocalization(context).home_page_destination, ), NavigationDestination( selectedIcon: IconConstants.instance.getMaterialIcon(Icons.settings), icon: IconConstants.instance.getMaterialIcon(Icons.settings_outlined), label: appLocalization(context).manager_page_destination, tooltip: appLocalization(context).device_manager_page_name, ), NavigationDestination( selectedIcon: IconConstants.instance.getMaterialIcon(Icons.location_on), icon: IconConstants.instance.getMaterialIcon(Icons.location_on_outlined), label: appLocalization(context).map_page_destination, tooltip: appLocalization(context).map_page_destination, ), NavigationDestination( // selectedIcon: IconConstants.instance.getMaterialIcon(Icons.histor), icon: IconConstants.instance.getMaterialIcon(Icons.history_rounded), label: appLocalization(context).history_page_destination, tooltip: appLocalization(context).history_page_destination_tooltip, ), NavigationDestination( selectedIcon: IconConstants.instance.getMaterialIcon(Icons.group), icon: IconConstants.instance.getMaterialIcon(Icons.group_outlined), label: appLocalization(context).group_page_destination, tooltip: appLocalization(context).group_page_destination_tooltip, ), ]; List userBody = [ 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(), ), ]; List modDestinations = [ NavigationDestination( selectedIcon: IconConstants.instance.getMaterialIcon(Icons.home), icon: IconConstants.instance.getMaterialIcon(Icons.home_outlined), label: appLocalization(context).home_page_destination, tooltip: appLocalization(context).home_page_destination, ), NavigationDestination( selectedIcon: IconConstants.instance.getMaterialIcon(Icons.settings), icon: IconConstants.instance.getMaterialIcon(Icons.settings_outlined), label: appLocalization(context).manager_page_destination, tooltip: appLocalization(context).device_manager_page_name, ), NavigationDestination( selectedIcon: IconConstants.instance.getMaterialIcon(Icons.location_on), icon: IconConstants.instance.getMaterialIcon(Icons.location_on_outlined), label: appLocalization(context).map_page_destination, tooltip: appLocalization(context).map_page_destination, ), ]; List modBody = [ BlocProvider(child: const HomeScreen(), blocBuilder: () => HomeBloc()), BlocProvider( child: const DevicesManagerScreen(), blocBuilder: () => DevicesManagerBloc()), BlocProvider( child: const MapScreen(), blocBuilder: () => MapBloc(), ), ]; return StreamBuilder( stream: mainBloc.streamRole, initialData: role, builder: (context, roleSnapshot) { return StreamBuilder( stream: mainBloc.streamCurrentPageIndex, initialData: currentPageIndex, builder: (context, indexSnapshot) { return Scaffold( appBar: AppBar( backgroundColor: Colors.transparent, centerTitle: true, title: StreamBuilder( stream: mainBloc.streamTitle, initialData: titlePage, builder: (context, titleSnapshot) { return Text( titleSnapshot.data ?? ApplicationConstants.APP_NAME, ); }, ), actions: [ StreamBuilder( stream: mainBloc.streamThemeMode, initialData: isLight, builder: (context, themeModeSnapshot) { return IconButton( onPressed: () { themeNotifier.changeTheme(); isLight = !isLight; mainBloc.sinkThemeMode.add(isLight); }, icon: Icon( themeModeSnapshot.data ?? isLight ? Icons.light_mode_outlined : Icons.dark_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: const RoundedRectangleBorder( borderRadius: BorderRadius.only( bottomLeft: Radius.circular(8.0), bottomRight: Radius.circular(8.0), topLeft: Radius.circular(8.0), topRight: Radius.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, ), ], ), ), ]; }, ) ], ), bottomNavigationBar: Container( decoration: BoxDecoration(borderRadius: BorderRadius.circular(50)), padding: context.paddingLow, child: NavigationBar( onDestinationSelected: (index) { currentPageIndex = index; mainBloc.sinkCurrentPageIndex.add(currentPageIndex); checkSelectedIndex(currentPageIndex); }, selectedIndex: indexSnapshot.data ?? currentPageIndex, destinations: roleSnapshot.data == RoleEnums.USER.name ? userDestinations : modDestinations, ), ), body: IndexedStack( index: indexSnapshot.data ?? currentPageIndex, children: roleSnapshot.data == RoleEnums.USER.name ? userBody : modBody, ), ); }, ); }, ); } 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); } void checkSelectedIndex(int current) { if (current == 0) { titlePage = appLocalization(context).home_page_name; mainBloc.sinkTitle.add(titlePage); } else if (current == 1) { titlePage = appLocalization(context).device_manager_page_name; mainBloc.sinkTitle.add(titlePage); } else if (current == 2) { titlePage = appLocalization(context).map_page_destination; mainBloc.sinkTitle.add(titlePage); } else if (current == 3) { titlePage = appLocalization(context).device_log_page_name; mainBloc.sinkTitle.add(titlePage); } else if (current == 4) { titlePage = appLocalization(context).interfamily_page_name; mainBloc.sinkTitle.add(titlePage); } } }