push garage door schedule

This commit is contained in:
ashrafzarkanisala
2024-10-06 23:31:36 +03:00
parent 1e2e2bf4e6
commit 4f833e86fb
14 changed files with 494 additions and 191 deletions
@@ -8,6 +8,7 @@ import 'package:syncrow_web/pages/device_managment/garage_door/bloc/garage_door_
import 'package:syncrow_web/pages/device_managment/garage_door/models/garage_door_model.dart';
import 'package:syncrow_web/pages/device_managment/water_heater/models/schedule_entry.dart';
import 'package:syncrow_web/pages/device_managment/water_heater/models/schedule_model.dart';
import 'package:syncrow_web/pages/device_managment/water_heater/models/water_heater_status_model.dart';
import 'package:syncrow_web/services/devices_mang_api.dart';
import 'package:syncrow_web/utils/format_date_time.dart';
@@ -39,27 +40,29 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorState> {
var response = await DevicesManagementApi().getDeviceStatus(event.deviceId);
deviceStatus = GarageDoorStatusModel.fromJson(deviceId, response.status);
emit(GarageDoorLoadedState(status: deviceStatus));
// _listenToChanges();
} catch (e) {
emit(GarageDoorErrorState(message: e.toString()));
}
}
void _toggleGarageDoor(ToggleGarageDoorEvent event, Emitter<GarageDoorState> emit) async {
emit(GarageDoorLoadingNewState(garageDoorModel: deviceStatus));
deviceStatus = deviceStatus.copyWith(isOpen: event.isOpen);
final oldValue = deviceStatus.switch1;
_updateLocalValue('switch_1', event.isOpen);
emit(GarageDoorLoadedState(status: deviceStatus));
await _runDeBouncer(
final success = await _runDeBouncer(
deviceId: event.deviceId,
code: event.code,
code: 'switch_1',
value: event.isOpen,
oldValue: oldValue,
emit: emit,
isBatch: false,
);
if (!success) {
_revertValue('switch_1', oldValue, emit);
}
}
Future<void> _addSchedule(AddGarageDoorScheduleEvent event, Emitter<GarageDoorState> emit) async {
emit(GarageDoorLoadingState());
try {
ScheduleEntry newSchedule = ScheduleEntry(
category: event.category,
@@ -67,23 +70,20 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorState> {
function: Status(code: 'switch_1', value: event.functionOn),
days: ScheduleModel.convertSelectedDaysToStrings(event.selectedDays),
);
bool success = await DevicesManagementApi().addScheduleRecord(newSchedule, deviceId);
if (success) {
add(FetchGarageDoorSchedulesEvent(deviceId: deviceId, category: event.category));
add(FetchGarageDoorSchedulesEvent(deviceId: deviceId, category: 'switch_1'));
} else {
emit(GarageDoorErrorState(message: 'Failed to add schedule.'));
emit(GarageDoorLoadedState(status: deviceStatus));
}
} catch (e) {
emit(GarageDoorErrorState(message: e.toString()));
emit(GarageDoorLoadedState(status: deviceStatus));
}
}
Future<void> _updateSchedule(UpdateGarageDoorScheduleEvent event, Emitter<GarageDoorState> emit) async {
emit(GarageDoorLoadingState());
try {
final updatedSchedules = deviceStatus.schedules.map((schedule) {
final updatedSchedules = deviceStatus.schedules?.map((schedule) {
if (schedule.scheduleId == event.scheduleId) {
return schedule.copyWith(
function: Status(code: 'switch_1', value: event.functionOn),
@@ -92,57 +92,61 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorState> {
}
return schedule;
}).toList();
bool success = await DevicesManagementApi().updateScheduleRecord(
enable: event.enable,
uuid: deviceStatus.uuid,
scheduleId: event.scheduleId,
);
if (success) {
deviceStatus = deviceStatus.copyWith(schedules: updatedSchedules);
emit(GarageDoorLoadedState(status: deviceStatus));
} else {
emit(GarageDoorErrorState(message: 'Failed to update schedule.'));
emit(GarageDoorLoadedState(status: deviceStatus));
}
} catch (e) {
emit(GarageDoorErrorState(message: e.toString()));
emit(GarageDoorLoadedState(status: deviceStatus));
}
}
Future<void> _deleteSchedule(DeleteGarageDoorScheduleEvent event, Emitter<GarageDoorState> emit) async {
emit(GarageDoorLoadingState());
try {
bool success = await DevicesManagementApi().deleteScheduleRecord(deviceStatus.uuid, event.scheduleId);
if (success) {
final updatedSchedules =
deviceStatus.schedules.where((schedule) => schedule.scheduleId != event.scheduleId).toList();
deviceStatus.schedules?.where((schedule) => schedule.scheduleId != event.scheduleId).toList();
deviceStatus = deviceStatus.copyWith(schedules: updatedSchedules);
emit(GarageDoorLoadedState(status: deviceStatus));
} else {
emit(GarageDoorErrorState(message: 'Failed to delete schedule.'));
emit(GarageDoorLoadedState(status: deviceStatus));
}
} catch (e) {
emit(GarageDoorErrorState(message: e.toString()));
emit(GarageDoorLoadedState(status: deviceStatus));
}
}
Future<void> _fetchSchedules(FetchGarageDoorSchedulesEvent event, Emitter<GarageDoorState> emit) async {
emit(GarageDoorLoadingState());
emit(ScheduleGarageLoadingState());
try {
List<ScheduleModel> schedules =
await DevicesManagementApi().getDeviceSchedules(deviceStatus.uuid, event.category);
deviceStatus = deviceStatus.copyWith(schedules: schedules);
emit(GarageDoorLoadedState(status: deviceStatus));
emit(
GarageDoorLoadedState(
status: deviceStatus,
scheduleMode: ScheduleModes.schedule,
),
);
} catch (e) {
emit(GarageDoorErrorState(message: 'Failed to fetch schedules.'));
emit(
GarageDoorLoadedState(
status: deviceStatus,
scheduleMode: ScheduleModes.schedule,
),
);
}
}
void _increaseDelay(IncreaseGarageDoorDelayEvent event, Emitter<GarageDoorState> emit) async {
emit(GarageDoorLoadingNewState(garageDoorModel: deviceStatus));
try {
deviceStatus = deviceStatus.copyWith(delay: deviceStatus.delay + Duration(minutes: 10));
emit(GarageDoorLoadedState(status: deviceStatus));
@@ -152,7 +156,6 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorState> {
}
void _decreaseDelay(DecreaseGarageDoorDelayEvent event, Emitter<GarageDoorState> emit) async {
emit(GarageDoorLoadingNewState(garageDoorModel: deviceStatus));
try {
if (deviceStatus.delay.inMinutes > 10) {
deviceStatus = deviceStatus.copyWith(delay: deviceStatus.delay - Duration(minutes: 10));
@@ -175,14 +178,14 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorState> {
if (currentState is GarageDoorLoadedState) {
List<bool> updatedDays = List.from(currentState.selectedDays);
updatedDays[event.dayIndex] = event.isSelected;
emit(currentState.copyWith(selectedDays: updatedDays));
emit(currentState.copyWith(selectedDays: updatedDays, selectedTime: currentState.selectedTime));
}
}
Future<void> _updateFunctionOn(UpdateFunctionOnEvent event, Emitter<GarageDoorState> emit) async {
final currentState = state;
if (currentState is GarageDoorLoadedState) {
emit(currentState.copyWith(functionOn: event.functionOn));
emit(currentState.copyWith(functionOn: event.functionOn, selectedTime: currentState.selectedTime));
}
}
@@ -201,7 +204,7 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorState> {
Future<void> _fetchRecords(FetchGarageDoorRecordsEvent event, Emitter<GarageDoorState> emit) async {
emit(GarageDoorReportsLoadingState());
try {
final DeviceReport records = await DevicesManagementApi.getDeviceReports(event.deviceId, 'code_for_records');
final DeviceReport records = await DevicesManagementApi.getDeviceReports(event.deviceId, 'switch_1');
emit(GarageDoorReportsState(deviceReport: records));
} catch (e) {
emit(GarageDoorReportsFailedState(error: e.toString()));
@@ -212,43 +215,68 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorState> {
emit(GarageDoorLoadedState(status: deviceStatus));
}
Future<void> _runDeBouncer({
Future<bool> _runDeBouncer({
required dynamic deviceId,
required String code,
required dynamic value,
required dynamic oldValue,
required Emitter<GarageDoorState> emit,
required bool isBatch,
}) async {
late String id;
if (deviceId is List) {
id = deviceId.first;
} else {
id = deviceId;
}
if (_timer != null) {
_timer!.cancel();
}
_timer = Timer(const Duration(seconds: 1), () async {
try {
late bool response;
if (isBatch) {
response = await DevicesManagementApi().deviceBatchControl(deviceId, code, value);
} else {
response = await DevicesManagementApi().deviceControl(deviceId, Status(code: code, value: value));
}
if (!response) {
add(GarageDoorInitialEvent(id));
} else if (response == true && code == 'scene') {
emit(GarageDoorLoadingState());
await Future.delayed(const Duration(seconds: 1));
add(GarageDoorInitialEvent(id));
}
} catch (_) {
await Future.delayed(const Duration(milliseconds: 500));
add(GarageDoorInitialEvent(id));
try {
late bool status;
await Future.delayed(const Duration(milliseconds: 500));
if (isBatch) {
status = await DevicesManagementApi().deviceBatchControl(deviceId, code, value);
} else {
status = await DevicesManagementApi().deviceControl(deviceId, Status(code: code, value: value));
}
});
if (!status) {
_revertValue(code, oldValue, emit);
return false;
} else {
return true;
}
} catch (e) {
_revertValue(code, oldValue, emit);
return false;
}
}
void _revertValue(String code, dynamic oldValue, Emitter<GarageDoorState> emit) {
switch (code) {
case 'switch_1':
if (oldValue is bool) {
deviceStatus = deviceStatus.copyWith(switch1: oldValue);
}
break;
// Add other cases if needed
default:
break;
}
if (state is GarageDoorLoadedState) {
final currentState = state as GarageDoorLoadedState;
emit(currentState.copyWith(status: deviceStatus));
}
}
void _updateLocalValue(String code, dynamic value) {
switch (code) {
case 'switch_1':
if (value is bool) {
deviceStatus = deviceStatus.copyWith(switch1: value);
}
break;
// Add other cases if needed
default:
break;
}
}
@override
Future<void> close() {
_timer?.cancel();
return super.close();
}
}
@@ -4,7 +4,6 @@ import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_reports.dart';
import 'package:syncrow_web/pages/device_managment/garage_door/models/garage_door_model.dart';
import 'package:syncrow_web/pages/device_managment/water_heater/models/schedule_model.dart';
import 'package:syncrow_web/pages/device_managment/water_heater/models/water_heater_status_model.dart';
abstract class GarageDoorState extends Equatable {
@@ -20,7 +19,6 @@ class GarageDoorLoadingState extends GarageDoorState {}
class GarageDoorLoadedState extends GarageDoorState {
final GarageDoorStatusModel status;
final List<ScheduleModel>? schedules;
final Duration? delay;
final DeviceReport? records;
final List<bool> selectedDays;
@@ -31,7 +29,6 @@ class GarageDoorLoadedState extends GarageDoorState {
const GarageDoorLoadedState({
required this.status,
this.schedules,
this.delay,
this.records,
this.selectedDays = const [false, false, false, false, false, false, false],
@@ -44,7 +41,6 @@ class GarageDoorLoadedState extends GarageDoorState {
@override
List<Object?> get props => [
status,
schedules,
delay,
records,
selectedDays,
@@ -56,7 +52,6 @@ class GarageDoorLoadedState extends GarageDoorState {
GarageDoorLoadedState copyWith({
GarageDoorStatusModel? status,
List<ScheduleModel>? schedules,
Duration? delay,
DeviceReport? records,
List<bool>? selectedDays,
@@ -67,7 +62,6 @@ class GarageDoorLoadedState extends GarageDoorState {
}) {
return GarageDoorLoadedState(
status: status ?? this.status,
schedules: schedules ?? this.schedules,
delay: delay ?? this.delay,
records: records ?? this.records,
selectedDays: selectedDays ?? this.selectedDays,
@@ -11,9 +11,9 @@ class GarageDoorStatusModel {
final String doorControl1;
final bool voiceControl1;
final String doorState1;
final bool isOpen;
// final bool isOpen;
final Duration delay;
final List<ScheduleModel> schedules; // Add schedules field
final List<ScheduleModel>? schedules; // Add schedules field
GarageDoorStatusModel({
required this.uuid,
@@ -25,7 +25,7 @@ class GarageDoorStatusModel {
required this.doorControl1,
required this.voiceControl1,
required this.doorState1,
required this.isOpen,
// required this.isOpen,
required this.delay,
required this.schedules, // Initialize schedules
});
@@ -80,7 +80,7 @@ class GarageDoorStatusModel {
doorControl1: doorControl1,
voiceControl1: voiceControl1,
doorState1: doorState1,
isOpen: doorState1 == 'open' ? true : false,
// isOpen: doorState1 == 'open' ? true : false,
delay: Duration(seconds: countdown1),
schedules: schedules, // Assign schedules
);
@@ -96,7 +96,7 @@ class GarageDoorStatusModel {
String? doorControl1,
bool? voiceControl1,
String? doorState1,
bool? isOpen,
// bool? isOpen,
Duration? delay,
List<ScheduleModel>? schedules, // Add schedules to copyWith
}) {
@@ -110,7 +110,7 @@ class GarageDoorStatusModel {
doorControl1: doorControl1 ?? this.doorControl1,
voiceControl1: voiceControl1 ?? this.voiceControl1,
doorState1: doorState1 ?? this.doorState1,
isOpen: isOpen ?? this.isOpen,
// isOpen: isOpen ?? this.isOpen,
delay: delay ?? this.delay,
schedules: schedules ?? this.schedules, // Copy schedules
);
@@ -118,6 +118,6 @@ class GarageDoorStatusModel {
@override
String toString() {
return 'GarageDoorStatusModel(uuid: $uuid, switch1: $switch1, countdown1: $countdown1, doorContactState: $doorContactState, trTimeCon: $trTimeCon, countdownAlarm: $countdownAlarm, doorControl1: $doorControl1, voiceControl1: $voiceControl1, doorState1: $doorState1, isOpen: $isOpen, delay: $delay, schedules: $schedules)';
return 'GarageDoorStatusModel(uuid: $uuid, switch1: $switch1, countdown1: $countdown1, doorContactState: $doorContactState, trTimeCon: $trTimeCon, countdownAlarm: $countdownAlarm, doorControl1: $doorControl1, voiceControl1: $voiceControl1, doorState1: $doorState1, delay: $delay, schedules: $schedules)';
}
}
@@ -1,12 +1,10 @@
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/garage_door/bloc/garage_door_bloc.dart';
import 'package:syncrow_web/pages/device_managment/garage_door/bloc/garage_door_event.dart';
import 'package:syncrow_web/pages/device_managment/garage_door/bloc/garage_door_state.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/device_controls_container.dart';
import 'package:syncrow_web/pages/device_managment/shared/toggle_widget.dart';
import 'package:syncrow_web/utils/color_manager.dart';
import 'package:syncrow_web/utils/constants/assets.dart';
@@ -22,22 +20,19 @@ class GarageDoorControlView extends StatelessWidget with HelperResponsiveLayout
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Garage Door Control')),
body: BlocProvider(
create: (context) => GarageDoorBloc(deviceId: deviceId)..add(GarageDoorInitialEvent(deviceId)),
child: BlocBuilder<GarageDoorBloc, GarageDoorState>(
builder: (context, state) {
if (state is GarageDoorLoadingState || state is GarageDoorLoadingNewState) {
return const Center(child: CircularProgressIndicator());
} else if (state is GarageDoorLoadedState) {
return _buildControlView(context, state.status);
} else if (state is GarageDoorErrorState) {
return Center(child: Text('Error: ${state.message}'));
}
return const Center(child: Text('Unknown state'));
},
),
return BlocProvider(
create: (context) => GarageDoorBloc(deviceId: deviceId)..add(GarageDoorInitialEvent(deviceId)),
child: BlocBuilder<GarageDoorBloc, GarageDoorState>(
builder: (context, state) {
if (state is GarageDoorLoadingState) {
return const Center(child: CircularProgressIndicator());
} else if (state is GarageDoorLoadedState) {
return _buildControlView(context, state.status);
} else if (state is GarageDoorErrorState) {
return Center(child: Text('Error: ${state.message}'));
}
return const Center(child: Text('Unknown state'));
},
),
);
}
@@ -50,6 +45,7 @@ class GarageDoorControlView extends StatelessWidget with HelperResponsiveLayout
return GridView(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
padding: const EdgeInsets.symmetric(horizontal: 50),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: isLarge || isExtraLarge
? 3
@@ -57,25 +53,29 @@ class GarageDoorControlView extends StatelessWidget with HelperResponsiveLayout
? 2
: 1,
childAspectRatio: 1.5,
mainAxisExtent: 170,
crossAxisSpacing: 12,
mainAxisSpacing: 12,
),
children: [
IconNameStatusContainer(
isFullIcon: true,
name: status.doorContactState ? 'Open' : 'Close',
icon: Assets.openCloseDoor,
isFullIcon: false,
name: status.switch1 ? 'Opened' : 'Closed',
icon: status.switch1 ? Assets.openedDoor : Assets.closedDoor,
onTap: () {
context.read<GarageDoorBloc>().add(
ToggleGarageDoorEvent(deviceId: status.uuid, isOpen: !status.isOpen, code: 'switch_1'),
ToggleGarageDoorEvent(deviceId: status.uuid, isOpen: !status.switch1, code: 'switch_1'),
);
},
status: status.doorContactState,
textColor: status.doorContactState ? ColorsManager.red : ColorsManager.blackColor,
paddingAmount: 8,
status: status.switch1,
textColor: ColorsManager.blackColor,
//paddingAmount: 6,
),
GestureDetector(
IconNameStatusContainer(
onTap: () {
context.read<GarageDoorBloc>().add(
FetchGarageDoorSchedulesEvent(deviceId: deviceId, category: 'switch_1'),
);
showDialog(
context: context,
builder: (ctx) => BlocProvider.value(
@@ -83,43 +83,18 @@ class GarageDoorControlView extends StatelessWidget with HelperResponsiveLayout
child: BuildGarageDoorScheduleView(status: status),
));
},
child: DeviceControlsContainer(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
Container(
width: 60,
height: 60,
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: ColorsManager.whiteColors,
),
padding: const EdgeInsets.all(12),
child: ClipOval(
child: SvgPicture.asset(
Assets.scheduling,
fit: BoxFit.fill,
),
),
),
const SizedBox(height: 8),
Text(
'Scheduling',
textAlign: TextAlign.center,
style: context.textTheme.titleMedium!.copyWith(
fontWeight: FontWeight.w400,
color: ColorsManager.blackColor,
),
),
],
),
),
name: 'Scheduling',
icon: Assets.acSchedule,
status: false,
textColor: ColorsManager.blackColor,
isFullIcon: false,
//paddingAmount: 15,
),
ToggleWidget(
label: '',
labelWidget: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
IconButton(
onPressed: () {
@@ -168,9 +143,35 @@ class GarageDoorControlView extends StatelessWidget with HelperResponsiveLayout
value: false,
code: 'switch_1',
deviceId: status.uuid,
icon: Assets.acSchedule,
icon: Assets.doorDelay,
onChange: (value) {},
),
IconNameStatusContainer(
isFullIcon: false,
name: 'Records',
icon: Assets.records,
onTap: () {
// context.read<GarageDoorBloc>().add(
// (deviceId: status.uuid, isOpen: !status.isOpen, code: 'switch_1'),
// );
},
status: false,
textColor: ColorsManager.blackColor,
//paddingAmount: 6,
),
IconNameStatusContainer(
isFullIcon: false,
name: 'Preferences',
icon: Assets.preferences,
onTap: () {
// context.read<GarageDoorBloc>().add(
// (deviceId: status.uuid, isOpen: !status.isOpen, code: 'switch_1'),
// );
},
status: false,
textColor: ColorsManager.blackColor,
// paddingAmount: 6,
),
],
);
}
@@ -52,7 +52,7 @@ class ScheduleGarageTableWidget extends StatelessWidget {
if (state is ScheduleGarageLoadingState) {
return const SizedBox(height: 200, child: Center(child: CircularProgressIndicator()));
}
if (state is GarageDoorLoadedState && state.schedules?.isEmpty == true) {
if (state is GarageDoorLoadedState && state.status.schedules == null) {
return _buildEmptyState(context);
} else if (state is GarageDoorLoadedState) {
return Container(
@@ -110,9 +110,9 @@ class ScheduleGarageTableWidget extends StatelessWidget {
border: TableBorder.all(color: ColorsManager.graysColor),
defaultVerticalAlignment: TableCellVerticalAlignment.middle,
children: [
if (state.schedules != null)
for (int i = 0; i < state.schedules!.length; i++)
_buildScheduleRow(state.schedules![i], i, context, state),
if (state.status.schedules != null)
for (int i = 0; i < state.status.schedules!.length; i++)
_buildScheduleRow(state.status.schedules![i], i, context, state),
],
),
),
@@ -3,10 +3,10 @@ import 'package:syncrow_web/pages/common/buttons/default_button.dart';
import 'package:syncrow_web/utils/color_manager.dart';
import 'package:syncrow_web/utils/extension/build_context_x.dart';
class ScheduleModeButtons extends StatelessWidget {
class ScheduleGarageModeButtons extends StatelessWidget {
final VoidCallback onSave;
const ScheduleModeButtons({
const ScheduleGarageModeButtons({
super.key,
required this.onSave,
});
@@ -6,7 +6,7 @@ import 'package:syncrow_web/pages/device_managment/garage_door/helper/garage_doo
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_header.dart';
import 'package:syncrow_web/pages/device_managment/garage_door/widgets/schedule_garage_managment_ui.dart';
import 'package:syncrow_web/pages/device_managment/garage_door/widgets/schedule_garage_mode_selector.dart';
import 'package:syncrow_web/pages/device_managment/garage_door/widgets/schedule_garage_mode_buttons.dart';
class BuildGarageDoorScheduleView extends StatefulWidget {
const BuildGarageDoorScheduleView({super.key, required this.status});
@@ -43,8 +43,6 @@ class _BuildScheduleViewState extends State<BuildGarageDoorScheduleView> {
children: [
const ScheduleGarageHeader(),
const SizedBox(height: 20),
ScheduleGarageDoorModeSelector(state: state),
const SizedBox(height: 20),
ScheduleGarageManagementUI(
state: state,
onAddSchedule: () {
@@ -52,20 +50,32 @@ class _BuildScheduleViewState extends State<BuildGarageDoorScheduleView> {
schedule: null, index: null, isEdit: false);
},
),
const SizedBox(height: 20),
ScheduleGarageModeButtons(
onSave: () {
Navigator.pop(context);
},
),
],
);
}
if (state is GarageDoorLoadingState) {
return const SizedBox(
if (state is ScheduleGarageLoadingState) {
return SizedBox(
height: 200,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
ScheduleGarageHeader(),
SizedBox(
const ScheduleGarageHeader(),
const SizedBox(
height: 50,
),
const Center(child: CircularProgressIndicator()),
const SizedBox(
height: 20,
),
Center(child: CircularProgressIndicator()),
ScheduleGarageModeButtons(
onSave: () {},
),
],
));
}
@@ -14,8 +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';
class MainDoorSensorControlView extends StatelessWidget
with HelperResponsiveLayout {
class MainDoorSensorControlView extends StatelessWidget with HelperResponsiveLayout {
const MainDoorSensorControlView({super.key, required this.device});
final AllDevicesModel device;
@@ -23,12 +22,10 @@ class MainDoorSensorControlView extends StatelessWidget
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (context) => MainDoorSensorBloc()
..add(MainDoorSensorFetchDeviceEvent(device.uuid!)),
create: (context) => MainDoorSensorBloc()..add(MainDoorSensorFetchDeviceEvent(device.uuid!)),
child: BlocBuilder<MainDoorSensorBloc, MainDoorSensorState>(
builder: (context, state) {
if (state is MainDoorSensorLoadingState ||
state is MainDoorSensorReportsLoadingState) {
if (state is MainDoorSensorLoadingState || state is MainDoorSensorReportsLoadingState) {
return const Center(child: CircularProgressIndicator());
} else if (state is MainDoorSensorDeviceStatusLoaded) {
return _buildStatusControls(context, state.status);
@@ -37,15 +34,12 @@ class MainDoorSensorControlView extends StatelessWidget
report: state.deviceReport,
onRowTap: (index) {},
onClose: () {
context
.read<MainDoorSensorBloc>()
.add(MainDoorSensorFetchDeviceEvent(device.uuid!));
context.read<MainDoorSensorBloc>().add(MainDoorSensorFetchDeviceEvent(device.uuid!));
},
hideValueShowDescription: true,
mainDoorSensor: true,
);
} else if (state is MainDoorSensorFailedState ||
state is MainDoorSensorBatchFailedState) {
} else if (state is MainDoorSensorFailedState || state is MainDoorSensorBatchFailedState) {
return const Center(child: Text('Error fetching status'));
} else {
return const Center(child: CircularProgressIndicator());
@@ -54,8 +48,7 @@ class MainDoorSensorControlView extends StatelessWidget
));
}
Widget _buildStatusControls(
BuildContext context, MainDoorSensorStatusModel status) {
Widget _buildStatusControls(BuildContext context, MainDoorSensorStatusModel status) {
final isExtraLarge = isExtraLargeScreenSize(context);
final isLarge = isLargeScreenSize(context);
final isMedium = isMediumScreenSize(context);
@@ -80,9 +73,7 @@ class MainDoorSensorControlView extends StatelessWidget
icon: Assets.openCloseDoor,
onTap: () {},
status: status.doorContactState,
textColor: status.doorContactState
? ColorsManager.red
: ColorsManager.blackColor,
textColor: status.doorContactState ? ColorsManager.red : ColorsManager.blackColor,
paddingAmount: 8,
),
IconNameStatusContainer(
@@ -90,9 +81,7 @@ class MainDoorSensorControlView extends StatelessWidget
name: 'Open/Close\nRecord',
icon: Assets.openCloseRecords,
onTap: () {
final from = DateTime.now()
.subtract(const Duration(days: 30))
.millisecondsSinceEpoch;
final from = DateTime.now().subtract(const Duration(days: 30)).millisecondsSinceEpoch;
final to = DateTime.now().millisecondsSinceEpoch;
context.read<MainDoorSensorBloc>().add(
MainDoorSensorReportsEvent(
@@ -161,22 +150,19 @@ class IconNameStatusContainer extends StatelessWidget {
),
)
else
Container(
width: 60,
ClipOval(
child: Container(
height: 60,
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: ColorsManager.whiteColors,
width: 60,
padding: EdgeInsets.all(paddingAmount ?? 8),
color: ColorsManager.whiteColors,
child: SvgPicture.asset(
icon,
width: 35,
height: 35,
fit: BoxFit.contain,
),
//margin: const EdgeInsets.symmetric(horizontal: 4),
padding: EdgeInsets.all(paddingAmount ?? 12),
child: ClipOval(
child: SvgPicture.asset(
icon,
fit: BoxFit.contain,
),
),
),
)),
const Spacer(),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 6),
@@ -1,8 +1,5 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.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/format_date_time.dart';
@@ -22,7 +19,7 @@ class DeviceControlDialog extends StatelessWidget with RouteControlsBasedCode {
),
child: SizedBox(
width: 798,
// height: context.screenHeight * 0.7,
//height: context.screenHeight * 0.7,
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(20.0),
@@ -113,13 +110,9 @@ class DeviceControlDialog extends StatelessWidget with RouteControlsBasedCode {
),
_buildInfoRow(
'Battery Level:',
device.batteryLevel != null
? '${device.batteryLevel ?? 0}%'
: "-",
device.batteryLevel != null ? '${device.batteryLevel ?? 0}%' : "-",
statusColor: device.batteryLevel != null
? (device.batteryLevel! < 20
? ColorsManager.red
: ColorsManager.green)
? (device.batteryLevel! < 20 ? ColorsManager.red : ColorsManager.green)
: null,
),
],
+5
View File
@@ -150,4 +150,9 @@ class Assets {
//assets/icons/preferences.svg
static const String preferences = 'assets/icons/preferences.svg';
static const String openedDoor = 'assets/icons/opened_door.svg';
static const String closedDoor = 'assets/icons/closed_door.svg';
static const String doorDelay = 'assets/icons/door_delay.svg';
static const String records = 'assets/icons/records.svg';
}