import 'dart:async'; import 'dart:convert'; import 'dart:developer'; import 'package:flutter/material.dart'; import 'shared/alert_card.dart'; import 'shared/warning_card.dart'; import '../../product/utils/device_utils.dart'; import 'device_alias_model.dart'; import 'shared/overview_card.dart'; import '../settings/device_notification_settings/device_notification_settings_model.dart'; import '../../product/extention/context_extention.dart'; import '../../product/services/api_services.dart'; import '../../product/services/language_services.dart'; import '../../bloc/home_bloc.dart'; import '../../product/base/bloc/base_bloc.dart'; class HomeScreen extends StatefulWidget { const HomeScreen({super.key}); @override State createState() => _HomeScreenState(); } class _HomeScreenState extends State { late HomeBloc homeBloc; APIServices apiServices = APIServices(); List devices = []; List allDevicesAlias = []; List onlineDevicesAlias = []; List offlineDevicesAlias = []; List warningDevicesAlias = []; List notUseDevicesAlias = []; List allDevicesAliasJoined = []; List onlineDevicesAliasJoined = []; List offlineDevicesAliasJoined = []; List warningDevicesAliasJoined = []; List notUseDevicesAliasJoined = []; bool isFunctionCall = false; Timer? getAllDevicesTimer; int notificationCount = 0; Map> ownerDevicesStatus = {}; List ownerDevicesState = []; @override void initState() { super.initState(); homeBloc = BlocProvider.of(context); getOwnerAndJoinedDevices(); const duration = Duration(seconds: 20); getAllDevicesTimer = Timer.periodic(duration, (Timer t) => getOwnerAndJoinedDevices()); } @override void dispose() { getAllDevicesTimer?.cancel(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( body: Padding( padding: context.paddingLow, child: SingleChildScrollView( child: Column( children: [ Row( children: [ Text( appLocalization(context).notification, style: context.titleMediumTextStyle, ), SizedBox(width: context.lowValue), StreamBuilder( stream: homeBloc.streamCountNotitication, builder: (context, countSnapshot) { return Text( "(${countSnapshot.data ?? 0})", style: context.titleMediumTextStyle, ); }, ) ], ), SizedBox( child: SingleChildScrollView( scrollDirection: Axis.horizontal, child: StreamBuilder>>( stream: homeBloc.streamOwnerDevicesStatus, builder: (context, snapshot) { if (snapshot.data?['state'] != null || snapshot.data?['battery'] != null) { return Row( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ if (snapshot.data?['state'] != null) ...snapshot.data!['state']! .map( (item) => FutureBuilder( future: warningCard( context, apiServices, item), builder: (context, warningCardSnapshot) { if (warningCardSnapshot.hasData) { return ConstrainedBox( constraints: const BoxConstraints( maxWidth: 400, maxHeight: 260, ), child: warningCardSnapshot.data!, ); } else { return const SizedBox.shrink(); } }, ), ) .toList(), if (snapshot.data?['battery'] != null) ...snapshot.data!['battery']! .map( (batteryItem) => FutureBuilder( future: notificationCard( context, "lowBattery", "Cảnh báo pin yếu", batteryItem ), builder: (context, warningCardSnapshot) { if (warningCardSnapshot.hasData) { return ConstrainedBox( constraints: const BoxConstraints( maxWidth: 400, maxHeight: 260, ), child: warningCardSnapshot.data!, ); } else { return const SizedBox.shrink(); } }, ), ) .toList(), ], ); } else { return Padding( padding: context.paddingMedium, child: Center( child: Row( children: [ const Icon( Icons.check_circle_outline_rounded, size: 40, color: Colors.green, ), SizedBox(width: context.lowValue), Text( appLocalization(context) .notification_description, maxLines: 2, overflow: TextOverflow.ellipsis, softWrap: true, textAlign: TextAlign.start, ), ], ), ), ); } }, ), ), ), StreamBuilder>( stream: homeBloc.streamAllDevicesAlias, initialData: allDevicesAlias, builder: (context, allDeviceSnapshot) { return StreamBuilder>( stream: homeBloc.streamOnlineDevicesAlias, initialData: onlineDevicesAlias, builder: (context, onlineDeviceSnapshot) { return StreamBuilder>( stream: homeBloc.streamOfflineDevicesAlias, initialData: offlineDevicesAlias, builder: (context, deviceDashboardSnapshot) { return StreamBuilder>( stream: homeBloc.streamWarningDevicesAlias, initialData: warningDevicesAlias, builder: (context, warningDeviceSnapshot) { return StreamBuilder>( stream: homeBloc.streamNotUseDevicesAlias, initialData: notUseDevicesAlias, builder: (context, notUseSnapshot) { return OverviewCard( isOwner: true, total: allDeviceSnapshot.data!.length, active: onlineDeviceSnapshot.data!.length, inactive: deviceDashboardSnapshot.data!.length, warning: warningDeviceSnapshot.data!.length, unused: notUseSnapshot.data!.length, ); }, ); }, ); }, ); }, ); }, ), SizedBox(height: context.lowValue), StreamBuilder>( stream: homeBloc.streamAllDevicesAliasJoined, initialData: allDevicesAliasJoined, builder: (context, allDeviceSnapshot) { if (allDeviceSnapshot.data?.isEmpty ?? true) { return const SizedBox.shrink(); } return StreamBuilder>( stream: homeBloc.streamOnlineDevicesAliasJoined, initialData: onlineDevicesAliasJoined, builder: (context, onlineDeviceSnapshot) { return StreamBuilder>( stream: homeBloc.streamOfflineDevicesAliasJoined, initialData: offlineDevicesAliasJoined, builder: (context, deviceDashboardSnapshot) { return StreamBuilder>( stream: homeBloc.streamWarningDevicesAliasJoined, initialData: warningDevicesAliasJoined, builder: (context, warningDeviceSnapshot) { return StreamBuilder>( stream: homeBloc.streamNotUseDevicesAliasJoined, initialData: notUseDevicesAliasJoined, builder: (context, notUseSnapshot) { return OverviewCard( isOwner: false, total: allDeviceSnapshot.data!.length, active: onlineDeviceSnapshot.data!.length, inactive: deviceDashboardSnapshot.data!.length, warning: warningDeviceSnapshot.data!.length, unused: notUseSnapshot.data!.length, ); }, ); }, ); }, ); }, ); }, ), ], ), ), ), ); } void getOwnerAndJoinedDevices() async { String response = await apiServices.getDashBoardDevices(); final data = jsonDecode(response); List result = data["items"]; devices = DeviceWithAlias.fromJsonDynamicList(result); getOwnerDeviceState(devices); getDevicesStatusAlias(devices); checkSettingdevice(devices); } void getOwnerDeviceState(List allDevices) async { List ownerDevices = []; for (var device in allDevices) { if (device.isOwner!) { ownerDevices.add(device); } } if (ownerDevicesState.isEmpty || ownerDevicesState.length < devices.length) { ownerDevicesState.clear(); ownerDevicesStatus.clear(); homeBloc.sinkOwnerDevicesStatus.add(ownerDevicesStatus); int count = 0; for (var device in ownerDevices) { Map sensorMap = DeviceUtils.instance .getDeviceSensors(context, device.status?.sensors ?? []); if (device.state == 1 || device.state == 3) { ownerDevicesStatus["state"] ??= []; ownerDevicesStatus["state"]!.add(device); homeBloc.sinkOwnerDevicesStatus.add(ownerDevicesStatus); count++; } if (sensorMap['sensorBattery'] != appLocalization(context).no_data_message) { if (double.parse(sensorMap['sensorBattery']) <= 20) { ownerDevicesStatus['battery'] ??= []; ownerDevicesStatus['battery']!.add(device); homeBloc.sinkOwnerDevicesStatus.add(ownerDevicesStatus); count++; } } notificationCount = count; homeBloc.sinkCountNotitication.add(notificationCount); } } } void getDevicesStatusAlias(List devices) async { clearAllDeviceStatusAlias(); for (DeviceWithAlias device in devices) { if (device.isOwner == true) { allDevicesAlias.add(device); if (device.state! == 0 || device.state! == 1) { onlineDevicesAlias.add(device); homeBloc.sinkOnlineDevicesAlias.add(onlineDevicesAlias); } if (device.state! == -1) { offlineDevicesAlias.add(device); homeBloc.sinkOfflineDevicesAlias.add(offlineDevicesAlias); } if (device.state! == 1) { warningDevicesAlias.add(device); homeBloc.sinkWarningDevicesAlias.add(warningDevicesAlias); } if (device.state! == -2) { notUseDevicesAlias.add(device); homeBloc.sinkNotUseDevicesAlias.add(notUseDevicesAlias); } } else { allDevicesAliasJoined.add(device); if (device.state! == 0 || device.state! == 1) { onlineDevicesAliasJoined.add(device); homeBloc.sinkOnlineDevicesAliasJoined.add(onlineDevicesAliasJoined); } if (device.state! == -1) { offlineDevicesAliasJoined.add(device); homeBloc.sinkOfflineDevicesAliasJoined.add(offlineDevicesAliasJoined); } if (device.state! == 1) { warningDevicesAliasJoined.add(device); homeBloc.sinkWarningDevicesAliasJoined.add(warningDevicesAliasJoined); } if (device.state! == -2) { notUseDevicesAliasJoined.add(device); homeBloc.sinkNotUseDevicesAliasJoined.add(notUseDevicesAliasJoined); } } } // checkSettingdevice(allDevicesAliasJoined); homeBloc.sinkAllDevicesAlias.add(allDevicesAlias); homeBloc.sinkAllDevicesAliasJoined.add(allDevicesAliasJoined); } void checkSettingdevice(List devices) async { if (isFunctionCall) { log("Ham check setting da duoc goi"); } else { String? response = await apiServices.getAllSettingsNotificationOfDevices(); if (response != "") { final data = jsonDecode(response); final result = data['data']; // log("Data ${DeviceNotificationSettings.mapFromJson(jsonDecode(data)).values.toList()}"); List list = DeviceNotificationSettings.mapFromJson(result).values.toList(); // log("List: $list"); Set thingIdsInList = list.map((device) => device.thingId!).toSet(); for (var device in devices) { if (!thingIdsInList.contains(device.thingId)) { log("Device with Thing ID ${device.thingId} is not in the notification settings list."); await apiServices.setupDeviceNotification( device.thingId!, device.name!); } else { log("All devices are in the notification settings list."); } } } else { log("apiServices: getAllSettingsNotificationofDevices error!"); } } isFunctionCall = true; } void clearAllDeviceStatusAlias() { allDevicesAlias.clear(); homeBloc.sinkAllDevicesAlias.add(allDevicesAlias); onlineDevicesAlias.clear(); homeBloc.sinkOnlineDevicesAlias.add(onlineDevicesAlias); offlineDevicesAlias.clear(); homeBloc.sinkOfflineDevicesAlias.add(offlineDevicesAlias); warningDevicesAlias.clear(); homeBloc.sinkWarningDevicesAlias.add(warningDevicesAlias); notUseDevicesAlias.clear(); homeBloc.sinkNotUseDevicesAlias.add(notUseDevicesAlias); allDevicesAliasJoined.clear(); homeBloc.sinkAllDevicesAliasJoined.add(allDevicesAliasJoined); onlineDevicesAliasJoined.clear(); homeBloc.sinkOnlineDevicesAliasJoined.add(onlineDevicesAliasJoined); offlineDevicesAliasJoined.clear(); homeBloc.sinkOfflineDevicesAliasJoined.add(offlineDevicesAliasJoined); warningDevicesAliasJoined.clear(); homeBloc.sinkWarningDevicesAliasJoined.add(warningDevicesAliasJoined); notUseDevicesAliasJoined.clear(); homeBloc.sinkNotUseDevicesAliasJoined.add(notUseDevicesAliasJoined); } }