fix(ui): display interfamily tags when interfamily's devices state = 1

This commit is contained in:
anhtunz
2025-02-17 11:09:55 +07:00
parent bfeba03490
commit 16244d6768
6 changed files with 304 additions and 276 deletions

View File

@@ -1,12 +1,11 @@
import 'dart:async'; import 'dart:async';
import 'dart:convert'; import 'dart:convert';
import 'dart:developer';
import 'package:sfm_app/feature/devices/device_model.dart'; import '../feature/devices/device_model.dart';
import 'package:sfm_app/product/base/bloc/base_bloc.dart'; import '../product/base/bloc/base_bloc.dart';
import 'package:sfm_app/product/constant/app/app_constants.dart'; import '../product/constant/app/app_constants.dart';
import 'package:sfm_app/product/services/api_services.dart'; import '../product/services/api_services.dart';
import 'package:sfm_app/product/utils/date_time_utils.dart'; import '../product/utils/date_time_utils.dart';
import '../product/utils/device_utils.dart'; import '../product/utils/device_utils.dart';
import '../feature/device_log/device_logs_model.dart'; import '../feature/device_log/device_logs_model.dart';

View File

@@ -1,4 +1,3 @@
import 'dart:developer';
import 'package:dropdown_button2/dropdown_button2.dart'; import 'package:dropdown_button2/dropdown_button2.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';

View File

