mirror of
https://github.com/SyncrowIOT/web.git
synced 2025-07-10 07:07:19 +00:00
Merged with dev
This commit is contained in:
@ -20,6 +20,8 @@ import 'package:syncrow_web/pages/device_managment/one_gang_switch/view/wall_lig
|
||||
import 'package:syncrow_web/pages/device_managment/one_gang_switch/view/wall_light_device_control.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/power_clamp/view/power_clamp_batch_control_view.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/power_clamp/view/smart_power_device_control.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/sos/view/sos_batch_control_view.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/sos/view/sos_device_control_view.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/three_g_glass_switch/view/three_gang_glass_switch_batch_control_view.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/three_g_glass_switch/view/three_gang_glass_switch_control_view.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/three_gang_switch/view/living_room_batch_controls.dart';
|
||||
@ -100,6 +102,8 @@ mixin RouteControlsBasedCode {
|
||||
return SmartPowerDeviceControl(
|
||||
deviceId: device.uuid!,
|
||||
);
|
||||
case 'SOS':
|
||||
return SosDeviceControlsView(device: device);
|
||||
default:
|
||||
return const SizedBox();
|
||||
}
|
||||
@ -123,119 +127,72 @@ mixin RouteControlsBasedCode {
|
||||
switch (devices.first.productType) {
|
||||
case '1G':
|
||||
return WallLightBatchControlView(
|
||||
deviceIds: devices
|
||||
.where((e) => (e.productType == '1G'))
|
||||
.map((e) => e.uuid!)
|
||||
.toList(),
|
||||
deviceIds: devices.where((e) => (e.productType == '1G')).map((e) => e.uuid!).toList(),
|
||||
);
|
||||
case '2G':
|
||||
return TwoGangBatchControlView(
|
||||
deviceIds: devices
|
||||
.where((e) => (e.productType == '2G'))
|
||||
.map((e) => e.uuid!)
|
||||
.toList(),
|
||||
deviceIds: devices.where((e) => (e.productType == '2G')).map((e) => e.uuid!).toList(),
|
||||
);
|
||||
case '3G':
|
||||
return LivingRoomBatchControlsView(
|
||||
deviceIds: devices
|
||||
.where((e) => (e.productType == '3G'))
|
||||
.map((e) => e.uuid!)
|
||||
.toList(),
|
||||
deviceIds: devices.where((e) => (e.productType == '3G')).map((e) => e.uuid!).toList(),
|
||||
);
|
||||
case '1GT':
|
||||
return OneGangGlassSwitchBatchControlView(
|
||||
deviceIds: devices
|
||||
.where((e) => (e.productType == '1GT'))
|
||||
.map((e) => e.uuid!)
|
||||
.toList(),
|
||||
deviceIds: devices.where((e) => (e.productType == '1GT')).map((e) => e.uuid!).toList(),
|
||||
);
|
||||
case '2GT':
|
||||
return TwoGangGlassSwitchBatchControlView(
|
||||
deviceIds: devices
|
||||
.where((e) => (e.productType == '2GT'))
|
||||
.map((e) => e.uuid!)
|
||||
.toList(),
|
||||
deviceIds: devices.where((e) => (e.productType == '2GT')).map((e) => e.uuid!).toList(),
|
||||
);
|
||||
case '3GT':
|
||||
return ThreeGangGlassSwitchBatchControlView(
|
||||
deviceIds: devices
|
||||
.where((e) => (e.productType == '3GT'))
|
||||
.map((e) => e.uuid!)
|
||||
.toList(),
|
||||
deviceIds: devices.where((e) => (e.productType == '3GT')).map((e) => e.uuid!).toList(),
|
||||
);
|
||||
case 'GW':
|
||||
return GatewayBatchControlView(
|
||||
gatewayIds: devices
|
||||
.where((e) => (e.productType == 'GW'))
|
||||
.map((e) => e.uuid!)
|
||||
.toList(),
|
||||
gatewayIds: devices.where((e) => (e.productType == 'GW')).map((e) => e.uuid!).toList(),
|
||||
);
|
||||
case 'DL':
|
||||
return DoorLockBatchControlView(
|
||||
devicesIds: devices
|
||||
.where((e) => (e.productType == 'DL'))
|
||||
.map((e) => e.uuid!)
|
||||
.toList());
|
||||
devicesIds: devices.where((e) => (e.productType == 'DL')).map((e) => e.uuid!).toList());
|
||||
case 'WPS':
|
||||
return WallSensorBatchControlView(
|
||||
devicesIds: devices
|
||||
.where((e) => (e.productType == 'WPS'))
|
||||
.map((e) => e.uuid!)
|
||||
.toList());
|
||||
devicesIds: devices.where((e) => (e.productType == 'WPS')).map((e) => e.uuid!).toList());
|
||||
case 'CPS':
|
||||
return CeilingSensorBatchControlView(
|
||||
devicesIds: devices
|
||||
.where((e) => (e.productType == 'CPS'))
|
||||
.map((e) => e.uuid!)
|
||||
.toList(),
|
||||
devicesIds: devices.where((e) => (e.productType == 'CPS')).map((e) => e.uuid!).toList(),
|
||||
);
|
||||
case 'CUR':
|
||||
return CurtainBatchStatusView(
|
||||
devicesIds: devices
|
||||
.where((e) => (e.productType == 'CUR'))
|
||||
.map((e) => e.uuid!)
|
||||
.toList(),
|
||||
devicesIds: devices.where((e) => (e.productType == 'CUR')).map((e) => e.uuid!).toList(),
|
||||
);
|
||||
case 'AC':
|
||||
return AcDeviceBatchControlView(
|
||||
devicesIds: devices
|
||||
.where((e) => (e.productType == 'AC'))
|
||||
.map((e) => e.uuid!)
|
||||
.toList());
|
||||
devicesIds: devices.where((e) => (e.productType == 'AC')).map((e) => e.uuid!).toList());
|
||||
case 'WH':
|
||||
return WaterHEaterBatchControlView(
|
||||
deviceIds: devices
|
||||
.where((e) => (e.productType == 'WH'))
|
||||
.map((e) => e.uuid!)
|
||||
.toList(),
|
||||
deviceIds: devices.where((e) => (e.productType == 'WH')).map((e) => e.uuid!).toList(),
|
||||
);
|
||||
case 'DS':
|
||||
return MainDoorSensorBatchView(
|
||||
devicesIds: devices
|
||||
.where((e) => (e.productType == 'DS'))
|
||||
.map((e) => e.uuid!)
|
||||
.toList(),
|
||||
devicesIds: devices.where((e) => (e.productType == 'DS')).map((e) => e.uuid!).toList(),
|
||||
);
|
||||
case 'GD':
|
||||
return GarageDoorBatchControlView(
|
||||
deviceIds: devices
|
||||
.where((e) => (e.productType == 'GD'))
|
||||
.map((e) => e.uuid!)
|
||||
.toList(),
|
||||
deviceIds: devices.where((e) => (e.productType == 'GD')).map((e) => e.uuid!).toList(),
|
||||
);
|
||||
case 'WL':
|
||||
return WaterLeakBatchControlView(
|
||||
deviceIds: devices
|
||||
.where((e) => (e.productType == 'WL'))
|
||||
.map((e) => e.uuid!)
|
||||
.toList(),
|
||||
deviceIds: devices.where((e) => (e.productType == 'WL')).map((e) => e.uuid!).toList(),
|
||||
);
|
||||
case 'PC':
|
||||
return PowerClampBatchControlView(
|
||||
deviceIds: devices
|
||||
.where((e) => (e.productType == 'PC'))
|
||||
.map((e) => e.uuid!)
|
||||
.toList(),
|
||||
deviceIds: devices.where((e) => (e.productType == 'PC')).map((e) => e.uuid!).toList(),
|
||||
);
|
||||
case 'SOS':
|
||||
return SOSBatchControlView(
|
||||
deviceIds: devices.where((e) => (e.productType == 'SOS')).map((e) => e.uuid!).toList(),
|
||||
);
|
||||
default:
|
||||
return const SizedBox();
|
||||
|
@ -6,6 +6,7 @@ import 'package:syncrow_web/pages/device_managment/garage_door/bloc/garage_door_
|
||||
import 'package:syncrow_web/pages/device_managment/garage_door/helper/garage_door_helper.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/garage_door/models/garage_door_model.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/garage_door/widgets/schedule_garage_view.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/shared/icon_name_status_container.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/shared/table/report_table.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/shared/toggle_widget.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
@ -13,10 +14,7 @@ import 'package:syncrow_web/utils/constants/assets.dart';
|
||||
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
||||
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
|
||||
|
||||
import '../../main_door_sensor/view/main_door_control_view.dart';
|
||||
|
||||
class GarageDoorControlView extends StatelessWidget
|
||||
with HelperResponsiveLayout {
|
||||
class GarageDoorControlView extends StatelessWidget with HelperResponsiveLayout {
|
||||
final String deviceId;
|
||||
|
||||
const GarageDoorControlView({required this.deviceId, super.key});
|
||||
@ -24,8 +22,7 @@ class GarageDoorControlView extends StatelessWidget
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocProvider(
|
||||
create: (context) => GarageDoorBloc(deviceId: deviceId)
|
||||
..add(GarageDoorInitialEvent(deviceId)),
|
||||
create: (context) => GarageDoorBloc(deviceId: deviceId)..add(GarageDoorInitialEvent(deviceId)),
|
||||
child: BlocBuilder<GarageDoorBloc, GarageDoorState>(
|
||||
builder: (context, state) {
|
||||
if (state is GarageDoorLoadingState) {
|
||||
@ -37,9 +34,7 @@ class GarageDoorControlView extends StatelessWidget
|
||||
garageDoorSensor: true,
|
||||
onRowTap: (index) {},
|
||||
onClose: () {
|
||||
context
|
||||
.read<GarageDoorBloc>()
|
||||
.add(BackToGarageDoorGridViewEvent());
|
||||
context.read<GarageDoorBloc>().add(BackToGarageDoorGridViewEvent());
|
||||
},
|
||||
);
|
||||
} else if (state is GarageDoorLoadedState) {
|
||||
@ -80,10 +75,7 @@ class GarageDoorControlView extends StatelessWidget
|
||||
icon: status.switch1 ? Assets.openedDoor : Assets.closedDoor,
|
||||
onTap: () {
|
||||
context.read<GarageDoorBloc>().add(
|
||||
GarageDoorControlEvent(
|
||||
deviceId: status.uuid,
|
||||
value: !status.switch1,
|
||||
code: 'switch_1'),
|
||||
GarageDoorControlEvent(deviceId: status.uuid, value: !status.switch1, code: 'switch_1'),
|
||||
);
|
||||
},
|
||||
status: status.switch1,
|
||||
@ -92,8 +84,7 @@ class GarageDoorControlView extends StatelessWidget
|
||||
IconNameStatusContainer(
|
||||
onTap: () {
|
||||
context.read<GarageDoorBloc>().add(
|
||||
FetchGarageDoorSchedulesEvent(
|
||||
deviceId: deviceId, category: 'switch_1'),
|
||||
FetchGarageDoorSchedulesEvent(deviceId: deviceId, category: 'switch_1'),
|
||||
);
|
||||
showDialog(
|
||||
context: context,
|
||||
@ -116,9 +107,7 @@ class GarageDoorControlView extends StatelessWidget
|
||||
children: [
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
context
|
||||
.read<GarageDoorBloc>()
|
||||
.add(DecreaseGarageDoorDelayEvent(deviceId: status.uuid));
|
||||
context.read<GarageDoorBloc>().add(DecreaseGarageDoorDelayEvent(deviceId: status.uuid));
|
||||
},
|
||||
icon: const Icon(
|
||||
Icons.remove,
|
||||
@ -136,8 +125,7 @@ class GarageDoorControlView extends StatelessWidget
|
||||
),
|
||||
Text(
|
||||
'h',
|
||||
style: context.textTheme.bodySmall!
|
||||
.copyWith(color: ColorsManager.blackColor),
|
||||
style: context.textTheme.bodySmall!.copyWith(color: ColorsManager.blackColor),
|
||||
),
|
||||
Text(
|
||||
(status.delay.inMinutes % 60).toString().padLeft(2, '0'),
|
||||
@ -148,14 +136,11 @@ class GarageDoorControlView extends StatelessWidget
|
||||
),
|
||||
Text(
|
||||
'm',
|
||||
style: context.textTheme.bodySmall!
|
||||
.copyWith(color: ColorsManager.blackColor),
|
||||
style: context.textTheme.bodySmall!.copyWith(color: ColorsManager.blackColor),
|
||||
),
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
context
|
||||
.read<GarageDoorBloc>()
|
||||
.add(IncreaseGarageDoorDelayEvent(deviceId: status.uuid));
|
||||
context.read<GarageDoorBloc>().add(IncreaseGarageDoorDelayEvent(deviceId: status.uuid));
|
||||
},
|
||||
icon: const Icon(
|
||||
Icons.add,
|
||||
@ -173,9 +158,7 @@ class GarageDoorControlView extends StatelessWidget
|
||||
onChange: (value) {
|
||||
context.read<GarageDoorBloc>().add(
|
||||
GarageDoorControlEvent(
|
||||
deviceId: status.uuid,
|
||||
value: value ? status.delay.inSeconds : 0,
|
||||
code: 'countdown_1'),
|
||||
deviceId: status.uuid, value: value ? status.delay.inSeconds : 0, code: 'countdown_1'),
|
||||
);
|
||||
},
|
||||
),
|
||||
@ -184,8 +167,7 @@ class GarageDoorControlView extends StatelessWidget
|
||||
name: 'Records',
|
||||
icon: Assets.records,
|
||||
onTap: () {
|
||||
context.read<GarageDoorBloc>().add(FetchGarageDoorRecordsEvent(
|
||||
code: 'switch_1', deviceId: status.uuid));
|
||||
context.read<GarageDoorBloc>().add(FetchGarageDoorRecordsEvent(code: 'switch_1', deviceId: status.uuid));
|
||||
},
|
||||
status: false,
|
||||
textColor: ColorsManager.blackColor,
|
||||
|
@ -1,17 +1,15 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_model.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/main_door_sensor/bloc/main_door_sensor_bloc.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/main_door_sensor/bloc/main_door_sensor_event.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/main_door_sensor/bloc/main_door_sensor_state.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/main_door_sensor/models/main_door_status_model.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/main_door_sensor/widgets/notification_dialog.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/shared/device_controls_container.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/shared/icon_name_status_container.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/shared/table/report_table.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
||||
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
|
||||
|
||||
class MainDoorSensorControlView extends StatelessWidget with HelperResponsiveLayout {
|
||||
@ -113,71 +111,3 @@ class MainDoorSensorControlView extends StatelessWidget with HelperResponsiveLay
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class IconNameStatusContainer extends StatelessWidget {
|
||||
const IconNameStatusContainer({
|
||||
super.key,
|
||||
required this.name,
|
||||
required this.icon,
|
||||
required this.onTap,
|
||||
required this.status,
|
||||
required this.textColor,
|
||||
this.paddingAmount = 12,
|
||||
required this.isFullIcon,
|
||||
});
|
||||
|
||||
final String name;
|
||||
final String icon;
|
||||
final GestureTapCallback onTap;
|
||||
final bool status;
|
||||
final Color textColor;
|
||||
final double? paddingAmount;
|
||||
final bool isFullIcon;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GestureDetector(
|
||||
onTap: onTap,
|
||||
child: DeviceControlsContainer(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
if (isFullIcon)
|
||||
ClipOval(
|
||||
child: SvgPicture.asset(
|
||||
icon,
|
||||
fit: BoxFit.contain,
|
||||
),
|
||||
)
|
||||
else
|
||||
ClipOval(
|
||||
child: Container(
|
||||
height: 60,
|
||||
width: 60,
|
||||
padding: EdgeInsets.all(paddingAmount ?? 8),
|
||||
color: ColorsManager.whiteColors,
|
||||
child: SvgPicture.asset(
|
||||
icon,
|
||||
width: 35,
|
||||
height: 35,
|
||||
fit: BoxFit.contain,
|
||||
),
|
||||
)),
|
||||
const Spacer(),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 6),
|
||||
child: Text(
|
||||
name,
|
||||
textAlign: TextAlign.start,
|
||||
style: context.textTheme.titleMedium!.copyWith(
|
||||
fontWeight: FontWeight.w400,
|
||||
color: textColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,10 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/all_devices/helper/route_controls_based_code.dart';
|
||||
|
||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_model.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
||||
|
||||
class DeviceBatchControlDialog extends StatelessWidget
|
||||
with RouteControlsBasedCode {
|
||||
class DeviceBatchControlDialog extends StatelessWidget with RouteControlsBasedCode {
|
||||
final List<AllDevicesModel> devices;
|
||||
|
||||
const DeviceBatchControlDialog({super.key, required this.devices});
|
||||
@ -139,6 +135,8 @@ String getBatchDialogName(AllDevicesModel device) {
|
||||
return "Garage Door Opener";
|
||||
case 'WL':
|
||||
return "Water Leak Sensor";
|
||||
case 'SOS':
|
||||
return "SOS";
|
||||
default:
|
||||
return device.categoryName ?? 'Device Control';
|
||||
}
|
||||
|
@ -0,0 +1,73 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/shared/device_controls_container.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
||||
|
||||
class IconNameStatusContainer extends StatelessWidget {
|
||||
const IconNameStatusContainer({
|
||||
super.key,
|
||||
required this.name,
|
||||
required this.icon,
|
||||
required this.onTap,
|
||||
required this.status,
|
||||
required this.textColor,
|
||||
this.paddingAmount = 12,
|
||||
required this.isFullIcon,
|
||||
});
|
||||
|
||||
final String name;
|
||||
final String icon;
|
||||
final GestureTapCallback onTap;
|
||||
final bool status;
|
||||
final Color textColor;
|
||||
final double? paddingAmount;
|
||||
final bool isFullIcon;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GestureDetector(
|
||||
onTap: onTap,
|
||||
child: DeviceControlsContainer(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
if (isFullIcon)
|
||||
ClipOval(
|
||||
child: SvgPicture.asset(
|
||||
icon,
|
||||
fit: BoxFit.contain,
|
||||
),
|
||||
)
|
||||
else
|
||||
ClipOval(
|
||||
child: Container(
|
||||
height: 60,
|
||||
width: 60,
|
||||
padding: EdgeInsets.all(paddingAmount ?? 8),
|
||||
color: ColorsManager.whiteColors,
|
||||
child: SvgPicture.asset(
|
||||
icon,
|
||||
width: 35,
|
||||
height: 35,
|
||||
fit: BoxFit.contain,
|
||||
),
|
||||
)),
|
||||
const Spacer(),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 6),
|
||||
child: Text(
|
||||
name,
|
||||
textAlign: TextAlign.start,
|
||||
style: context.textTheme.titleMedium!.copyWith(
|
||||
fontWeight: FontWeight.w400,
|
||||
color: textColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
90
lib/pages/device_managment/sos/bloc/sos_device_bloc.dart
Normal file
90
lib/pages/device_managment/sos/bloc/sos_device_bloc.dart
Normal file
@ -0,0 +1,90 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:bloc/bloc.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_reports.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/sos/models/sos_status_model.dart';
|
||||
import 'package:syncrow_web/services/devices_mang_api.dart';
|
||||
|
||||
part 'sos_device_event.dart';
|
||||
part 'sos_device_state.dart';
|
||||
|
||||
class SosDeviceBloc extends Bloc<SosDeviceEvent, SosDeviceState> {
|
||||
SosDeviceBloc() : super(SosDeviceInitial()) {
|
||||
on<GetDeviceStatus>(_getDeviceStatus);
|
||||
on<GetBatchStatus>(_getBatchStatus);
|
||||
on<GetDeviceRecords>(_getDeviceRecords);
|
||||
on<GetDeviceAutomationRecords>(_getDeviceAutomationRecords);
|
||||
on<BackToSosStatusView>(_backToSosStatusView);
|
||||
on<SosFactoryReset>(_sosFactoryReset);
|
||||
}
|
||||
|
||||
late SosStatusModel deviceStatus;
|
||||
|
||||
FutureOr<void> _getDeviceStatus(GetDeviceStatus event, Emitter<SosDeviceState> emit) async {
|
||||
emit(SosDeviceLoadingState());
|
||||
try {
|
||||
final status = await DevicesManagementApi().getDeviceStatus(event.uuid);
|
||||
deviceStatus = SosStatusModel.fromJson(event.uuid, status.status);
|
||||
emit(SosDeviceLoadedState(deviceStatus));
|
||||
} catch (e) {
|
||||
emit(SosDeviceErrorState(e.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
FutureOr<void> _getBatchStatus(GetBatchStatus event, Emitter<SosDeviceState> emit) async {
|
||||
emit(SosDeviceLoadingState());
|
||||
try {
|
||||
final status = await DevicesManagementApi().getBatchStatus(event.uuids);
|
||||
deviceStatus = SosStatusModel.fromJson(event.uuids.first, status.status);
|
||||
emit(SosDeviceLoadedState(deviceStatus));
|
||||
} catch (e) {
|
||||
emit(SosDeviceErrorState(e.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
FutureOr<void> _getDeviceRecords(GetDeviceRecords event, Emitter<SosDeviceState> emit) async {
|
||||
emit(SosReportLoadingState());
|
||||
try {
|
||||
final from = DateTime.now().subtract(const Duration(days: 30)).millisecondsSinceEpoch;
|
||||
final to = DateTime.now().millisecondsSinceEpoch;
|
||||
final DeviceReport records =
|
||||
await DevicesManagementApi.getDeviceReportsByDate(event.uuid, 'sos', from.toString(), to.toString());
|
||||
emit(SosReportLoadedState(records));
|
||||
} catch (e) {
|
||||
emit(SosReportErrorState(e.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
FutureOr<void> _getDeviceAutomationRecords(GetDeviceAutomationRecords event, Emitter<SosDeviceState> emit) async {
|
||||
emit(SosAutomationReportLoadingState());
|
||||
try {
|
||||
final from = DateTime.now().subtract(const Duration(days: 30)).millisecondsSinceEpoch;
|
||||
final to = DateTime.now().millisecondsSinceEpoch;
|
||||
final DeviceReport records = await DevicesManagementApi.getDeviceReportsByDate(
|
||||
event.uuid, 'sos_automation', from.toString(), to.toString());
|
||||
emit(SosAutomationReportLoadedState(records));
|
||||
} catch (e) {
|
||||
emit(SosAutomationReportErrorState(e.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
FutureOr<void> _backToSosStatusView(BackToSosStatusView event, Emitter<SosDeviceState> emit) {
|
||||
emit(SosDeviceLoadedState(deviceStatus));
|
||||
}
|
||||
|
||||
FutureOr<void> _sosFactoryReset(SosFactoryReset event, Emitter<SosDeviceState> emit) async {
|
||||
emit(SosDeviceLoadingState());
|
||||
try {
|
||||
final response = await DevicesManagementApi().factoryReset(event.factoryReset, event.deviceId);
|
||||
if (response) {
|
||||
emit(SosDeviceLoadedState(deviceStatus));
|
||||
} else {
|
||||
emit(const SosDeviceErrorState('Factory reset failed'));
|
||||
}
|
||||
} catch (e) {
|
||||
emit(SosDeviceErrorState(e.toString()));
|
||||
}
|
||||
}
|
||||
}
|
49
lib/pages/device_managment/sos/bloc/sos_device_event.dart
Normal file
49
lib/pages/device_managment/sos/bloc/sos_device_event.dart
Normal file
@ -0,0 +1,49 @@
|
||||
part of 'sos_device_bloc.dart';
|
||||
|
||||
sealed class SosDeviceEvent extends Equatable {
|
||||
const SosDeviceEvent();
|
||||
}
|
||||
|
||||
class GetDeviceStatus extends SosDeviceEvent {
|
||||
final String uuid;
|
||||
const GetDeviceStatus(this.uuid);
|
||||
@override
|
||||
List<Object?> get props => [uuid];
|
||||
}
|
||||
|
||||
class GetBatchStatus extends SosDeviceEvent {
|
||||
final List<String> uuids;
|
||||
const GetBatchStatus(this.uuids);
|
||||
@override
|
||||
List<Object?> get props => [uuids];
|
||||
}
|
||||
|
||||
class GetDeviceRecords extends SosDeviceEvent {
|
||||
final String uuid;
|
||||
|
||||
const GetDeviceRecords(this.uuid);
|
||||
@override
|
||||
List<Object?> get props => [uuid];
|
||||
}
|
||||
|
||||
class GetDeviceAutomationRecords extends SosDeviceEvent {
|
||||
final String uuid;
|
||||
const GetDeviceAutomationRecords(this.uuid);
|
||||
@override
|
||||
List<Object?> get props => [uuid];
|
||||
}
|
||||
|
||||
class BackToSosStatusView extends SosDeviceEvent {
|
||||
@override
|
||||
List<Object?> get props => [];
|
||||
}
|
||||
|
||||
class SosFactoryReset extends SosDeviceEvent {
|
||||
final String deviceId;
|
||||
final FactoryResetModel factoryReset;
|
||||
|
||||
const SosFactoryReset({required this.deviceId, required this.factoryReset});
|
||||
|
||||
@override
|
||||
List<Object> get props => [deviceId, factoryReset];
|
||||
}
|
82
lib/pages/device_managment/sos/bloc/sos_device_state.dart
Normal file
82
lib/pages/device_managment/sos/bloc/sos_device_state.dart
Normal file
@ -0,0 +1,82 @@
|
||||
part of 'sos_device_bloc.dart';
|
||||
|
||||
sealed class SosDeviceState extends Equatable {
|
||||
const SosDeviceState();
|
||||
}
|
||||
|
||||
final class SosDeviceInitial extends SosDeviceState {
|
||||
@override
|
||||
List<Object> get props => [];
|
||||
}
|
||||
|
||||
final class SosDeviceLoadingState extends SosDeviceState {
|
||||
@override
|
||||
List<Object> get props => [];
|
||||
}
|
||||
|
||||
final class SosDeviceLoadedState extends SosDeviceState {
|
||||
final SosStatusModel sosStatusModel;
|
||||
|
||||
const SosDeviceLoadedState(this.sosStatusModel);
|
||||
|
||||
@override
|
||||
List<Object> get props => [sosStatusModel];
|
||||
}
|
||||
|
||||
final class SosDeviceErrorState extends SosDeviceState {
|
||||
final String message;
|
||||
|
||||
const SosDeviceErrorState(this.message);
|
||||
|
||||
@override
|
||||
List<Object> get props => [message];
|
||||
}
|
||||
|
||||
/// report state
|
||||
final class SosReportLoadingState extends SosDeviceState {
|
||||
@override
|
||||
List<Object> get props => [];
|
||||
}
|
||||
|
||||
final class SosReportLoadedState extends SosDeviceState {
|
||||
final DeviceReport sosReport;
|
||||
|
||||
const SosReportLoadedState(this.sosReport);
|
||||
|
||||
@override
|
||||
List<Object> get props => [sosReport];
|
||||
}
|
||||
|
||||
final class SosReportErrorState extends SosDeviceState {
|
||||
final String message;
|
||||
|
||||
const SosReportErrorState(this.message);
|
||||
|
||||
@override
|
||||
List<Object> get props => [message];
|
||||
}
|
||||
|
||||
/// automation reports
|
||||
|
||||
final class SosAutomationReportLoadingState extends SosDeviceState {
|
||||
@override
|
||||
List<Object> get props => [];
|
||||
}
|
||||
|
||||
final class SosAutomationReportLoadedState extends SosDeviceState {
|
||||
final DeviceReport automationReport;
|
||||
|
||||
const SosAutomationReportLoadedState(this.automationReport);
|
||||
|
||||
@override
|
||||
List<Object> get props => [automationReport];
|
||||
}
|
||||
|
||||
final class SosAutomationReportErrorState extends SosDeviceState {
|
||||
final String message;
|
||||
|
||||
const SosAutomationReportErrorState(this.message);
|
||||
|
||||
@override
|
||||
List<Object> get props => [message];
|
||||
}
|
34
lib/pages/device_managment/sos/models/sos_status_model.dart
Normal file
34
lib/pages/device_managment/sos/models/sos_status_model.dart
Normal file
@ -0,0 +1,34 @@
|
||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart';
|
||||
|
||||
class SosStatusModel {
|
||||
final int batteryLevel;
|
||||
final String sosStatus;
|
||||
final String deviceId;
|
||||
|
||||
SosStatusModel({
|
||||
required this.batteryLevel,
|
||||
required this.sosStatus,
|
||||
required this.deviceId,
|
||||
});
|
||||
|
||||
factory SosStatusModel.fromJson(String deviceId, List<Status> statuses) {
|
||||
late int batteryLevel;
|
||||
late String sosStatus;
|
||||
|
||||
for (var status in statuses) {
|
||||
switch (status.code) {
|
||||
case 'battery_percentage':
|
||||
batteryLevel = status.value;
|
||||
break;
|
||||
case 'sos':
|
||||
sosStatus = status.value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return SosStatusModel(
|
||||
deviceId: deviceId,
|
||||
batteryLevel: batteryLevel,
|
||||
sosStatus: sosStatus,
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/shared/batch_control/factory_reset.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/shared/batch_control/firmware_update.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/sos/bloc/sos_device_bloc.dart';
|
||||
|
||||
class SOSBatchControlView extends StatelessWidget {
|
||||
const SOSBatchControlView({
|
||||
super.key,
|
||||
required this.deviceIds,
|
||||
});
|
||||
|
||||
final List<String> deviceIds;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 170,
|
||||
// height: 140,
|
||||
child: FirmwareUpdateWidget(deviceId: deviceIds.first, version: 2)),
|
||||
const SizedBox(
|
||||
width: 12,
|
||||
),
|
||||
SizedBox(
|
||||
width: 170,
|
||||
height: 140,
|
||||
child: FactoryResetWidget(
|
||||
callFactoryReset: () {
|
||||
context.read<SosDeviceBloc>().add(
|
||||
SosFactoryReset(deviceId: deviceIds.first, factoryReset: FactoryResetModel(devicesUuid: deviceIds)));
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
138
lib/pages/device_managment/sos/view/sos_device_control_view.dart
Normal file
138
lib/pages/device_managment/sos/view/sos_device_control_view.dart
Normal file
@ -0,0 +1,138 @@
|
||||
// sos device control view
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_model.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/shared/icon_name_status_container.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/shared/table/report_table.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/sos/bloc/sos_device_bloc.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/sos/widgets/sos_notification_dialog.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
|
||||
|
||||
import '../models/sos_status_model.dart';
|
||||
|
||||
class SosDeviceControlsView extends StatelessWidget with HelperResponsiveLayout {
|
||||
const SosDeviceControlsView({
|
||||
super.key,
|
||||
required this.device,
|
||||
});
|
||||
|
||||
final AllDevicesModel device;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocProvider(
|
||||
create: (context) => SosDeviceBloc()..add(GetDeviceStatus(device.uuid!)),
|
||||
child: BlocBuilder<SosDeviceBloc, SosDeviceState>(
|
||||
builder: (context, state) {
|
||||
if (state is SosDeviceLoadingState) {
|
||||
return const Center(child: CircularProgressIndicator());
|
||||
} else if (state is SosDeviceLoadedState) {
|
||||
return _buildStatusControls(context, state.sosStatusModel);
|
||||
} else if (state is SosReportLoadedState) {
|
||||
return ReportsTable(
|
||||
report: state.sosReport,
|
||||
hideValueShowDescription: true,
|
||||
garageDoorSensor: true,
|
||||
onRowTap: (index) {},
|
||||
onClose: () {
|
||||
context.read<SosDeviceBloc>().add(BackToSosStatusView());
|
||||
},
|
||||
);
|
||||
} else if (state is SosAutomationReportLoadedState) {
|
||||
return ReportsTable(
|
||||
report: state.automationReport,
|
||||
hideValueShowDescription: true,
|
||||
garageDoorSensor: true,
|
||||
onRowTap: (index) {},
|
||||
onClose: () {
|
||||
context.read<SosDeviceBloc>().add(BackToSosStatusView());
|
||||
},
|
||||
);
|
||||
} else if (state is SosDeviceErrorState) {
|
||||
return const Center(child: Text('Error fetching status'));
|
||||
} else if (state is SosAutomationReportErrorState) {
|
||||
return Center(child: Text('Error: ${state.message.toString()}'));
|
||||
} else if (state is SosReportErrorState) {
|
||||
return Center(child: Text('Error: ${state.message.toString()}'));
|
||||
}
|
||||
return const Center(child: CircularProgressIndicator());
|
||||
},
|
||||
));
|
||||
}
|
||||
|
||||
Widget _buildStatusControls(BuildContext context, SosStatusModel deviceStatus) {
|
||||
final isExtraLarge = isExtraLargeScreenSize(context);
|
||||
final isLarge = isLargeScreenSize(context);
|
||||
final isMedium = isMediumScreenSize(context);
|
||||
return GridView(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 50),
|
||||
shrinkWrap: true,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: isLarge || isExtraLarge
|
||||
? 3
|
||||
: isMedium
|
||||
? 2
|
||||
: 1,
|
||||
mainAxisExtent: 140,
|
||||
crossAxisSpacing: 12,
|
||||
mainAxisSpacing: 12,
|
||||
),
|
||||
children: [
|
||||
IconNameStatusContainer(
|
||||
isFullIcon: false,
|
||||
name: deviceStatus.sosStatus == 'sos' ? 'SOS' : 'Normal',
|
||||
icon: deviceStatus.sosStatus == 'sos' ? Assets.sos : Assets.sosNormal,
|
||||
onTap: () {},
|
||||
status: false,
|
||||
textColor: ColorsManager.blackColor,
|
||||
),
|
||||
IconNameStatusContainer(
|
||||
isFullIcon: false,
|
||||
name: 'SOS Records',
|
||||
icon: Assets.records,
|
||||
onTap: () {
|
||||
context.read<SosDeviceBloc>().add(
|
||||
GetDeviceRecords(
|
||||
device.uuid!,
|
||||
),
|
||||
);
|
||||
},
|
||||
status: false,
|
||||
textColor: ColorsManager.blackColor,
|
||||
),
|
||||
IconNameStatusContainer(
|
||||
isFullIcon: false,
|
||||
name: 'Automation Record',
|
||||
icon: Assets.automationRecords,
|
||||
onTap: () {
|
||||
// context.read<SosDeviceBloc>().add(
|
||||
// GetDeviceAutomationRecords(
|
||||
// device.uuid!,
|
||||
// ),
|
||||
// );
|
||||
},
|
||||
status: false,
|
||||
textColor: ColorsManager.blackColor,
|
||||
),
|
||||
IconNameStatusContainer(
|
||||
isFullIcon: false,
|
||||
name: 'Alarm Settings',
|
||||
icon: Assets.mainDoorNotifi,
|
||||
onTap: () {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => const SosNotificationDialog(),
|
||||
);
|
||||
},
|
||||
status: false,
|
||||
textColor: ColorsManager.blackColor,
|
||||
paddingAmount: 14,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,116 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/shared/toggle_widget.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
|
||||
class SosNotificationDialog extends StatefulWidget {
|
||||
const SosNotificationDialog({super.key});
|
||||
|
||||
@override
|
||||
State<SosNotificationDialog> createState() => _NotificationDialogState();
|
||||
}
|
||||
|
||||
class _NotificationDialogState extends State<SosNotificationDialog> {
|
||||
bool isLowBatteryNotificationEnabled = true;
|
||||
bool isSosAlarmEnabled = true;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Dialog(
|
||||
backgroundColor: Colors.white,
|
||||
insetPadding: const EdgeInsets.all(20),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
),
|
||||
child: SizedBox(
|
||||
width: 550,
|
||||
child: SingleChildScrollView(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(20.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
const SizedBox(),
|
||||
Text(
|
||||
'Notification Settings',
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 22,
|
||||
color: ColorsManager.dialogBlueTitle,
|
||||
),
|
||||
),
|
||||
Container(
|
||||
width: 25,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.transparent,
|
||||
shape: BoxShape.circle,
|
||||
border: Border.all(
|
||||
color: Colors.grey,
|
||||
width: 1.0,
|
||||
),
|
||||
),
|
||||
child: IconButton(
|
||||
padding: EdgeInsets.all(1),
|
||||
icon: const Icon(
|
||||
Icons.close,
|
||||
color: Colors.grey,
|
||||
size: 18,
|
||||
),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 170,
|
||||
height: 135,
|
||||
child: ToggleWidget(
|
||||
value: isSosAlarmEnabled,
|
||||
code: 'notification',
|
||||
deviceId: '',
|
||||
label: 'SOS Alarm',
|
||||
onChange: (v) {
|
||||
setState(() {
|
||||
isSosAlarmEnabled = v;
|
||||
});
|
||||
},
|
||||
icon: '-1',
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 16,
|
||||
),
|
||||
SizedBox(
|
||||
width: 170,
|
||||
height: 135,
|
||||
child: ToggleWidget(
|
||||
value: isLowBatteryNotificationEnabled,
|
||||
code: 'notification',
|
||||
deviceId: '',
|
||||
label: 'Low Battery',
|
||||
onChange: (v) {
|
||||
setState(() {
|
||||
isLowBatteryNotificationEnabled = v;
|
||||
});
|
||||
},
|
||||
icon: '-1',
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -1,13 +1,13 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/main_door_sensor/view/main_door_control_view.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/shared/icon_name_status_container.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/shared/table/report_table.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/water_leak/bloc/water_leak_bloc.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/water_leak/bloc/water_leak_event.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/water_leak/bloc/water_leak_state.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/water_leak/widgets/water_leak_notifi_dialog.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/shared/table/report_table.dart';
|
||||
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
|
||||
|
||||
class WaterLeakView extends StatelessWidget with HelperResponsiveLayout {
|
||||
@ -21,8 +21,7 @@ class WaterLeakView extends StatelessWidget with HelperResponsiveLayout {
|
||||
final isLarge = isLargeScreenSize(context);
|
||||
final isMedium = isMediumScreenSize(context);
|
||||
return BlocProvider(
|
||||
create: (context) =>
|
||||
WaterLeakBloc(deviceId)..add(FetchWaterLeakStatusEvent(deviceId)),
|
||||
create: (context) => WaterLeakBloc(deviceId)..add(FetchWaterLeakStatusEvent(deviceId)),
|
||||
child: BlocBuilder<WaterLeakBloc, WaterLeakState>(
|
||||
builder: (context, state) {
|
||||
if (state is WaterLeakLoadingState) {
|
||||
@ -45,31 +44,21 @@ class WaterLeakView extends StatelessWidget with HelperResponsiveLayout {
|
||||
children: [
|
||||
IconNameStatusContainer(
|
||||
isFullIcon: false,
|
||||
name: state.status.watersensorState == 'normal'
|
||||
? 'Normal'
|
||||
: 'Leak Detection',
|
||||
icon: state.status.watersensorState == 'normal'
|
||||
? Assets.waterLeakNormal
|
||||
: Assets.waterLeakDetected,
|
||||
name: state.status.watersensorState == 'normal' ? 'Normal' : 'Leak Detection',
|
||||
icon: state.status.watersensorState == 'normal' ? Assets.waterLeakNormal : Assets.waterLeakDetected,
|
||||
onTap: () {},
|
||||
status: state.status.watersensorState == 'normal',
|
||||
textColor: state.status.watersensorState == 'normal'
|
||||
? ColorsManager.blackColor
|
||||
: ColorsManager.red,
|
||||
textColor: state.status.watersensorState == 'normal' ? ColorsManager.blackColor : ColorsManager.red,
|
||||
),
|
||||
IconNameStatusContainer(
|
||||
isFullIcon: false,
|
||||
name: 'Records',
|
||||
icon: Assets.records,
|
||||
onTap: () {
|
||||
context
|
||||
.read<WaterLeakBloc>()
|
||||
.add(FetchWaterLeakReportsEvent(
|
||||
context.read<WaterLeakBloc>().add(FetchWaterLeakReportsEvent(
|
||||
deviceId: deviceId,
|
||||
code: 'watersensor_state',
|
||||
from: DateTime.now()
|
||||
.subtract(const Duration(days: 30))
|
||||
.millisecondsSinceEpoch,
|
||||
from: DateTime.now().subtract(const Duration(days: 30)).millisecondsSinceEpoch,
|
||||
to: DateTime.now().millisecondsSinceEpoch,
|
||||
));
|
||||
},
|
||||
@ -109,9 +98,7 @@ class WaterLeakView extends StatelessWidget with HelperResponsiveLayout {
|
||||
waterLeak: true,
|
||||
onRowTap: (index) {},
|
||||
onClose: () {
|
||||
context
|
||||
.read<WaterLeakBloc>()
|
||||
.add(FetchWaterLeakStatusEvent(deviceId));
|
||||
context.read<WaterLeakBloc>().add(FetchWaterLeakStatusEvent(deviceId));
|
||||
},
|
||||
);
|
||||
} else if (state is WaterLeakReportsFailedState) {
|
||||
|
Reference in New Issue
Block a user