mirror of
https://github.com/SyncrowIOT/web.git
synced 2026-10-23 11:47:57 +00:00
push garage door schedule
This commit is contained in:
@@ -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,
|
||||
),
|
||||
],
|
||||
|
||||
@@ -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';
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user