Fix bugs in app
This commit is contained in:
@@ -89,7 +89,7 @@ class DevicesManagerBloc extends BlocBase {
|
|||||||
|
|
||||||
if (state != -2) {
|
if (state != -2) {
|
||||||
body =
|
body =
|
||||||
await apiServices.getOwnerDevieByState({"state": state.toString()});
|
await apiServices.getOwnerDeviceByState({"state": state.toString()});
|
||||||
} else {
|
} else {
|
||||||
body = await apiServices.getOwnerDevices();
|
body = await apiServices.getOwnerDevices();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,79 +5,22 @@ import '../feature/home/device_alias_model.dart';
|
|||||||
import '../product/base/bloc/base_bloc.dart';
|
import '../product/base/bloc/base_bloc.dart';
|
||||||
|
|
||||||
class HomeBloc extends BlocBase {
|
class HomeBloc extends BlocBase {
|
||||||
|
|
||||||
final allDevicesAlias = StreamController<List<DeviceWithAlias>>.broadcast();
|
|
||||||
StreamSink<List<DeviceWithAlias>> get sinkAllDevicesAlias =>
|
|
||||||
allDevicesAlias.sink;
|
|
||||||
Stream<List<DeviceWithAlias>> get streamAllDevicesAlias =>
|
|
||||||
allDevicesAlias.stream;
|
|
||||||
|
|
||||||
final onlineDevicesAlias =
|
final allDevicesAliasMap = StreamController<Map<String,List<DeviceWithAlias>>>.broadcast();
|
||||||
StreamController<List<DeviceWithAlias>>.broadcast();
|
StreamSink<Map<String,List<DeviceWithAlias>>> get sinkAllDevicesAliasMap =>
|
||||||
StreamSink<List<DeviceWithAlias>> get sinkOnlineDevicesAlias =>
|
allDevicesAliasMap.sink;
|
||||||
onlineDevicesAlias.sink;
|
Stream<Map<String,List<DeviceWithAlias>>> get streamAllDevicesAliasMap =>
|
||||||
Stream<List<DeviceWithAlias>> get streamOnlineDevicesAlias =>
|
allDevicesAliasMap.stream;
|
||||||
onlineDevicesAlias.stream;
|
|
||||||
|
|
||||||
final offlineDevicesAlias =
|
final allDevicesAliasJoinedMap = StreamController<Map<String,List<DeviceWithAlias>>>.broadcast();
|
||||||
StreamController<List<DeviceWithAlias>>.broadcast();
|
StreamSink<Map<String,List<DeviceWithAlias>>> get sinkAllDevicesAliasJoinedMap =>
|
||||||
StreamSink<List<DeviceWithAlias>> get sinkOfflineDevicesAlias =>
|
allDevicesAliasJoinedMap.sink;
|
||||||
offlineDevicesAlias.sink;
|
Stream<Map<String,List<DeviceWithAlias>>> get streamAllDevicesAliasJoinedMap =>
|
||||||
Stream<List<DeviceWithAlias>> get streamOfflineDevicesAlias =>
|
allDevicesAliasJoinedMap.stream;
|
||||||
offlineDevicesAlias.stream;
|
|
||||||
|
|
||||||
final warningDevicesAlias =
|
final countNotification = StreamController<int>.broadcast();
|
||||||
StreamController<List<DeviceWithAlias>>.broadcast();
|
StreamSink<int> get sinkCountNotification => countNotification.sink;
|
||||||
StreamSink<List<DeviceWithAlias>> get sinkWarningDevicesAlias =>
|
Stream<int> get streamCountNotification => countNotification.stream;
|
||||||
warningDevicesAlias.sink;
|
|
||||||
Stream<List<DeviceWithAlias>> get streamWarningDevicesAlias =>
|
|
||||||
warningDevicesAlias.stream;
|
|
||||||
|
|
||||||
final notUseDevicesAlias =
|
|
||||||
StreamController<List<DeviceWithAlias>>.broadcast();
|
|
||||||
StreamSink<List<DeviceWithAlias>> get sinkNotUseDevicesAlias =>
|
|
||||||
notUseDevicesAlias.sink;
|
|
||||||
Stream<List<DeviceWithAlias>> get streamNotUseDevicesAlias =>
|
|
||||||
notUseDevicesAlias.stream;
|
|
||||||
|
|
||||||
final allDevicesAliasJoined =
|
|
||||||
StreamController<List<DeviceWithAlias>>.broadcast();
|
|
||||||
StreamSink<List<DeviceWithAlias>> get sinkAllDevicesAliasJoined =>
|
|
||||||
allDevicesAliasJoined.sink;
|
|
||||||
Stream<List<DeviceWithAlias>> get streamAllDevicesAliasJoined =>
|
|
||||||
allDevicesAliasJoined.stream;
|
|
||||||
|
|
||||||
final onlineDevicesAliasJoined =
|
|
||||||
StreamController<List<DeviceWithAlias>>.broadcast();
|
|
||||||
StreamSink<List<DeviceWithAlias>> get sinkOnlineDevicesAliasJoined =>
|
|
||||||
onlineDevicesAliasJoined.sink;
|
|
||||||
Stream<List<DeviceWithAlias>> get streamOnlineDevicesAliasJoined =>
|
|
||||||
onlineDevicesAliasJoined.stream;
|
|
||||||
|
|
||||||
final offlineDevicesAliasJoined =
|
|
||||||
StreamController<List<DeviceWithAlias>>.broadcast();
|
|
||||||
StreamSink<List<DeviceWithAlias>> get sinkOfflineDevicesAliasJoined =>
|
|
||||||
offlineDevicesAliasJoined.sink;
|
|
||||||
Stream<List<DeviceWithAlias>> get streamOfflineDevicesAliasJoined =>
|
|
||||||
offlineDevicesAliasJoined.stream;
|
|
||||||
|
|
||||||
final warningDevicesAliasJoined =
|
|
||||||
StreamController<List<DeviceWithAlias>>.broadcast();
|
|
||||||
StreamSink<List<DeviceWithAlias>> get sinkWarningDevicesAliasJoined =>
|
|
||||||
warningDevicesAliasJoined.sink;
|
|
||||||
Stream<List<DeviceWithAlias>> get streamWarningDevicesAliasJoined =>
|
|
||||||
warningDevicesAliasJoined.stream;
|
|
||||||
|
|
||||||
final notUseDevicesAliasJoined =
|
|
||||||
StreamController<List<DeviceWithAlias>>.broadcast();
|
|
||||||
StreamSink<List<DeviceWithAlias>> get sinkNotUseDevicesAliasJoined =>
|
|
||||||
notUseDevicesAliasJoined.sink;
|
|
||||||
Stream<List<DeviceWithAlias>> get streamNotUseDevicesAliasJoined =>
|
|
||||||
notUseDevicesAliasJoined.stream;
|
|
||||||
|
|
||||||
final countNotitication = StreamController<int>.broadcast();
|
|
||||||
StreamSink<int> get sinkCountNotitication => countNotitication.sink;
|
|
||||||
Stream<int> get streamCountNotitication => countNotitication.stream;
|
|
||||||
|
|
||||||
final ownerDevicesStatus =
|
final ownerDevicesStatus =
|
||||||
StreamController<Map<String, List<DeviceWithAlias>>>.broadcast();
|
StreamController<Map<String, List<DeviceWithAlias>>>.broadcast();
|
||||||
@@ -86,7 +29,6 @@ class HomeBloc extends BlocBase {
|
|||||||
Stream<Map<String, List<DeviceWithAlias>>> get streamOwnerDevicesStatus =>
|
Stream<Map<String, List<DeviceWithAlias>>> get streamOwnerDevicesStatus =>
|
||||||
ownerDevicesStatus.stream;
|
ownerDevicesStatus.stream;
|
||||||
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {}
|
void dispose() {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import '../../../../product/constant/enums/local_keys_enums.dart';
|
|||||||
import '../../../../product/services/api_services.dart';
|
import '../../../../product/services/api_services.dart';
|
||||||
import '../../../../product/shared/shared_snack_bar.dart';
|
import '../../../../product/shared/shared_snack_bar.dart';
|
||||||
import '../../../../product/constant/icon/icon_constants.dart';
|
import '../../../../product/constant/icon/icon_constants.dart';
|
||||||
import '../../../../product/extention/context_extention.dart';
|
import '../../../../product/extension/context_extension.dart';
|
||||||
import '../../../../product/constant/image/image_constants.dart';
|
import '../../../../product/constant/image/image_constants.dart';
|
||||||
import '../../../../product/services/language_services.dart';
|
import '../../../../product/services/language_services.dart';
|
||||||
import '../../../../bloc/login_bloc.dart';
|
import '../../../../bloc/login_bloc.dart';
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import '../../product/extention/context_extention.dart';
|
import '../../product/extension/context_extension.dart';
|
||||||
import '../../product/services/language_services.dart';
|
import '../../product/services/language_services.dart';
|
||||||
import '../../bloc/bell_bloc.dart';
|
import '../../bloc/bell_bloc.dart';
|
||||||
import '../../product/base/bloc/base_bloc.dart';
|
import '../../product/base/bloc/base_bloc.dart';
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import 'widgets/tag_widget.dart';
|
|||||||
import '../devices/device_model.dart';
|
import '../devices/device_model.dart';
|
||||||
import '../../bloc/device_logs_bloc.dart';
|
import '../../bloc/device_logs_bloc.dart';
|
||||||
import '../../product/constant/icon/icon_constants.dart';
|
import '../../product/constant/icon/icon_constants.dart';
|
||||||
import '../../product/extention/context_extention.dart';
|
import '../../product/extension/context_extension.dart';
|
||||||
import '../../product/services/language_services.dart';
|
import '../../product/services/language_services.dart';
|
||||||
import '../../product/shared/shared_snack_bar.dart';
|
import '../../product/shared/shared_snack_bar.dart';
|
||||||
import '../../product/utils/date_time_utils.dart';
|
import '../../product/utils/date_time_utils.dart';
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import '../../product/constant/enums/role_enums.dart';
|
|||||||
import '../../product/services/api_services.dart';
|
import '../../product/services/api_services.dart';
|
||||||
import '../../product/utils/qr_utils.dart';
|
import '../../product/utils/qr_utils.dart';
|
||||||
import '../../product/constant/icon/icon_constants.dart';
|
import '../../product/constant/icon/icon_constants.dart';
|
||||||
import '../../product/extention/context_extention.dart';
|
import '../../product/extension/context_extension.dart';
|
||||||
import '../../product/services/language_services.dart';
|
import '../../product/services/language_services.dart';
|
||||||
|
|
||||||
addNewDevice(BuildContext context, String role) async {
|
addNewDevice(BuildContext context, String role) async {
|
||||||
|
|||||||
@@ -2,14 +2,14 @@ import 'dart:async';
|
|||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:google_maps_flutter/google_maps_flutter.dart';
|
import 'package:google_maps_flutter/google_maps_flutter.dart';
|
||||||
import 'package:sfm_app/feature/device_log/device_logs_model.dart';
|
|
||||||
import 'package:sfm_app/product/constant/image/image_constants.dart';
|
|
||||||
import 'package:sfm_app/product/shared/shared_line_chart.dart';
|
|
||||||
import 'package:simple_ripple_animation/simple_ripple_animation.dart';
|
import 'package:simple_ripple_animation/simple_ripple_animation.dart';
|
||||||
|
import 'package:sfm_app/feature/device_log/device_logs_model.dart';
|
||||||
|
import '../../../product/constant/image/image_constants.dart';
|
||||||
|
import '../../../product/shared/shared_line_chart.dart';
|
||||||
import '../../../product/shared/shared_curve.dart';
|
import '../../../product/shared/shared_curve.dart';
|
||||||
import '../device_model.dart';
|
import '../device_model.dart';
|
||||||
import '../../../product/base/bloc/base_bloc.dart';
|
import '../../../product/base/bloc/base_bloc.dart';
|
||||||
import '../../../product/extention/context_extention.dart';
|
import '../../../product/extension/context_extension.dart';
|
||||||
import '../../../product/services/language_services.dart';
|
import '../../../product/services/language_services.dart';
|
||||||
import '../../../product/utils/device_utils.dart';
|
import '../../../product/utils/device_utils.dart';
|
||||||
|
|
||||||
@@ -18,7 +18,9 @@ import '../../../bloc/device_detail_bloc.dart';
|
|||||||
|
|
||||||
class DetailDeviceScreen extends StatefulWidget {
|
class DetailDeviceScreen extends StatefulWidget {
|
||||||
const DetailDeviceScreen({super.key, required this.thingID});
|
const DetailDeviceScreen({super.key, required this.thingID});
|
||||||
|
|
||||||
final String thingID;
|
final String thingID;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<DetailDeviceScreen> createState() => _DetailDeviceScreenState();
|
State<DetailDeviceScreen> createState() => _DetailDeviceScreenState();
|
||||||
}
|
}
|
||||||
@@ -44,18 +46,29 @@ class _DetailDeviceScreenState extends State<DetailDeviceScreen> {
|
|||||||
|
|
||||||
late DetailDeviceBloc detailDeviceBloc;
|
late DetailDeviceBloc detailDeviceBloc;
|
||||||
Completer<GoogleMapController> controller = Completer();
|
Completer<GoogleMapController> controller = Completer();
|
||||||
CameraPosition initialCamera = const CameraPosition(
|
CameraPosition initialCamera =
|
||||||
target: LatLng(20.966048511844402, 105.74977710843086), zoom: 15);
|
const CameraPosition(target: LatLng(20.966048511844402, 105.74977710843086), zoom: 15);
|
||||||
|
Timer? getDeviceDetailTimer;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
detailDeviceBloc = BlocProvider.of(context);
|
detailDeviceBloc = BlocProvider.of(context);
|
||||||
|
const duration = Duration(seconds: 10);
|
||||||
|
getDeviceDetailTimer = Timer.periodic(
|
||||||
|
duration,
|
||||||
|
(Timer t) => detailDeviceBloc.getDeviceDetail(
|
||||||
|
context,
|
||||||
|
widget.thingID,
|
||||||
|
controller,
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
TextStyle textstyle = const TextStyle(
|
@override
|
||||||
fontSize: 25,
|
void dispose() {
|
||||||
fontWeight: FontWeight.w600,
|
getDeviceDetailTimer?.cancel();
|
||||||
);
|
}
|
||||||
|
|
||||||
BoxDecoration boxDecoration = BoxDecoration(
|
BoxDecoration boxDecoration = BoxDecoration(
|
||||||
borderRadius: BorderRadius.circular(15),
|
borderRadius: BorderRadius.circular(15),
|
||||||
@@ -105,8 +118,7 @@ class _DetailDeviceScreenState extends State<DetailDeviceScreen> {
|
|||||||
children: [
|
children: [
|
||||||
Positioned.fill(
|
Positioned.fill(
|
||||||
child: Image.asset(
|
child: Image.asset(
|
||||||
ImageConstants.instance
|
ImageConstants.instance.getImage('smoke-detector'),
|
||||||
.getImage('smoke-detector'),
|
|
||||||
fit: BoxFit.fill,
|
fit: BoxFit.fill,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -116,11 +128,9 @@ class _DetailDeviceScreenState extends State<DetailDeviceScreen> {
|
|||||||
width: 400,
|
width: 400,
|
||||||
// color: Colors.blueAccent,
|
// color: Colors.blueAccent,
|
||||||
alignment: Alignment.centerRight,
|
alignment: Alignment.centerRight,
|
||||||
margin: const EdgeInsets.fromLTRB(
|
margin: const EdgeInsets.fromLTRB(0, 0, 0, 50),
|
||||||
0, 0, 0, 50),
|
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisAlignment:
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
children: [
|
||||||
const SizedBox(),
|
const SizedBox(),
|
||||||
Text(
|
Text(
|
||||||
@@ -146,14 +156,13 @@ class _DetailDeviceScreenState extends State<DetailDeviceScreen> {
|
|||||||
height: context.dynamicHeight(0.08),
|
height: context.dynamicHeight(0.08),
|
||||||
width: context.dynamicWidth(0.5),
|
width: context.dynamicWidth(0.5),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: DeviceUtils.instance.getTableRowColor(
|
color: DeviceUtils.instance
|
||||||
deviceSnapshot.data?.state ?? 3),
|
.getTableRowColor(deviceSnapshot.data?.state ?? 3),
|
||||||
borderRadius: BorderRadius.circular(50),
|
borderRadius: BorderRadius.circular(50),
|
||||||
),
|
),
|
||||||
alignment: Alignment.bottomCenter,
|
alignment: Alignment.bottomCenter,
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisAlignment:
|
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||||
MainAxisAlignment.spaceAround,
|
|
||||||
children: [
|
children: [
|
||||||
SizedBox(
|
SizedBox(
|
||||||
height: context.mediumValue,
|
height: context.mediumValue,
|
||||||
@@ -161,18 +170,17 @@ class _DetailDeviceScreenState extends State<DetailDeviceScreen> {
|
|||||||
child: deviceSnapshot.data?.state == 1
|
child: deviceSnapshot.data?.state == 1
|
||||||
? RippleAnimation(
|
? RippleAnimation(
|
||||||
color: Colors.red,
|
color: Colors.red,
|
||||||
delay: context
|
delay: context.dynamicMilliSecondDuration(
|
||||||
.dynamicMilliSecondDuration(
|
|
||||||
800,
|
800,
|
||||||
),
|
),
|
||||||
repeat: true,
|
repeat: true,
|
||||||
minRadius: 10,
|
minRadius: 10,
|
||||||
ripplesCount: 5,
|
ripplesCount: 5,
|
||||||
duration: context
|
duration: context.dynamicMilliSecondDuration(
|
||||||
.dynamicMilliSecondDuration(
|
|
||||||
1800,
|
1800,
|
||||||
),
|
),
|
||||||
child: CircleAvatar(
|
child: CircleAvatar(
|
||||||
|
backgroundColor: Colors.transparent,
|
||||||
minRadius: context.mediumValue,
|
minRadius: context.mediumValue,
|
||||||
maxRadius: context.mediumValue,
|
maxRadius: context.mediumValue,
|
||||||
backgroundImage: AssetImage(
|
backgroundImage: AssetImage(
|
||||||
@@ -183,9 +191,8 @@ class _DetailDeviceScreenState extends State<DetailDeviceScreen> {
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
: CircleAvatar(
|
: CircleAvatar(
|
||||||
backgroundColor: DeviceUtils
|
backgroundColor:
|
||||||
.instance
|
DeviceUtils.instance.getTableRowColor(
|
||||||
.getTableRowColor(
|
|
||||||
deviceSnapshot.data?.state ?? 3,
|
deviceSnapshot.data?.state ?? 3,
|
||||||
),
|
),
|
||||||
minRadius: context.mediumValue,
|
minRadius: context.mediumValue,
|
||||||
@@ -230,12 +237,10 @@ class _DetailDeviceScreenState extends State<DetailDeviceScreen> {
|
|||||||
child: Padding(
|
child: Padding(
|
||||||
padding: context.paddingLow,
|
padding: context.paddingLow,
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisAlignment:
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
children: [
|
||||||
Row(
|
Row(
|
||||||
mainAxisAlignment:
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
appLocalization(context)
|
appLocalization(context)
|
||||||
@@ -254,8 +259,7 @@ class _DetailDeviceScreenState extends State<DetailDeviceScreen> {
|
|||||||
sensorSnapshot.data!['sensorCsq'],
|
sensorSnapshot.data!['sensorCsq'],
|
||||||
),
|
),
|
||||||
size: 30,
|
size: 30,
|
||||||
color: DeviceUtils.instance
|
color: DeviceUtils.instance.getSignalIconColor(
|
||||||
.getSignalIconColor(
|
|
||||||
context,
|
context,
|
||||||
sensorSnapshot.data!['sensorCsq'],
|
sensorSnapshot.data!['sensorCsq'],
|
||||||
),
|
),
|
||||||
@@ -264,10 +268,8 @@ class _DetailDeviceScreenState extends State<DetailDeviceScreen> {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
Row(
|
Row(
|
||||||
mainAxisAlignment:
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
MainAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
crossAxisAlignment:
|
|
||||||
CrossAxisAlignment.center,
|
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Container(
|
Container(
|
||||||
height: context.dynamicHeight(0.09),
|
height: context.dynamicHeight(0.09),
|
||||||
@@ -275,11 +277,9 @@ class _DetailDeviceScreenState extends State<DetailDeviceScreen> {
|
|||||||
child: Text(
|
child: Text(
|
||||||
sensorSnapshot.data!['sensorCsq'],
|
sensorSnapshot.data!['sensorCsq'],
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: DeviceUtils.instance
|
color: DeviceUtils.instance.getSignalIconColor(
|
||||||
.getSignalIconColor(
|
|
||||||
context,
|
context,
|
||||||
sensorSnapshot
|
sensorSnapshot.data!['sensorCsq'],
|
||||||
.data!['sensorCsq'],
|
|
||||||
),
|
),
|
||||||
fontSize: 40,
|
fontSize: 40,
|
||||||
fontWeight: FontWeight.w900,
|
fontWeight: FontWeight.w900,
|
||||||
@@ -299,12 +299,10 @@ class _DetailDeviceScreenState extends State<DetailDeviceScreen> {
|
|||||||
child: Padding(
|
child: Padding(
|
||||||
padding: context.paddingLow,
|
padding: context.paddingLow,
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisAlignment:
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
children: [
|
||||||
Row(
|
Row(
|
||||||
mainAxisAlignment:
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
appLocalization(context)
|
appLocalization(context)
|
||||||
@@ -318,18 +316,14 @@ class _DetailDeviceScreenState extends State<DetailDeviceScreen> {
|
|||||||
height: context.dynamicWidth(0.12),
|
height: context.dynamicWidth(0.12),
|
||||||
width: context.dynamicWidth(0.12),
|
width: context.dynamicWidth(0.12),
|
||||||
child: Image.asset(
|
child: Image.asset(
|
||||||
DeviceUtils.instance
|
DeviceUtils.instance.getDeviceBatteryImg(
|
||||||
.getDeviceBatteryImg(
|
|
||||||
int.parse(
|
int.parse(
|
||||||
sensorSnapshot
|
sensorSnapshot.data!['sensorBattery'],
|
||||||
.data!['sensorBattery'],
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
color: DeviceUtils.instance
|
color: DeviceUtils.instance.getDeviceBatteryColor(
|
||||||
.getDeviceBatteryColor(
|
|
||||||
int.parse(
|
int.parse(
|
||||||
sensorSnapshot
|
sensorSnapshot.data!['sensorBattery'],
|
||||||
.data!['sensorBattery'],
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -337,23 +331,18 @@ class _DetailDeviceScreenState extends State<DetailDeviceScreen> {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
Row(
|
Row(
|
||||||
mainAxisAlignment:
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
MainAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
crossAxisAlignment:
|
|
||||||
CrossAxisAlignment.center,
|
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Container(
|
Container(
|
||||||
height: context.dynamicHeight(0.09),
|
height: context.dynamicHeight(0.09),
|
||||||
alignment: Alignment.centerLeft,
|
alignment: Alignment.centerLeft,
|
||||||
child: Text(
|
child: Text(
|
||||||
sensorSnapshot
|
sensorSnapshot.data!['sensorBattery'],
|
||||||
.data!['sensorBattery'],
|
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: DeviceUtils.instance
|
color: DeviceUtils.instance.getDeviceBatteryColor(
|
||||||
.getDeviceBatteryColor(
|
|
||||||
int.parse(
|
int.parse(
|
||||||
sensorSnapshot
|
sensorSnapshot.data!['sensorBattery'],
|
||||||
.data!['sensorBattery'],
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
fontSize: 50,
|
fontSize: 50,
|
||||||
@@ -371,11 +360,9 @@ class _DetailDeviceScreenState extends State<DetailDeviceScreen> {
|
|||||||
child: Text(
|
child: Text(
|
||||||
'%',
|
'%',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: DeviceUtils.instance
|
color: DeviceUtils.instance.getDeviceBatteryColor(
|
||||||
.getDeviceBatteryColor(
|
|
||||||
int.parse(
|
int.parse(
|
||||||
sensorSnapshot
|
sensorSnapshot.data!['sensorBattery'],
|
||||||
.data!['sensorBattery'],
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
fontSize: 30,
|
fontSize: 30,
|
||||||
@@ -403,8 +390,7 @@ class _DetailDeviceScreenState extends State<DetailDeviceScreen> {
|
|||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
Row(
|
Row(
|
||||||
mainAxisAlignment:
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
appLocalization(context)
|
appLocalization(context)
|
||||||
@@ -419,11 +405,9 @@ class _DetailDeviceScreenState extends State<DetailDeviceScreen> {
|
|||||||
width: context.dynamicWidth(0.12),
|
width: context.dynamicWidth(0.12),
|
||||||
child: Image.asset(
|
child: Image.asset(
|
||||||
'assets/icons/temperature.png',
|
'assets/icons/temperature.png',
|
||||||
color: DeviceUtils.instance
|
color: DeviceUtils.instance.getDeviceTempColor(
|
||||||
.getDeviceTempColor(
|
|
||||||
int.parse(
|
int.parse(
|
||||||
sensorSnapshot
|
sensorSnapshot.data!['sensorTemp'],
|
||||||
.data!['sensorTemp'],
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -439,28 +423,20 @@ class _DetailDeviceScreenState extends State<DetailDeviceScreen> {
|
|||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
height: 20,
|
height: 20,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Colors.grey
|
color: Colors.grey.withValues(alpha: 0.3),
|
||||||
.withValues(alpha: 0.3),
|
borderRadius: BorderRadius.circular(10),
|
||||||
borderRadius:
|
|
||||||
BorderRadius.circular(10),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
LayoutBuilder(
|
LayoutBuilder(
|
||||||
builder: (context, constraints) =>
|
builder: (context, constraints) => Container(
|
||||||
Container(
|
|
||||||
width: constraints.maxWidth *
|
width: constraints.maxWidth *
|
||||||
(int.parse(sensorSnapshot
|
(int.parse(sensorSnapshot.data!['sensorTemp']) / 75),
|
||||||
.data!['sensorTemp']) /
|
|
||||||
75),
|
|
||||||
height: 20,
|
height: 20,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: DeviceUtils.instance
|
color: DeviceUtils.instance.getDeviceTempColor(
|
||||||
.getDeviceTempColor(
|
int.parse(sensorSnapshot.data!['sensorTemp']),
|
||||||
int.parse(sensorSnapshot
|
|
||||||
.data!['sensorTemp']),
|
|
||||||
),
|
),
|
||||||
borderRadius:
|
borderRadius: BorderRadius.circular(10),
|
||||||
BorderRadius.circular(10),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
@@ -470,17 +446,14 @@ class _DetailDeviceScreenState extends State<DetailDeviceScreen> {
|
|||||||
height: 5,
|
height: 5,
|
||||||
),
|
),
|
||||||
Row(
|
Row(
|
||||||
mainAxisAlignment:
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
"${sensorSnapshot.data!['sensorTemp']} °C",
|
"${sensorSnapshot.data!['sensorTemp']} °C",
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: DeviceUtils.instance
|
color: DeviceUtils.instance.getDeviceTempColor(
|
||||||
.getDeviceTempColor(
|
|
||||||
int.parse(
|
int.parse(
|
||||||
sensorSnapshot
|
sensorSnapshot.data!['sensorTemp'],
|
||||||
.data!['sensorTemp'],
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
fontSize: 30,
|
fontSize: 30,
|
||||||
@@ -507,8 +480,7 @@ class _DetailDeviceScreenState extends State<DetailDeviceScreen> {
|
|||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
appLocalization(context)
|
appLocalization(context).paginated_data_table_column_devicePower,
|
||||||
.paginated_data_table_column_devicePower,
|
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
fontSize: 18,
|
fontSize: 18,
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
@@ -532,8 +504,7 @@ class _DetailDeviceScreenState extends State<DetailDeviceScreen> {
|
|||||||
stream: detailDeviceBloc.streamSensorTemps,
|
stream: detailDeviceBloc.streamSensorTemps,
|
||||||
builder: (context, sensorTempsSnapshot) {
|
builder: (context, sensorTempsSnapshot) {
|
||||||
if (sensorTempsSnapshot.data == null) {
|
if (sensorTempsSnapshot.data == null) {
|
||||||
detailDeviceBloc
|
detailDeviceBloc.getNearerSensorValue(widget.thingID);
|
||||||
.getNearerSensorValue(widget.thingID);
|
|
||||||
return const AspectRatio(
|
return const AspectRatio(
|
||||||
aspectRatio: 3,
|
aspectRatio: 3,
|
||||||
child: Center(
|
child: Center(
|
||||||
@@ -552,8 +523,7 @@ class _DetailDeviceScreenState extends State<DetailDeviceScreen> {
|
|||||||
child: Container(
|
child: Container(
|
||||||
margin: context.paddingLow,
|
margin: context.paddingLow,
|
||||||
child: sharedLineChart(
|
child: sharedLineChart(
|
||||||
appLocalization(context)
|
appLocalization(context).detail_device_volt_message,
|
||||||
.detail_device_volt_message,
|
|
||||||
sensorTempsSnapshot.data ?? [],
|
sensorTempsSnapshot.data ?? [],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -580,48 +550,33 @@ class _DetailDeviceScreenState extends State<DetailDeviceScreen> {
|
|||||||
Radius.circular(15),
|
Radius.circular(15),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
child: deviceSnapshot
|
child: deviceSnapshot.data!.settings!.latitude != ""
|
||||||
.data!.settings!.latitude !=
|
|
||||||
""
|
|
||||||
? StreamBuilder<String>(
|
? StreamBuilder<String>(
|
||||||
stream: detailDeviceBloc
|
stream: detailDeviceBloc.streamDeviceLocation,
|
||||||
.streamDeviceLocation,
|
|
||||||
builder: (context, locationSnapshot) {
|
builder: (context, locationSnapshot) {
|
||||||
if (locationSnapshot.data == null) {
|
if (locationSnapshot.data == null) {
|
||||||
detailDeviceBloc.findLocation(
|
detailDeviceBloc.findLocation(
|
||||||
context,
|
context, deviceSnapshot.data!.areaPath!);
|
||||||
deviceSnapshot
|
|
||||||
.data!.areaPath!);
|
|
||||||
}
|
}
|
||||||
return GoogleMap(
|
return GoogleMap(
|
||||||
initialCameraPosition:
|
initialCameraPosition: initialCamera,
|
||||||
initialCamera,
|
|
||||||
mapType: MapType.normal,
|
mapType: MapType.normal,
|
||||||
markers: {
|
markers: {
|
||||||
Marker(
|
Marker(
|
||||||
infoWindow: InfoWindow(
|
infoWindow: InfoWindow(
|
||||||
title:
|
title: locationSnapshot.data ?? "",
|
||||||
locationSnapshot.data ??
|
|
||||||
"",
|
|
||||||
),
|
),
|
||||||
markerId: MarkerId(
|
markerId: MarkerId(deviceSnapshot.data!.thingId!),
|
||||||
deviceSnapshot
|
|
||||||
.data!.thingId!),
|
|
||||||
position: LatLng(
|
position: LatLng(
|
||||||
double.parse(deviceSnapshot
|
double.parse(
|
||||||
.data!
|
deviceSnapshot.data!.settings!.latitude!),
|
||||||
.settings!
|
double.parse(
|
||||||
.latitude!),
|
deviceSnapshot.data!.settings!.longitude!),
|
||||||
double.parse(deviceSnapshot
|
|
||||||
.data!
|
|
||||||
.settings!
|
|
||||||
.longitude!),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
onMapCreated: (mapcontroller) {
|
onMapCreated: (mapcontroller) {
|
||||||
controller
|
controller.complete(mapcontroller);
|
||||||
.complete(mapcontroller);
|
|
||||||
},
|
},
|
||||||
mapToolbarEnabled: false,
|
mapToolbarEnabled: false,
|
||||||
zoomControlsEnabled: false,
|
zoomControlsEnabled: false,
|
||||||
@@ -636,8 +591,7 @@ class _DetailDeviceScreenState extends State<DetailDeviceScreen> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
appLocalization(context)
|
appLocalization(context).device_update_location,
|
||||||
.device_update_location,
|
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
fontSize: 18,
|
fontSize: 18,
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import '../device_model.dart';
|
|||||||
import '../../../bloc/device_update_bloc.dart';
|
import '../../../bloc/device_update_bloc.dart';
|
||||||
import 'map_dialog.dart';
|
import 'map_dialog.dart';
|
||||||
import '../../../product/base/bloc/base_bloc.dart';
|
import '../../../product/base/bloc/base_bloc.dart';
|
||||||
import '../../../product/extention/context_extention.dart';
|
import '../../../product/extension/context_extension.dart';
|
||||||
import '../../../product/services/api_services.dart';
|
import '../../../product/services/api_services.dart';
|
||||||
import '../../../product/services/language_services.dart';
|
import '../../../product/services/language_services.dart';
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:google_maps_flutter/google_maps_flutter.dart' ;
|
import 'package:google_maps_flutter/google_maps_flutter.dart' ;
|
||||||
import '../../../bloc/device_update_bloc.dart';
|
import '../../../bloc/device_update_bloc.dart';
|
||||||
import '../../../product/constant/app/app_constants.dart';
|
import '../../../product/constant/app/app_constants.dart';
|
||||||
import '../../../product/extention/context_extention.dart';
|
import '../../../product/extension/context_extension.dart';
|
||||||
import '../../../product/services/language_services.dart';
|
import '../../../product/services/language_services.dart';
|
||||||
import '../../../product/shared/find_location_maps/shared_map_search_location.dart';
|
import '../../../product/shared/find_location_maps/shared_map_search_location.dart';
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import '../../product/base/bloc/base_bloc.dart';
|
|||||||
import '../../product/constant/enums/app_route_enums.dart';
|
import '../../product/constant/enums/app_route_enums.dart';
|
||||||
import '../../product/constant/enums/role_enums.dart';
|
import '../../product/constant/enums/role_enums.dart';
|
||||||
import '../../product/constant/icon/icon_constants.dart';
|
import '../../product/constant/icon/icon_constants.dart';
|
||||||
import '../../product/extention/context_extention.dart';
|
import '../../product/extension/context_extension.dart';
|
||||||
import '../../product/services/api_services.dart';
|
import '../../product/services/api_services.dart';
|
||||||
import '../../product/services/language_services.dart';
|
import '../../product/services/language_services.dart';
|
||||||
import '../../product/utils/device_utils.dart';
|
import '../../product/utils/device_utils.dart';
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import '../../product/utils/device_utils.dart';
|
|||||||
import 'device_alias_model.dart';
|
import 'device_alias_model.dart';
|
||||||
import 'shared/overview_card.dart';
|
import 'shared/overview_card.dart';
|
||||||
import '../settings/device_notification_settings/device_notification_settings_model.dart';
|
import '../settings/device_notification_settings/device_notification_settings_model.dart';
|
||||||
import '../../product/extention/context_extention.dart';
|
import '../../product/extension/context_extension.dart';
|
||||||
import '../../product/services/api_services.dart';
|
import '../../product/services/api_services.dart';
|
||||||
import '../../product/services/language_services.dart';
|
import '../../product/services/language_services.dart';
|
||||||
import '../../bloc/home_bloc.dart';
|
import '../../bloc/home_bloc.dart';
|
||||||
@@ -25,18 +25,9 @@ class HomeScreen extends StatefulWidget {
|
|||||||
class _HomeScreenState extends State<HomeScreen> {
|
class _HomeScreenState extends State<HomeScreen> {
|
||||||
late HomeBloc homeBloc;
|
late HomeBloc homeBloc;
|
||||||
APIServices apiServices = APIServices();
|
APIServices apiServices = APIServices();
|
||||||
|
Map<String, List<DeviceWithAlias>> allDevicesAliasMap = {};
|
||||||
|
Map<String, List<DeviceWithAlias>> allDevicesAliasJoinedMap = {};
|
||||||
List<DeviceWithAlias> devices = [];
|
List<DeviceWithAlias> devices = [];
|
||||||
List<DeviceWithAlias> allDevicesAlias = [];
|
|
||||||
List<DeviceWithAlias> onlineDevicesAlias = [];
|
|
||||||
List<DeviceWithAlias> offlineDevicesAlias = [];
|
|
||||||
List<DeviceWithAlias> warningDevicesAlias = [];
|
|
||||||
List<DeviceWithAlias> notUseDevicesAlias = [];
|
|
||||||
|
|
||||||
List<DeviceWithAlias> allDevicesAliasJoined = [];
|
|
||||||
List<DeviceWithAlias> onlineDevicesAliasJoined = [];
|
|
||||||
List<DeviceWithAlias> offlineDevicesAliasJoined = [];
|
|
||||||
List<DeviceWithAlias> warningDevicesAliasJoined = [];
|
|
||||||
List<DeviceWithAlias> notUseDevicesAliasJoined = [];
|
|
||||||
bool isFunctionCall = false;
|
bool isFunctionCall = false;
|
||||||
Timer? getAllDevicesTimer;
|
Timer? getAllDevicesTimer;
|
||||||
int notificationCount = 0;
|
int notificationCount = 0;
|
||||||
@@ -49,8 +40,7 @@ class _HomeScreenState extends State<HomeScreen> {
|
|||||||
homeBloc = BlocProvider.of(context);
|
homeBloc = BlocProvider.of(context);
|
||||||
getOwnerAndJoinedDevices();
|
getOwnerAndJoinedDevices();
|
||||||
const duration = Duration(seconds: 10);
|
const duration = Duration(seconds: 10);
|
||||||
getAllDevicesTimer =
|
getAllDevicesTimer = Timer.periodic(duration, (Timer t) => getOwnerAndJoinedDevices());
|
||||||
Timer.periodic(duration, (Timer t) => getOwnerAndJoinedDevices());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -75,7 +65,7 @@ class _HomeScreenState extends State<HomeScreen> {
|
|||||||
),
|
),
|
||||||
SizedBox(width: context.lowValue),
|
SizedBox(width: context.lowValue),
|
||||||
StreamBuilder<int>(
|
StreamBuilder<int>(
|
||||||
stream: homeBloc.streamCountNotitication,
|
stream: homeBloc.streamCountNotification,
|
||||||
builder: (context, countSnapshot) {
|
builder: (context, countSnapshot) {
|
||||||
return Text(
|
return Text(
|
||||||
"(${countSnapshot.data ?? 0})",
|
"(${countSnapshot.data ?? 0})",
|
||||||
@@ -91,8 +81,7 @@ class _HomeScreenState extends State<HomeScreen> {
|
|||||||
child: StreamBuilder<Map<String, List<DeviceWithAlias>>>(
|
child: StreamBuilder<Map<String, List<DeviceWithAlias>>>(
|
||||||
stream: homeBloc.streamOwnerDevicesStatus,
|
stream: homeBloc.streamOwnerDevicesStatus,
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
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,
|
||||||
@@ -101,8 +90,7 @@ class _HomeScreenState extends State<HomeScreen> {
|
|||||||
...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: (context, warningCardSnapshot) {
|
builder: (context, warningCardSnapshot) {
|
||||||
if (warningCardSnapshot.hasData) {
|
if (warningCardSnapshot.hasData) {
|
||||||
return ConstrainedBox(
|
return ConstrainedBox(
|
||||||
@@ -124,11 +112,7 @@ class _HomeScreenState extends State<HomeScreen> {
|
|||||||
.map(
|
.map(
|
||||||
(batteryItem) => FutureBuilder<Widget>(
|
(batteryItem) => FutureBuilder<Widget>(
|
||||||
future: notificationCard(
|
future: notificationCard(
|
||||||
context,
|
context, "lowBattery", appLocalization(context).low_battery_message, batteryItem),
|
||||||
"lowBattery",
|
|
||||||
"Cảnh báo pin yếu",
|
|
||||||
batteryItem
|
|
||||||
),
|
|
||||||
builder: (context, warningCardSnapshot) {
|
builder: (context, warningCardSnapshot) {
|
||||||
if (warningCardSnapshot.hasData) {
|
if (warningCardSnapshot.hasData) {
|
||||||
return ConstrainedBox(
|
return ConstrainedBox(
|
||||||
@@ -160,8 +144,7 @@ class _HomeScreenState extends State<HomeScreen> {
|
|||||||
),
|
),
|
||||||
SizedBox(width: context.lowValue),
|
SizedBox(width: context.lowValue),
|
||||||
Text(
|
Text(
|
||||||
appLocalization(context)
|
appLocalization(context).notification_description,
|
||||||
.notification_description,
|
|
||||||
maxLines: 2,
|
maxLines: 2,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
softWrap: true,
|
softWrap: true,
|
||||||
@@ -176,85 +159,47 @@ class _HomeScreenState extends State<HomeScreen> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
StreamBuilder<List<DeviceWithAlias>>(
|
StreamBuilder<Map<String, List<DeviceWithAlias>>>(
|
||||||
stream: homeBloc.streamAllDevicesAlias,
|
stream: homeBloc.streamAllDevicesAliasMap,
|
||||||
initialData: allDevicesAlias,
|
builder: (context, allDevicesAliasMapSnapshot) {
|
||||||
builder: (context, allDeviceSnapshot) {
|
if (!allDevicesAliasMapSnapshot.hasData ||
|
||||||
return StreamBuilder<List<DeviceWithAlias>>(
|
allDevicesAliasMapSnapshot.data == null) {
|
||||||
stream: homeBloc.streamOnlineDevicesAlias,
|
return const Center(child: CircularProgressIndicator());
|
||||||
initialData: onlineDevicesAlias,
|
}
|
||||||
builder: (context, onlineDeviceSnapshot) {
|
final data = allDevicesAliasMapSnapshot.data!;
|
||||||
return StreamBuilder<List<DeviceWithAlias>>(
|
return OverviewCard(
|
||||||
stream: homeBloc.streamOfflineDevicesAlias,
|
isOwner: true,
|
||||||
initialData: offlineDevicesAlias,
|
total: data['all']?.length ?? 0,
|
||||||
builder: (context, deviceDashboardSnapshot) {
|
active: data['online']?.length ?? 0,
|
||||||
return StreamBuilder<List<DeviceWithAlias>>(
|
inactive: data['offline']?.length ?? 0,
|
||||||
stream: homeBloc.streamWarningDevicesAlias,
|
warning: data['warn']?.length ?? 0,
|
||||||
initialData: warningDevicesAlias,
|
unused: data['not-use']?.length ?? 0);
|
||||||
builder: (context, warningDeviceSnapshot) {
|
}),
|
||||||
return StreamBuilder<List<DeviceWithAlias>>(
|
|
||||||
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),
|
SizedBox(height: context.lowValue),
|
||||||
StreamBuilder<List<DeviceWithAlias>>(
|
StreamBuilder<Map<String, List<DeviceWithAlias>>>(
|
||||||
stream: homeBloc.streamAllDevicesAliasJoined,
|
stream: homeBloc.streamAllDevicesAliasJoinedMap,
|
||||||
initialData: allDevicesAliasJoined,
|
builder: (context, allDevicesAliasJoinedMapSnapshot) {
|
||||||
builder: (context, allDeviceSnapshot) {
|
if (!allDevicesAliasJoinedMapSnapshot.hasData ||
|
||||||
if (allDeviceSnapshot.data?.isEmpty ?? true) {
|
allDevicesAliasJoinedMapSnapshot.data == null) {
|
||||||
|
return const Center(child: CircularProgressIndicator());
|
||||||
|
}
|
||||||
|
final data = allDevicesAliasJoinedMapSnapshot.data!;
|
||||||
|
final total = data['all']?.length ?? 0;
|
||||||
|
final active = data['online']?.length ?? 0;
|
||||||
|
final inactive = data['offline']?.length ?? 0;
|
||||||
|
final warning = data['warn']?.length ?? 0;
|
||||||
|
final unused = data['not-use']?.length ?? 0;
|
||||||
|
|
||||||
|
if (total == 0 && active == 0 && inactive == 0 && warning == 0 && unused == 0) {
|
||||||
return const SizedBox.shrink();
|
return const SizedBox.shrink();
|
||||||
}
|
}
|
||||||
return StreamBuilder<List<DeviceWithAlias>>(
|
return OverviewCard(
|
||||||
stream: homeBloc.streamOnlineDevicesAliasJoined,
|
isOwner: false,
|
||||||
initialData: onlineDevicesAliasJoined,
|
total: total,
|
||||||
builder: (context, onlineDeviceSnapshot) {
|
active: active,
|
||||||
return StreamBuilder<List<DeviceWithAlias>>(
|
inactive: inactive,
|
||||||
stream: homeBloc.streamOfflineDevicesAliasJoined,
|
warning: warning,
|
||||||
initialData: offlineDevicesAliasJoined,
|
unused: unused,
|
||||||
builder: (context, deviceDashboardSnapshot) {
|
|
||||||
return StreamBuilder<List<DeviceWithAlias>>(
|
|
||||||
stream: homeBloc.streamWarningDevicesAliasJoined,
|
|
||||||
initialData: warningDevicesAliasJoined,
|
|
||||||
builder: (context, warningDeviceSnapshot) {
|
|
||||||
return StreamBuilder<List<DeviceWithAlias>>(
|
|
||||||
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,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@@ -271,8 +216,8 @@ class _HomeScreenState extends State<HomeScreen> {
|
|||||||
List<dynamic> result = data["items"];
|
List<dynamic> result = data["items"];
|
||||||
devices = DeviceWithAlias.fromJsonDynamicList(result);
|
devices = DeviceWithAlias.fromJsonDynamicList(result);
|
||||||
getOwnerDeviceState(devices);
|
getOwnerDeviceState(devices);
|
||||||
getDevicesStatusAlias(devices);
|
checkSettingDevice(devices);
|
||||||
checkSettingdevice(devices);
|
getDeviceStatusAliasMap(devices);
|
||||||
}
|
}
|
||||||
|
|
||||||
void getOwnerDeviceState(List<DeviceWithAlias> allDevices) async {
|
void getOwnerDeviceState(List<DeviceWithAlias> allDevices) async {
|
||||||
@@ -282,23 +227,21 @@ class _HomeScreenState extends State<HomeScreen> {
|
|||||||
ownerDevices.add(device);
|
ownerDevices.add(device);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ownerDevicesState.isEmpty ||
|
if (ownerDevicesState.isEmpty || ownerDevicesState.length < devices.length) {
|
||||||
ownerDevicesState.length < devices.length) {
|
|
||||||
ownerDevicesState.clear();
|
ownerDevicesState.clear();
|
||||||
ownerDevicesStatus.clear();
|
ownerDevicesStatus.clear();
|
||||||
homeBloc.sinkOwnerDevicesStatus.add(ownerDevicesStatus);
|
homeBloc.sinkOwnerDevicesStatus.add(ownerDevicesStatus);
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for (var device in ownerDevices) {
|
for (var device in ownerDevices) {
|
||||||
Map<String, dynamic> sensorMap = DeviceUtils.instance
|
Map<String, dynamic> sensorMap =
|
||||||
.getDeviceSensors(context, device.status?.sensors ?? []);
|
DeviceUtils.instance.getDeviceSensors(context, device.status?.sensors ?? []);
|
||||||
if (device.state == 1 || device.state == 3) {
|
if (device.state == 1 || device.state == 3) {
|
||||||
ownerDevicesStatus["state"] ??= [];
|
ownerDevicesStatus["state"] ??= [];
|
||||||
ownerDevicesStatus["state"]!.add(device);
|
ownerDevicesStatus["state"]!.add(device);
|
||||||
homeBloc.sinkOwnerDevicesStatus.add(ownerDevicesStatus);
|
homeBloc.sinkOwnerDevicesStatus.add(ownerDevicesStatus);
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
if (sensorMap['sensorBattery'] !=
|
if (sensorMap['sensorBattery'] != appLocalization(context).no_data_message) {
|
||||||
appLocalization(context).no_data_message) {
|
|
||||||
if (double.parse(sensorMap['sensorBattery']) <= 20) {
|
if (double.parse(sensorMap['sensorBattery']) <= 20) {
|
||||||
ownerDevicesStatus['battery'] ??= [];
|
ownerDevicesStatus['battery'] ??= [];
|
||||||
ownerDevicesStatus['battery']!.add(device);
|
ownerDevicesStatus['battery']!.add(device);
|
||||||
@@ -307,63 +250,61 @@ class _HomeScreenState extends State<HomeScreen> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
notificationCount = count;
|
notificationCount = count;
|
||||||
homeBloc.sinkCountNotitication.add(notificationCount);
|
homeBloc.sinkCountNotification.add(notificationCount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void getDevicesStatusAlias(List<DeviceWithAlias> devices) async {
|
void getDeviceStatusAliasMap(List<DeviceWithAlias> devices) {
|
||||||
clearAllDeviceStatusAlias();
|
allDevicesAliasMap.clear();
|
||||||
|
allDevicesAliasJoinedMap.clear();
|
||||||
|
|
||||||
|
for (var key in ['all', 'online', 'offline', 'warning', 'not-use']) {
|
||||||
|
allDevicesAliasMap[key] = [];
|
||||||
|
allDevicesAliasJoinedMap[key] = [];
|
||||||
|
}
|
||||||
|
|
||||||
for (DeviceWithAlias device in devices) {
|
for (DeviceWithAlias device in devices) {
|
||||||
if (device.isOwner == true) {
|
if (device.isOwner == true) {
|
||||||
allDevicesAlias.add(device);
|
allDevicesAliasMap['all']!.add(device);
|
||||||
if (device.state! == 0 || device.state! == 1) {
|
if (device.state == 0 || device.state == 1) {
|
||||||
onlineDevicesAlias.add(device);
|
allDevicesAliasMap['online']!.add(device);
|
||||||
homeBloc.sinkOnlineDevicesAlias.add(onlineDevicesAlias);
|
|
||||||
}
|
}
|
||||||
if (device.state! == -1) {
|
if (device.state == -1) {
|
||||||
offlineDevicesAlias.add(device);
|
allDevicesAliasMap['offline']!.add(device);
|
||||||
homeBloc.sinkOfflineDevicesAlias.add(offlineDevicesAlias);
|
|
||||||
}
|
}
|
||||||
if (device.state! == 1) {
|
if (device.state == 1) {
|
||||||
warningDevicesAlias.add(device);
|
allDevicesAliasMap['warning']!.add(device);
|
||||||
homeBloc.sinkWarningDevicesAlias.add(warningDevicesAlias);
|
|
||||||
}
|
}
|
||||||
if (device.state! == -2) {
|
if (device.state == -2) {
|
||||||
notUseDevicesAlias.add(device);
|
allDevicesAliasMap['not-use']!.add(device);
|
||||||
homeBloc.sinkNotUseDevicesAlias.add(notUseDevicesAlias);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
allDevicesAliasJoined.add(device);
|
allDevicesAliasJoinedMap['all']!.add(device);
|
||||||
if (device.state! == 0 || device.state! == 1) {
|
if (device.state == 0 || device.state == 1) {
|
||||||
onlineDevicesAliasJoined.add(device);
|
allDevicesAliasJoinedMap['online']!.add(device);
|
||||||
homeBloc.sinkOnlineDevicesAliasJoined.add(onlineDevicesAliasJoined);
|
|
||||||
}
|
}
|
||||||
if (device.state! == -1) {
|
if (device.state == -1) {
|
||||||
offlineDevicesAliasJoined.add(device);
|
allDevicesAliasJoinedMap['offline']!.add(device);
|
||||||
homeBloc.sinkOfflineDevicesAliasJoined.add(offlineDevicesAliasJoined);
|
|
||||||
}
|
}
|
||||||
if (device.state! == 1) {
|
if (device.state == 1) {
|
||||||
warningDevicesAliasJoined.add(device);
|
allDevicesAliasJoinedMap['warning']!.add(device);
|
||||||
homeBloc.sinkWarningDevicesAliasJoined.add(warningDevicesAliasJoined);
|
|
||||||
}
|
}
|
||||||
if (device.state! == -2) {
|
if (device.state == -2) {
|
||||||
notUseDevicesAliasJoined.add(device);
|
allDevicesAliasJoinedMap['not-use']!.add(device);
|
||||||
homeBloc.sinkNotUseDevicesAliasJoined.add(notUseDevicesAliasJoined);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// checkSettingdevice(allDevicesAliasJoined);
|
|
||||||
homeBloc.sinkAllDevicesAlias.add(allDevicesAlias);
|
homeBloc.sinkAllDevicesAliasMap.add(allDevicesAliasMap);
|
||||||
homeBloc.sinkAllDevicesAliasJoined.add(allDevicesAliasJoined);
|
homeBloc.sinkAllDevicesAliasJoinedMap.add(allDevicesAliasJoinedMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
void checkSettingdevice(List<DeviceWithAlias> devices) async {
|
void checkSettingDevice(List<DeviceWithAlias> devices) async {
|
||||||
if (isFunctionCall) {
|
if (isFunctionCall) {
|
||||||
log("Ham check setting da duoc goi");
|
log("Ham check setting da duoc goi");
|
||||||
} else {
|
} else {
|
||||||
String? response =
|
String? response = await apiServices.getAllSettingsNotificationOfDevices();
|
||||||
await apiServices.getAllSettingsNotificationOfDevices();
|
|
||||||
if (response != "") {
|
if (response != "") {
|
||||||
final data = jsonDecode(response);
|
final data = jsonDecode(response);
|
||||||
final result = data['data'];
|
final result = data['data'];
|
||||||
@@ -371,13 +312,11 @@ class _HomeScreenState extends State<HomeScreen> {
|
|||||||
List<DeviceNotificationSettings> list =
|
List<DeviceNotificationSettings> list =
|
||||||
DeviceNotificationSettings.mapFromJson(result).values.toList();
|
DeviceNotificationSettings.mapFromJson(result).values.toList();
|
||||||
// log("List: $list");
|
// log("List: $list");
|
||||||
Set<String> thingIdsInList =
|
Set<String> thingIdsInList = list.map((device) => device.thingId!).toSet();
|
||||||
list.map((device) => device.thingId!).toSet();
|
|
||||||
for (var device in devices) {
|
for (var device in devices) {
|
||||||
if (!thingIdsInList.contains(device.thingId)) {
|
if (!thingIdsInList.contains(device.thingId)) {
|
||||||
log("Device with Thing ID ${device.thingId} is not in the notification settings list.");
|
log("Device with Thing ID ${device.thingId} is not in the notification settings list.");
|
||||||
await apiServices.setupDeviceNotification(
|
await apiServices.setupDeviceNotification(device.thingId!, device.name!);
|
||||||
device.thingId!, device.name!);
|
|
||||||
} else {
|
} else {
|
||||||
log("All devices are in the notification settings list.");
|
log("All devices are in the notification settings list.");
|
||||||
}
|
}
|
||||||
@@ -388,27 +327,4 @@ class _HomeScreenState extends State<HomeScreen> {
|
|||||||
}
|
}
|
||||||
isFunctionCall = true;
|
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import 'package:intl/intl.dart';
|
|||||||
import 'package:sfm_app/feature/home/device_alias_model.dart';
|
import 'package:sfm_app/feature/home/device_alias_model.dart';
|
||||||
import '../../../product/constant/enums/app_route_enums.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/extension/context_extension.dart';
|
||||||
import '../../../product/services/language_services.dart';
|
import '../../../product/services/language_services.dart';
|
||||||
import '../../../product/utils/device_utils.dart';
|
import '../../../product/utils/device_utils.dart';
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:sfm_app/feature/home/shared/status_card.dart';
|
import 'status_card.dart';
|
||||||
import 'package:sfm_app/product/extention/context_extention.dart';
|
import '../../../product/extension/context_extension.dart';
|
||||||
import 'package:sfm_app/product/services/language_services.dart';
|
import '../../../product/services/language_services.dart';
|
||||||
|
|
||||||
class OverviewCard extends StatelessWidget {
|
class OverviewCard extends StatelessWidget {
|
||||||
final bool isOwner;
|
final bool isOwner;
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ 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';
|
||||||
import '../../../product/extention/context_extention.dart';
|
import '../../../product/extension/context_extension.dart';
|
||||||
import '../../../product/services/api_services.dart';
|
import '../../../product/services/api_services.dart';
|
||||||
import '../../../product/services/language_services.dart';
|
import '../../../product/services/language_services.dart';
|
||||||
import '../../../product/utils/device_utils.dart';
|
import '../../../product/utils/device_utils.dart';
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
// ignore_for_file: use_build_context_synchronously
|
// ignore_for_file: use_build_context_synchronously
|
||||||
|
|
||||||
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import '../../../bloc/group_detail_bloc.dart';
|
import '../../../bloc/group_detail_bloc.dart';
|
||||||
import 'group_detail_model.dart';
|
import 'group_detail_model.dart';
|
||||||
import '../../../product/base/bloc/base_bloc.dart';
|
import '../../../product/base/bloc/base_bloc.dart';
|
||||||
import '../../../product/constant/app/app_constants.dart';
|
import '../../../product/constant/app/app_constants.dart';
|
||||||
import '../../../product/constant/icon/icon_constants.dart';
|
import '../../../product/constant/icon/icon_constants.dart';
|
||||||
import '../../../product/extention/context_extention.dart';
|
import '../../../product/extension/context_extension.dart';
|
||||||
import '../../../product/services/api_services.dart';
|
import '../../../product/services/api_services.dart';
|
||||||
import '../../../product/services/language_services.dart';
|
import '../../../product/services/language_services.dart';
|
||||||
import '../../../product/utils/device_utils.dart';
|
import '../../../product/utils/device_utils.dart';
|
||||||
@@ -25,10 +27,22 @@ class DetailGroupScreen extends StatefulWidget {
|
|||||||
class _DetailGroupScreenState extends State<DetailGroupScreen> {
|
class _DetailGroupScreenState extends State<DetailGroupScreen> {
|
||||||
late DetailGroupBloc detailGroupBloc;
|
late DetailGroupBloc detailGroupBloc;
|
||||||
final scaffoldKey = GlobalKey<ScaffoldState>();
|
final scaffoldKey = GlobalKey<ScaffoldState>();
|
||||||
|
Timer? getGroupDetailTimer;
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
detailGroupBloc = BlocProvider.of(context);
|
detailGroupBloc = BlocProvider.of(context);
|
||||||
|
const duration = Duration(seconds: 10);
|
||||||
|
getGroupDetailTimer = Timer.periodic(
|
||||||
|
duration,
|
||||||
|
(Timer t) => detailGroupBloc.getGroupDetail(widget.group),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
getGroupDetailTimer?.cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
// ignore_for_file: use_build_context_synchronously
|
// ignore_for_file: use_build_context_synchronously
|
||||||
|
|
||||||
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
|
|
||||||
@@ -10,26 +12,38 @@ import '../inter_family_widget.dart';
|
|||||||
import '../../../product/base/bloc/base_bloc.dart';
|
import '../../../product/base/bloc/base_bloc.dart';
|
||||||
import '../../../product/constant/app/app_constants.dart';
|
import '../../../product/constant/app/app_constants.dart';
|
||||||
import '../../../product/constant/icon/icon_constants.dart';
|
import '../../../product/constant/icon/icon_constants.dart';
|
||||||
import '../../../product/extention/context_extention.dart';
|
import '../../../product/extension/context_extension.dart';
|
||||||
import '../../../product/services/language_services.dart';
|
import '../../../product/services/language_services.dart';
|
||||||
|
|
||||||
import 'groups_widget.dart';
|
import 'groups_widget.dart';
|
||||||
|
|
||||||
class GroupsScreen extends StatefulWidget {
|
class GroupsScreen extends StatefulWidget {
|
||||||
const GroupsScreen({super.key, required this.role});
|
const GroupsScreen({super.key, required this.role});
|
||||||
|
|
||||||
final String role;
|
final String role;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<GroupsScreen> createState() => _GroupsScreenState();
|
State<GroupsScreen> createState() => _GroupsScreenState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _GroupsScreenState extends State<GroupsScreen> {
|
class _GroupsScreenState extends State<GroupsScreen> {
|
||||||
late InterFamilyBloc interFamilyBloc;
|
late InterFamilyBloc interFamilyBloc;
|
||||||
|
Timer? getAllGroupsTimer;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
interFamilyBloc = BlocProvider.of(context);
|
interFamilyBloc = BlocProvider.of(context);
|
||||||
// interFamilyBloc.getAllGroup(widget.role);
|
const duration = Duration(seconds: 10);
|
||||||
|
getAllGroupsTimer = Timer.periodic(
|
||||||
|
duration,
|
||||||
|
(Timer t) => interFamilyBloc.getAllGroup(widget.role),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
getAllGroupsTimer?.cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -51,56 +65,44 @@ class _GroupsScreenState extends State<GroupsScreen> {
|
|||||||
return ListTile(
|
return ListTile(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
context.pushNamed(AppRoutes.GROUP_DETAIL.name,
|
context.pushNamed(AppRoutes.GROUP_DETAIL.name,
|
||||||
pathParameters: {
|
pathParameters: {"groupId": groupsSnapshot.data![index].id!},
|
||||||
"groupId": groupsSnapshot.data![index].id!
|
|
||||||
},
|
|
||||||
extra: widget.role);
|
extra: widget.role);
|
||||||
},
|
},
|
||||||
leading: IconConstants.instance
|
leading: IconConstants.instance.getMaterialIcon(Icons.diversity_2),
|
||||||
.getMaterialIcon(Icons.diversity_2),
|
|
||||||
title: Text(
|
title: Text(
|
||||||
groupsSnapshot.data![index].name ?? '',
|
groupsSnapshot.data![index].name ?? '',
|
||||||
style: const TextStyle(fontWeight: FontWeight.bold),
|
style: const TextStyle(fontWeight: FontWeight.bold),
|
||||||
),
|
),
|
||||||
subtitle:
|
subtitle: Text(groupsSnapshot.data![index].description ?? ""),
|
||||||
Text(groupsSnapshot.data![index].description ?? ""),
|
trailing: widget.role == ApplicationConstants.OWNER_GROUP
|
||||||
trailing:
|
? PopupMenuButton(
|
||||||
widget.role == ApplicationConstants.OWNER_GROUP
|
shape: const RoundedRectangleBorder(
|
||||||
? PopupMenuButton(
|
borderRadius: BorderRadius.only(
|
||||||
shape: const RoundedRectangleBorder(
|
bottomLeft: Radius.circular(8.0),
|
||||||
borderRadius: BorderRadius.only(
|
bottomRight: Radius.circular(8.0),
|
||||||
bottomLeft: Radius.circular(8.0),
|
topLeft: Radius.circular(8.0),
|
||||||
bottomRight: Radius.circular(8.0),
|
topRight: Radius.circular(8.0),
|
||||||
topLeft: Radius.circular(8.0),
|
),
|
||||||
topRight: Radius.circular(8.0),
|
),
|
||||||
),
|
itemBuilder: (ctx) => [
|
||||||
),
|
_buildPopupMenuItem(groupsSnapshot.data![index], context,
|
||||||
itemBuilder: (ctx) => [
|
appLocalization(context).share_group_title, Icons.share, 4),
|
||||||
_buildPopupMenuItem(
|
_buildPopupMenuItem(
|
||||||
groupsSnapshot.data![index],
|
groupsSnapshot.data![index],
|
||||||
context,
|
context,
|
||||||
appLocalization(context)
|
appLocalization(context).change_group_infomation_title,
|
||||||
.share_group_title,
|
Icons.settings_backup_restore,
|
||||||
Icons.share,
|
2),
|
||||||
4),
|
_buildPopupMenuItem(
|
||||||
_buildPopupMenuItem(
|
groupsSnapshot.data![index],
|
||||||
groupsSnapshot.data![index],
|
context,
|
||||||
context,
|
appLocalization(context).delete_group_title,
|
||||||
appLocalization(context)
|
Icons.delete_forever_rounded,
|
||||||
.change_group_infomation_title,
|
3),
|
||||||
Icons.settings_backup_restore,
|
],
|
||||||
2),
|
icon: const Icon(Icons.more_horiz),
|
||||||
_buildPopupMenuItem(
|
)
|
||||||
groupsSnapshot.data![index],
|
: const SizedBox.shrink(),
|
||||||
context,
|
|
||||||
appLocalization(context)
|
|
||||||
.delete_group_title,
|
|
||||||
Icons.delete_forever_rounded,
|
|
||||||
3),
|
|
||||||
],
|
|
||||||
icon: const Icon(Icons.more_horiz),
|
|
||||||
)
|
|
||||||
: const SizedBox.shrink(),
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@@ -112,16 +114,15 @@ class _GroupsScreenState extends State<GroupsScreen> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PopupMenuItem _buildPopupMenuItem(Group group, BuildContext context,
|
PopupMenuItem _buildPopupMenuItem(
|
||||||
String title, IconData iconData, int position) {
|
Group group, BuildContext context, String title, IconData iconData, int position) {
|
||||||
return PopupMenuItem(
|
return PopupMenuItem(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
if (title == appLocalization(context).share_group_title) {
|
if (title == appLocalization(context).share_group_title) {
|
||||||
Future.delayed(context.lowDuration, () {
|
Future.delayed(context.lowDuration, () {
|
||||||
shareGroup(context, group);
|
shareGroup(context, group);
|
||||||
});
|
});
|
||||||
} else if (title ==
|
} else if (title == appLocalization(context).change_group_infomation_title) {
|
||||||
appLocalization(context).change_group_infomation_title) {
|
|
||||||
Future.delayed(context.lowDuration, () {
|
Future.delayed(context.lowDuration, () {
|
||||||
createOrJoinGroupDialog(
|
createOrJoinGroupDialog(
|
||||||
context,
|
context,
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:qr_flutter/qr_flutter.dart';
|
import 'package:qr_flutter/qr_flutter.dart';
|
||||||
import '../../../bloc/inter_family_bloc.dart';
|
import '../../../bloc/inter_family_bloc.dart';
|
||||||
import '../../../product/constant/icon/icon_constants.dart';
|
import '../../../product/constant/icon/icon_constants.dart';
|
||||||
import '../../../product/extention/context_extention.dart';
|
import '../../../product/extension/context_extension.dart';
|
||||||
import '../../../product/services/language_services.dart';
|
import '../../../product/services/language_services.dart';
|
||||||
|
|
||||||
import 'groups_model.dart';
|
import 'groups_model.dart';
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import 'inter_family_widget.dart';
|
|||||||
import '../../product/base/bloc/base_bloc.dart';
|
import '../../product/base/bloc/base_bloc.dart';
|
||||||
import '../../product/constant/app/app_constants.dart';
|
import '../../product/constant/app/app_constants.dart';
|
||||||
import '../../product/constant/icon/icon_constants.dart';
|
import '../../product/constant/icon/icon_constants.dart';
|
||||||
import '../../product/extention/context_extention.dart';
|
import '../../product/extension/context_extension.dart';
|
||||||
import '../../product/services/language_services.dart';
|
import '../../product/services/language_services.dart';
|
||||||
|
|
||||||
class InterFamilyScreen extends StatefulWidget {
|
class InterFamilyScreen extends StatefulWidget {
|
||||||
|
|||||||
@@ -5,13 +5,11 @@ import 'dart:developer';
|
|||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:go_router/go_router.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 'package:badges/badges.dart' as badges;
|
||||||
import 'package:persistent_bottom_nav_bar/persistent_bottom_nav_bar.dart';
|
import 'package:persistent_bottom_nav_bar/persistent_bottom_nav_bar.dart';
|
||||||
import 'package:sfm_app/feature/sound_notification_test/notification_screen.dart';
|
import '../../product/permission/notification_permission.dart';
|
||||||
import 'package:sfm_app/product/permission/notification_permission.dart';
|
|
||||||
import '../settings/profile/profile_model.dart';
|
import '../settings/profile/profile_model.dart';
|
||||||
import '../../product/extention/context_extention.dart';
|
import '../../product/extension/context_extension.dart';
|
||||||
import '../../bloc/home_bloc.dart';
|
import '../../bloc/home_bloc.dart';
|
||||||
import '../../product/constant/app/app_constants.dart';
|
import '../../product/constant/app/app_constants.dart';
|
||||||
import '../../product/constant/enums/app_route_enums.dart';
|
import '../../product/constant/enums/app_route_enums.dart';
|
||||||
@@ -35,7 +33,6 @@ import '../../product/constant/icon/icon_constants.dart';
|
|||||||
import '../../product/constant/lang/language_constants.dart';
|
import '../../product/constant/lang/language_constants.dart';
|
||||||
import '../../product/services/language_services.dart';
|
import '../../product/services/language_services.dart';
|
||||||
import '../bell/bell_model.dart';
|
import '../bell/bell_model.dart';
|
||||||
import '../sound_notification_test/notification_bloc.dart';
|
|
||||||
|
|
||||||
class MainScreen extends StatefulWidget {
|
class MainScreen extends StatefulWidget {
|
||||||
const MainScreen({super.key});
|
const MainScreen({super.key});
|
||||||
@@ -192,6 +189,7 @@ class _MainScreenState extends State<MainScreen> with WidgetsBindingObserver {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
|
||||||
return StreamBuilder<bool>(
|
return StreamBuilder<bool>(
|
||||||
stream: mainBloc.streamThemeMode,
|
stream: mainBloc.streamThemeMode,
|
||||||
initialData: isLight,
|
initialData: isLight,
|
||||||
@@ -344,7 +342,7 @@ class _MainScreenState extends State<MainScreen> with WidgetsBindingObserver {
|
|||||||
controller: controller,
|
controller: controller,
|
||||||
screens: _buildScreens(),
|
screens: _buildScreens(),
|
||||||
items: _navBarsItems(),
|
items: _navBarsItems(),
|
||||||
handleAndroidBackButtonPress: false,
|
handleAndroidBackButtonPress: true,
|
||||||
resizeToAvoidBottomInset: true,
|
resizeToAvoidBottomInset: true,
|
||||||
stateManagement: true,
|
stateManagement: true,
|
||||||
backgroundColor:
|
backgroundColor:
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import 'package:google_maps_flutter/google_maps_flutter.dart';
|
|||||||
import 'show_direction_widget.dart';
|
import 'show_direction_widget.dart';
|
||||||
import 'show_nearest_place.dart';
|
import 'show_nearest_place.dart';
|
||||||
import '../../../product/constant/icon/icon_constants.dart';
|
import '../../../product/constant/icon/icon_constants.dart';
|
||||||
import '../../../product/extention/context_extention.dart';
|
import '../../../product/extension/context_extension.dart';
|
||||||
import '../../../bloc/map_bloc.dart';
|
import '../../../bloc/map_bloc.dart';
|
||||||
import '../../../product/services/api_services.dart';
|
import '../../../product/services/api_services.dart';
|
||||||
import '../../../product/services/language_services.dart';
|
import '../../../product/services/language_services.dart';
|
||||||
|
|||||||
@@ -3,9 +3,9 @@ import 'dart:async';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:google_maps_flutter/google_maps_flutter.dart';
|
import 'package:google_maps_flutter/google_maps_flutter.dart';
|
||||||
import 'package:maps_launcher/maps_launcher.dart';
|
import 'package:maps_launcher/maps_launcher.dart';
|
||||||
import 'package:sfm_app/product/constant/icon/icon_constants.dart';
|
import '../../../product/constant/icon/icon_constants.dart';
|
||||||
import 'package:sfm_app/product/extention/context_extention.dart';
|
import '../../../product/extension/context_extension.dart';
|
||||||
import 'package:sfm_app/product/services/language_services.dart';
|
import '../../../product/services/language_services.dart';
|
||||||
|
|
||||||
import '../../../bloc/map_bloc.dart';
|
import '../../../bloc/map_bloc.dart';
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import 'package:google_maps_flutter/google_maps_flutter.dart';
|
|||||||
import '../../../bloc/map_bloc.dart';
|
import '../../../bloc/map_bloc.dart';
|
||||||
import 'show_direction_widget.dart';
|
import 'show_direction_widget.dart';
|
||||||
import '../../../product/constant/icon/icon_constants.dart';
|
import '../../../product/constant/icon/icon_constants.dart';
|
||||||
import '../../../product/extention/context_extention.dart';
|
import '../../../product/extension/context_extension.dart';
|
||||||
import '../../../product/services/language_services.dart';
|
import '../../../product/services/language_services.dart';
|
||||||
import '../../../product/services/map_services.dart';
|
import '../../../product/services/map_services.dart';
|
||||||
import '../../../product/shared/model/near_by_search_model.dart';
|
import '../../../product/shared/model/near_by_search_model.dart';
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import '../../../product/shared/shared_snack_bar.dart';
|
|||||||
import '../../../bloc/device_notification_settings_bloc.dart';
|
import '../../../bloc/device_notification_settings_bloc.dart';
|
||||||
import 'device_notification_settings_model.dart';
|
import 'device_notification_settings_model.dart';
|
||||||
import '../../../product/base/bloc/base_bloc.dart';
|
import '../../../product/base/bloc/base_bloc.dart';
|
||||||
import '../../../product/extention/context_extention.dart';
|
import '../../../product/extension/context_extension.dart';
|
||||||
import '../../../product/services/api_services.dart';
|
import '../../../product/services/api_services.dart';
|
||||||
import '../../../product/services/language_services.dart';
|
import '../../../product/services/language_services.dart';
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import '../../../product/constant/icon/icon_constants.dart';
|
|||||||
import '../../../product/services/api_services.dart';
|
import '../../../product/services/api_services.dart';
|
||||||
import '../../../bloc/settings_bloc.dart';
|
import '../../../bloc/settings_bloc.dart';
|
||||||
import '../../../product/shared/shared_input_decoration.dart';
|
import '../../../product/shared/shared_input_decoration.dart';
|
||||||
import '../../../product/extention/context_extention.dart';
|
import '../../../product/extension/context_extension.dart';
|
||||||
import '../../../product/services/language_services.dart';
|
import '../../../product/services/language_services.dart';
|
||||||
|
|
||||||
import 'profile_model.dart';
|
import 'profile_model.dart';
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import 'package:go_router/go_router.dart';
|
|||||||
import '../../product/constant/app/app_constants.dart';
|
import '../../product/constant/app/app_constants.dart';
|
||||||
import 'profile/profile_screen.dart';
|
import 'profile/profile_screen.dart';
|
||||||
import '../../product/constant/icon/icon_constants.dart';
|
import '../../product/constant/icon/icon_constants.dart';
|
||||||
import '../../product/extention/context_extention.dart';
|
import '../../product/extension/context_extension.dart';
|
||||||
import '../../product/services/api_services.dart';
|
import '../../product/services/api_services.dart';
|
||||||
import 'profile/profile_model.dart';
|
import 'profile/profile_model.dart';
|
||||||
import '../../bloc/settings_bloc.dart';
|
import '../../bloc/settings_bloc.dart';
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
import 'package:sfm_app/product/base/bloc/base_bloc.dart';
|
|
||||||
|
|
||||||
class NotificationBloc extends BlocBase{
|
|
||||||
|
|
||||||
|
|
||||||
@override
|
|
||||||
void dispose() {
|
|
||||||
// TODO: implement dispose
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,77 +0,0 @@
|
|||||||
// ignore_for_file: avoid_print
|
|
||||||
|
|
||||||
import 'dart:math' as math;
|
|
||||||
import 'dart:developer' as dev;
|
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
|
||||||
import 'notification_bloc.dart';
|
|
||||||
import '../../product/base/bloc/base_bloc.dart';
|
|
||||||
import '../../product/services/notification_services.dart';
|
|
||||||
|
|
||||||
class NotificationScreen extends StatefulWidget {
|
|
||||||
const NotificationScreen({super.key});
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<NotificationScreen> createState() => _NotificationScreenState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _NotificationScreenState extends State<NotificationScreen> {
|
|
||||||
late NotificationBloc notificationBloc;
|
|
||||||
final notificationPlugin = FlutterLocalNotificationsPlugin();
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
initNotification();
|
|
||||||
notificationBloc = BlocProvider.of<NotificationBloc>(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Scaffold(
|
|
||||||
body: Column(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
|
||||||
children: [
|
|
||||||
TextButton(
|
|
||||||
onPressed: () async {
|
|
||||||
showNewAlarmSoundNotification("warning_alarm");
|
|
||||||
dev.log("Da vao day");
|
|
||||||
},
|
|
||||||
child: const Text("Show new Alarm Notification"),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> initNotification() async{
|
|
||||||
const isSettingAndroid = AndroidInitializationSettings('@mipmap/ic_launcher');
|
|
||||||
const initSetting = InitializationSettings(android: isSettingAndroid);
|
|
||||||
await notificationPlugin.initialize(initSetting);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> showNewAlarmSoundNotification(String sound) async {
|
|
||||||
AndroidNotificationChannel androidNotificationChannel =
|
|
||||||
AndroidNotificationChannel(
|
|
||||||
math.Random.secure().nextInt(1000000).toString(),
|
|
||||||
'high Important Notification',
|
|
||||||
importance: Importance.max);
|
|
||||||
AndroidNotificationDetails androidNotificationDetails =
|
|
||||||
AndroidNotificationDetails(
|
|
||||||
"androidNotificationChannel.id.toString()",
|
|
||||||
androidNotificationChannel.name.toString(),
|
|
||||||
sound: RawResourceAndroidNotificationSound(sound),
|
|
||||||
channelDescription: "Channel description",
|
|
||||||
importance: androidNotificationChannel.importance,
|
|
||||||
priority: Priority.high,
|
|
||||||
ticker: 'ticker',
|
|
||||||
);
|
|
||||||
|
|
||||||
final NotificationDetails notificationDetails =
|
|
||||||
NotificationDetails(android: androidNotificationDetails);
|
|
||||||
await FlutterLocalNotificationsPlugin().show(0, 'New Notification',
|
|
||||||
'Sound Notification Example', notificationDetails);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import 'package:app_settings/app_settings.dart';
|
import 'package:app_settings/app_settings.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import '../../../extention/context_extention.dart';
|
import '../../../extension/context_extension.dart';
|
||||||
import '../../../services/language_services.dart';
|
import '../../../services/language_services.dart';
|
||||||
|
|
||||||
class RequestPermissionDialog {
|
class RequestPermissionDialog {
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import '../../../feature/sound_notification_test/notification_bloc.dart';
|
|
||||||
import '../../../feature/sound_notification_test/notification_screen.dart';
|
|
||||||
import '../../../bloc/device_detail_bloc.dart';
|
import '../../../bloc/device_detail_bloc.dart';
|
||||||
import '../../../feature/devices/device_detail/device_detail_screen.dart';
|
import '../../../feature/devices/device_detail/device_detail_screen.dart';
|
||||||
import '../../../bloc/device_notification_settings_bloc.dart';
|
import '../../../bloc/device_notification_settings_bloc.dart';
|
||||||
@@ -153,14 +151,6 @@ GoRouter goRouter() {
|
|||||||
),
|
),
|
||||||
transitionsBuilder: transitionsRightToLeft),
|
transitionsBuilder: transitionsRightToLeft),
|
||||||
),
|
),
|
||||||
GoRoute(
|
|
||||||
path: "/notification",
|
|
||||||
name: 'notification',
|
|
||||||
builder: (context, state) => BlocProvider(
|
|
||||||
child: const NotificationScreen(),
|
|
||||||
blocBuilder: () => NotificationBloc(),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
"button_fake_fire_message": "False fire alarm",
|
"button_fake_fire_message": "False fire alarm",
|
||||||
"in_progress_message": "In progress",
|
"in_progress_message": "In progress",
|
||||||
"smoke_detecting_message": "Smoke detecting!",
|
"smoke_detecting_message": "Smoke detecting!",
|
||||||
|
"low_battery_message": "Low Battery!",
|
||||||
"smoke_detecting_message_lowercase": "smoke detecting!",
|
"smoke_detecting_message_lowercase": "smoke detecting!",
|
||||||
"disconnect_message_uppercase": "Disconnected",
|
"disconnect_message_uppercase": "Disconnected",
|
||||||
"disconnect_message_lowercase": "disconnected",
|
"disconnect_message_lowercase": "disconnected",
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
"button_fake_fire_message": "Cháy giả?",
|
"button_fake_fire_message": "Cháy giả?",
|
||||||
"in_progress_message": "Đang xử lý",
|
"in_progress_message": "Đang xử lý",
|
||||||
"smoke_detecting_message": "Phát hiện khói!",
|
"smoke_detecting_message": "Phát hiện khói!",
|
||||||
|
"low_battery_message": "Cảnh báo pin yếu!",
|
||||||
"smoke_detecting_message_lowercase": "Phát hiện khói!",
|
"smoke_detecting_message_lowercase": "Phát hiện khói!",
|
||||||
"disconnect_message_uppercase": "Mất kết nối",
|
"disconnect_message_uppercase": "Mất kết nối",
|
||||||
"disconnect_message_lowercase": "mất kết nối",
|
"disconnect_message_lowercase": "mất kết nối",
|
||||||
|
|||||||
@@ -282,7 +282,7 @@ class APIServices {
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<String> getOwnerDevieByState(Map<String, dynamic> params) async {
|
Future<String> getOwnerDeviceByState(Map<String, dynamic> params) async {
|
||||||
String? data = await NetworkManager.instance!
|
String? data = await NetworkManager.instance!
|
||||||
.getDataFromServerWithParams(APIPathConstants.DEVICE_PATH, params);
|
.getDataFromServerWithParams(APIPathConstants.DEVICE_PATH, params);
|
||||||
return data;
|
return data;
|
||||||
|
|||||||
@@ -128,8 +128,6 @@ class NotificationServices {
|
|||||||
|
|
||||||
void handleMessage(String? payload) {
|
void handleMessage(String? payload) {
|
||||||
dev.log("Handling notification tap with payload: $payload");
|
dev.log("Handling notification tap with payload: $payload");
|
||||||
// Thêm logic xử lý khi nhấn thông báo ở đây
|
|
||||||
// Ví dụ: Điều hướng màn hình hoặc xử lý dữ liệu
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> setupInteractMessage() async {
|
Future<void> setupInteractMessage() async {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import '../extention/context_extention.dart';
|
import '../extension/context_extension.dart';
|
||||||
|
|
||||||
InputDecoration borderRadiusTopLeftAndBottomRight(
|
InputDecoration borderRadiusTopLeftAndBottomRight(
|
||||||
BuildContext context, String hintText) =>
|
BuildContext context, String hintText) =>
|
||||||
|
|||||||
@@ -2,10 +2,10 @@ import 'dart:developer';
|
|||||||
|
|
||||||
import 'package:fl_chart/fl_chart.dart';
|
import 'package:fl_chart/fl_chart.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:sfm_app/bloc/devices_manager_bloc.dart';
|
import '../../bloc/devices_manager_bloc.dart';
|
||||||
import 'package:sfm_app/feature/devices/device_model.dart';
|
import '../../feature/devices/device_model.dart';
|
||||||
import 'package:sfm_app/product/extention/context_extention.dart';
|
import '../extension/context_extension.dart';
|
||||||
import 'package:sfm_app/product/services/language_services.dart';
|
import '../services/language_services.dart';
|
||||||
|
|
||||||
import '../constant/app/app_constants.dart';
|
import '../constant/app/app_constants.dart';
|
||||||
|
|
||||||
@@ -54,18 +54,18 @@ class _SharedPieChartState extends State<SharedPieChart> {
|
|||||||
aspectRatio: 1,
|
aspectRatio: 1,
|
||||||
child: PieChart(
|
child: PieChart(
|
||||||
PieChartData(
|
PieChartData(
|
||||||
pieTouchData: PieTouchData(
|
// pieTouchData: PieTouchData(
|
||||||
touchCallback: (FlTouchEvent event, pieTouchResponse) {
|
// touchCallback: (FlTouchEvent event, pieTouchResponse) {
|
||||||
if (!event.isInterestedForInteractions ||
|
// if (!event.isInterestedForInteractions ||
|
||||||
pieTouchResponse == null ||
|
// pieTouchResponse == null ||
|
||||||
pieTouchResponse.touchedSection == null) {
|
// pieTouchResponse.touchedSection == null) {
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
int newTouchedIndex =
|
// int newTouchedIndex =
|
||||||
pieTouchResponse.touchedSection!.touchedSectionIndex;
|
// pieTouchResponse.touchedSection!.touchedSectionIndex;
|
||||||
updateDevicesOnTapPieChart(newTouchedIndex);
|
// updateDevicesOnTapPieChart(newTouchedIndex);
|
||||||
},
|
// },
|
||||||
),
|
// ),
|
||||||
sections: [
|
sections: [
|
||||||
PieChartSectionData(
|
PieChartSectionData(
|
||||||
color: Colors.grey,
|
color: Colors.grey,
|
||||||
@@ -96,7 +96,7 @@ class _SharedPieChartState extends State<SharedPieChart> {
|
|||||||
titleStyle: titleStyle,
|
titleStyle: titleStyle,
|
||||||
),
|
),
|
||||||
PieChartSectionData(
|
PieChartSectionData(
|
||||||
color: Colors.black, // Có thể thêm màu cho trạng thái lỗi
|
color: Colors.black,
|
||||||
value: errorCount.toDouble(),
|
value: errorCount.toDouble(),
|
||||||
title: errorCount.toString(),
|
title: errorCount.toString(),
|
||||||
radius: context.dynamicWidth(0.2),
|
radius: context.dynamicWidth(0.2),
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:sfm_app/product/extention/context_extention.dart';
|
import 'package:sfm_app/product/extension/context_extension.dart';
|
||||||
import 'package:top_snackbar_flutter/custom_snack_bar.dart';
|
import 'package:top_snackbar_flutter/custom_snack_bar.dart';
|
||||||
import 'package:top_snackbar_flutter/top_snack_bar.dart';
|
import 'package:top_snackbar_flutter/top_snack_bar.dart';
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user