@@ -94,61 +94,59 @@ class _HomeScreenState extends State<HomeScreen> {
if (snapshot.data?['state'] != null || if (snapshot.data?['state'] != null ||
snapshot.data?['battery'] != null) { snapshot.data?['battery'] != null) {
return Row( return Row(
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
if (snapshot.data?['state'] != null) if (snapshot.data?['state'] != null)
...snapshot.data!['state']! ...snapshot.data!['state']!
.map( .map(
(item) => FutureBuilder<Widget>( (item) => FutureBuilder<Widget>(
future: warningCard( future: warningCard(
context, apiServices, item), context, apiServices, item),
builder: builder: (context, warningCardSnapshot) {
(context, warningCardSnapshot) { if (warningCardSnapshot.hasData) {
if (warningCardSnapshot.hasData) { return ConstrainedBox(
return ConstrainedBox( constraints: const BoxConstraints(
constraints: const BoxConstraints( maxWidth: 400,
maxWidth: 400, maxHeight: 260,
maxHeight: 260, ),
), child: warningCardSnapshot.data!,
child: warningCardSnapshot.data!, );
); } else {
} else { return const SizedBox.shrink();
return const SizedBox.shrink(); }
} },
}, ),
)
.toList(),
if (snapshot.data?['battery'] != null)
...snapshot.data!['battery']!
.map(
(batteryItem) => FutureBuilder<Widget>(
future: notificationCard(
context,
"lowBattery",
"Cảnh báo pin yếu",
batteryItem
), ),
) builder: (context, warningCardSnapshot) {
.toList(), if (warningCardSnapshot.hasData) {
if (snapshot.data?['battery'] != null) return ConstrainedBox(
...snapshot.data!['battery']! constraints: const BoxConstraints(
.map( maxWidth: 400,
(batteryItem) => FutureBuilder<Widget>( maxHeight: 260,
future: notificationCard( ),
context, child: warningCardSnapshot.data!,
"lowBattery", );
"Cảnh báo pin yếu", } else {
batteryItem.name!, return const SizedBox.shrink();
batteryItem.areaPath!, }
), },
builder: ),
(context, warningCardSnapshot) { )
if (warningCardSnapshot.hasData) { .toList(),
return ConstrainedBox( ],
constraints: const BoxConstraints( );
maxWidth: 400,
maxHeight: 260,
),
child: warningCardSnapshot.data!,
);
} else {
return const SizedBox.shrink();
}
},
),
)
.toList(),
]);
} else { } else {
return Padding( return Padding(
padding: context.paddingMedium, padding: context.paddingMedium,
@@ -355,13 +353,14 @@ class _HomeScreenState extends State<HomeScreen> {
} }
} }
} }
checkSettingdevice(allDevicesAliasJoined); // checkSettingdevice(allDevicesAliasJoined);
homeBloc.sinkAllDevicesAlias.add(allDevicesAlias); homeBloc.sinkAllDevicesAlias.add(allDevicesAlias);
homeBloc.sinkAllDevicesAliasJoined.add(allDevicesAliasJoined); homeBloc.sinkAllDevicesAliasJoined.add(allDevicesAliasJoined);
} }
void checkSettingdevice(List<DeviceWithAlias> devices) async { void checkSettingdevice(List<DeviceWithAlias> devices) async {
if (isFunctionCall) { if (isFunctionCall) {
log("Ham check setting da duoc goi");
} else { } else {
String? response = String? response =
await apiServices.getAllSettingsNotificationOfDevices(); await apiServices.getAllSettingsNotificationOfDevices();
@@ -380,7 +379,7 @@ class _HomeScreenState extends State<HomeScreen> {
await apiServices.setupDeviceNotification( await apiServices.setupDeviceNotification(
device.thingId!, device.name!); device.thingId!, device.name!);
} else { } else {
log("All devives are in the notification settings list."); log("All devices are in the notification settings list.");
} }
} }
} else { } else {

View File

@@ -1,6 +1,9 @@
// ignore_for_file: use_build_context_synchronously // ignore_for_file: use_build_context_synchronously
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:sfm_app/feature/home/device_alias_model.dart';
import '../../../product/constant/enums/app_route_enums.dart';
import '../../../product/constant/image/image_constants.dart'; import '../../../product/constant/image/image_constants.dart';
import '../../../product/extention/context_extention.dart'; import '../../../product/extention/context_extention.dart';
import '../../../product/services/language_services.dart'; import '../../../product/services/language_services.dart';
@@ -8,14 +11,13 @@ import '../../../product/utils/device_utils.dart';
import '../../../product/constant/icon/icon_constants.dart'; import '../../../product/constant/icon/icon_constants.dart';
Future<Widget> notificationCard( Future<Widget> notificationCard(BuildContext context, String notiticationType,
BuildContext context, String notificationTitle, DeviceWithAlias device) async {
String notiticationType, String location = "";
String notificationTitle, if (device.areaPath != "") {
String notificationDevicename, location = await DeviceUtils.instance
String notificationLocation) async { .getFullDeviceLocation(context, device.areaPath!);
String location = await DeviceUtils.instance }
.getFullDeviceLocation(context, notificationLocation);
String path = ""; String path = "";
DateTime time = DateTime.now(); DateTime time = DateTime.now();
if (notiticationType == "lowBattery") { if (notiticationType == "lowBattery") {
@@ -50,7 +52,7 @@ Future<Widget> notificationCard(
SizedBox(height: context.lowValue), SizedBox(height: context.lowValue),
SizedBox( SizedBox(
child: Text( child: Text(
"${appLocalization(context).device_title} $notificationDevicename", "${appLocalization(context).device_title} ${device.isOwner! ? device.name : device.alias}",
style: const TextStyle( style: const TextStyle(
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
fontSize: 18, fontSize: 18,
@@ -113,8 +115,12 @@ Future<Widget> notificationCard(
alignment: Alignment.centerRight, alignment: Alignment.centerRight,
child: OutlinedButton( child: OutlinedButton(
style: const ButtonStyle( style: const ButtonStyle(
backgroundColor: WidgetStatePropertyAll(Colors.blueAccent)), backgroundColor: WidgetStatePropertyAll(Colors.blueAccent),
onPressed: () {}, ),
onPressed: () {
context.pushNamed(AppRoutes.DEVICE_DETAIL.name,
pathParameters: {'thingID': device.thingId!});
},
child: Text( child: Text(
appLocalization(context).detail_message, appLocalization(context).detail_message,
style: const TextStyle( style: const TextStyle(

View File

@@ -3,6 +3,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:maps_launcher/maps_launcher.dart'; import 'package:maps_launcher/maps_launcher.dart';
import 'package:badges/badges.dart' as badges;
import '../device_alias_model.dart'; import '../device_alias_model.dart';
import '../../../product/constant/icon/icon_constants.dart'; import '../../../product/constant/icon/icon_constants.dart';
import '../../../product/constant/image/image_constants.dart'; import '../../../product/constant/image/image_constants.dart';
@@ -12,30 +13,33 @@ import '../../../product/services/language_services.dart';
import '../../../product/utils/device_utils.dart'; import '../../../product/utils/device_utils.dart';
import '../../../product/shared/shared_snack_bar.dart'; import '../../../product/shared/shared_snack_bar.dart';
Future<Widget> warningCard( Future<Widget> warningCard(BuildContext context, APIServices apiServices,
BuildContext context, APIServices apiServices, DeviceWithAlias item) async { DeviceWithAlias device) async {
Color backgroundColor = Colors.blue; Color backgroundColor = Colors.blue;
Color textColor = Colors.white; Color textColor = Colors.white;
String message = ""; String message = "";
String fullLocation = String fullLocation = "";
await DeviceUtils.instance.getFullDeviceLocation(context, item.areaPath!); if (device.areaPath != "") {
fullLocation = await DeviceUtils.instance
.getFullDeviceLocation(context, device.areaPath!);
}
String time = ""; String time = "";
for (var sensor in item.status!.sensors!) { for (var sensor in device.status!.sensors!) {
if (sensor.name! == "11") { if (sensor.name! == "11") {
DateTime dateTime = DateTime dateTime =
DateTime.fromMillisecondsSinceEpoch((sensor.time!) * 1000); DateTime.fromMillisecondsSinceEpoch((sensor.time!) * 1000);
time = DateFormat('yyyy-MM-dd HH:mm:ss').format(dateTime); time = DateFormat('yyyy-MM-dd HH:mm:ss').format(dateTime);
} }
} }
if (item.state! == 3) { if (device.state! == 3) {
backgroundColor = Colors.grey; backgroundColor = Colors.grey;
textColor = Colors.black; textColor = Colors.black;
message = appLocalization(context).in_progress_message; message = appLocalization(context).in_progress_message;
} else if (item.state! == 2) { } else if (device.state! == 2) {
backgroundColor = const Color.fromARGB(255, 6, 138, 72); backgroundColor = const Color.fromARGB(255, 6, 138, 72);
textColor = const Color.fromARGB(255, 255, 255, 255); textColor = const Color.fromARGB(255, 255, 255, 255);
message = appLocalization(context).gf_in_firefighting_message; message = appLocalization(context).gf_in_firefighting_message;
} else if (item.state! == 1) { } else if (device.state! == 1) {
backgroundColor = const Color.fromARGB(255, 250, 63, 63); backgroundColor = const Color.fromARGB(255, 250, 63, 63);
textColor = Colors.white; textColor = Colors.white;
message = appLocalization(context).button_fake_fire_message; message = appLocalization(context).button_fake_fire_message;
@@ -44,204 +48,224 @@ Future<Widget> warningCard(
textColor = Colors.white; textColor = Colors.white;
message = appLocalization(context).disconnect_message_uppercase; message = appLocalization(context).disconnect_message_uppercase;
} }
return Card( return badges.Badge(
// color: Color.fromARGB(255, 208, 212, 217), badgeAnimation: const badges.BadgeAnimation.fade(),
child: Padding( position: badges.BadgePosition.bottomStart(bottom: 15, start: 10),
padding: context.paddingLow, badgeContent: device.isOwner!
child: Column( ? null
mainAxisAlignment: MainAxisAlignment.start, : Text(
crossAxisAlignment: CrossAxisAlignment.start, appLocalization(context).interfamily_page_name,
mainAxisSize: MainAxisSize.min, style: TextStyle(
children: [ fontSize: 20,
Row( color: Theme.of(context).colorScheme.onSurface,
mainAxisAlignment: MainAxisAlignment.spaceBetween, fontWeight: FontWeight.bold),
children: [ ),
Column( badgeStyle: badges.BadgeStyle(
mainAxisAlignment: MainAxisAlignment.start, shape: badges.BadgeShape.square,
crossAxisAlignment: CrossAxisAlignment.start, borderRadius: BorderRadius.circular(10),
children: [ borderSide: const BorderSide(color: Colors.white, width: 2),
SizedBox( badgeColor: Theme.of(context).colorScheme.surfaceDim,
child: Text( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2),
appLocalization(context).smoke_detecting_message, ),
style: const TextStyle( child: Card(
letterSpacing: 1, child: Padding(
fontWeight: FontWeight.bold, padding: context.paddingLow,
color: Colors.red, child: Column(
fontSize: 18, mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
child: Text(
appLocalization(context).smoke_detecting_message,
style: const TextStyle(
letterSpacing: 1,
fontWeight: FontWeight.bold,
color: Colors.red,
fontSize: 18,
),
),
),
SizedBox(height: context.lowValue),
SizedBox(
child: Text(
"${appLocalization(context).device_title}: ${device.isOwner! ? device.name : device.alias}",
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18,
),
maxLines: 2,
overflow: TextOverflow.ellipsis,
softWrap: true,
textAlign: TextAlign.start,
),
),
],
),
SizedBox(
height: context.dynamicWidth(0.15),
width: context.dynamicWidth(0.15),
child: Image.asset(
ImageConstants.instance.getImage("fire_warning")),
)
],
),
SizedBox(height: context.lowValue),
Row(
children: [
IconConstants.instance
.getMaterialIcon(Icons.location_on_outlined),
SizedBox(
width: context.lowValue,
),
Expanded(
child: Text(
fullLocation,
style: const TextStyle(fontSize: 15),
maxLines: 2,
overflow: TextOverflow.ellipsis,
softWrap: true,
textAlign: TextAlign.start,
),
),
],
),
SizedBox(height: context.lowValue),
Row(
children: [
IconConstants.instance.getMaterialIcon(Icons.schedule),
SizedBox(
width: context.lowValue,
),
Expanded(
child: Text(
time,
style: const TextStyle(fontSize: 15),
maxLines: 2,
overflow: TextOverflow.ellipsis,
softWrap: true,
textAlign: TextAlign.start,
),
),
],
),
SizedBox(
height: context.lowValue,
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
IconButton.outlined(
onPressed: () async => {},
// displayListOfFireStationPhoneNumbers(testDevice),
icon: IconConstants.instance.getMaterialIcon(Icons.call),
iconSize: 25,
style: ButtonStyle(
backgroundColor:
WidgetStateProperty.all<Color>(Colors.blue[300]!),
),
),
const SizedBox(width: 10),
IconButton.outlined(
onPressed: () async {
String markerLabel = "Destination";
MapsLauncher.launchCoordinates(
double.parse(device.settings!.latitude!),
double.parse(device.settings!.longitude!),
markerLabel);
},
icon: const Icon(Icons.directions),
iconSize: 25,
style: ButtonStyle(
backgroundColor:
WidgetStateProperty.all<Color>(Colors.blue[300]!),
),
),
SizedBox(width: context.mediumValue),
Expanded(
child: Align(
alignment: Alignment.centerRight,
child: OutlinedButton(
style: ButtonStyle(
backgroundColor:
WidgetStatePropertyAll(backgroundColor)),
onPressed: () async {
if (message ==
appLocalization(context).button_fake_fire_message) {
await showDialog(
context: context,
builder: (context) => AlertDialog(
icon: const Icon(Icons.warning),
iconColor: Colors.red,
title: Text(appLocalization(context)
.confirm_fake_fire_message),
content: Text(appLocalization(context)
.confirm_fake_fire_body),
actions: [
TextButton(
onPressed: () async {
int statusCode = await apiServices
.confirmFakeFireByUser(device.thingId!);
if (statusCode == 200) {
showNoIconTopSnackBar(
context,
appLocalization(context)
.notification_confirm_fake_fire_success,
Colors.green,
Colors.white);
} else {
showNoIconTopSnackBar(
context,
appLocalization(context)
.notification_confirm_fake_fire_failed,
Colors.red,
Colors.red);
}
Navigator.of(context).pop();
},
child: Text(
appLocalization(context)
.confirm_fake_fire_sure_message,
style:
const TextStyle(color: Colors.red)),
),
TextButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text(appLocalization(context)
.cancel_button_content),
),
],
),
);
} else {
showNoIconTopSnackBar(
context,
appLocalization(context).let_PCCC_handle_message,
Colors.orange,
Colors.white);
}
},
child: Text(
message,
style: TextStyle(color: textColor),
), ),
), ),
), ),
SizedBox(height: context.lowValue),
SizedBox(
child: Text(
"${appLocalization(context).device_title}: ${item.name}",
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18,
),
maxLines: 2,
overflow: TextOverflow.ellipsis,
softWrap: true,
textAlign: TextAlign.start,
),
),
],
),
SizedBox(
height: context.dynamicWidth(0.15),
width: context.dynamicWidth(0.15),
child: Image.asset(
ImageConstants.instance.getImage("fire_warning")),
)
],
),
SizedBox(height: context.lowValue),
Row(
children: [
IconConstants.instance
.getMaterialIcon(Icons.location_on_outlined),
SizedBox(
width: context.lowValue,
),
Expanded(
child: Text(
fullLocation,
style: const TextStyle(fontSize: 15),
maxLines: 2,
overflow: TextOverflow.ellipsis,
softWrap: true,
textAlign: TextAlign.start,
), ),
), ],
], ),
), ],
SizedBox(height: context.lowValue), ),
Row(
children: [
IconConstants.instance.getMaterialIcon(Icons.schedule),
SizedBox(
width: context.lowValue,
),
Expanded(
child: Text(
time,
style: const TextStyle(fontSize: 15),
maxLines: 2,
overflow: TextOverflow.ellipsis,
softWrap: true,
textAlign: TextAlign.start,
),
),
],
),
SizedBox(
height: context.lowValue,
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
IconButton.outlined(
onPressed: () async => {},
// displayListOfFireStationPhoneNumbers(testDevice),
icon: IconConstants.instance.getMaterialIcon(Icons.call),
iconSize: 25,
style: ButtonStyle(
backgroundColor:
WidgetStateProperty.all<Color>(Colors.blue[300]!),
),
),
const SizedBox(width: 10),
IconButton.outlined(
onPressed: () async {
String markerLabel = "Destination";
MapsLauncher.launchCoordinates(
double.parse(item.settings!.latitude!),
double.parse(item.settings!.longitude!),
markerLabel);
},
icon: const Icon(Icons.directions),
iconSize: 25,
style: ButtonStyle(
backgroundColor:
WidgetStateProperty.all<Color>(Colors.blue[300]!),
),
),
SizedBox(width: context.mediumValue),
Expanded(
child: Align(
alignment: Alignment.centerRight,
child: OutlinedButton(
style: ButtonStyle(
backgroundColor:
WidgetStatePropertyAll(backgroundColor)),
onPressed: () async {
if (message ==
appLocalization(context).button_fake_fire_message) {
await showDialog(
context: context,
builder: (context) => AlertDialog(
icon: const Icon(Icons.warning),
iconColor: Colors.red,
title: Text(appLocalization(context)
.confirm_fake_fire_message),
content: Text(appLocalization(context)
.confirm_fake_fire_body),
actions: [
TextButton(
onPressed: () async {
int statusCode = await apiServices
.confirmFakeFireByUser(item.thingId!);
if (statusCode == 200) {
showNoIconTopSnackBar(
context,
appLocalization(context)
.notification_confirm_fake_fire_success,
Colors.green,
Colors.white);
} else {
showNoIconTopSnackBar(
context,
appLocalization(context)
.notification_confirm_fake_fire_failed,
Colors.red,
Colors.red);
}
Navigator.of(context).pop();
},
child: Text(
appLocalization(context)
.confirm_fake_fire_sure_message,
style: const TextStyle(color: Colors.red)),
),
TextButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text(appLocalization(context)
.cancel_button_content),
),
],
),
);
} else {
showNoIconTopSnackBar(
context,
appLocalization(context).let_PCCC_handle_message,
Colors.orange,
Colors.white);
}
},
child: Text(
message,
style: TextStyle(color: textColor),
),
),
),
),
],
),
],
), ),
), ),
); );

View File

@@ -329,4 +329,5 @@ class DeviceUtils {
return Colors.red; return Colors.red;
} }
} }
} }