406 lines
14 KiB
Dart
406 lines
14 KiB
Dart
// 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: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 'package:sfm_app/product/shared/shared_language_switch.dart';
|
|
import '../../product/shared/shared_light_dark_switch.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/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<MainScreen> createState() => _MainScreenState();
|
|
}
|
|
|
|
class _MainScreenState extends State<MainScreen> 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);
|
|
log("role: $role");
|
|
LocationPermissionRequest.instance.checkLocationPermission(context);
|
|
}
|
|
|
|
// For test
|
|
late bool dayNightToggle2;
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
dayNightToggle2 = false;
|
|
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<PersistentBottomNavBarItem> _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<Widget> _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) {
|
|
ThemeNotifier themeNotifier = context.watch<ThemeNotifier>();
|
|
return Scaffold(
|
|
appBar: AppBar(
|
|
backgroundColor: Colors.transparent,
|
|
actions: [
|
|
// LightDarkSwitch(
|
|
// value: !isLight,
|
|
// onChanged: (value) {
|
|
// themeNotifier.changeTheme();
|
|
// isLight = !isLight;
|
|
// },
|
|
// ),
|
|
// SizedBox(
|
|
// width: context.lowValue,
|
|
// ),
|
|
// StreamBuilder<bool>(
|
|
// 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,
|
|
// ),
|
|
StreamBuilder<bool>(
|
|
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<bool>(
|
|
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<Bell>(
|
|
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,
|
|
),
|
|
],
|
|
),
|
|
),
|
|
];
|
|
},
|
|
)
|
|
],
|
|
),
|
|
// 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,
|
|
// ),
|
|
body: PersistentTabView(
|
|
context,
|
|
controller: controller,
|
|
screens: _buildScreens(),
|
|
items: _navBarsItems(),
|
|
confineInSafeArea: true,
|
|
handleAndroidBackButtonPress: true,
|
|
resizeToAvoidBottomInset: true,
|
|
stateManagement: true,
|
|
hideNavigationBarWhenKeyboardShows: true,
|
|
// backgroundColor: Colors.transparent,
|
|
decoration: NavBarDecoration(
|
|
borderRadius: BorderRadius.circular(30.0),
|
|
),
|
|
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<void> getBellNotification() async {
|
|
bell = await apiServices.getBellNotifications("0", "20");
|
|
mainBloc.bellBloc.add(bell);
|
|
}
|
|
|
|
bool checkStatus(List<BellItems> bells) {
|
|
if (bells.isEmpty) {
|
|
return true;
|
|
}
|
|
return !bells.any((bell) => bell.status == 0);
|
|
}
|
|
}
|