mirror of
https://github.com/SyncrowIOT/web.git
synced 2025-11-27 02:34:56 +00:00
Compare commits
1 Commits
fix-schedu
...
SP-1805-fe
| Author | SHA1 | Date | |
|---|---|---|---|
| e6fe9f35b0 |
@ -17,8 +17,8 @@ class DeviceLocationDetailsServiceDecorator implements DeviceLocationService {
|
|||||||
'reverse',
|
'reverse',
|
||||||
queryParameters: {
|
queryParameters: {
|
||||||
'format': 'json',
|
'format': 'json',
|
||||||
'lat': 25.1880567,
|
'lat': param.latitude,
|
||||||
'lon': 55.266608,
|
'lon': param.longitude,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -57,9 +57,6 @@ class Status {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
factory Status.fromJson(String source) => Status.fromMap(json.decode(source));
|
|
||||||
|
|
||||||
String toJson() => json.encode(toMap());
|
|
||||||
Status copyWith({
|
Status copyWith({
|
||||||
String? code,
|
String? code,
|
||||||
dynamic value,
|
dynamic value,
|
||||||
@ -69,4 +66,8 @@ class Status {
|
|||||||
value: value ?? this.value,
|
value: value ?? this.value,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
factory Status.fromJson(String source) => Status.fromMap(json.decode(source));
|
||||||
|
|
||||||
|
String toJson() => json.encode(toMap());
|
||||||
}
|
}
|
||||||
|
|||||||
@ -68,6 +68,7 @@ class DeviceManagementBody extends StatelessWidget with HelperResponsiveLayout {
|
|||||||
children: [
|
children: [
|
||||||
Expanded(child: SpaceTreeView(
|
Expanded(child: SpaceTreeView(
|
||||||
onSelect: () {
|
onSelect: () {
|
||||||
|
context.read<DeviceManagementBloc>().add(ResetFilters());
|
||||||
context.read<DeviceManagementBloc>().add(FetchDevices(context));
|
context.read<DeviceManagementBloc>().add(FetchDevices(context));
|
||||||
},
|
},
|
||||||
)),
|
)),
|
||||||
|
|||||||
@ -62,10 +62,9 @@ class CurtainModuleItems extends StatelessWidget with HelperResponsiveLayout {
|
|||||||
BlocProvider.of<CurtainModuleBloc>(context),
|
BlocProvider.of<CurtainModuleBloc>(context),
|
||||||
child: BuildScheduleView(
|
child: BuildScheduleView(
|
||||||
deviceUuid: deviceId,
|
deviceUuid: deviceId,
|
||||||
category: 'timer',
|
category: 'CUR_2',
|
||||||
code: 'control',
|
code: 'control',
|
||||||
countdownCode: 'timer',
|
|
||||||
deviceType: 'CUR_2',
|
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
},
|
},
|
||||||
|
|||||||
@ -40,7 +40,7 @@ class OneGangGlassSwitchBloc
|
|||||||
emit(OneGangGlassSwitchLoading());
|
emit(OneGangGlassSwitchLoading());
|
||||||
try {
|
try {
|
||||||
final status = await DevicesManagementApi().getDeviceStatus(event.deviceId);
|
final status = await DevicesManagementApi().getDeviceStatus(event.deviceId);
|
||||||
_listenToChanges(event.deviceId);
|
_listenToChanges(event.deviceId, emit);
|
||||||
deviceStatus = OneGangGlassStatusModel.fromJson(event.deviceId, status.status);
|
deviceStatus = OneGangGlassStatusModel.fromJson(event.deviceId, status.status);
|
||||||
emit(OneGangGlassSwitchStatusLoaded(deviceStatus));
|
emit(OneGangGlassSwitchStatusLoaded(deviceStatus));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -48,28 +48,42 @@ class OneGangGlassSwitchBloc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StreamSubscription<DatabaseEvent>? _deviceStatusSubscription;
|
void _listenToChanges(
|
||||||
|
String deviceId,
|
||||||
void _listenToChanges(String deviceId) {
|
Emitter<OneGangGlassSwitchState> emit,
|
||||||
|
) {
|
||||||
try {
|
try {
|
||||||
final ref = FirebaseDatabase.instance.ref('device-status/$deviceId');
|
final ref = FirebaseDatabase.instance.ref('device-status/$deviceId');
|
||||||
_deviceStatusSubscription = ref.onValue.listen((DatabaseEvent event) async {
|
final stream = ref.onValue;
|
||||||
if (event.snapshot.value == null) return;
|
|
||||||
|
|
||||||
final usersMap = event.snapshot.value! as Map<dynamic, dynamic>;
|
stream.listen((DatabaseEvent event) {
|
||||||
|
final data = event.snapshot.value as Map<dynamic, dynamic>?;
|
||||||
|
if (data == null) return;
|
||||||
|
|
||||||
final statusList = <Status>[];
|
final statusList = <Status>[];
|
||||||
|
if (data['status'] != null) {
|
||||||
usersMap['status'].forEach((element) {
|
for (var element in data['status']) {
|
||||||
statusList.add(Status(code: element['code'], value: element['value']));
|
statusList.add(
|
||||||
});
|
Status(
|
||||||
|
code: element['code'].toString(),
|
||||||
deviceStatus =
|
value: element['value'].toString(),
|
||||||
OneGangGlassStatusModel.fromJson(usersMap['productUuid'], statusList);
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (statusList.isNotEmpty) {
|
||||||
|
final newStatus = OneGangGlassStatusModel.fromJson(deviceId, statusList);
|
||||||
|
if (newStatus != deviceStatus) {
|
||||||
|
deviceStatus = newStatus;
|
||||||
|
if (!isClosed) {
|
||||||
add(StatusUpdated(deviceStatus));
|
add(StatusUpdated(deviceStatus));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
} catch (_) {}
|
} catch (e) {
|
||||||
|
emit(OneGangGlassSwitchError('Failed to listen to changes: $e'));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onStatusUpdated(
|
void _onStatusUpdated(
|
||||||
@ -160,10 +174,4 @@ class OneGangGlassSwitchBloc
|
|||||||
deviceStatus = deviceStatus.copyWith(switch1: value);
|
deviceStatus = deviceStatus.copyWith(switch1: value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> close() {
|
|
||||||
_deviceStatusSubscription?.cancel();
|
|
||||||
return super.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -90,8 +90,6 @@ class OneGangGlassSwitchControlView extends StatelessWidget
|
|||||||
child: BuildScheduleView(
|
child: BuildScheduleView(
|
||||||
category: 'switch_1',
|
category: 'switch_1',
|
||||||
deviceUuid: deviceId,
|
deviceUuid: deviceId,
|
||||||
countdownCode: 'countdown_1',
|
|
||||||
deviceType: '1GT',
|
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
},
|
},
|
||||||
|
|||||||
@ -80,8 +80,6 @@ class WallLightDeviceControl extends StatelessWidget
|
|||||||
child: BuildScheduleView(
|
child: BuildScheduleView(
|
||||||
category: 'switch_1',
|
category: 'switch_1',
|
||||||
deviceUuid: deviceId,
|
deviceUuid: deviceId,
|
||||||
countdownCode: 'countdown_1',
|
|
||||||
deviceType: '1G',
|
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
},
|
},
|
||||||
|
|||||||
@ -47,7 +47,7 @@ class ScheduleBloc extends Bloc<ScheduleEvent, ScheduleState> {
|
|||||||
final success = await RemoteControlDeviceService().controlDevice(
|
final success = await RemoteControlDeviceService().controlDevice(
|
||||||
deviceUuid: deviceId,
|
deviceUuid: deviceId,
|
||||||
status: Status(
|
status: Status(
|
||||||
code: event.countdownCode,
|
code: 'countdown_1',
|
||||||
value: 0,
|
value: 0,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@ -80,18 +80,15 @@ class ScheduleBloc extends Bloc<ScheduleEvent, ScheduleState> {
|
|||||||
) {
|
) {
|
||||||
if (state is ScheduleLoaded) {
|
if (state is ScheduleLoaded) {
|
||||||
final currentState = state as ScheduleLoaded;
|
final currentState = state as ScheduleLoaded;
|
||||||
|
|
||||||
emit(currentState.copyWith(
|
emit(currentState.copyWith(
|
||||||
countdownSeconds: currentState.countdownSeconds,
|
|
||||||
selectedTime: currentState.selectedTime,
|
|
||||||
deviceId: deviceId,
|
|
||||||
scheduleMode: event.scheduleMode,
|
scheduleMode: event.scheduleMode,
|
||||||
countdownHours: currentState.countdownHours,
|
countdownRemaining: Duration.zero,
|
||||||
countdownMinutes: currentState.countdownMinutes,
|
countdownHours: 0,
|
||||||
inchingHours: currentState.inchingHours,
|
countdownMinutes: 0,
|
||||||
inchingMinutes: currentState.inchingMinutes,
|
inchingHours: 0,
|
||||||
|
inchingMinutes: 0,
|
||||||
|
isCountdownActive: false,
|
||||||
isInchingActive: false,
|
isInchingActive: false,
|
||||||
isCountdownActive: currentState.countdownRemaining > Duration.zero,
|
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -224,6 +221,7 @@ class ScheduleBloc extends Bloc<ScheduleEvent, ScheduleState> {
|
|||||||
deviceId,
|
deviceId,
|
||||||
event.category,
|
event.category,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (state is ScheduleLoaded) {
|
if (state is ScheduleLoaded) {
|
||||||
final currentState = state as ScheduleLoaded;
|
final currentState = state as ScheduleLoaded;
|
||||||
emit(currentState.copyWith(
|
emit(currentState.copyWith(
|
||||||
@ -287,8 +285,9 @@ class ScheduleBloc extends Bloc<ScheduleEvent, ScheduleState> {
|
|||||||
) async {
|
) async {
|
||||||
try {
|
try {
|
||||||
if (state is ScheduleLoaded) {
|
if (state is ScheduleLoaded) {
|
||||||
|
final dateTime = DateTime.parse(event.time);
|
||||||
Status status = Status(code: '', value: '');
|
Status status = Status(code: '', value: '');
|
||||||
if (event.deviceType == 'CUR_2') {
|
if (event.category == 'CUR_2') {
|
||||||
status = status.copyWith(
|
status = status.copyWith(
|
||||||
code: 'control',
|
code: 'control',
|
||||||
value: event.functionOn == true ? 'open' : 'close');
|
value: event.functionOn == true ? 'open' : 'close');
|
||||||
@ -296,8 +295,6 @@ class ScheduleBloc extends Bloc<ScheduleEvent, ScheduleState> {
|
|||||||
status =
|
status =
|
||||||
status.copyWith(code: event.category, value: event.functionOn);
|
status.copyWith(code: event.category, value: event.functionOn);
|
||||||
}
|
}
|
||||||
|
|
||||||
final dateTime = DateTime.parse(event.time);
|
|
||||||
final updatedSchedule = ScheduleEntry(
|
final updatedSchedule = ScheduleEntry(
|
||||||
scheduleId: event.scheduleId,
|
scheduleId: event.scheduleId,
|
||||||
category: event.category,
|
category: event.category,
|
||||||
@ -408,7 +405,7 @@ class ScheduleBloc extends Bloc<ScheduleEvent, ScheduleState> {
|
|||||||
final totalSeconds =
|
final totalSeconds =
|
||||||
Duration(hours: event.hours, minutes: event.minutes).inSeconds;
|
Duration(hours: event.hours, minutes: event.minutes).inSeconds;
|
||||||
final code = event.mode == ScheduleModes.countdown
|
final code = event.mode == ScheduleModes.countdown
|
||||||
? event.countDownCode
|
? 'countdown_1'
|
||||||
: 'switch_inching';
|
: 'switch_inching';
|
||||||
final currentState = state as ScheduleLoaded;
|
final currentState = state as ScheduleLoaded;
|
||||||
final duration = Duration(seconds: totalSeconds);
|
final duration = Duration(seconds: totalSeconds);
|
||||||
@ -435,7 +432,7 @@ class ScheduleBloc extends Bloc<ScheduleEvent, ScheduleState> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
if (code == event.countDownCode) {
|
if (code == 'countdown_1') {
|
||||||
final countdownDuration = Duration(seconds: totalSeconds);
|
final countdownDuration = Duration(seconds: totalSeconds);
|
||||||
|
|
||||||
emit(
|
emit(
|
||||||
@ -449,7 +446,7 @@ class ScheduleBloc extends Bloc<ScheduleEvent, ScheduleState> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (countdownDuration.inSeconds > 0) {
|
if (countdownDuration.inSeconds > 0) {
|
||||||
_startCountdownTimer(emit, countdownDuration, event.countDownCode);
|
_startCountdownTimer(emit, countdownDuration);
|
||||||
} else {
|
} else {
|
||||||
_countdownTimer?.cancel();
|
_countdownTimer?.cancel();
|
||||||
emit(
|
emit(
|
||||||
@ -479,7 +476,9 @@ class ScheduleBloc extends Bloc<ScheduleEvent, ScheduleState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _startCountdownTimer(
|
void _startCountdownTimer(
|
||||||
Emitter<ScheduleState> emit, Duration duration, String countdownCode) {
|
Emitter<ScheduleState> emit,
|
||||||
|
Duration duration,
|
||||||
|
) {
|
||||||
_countdownTimer?.cancel();
|
_countdownTimer?.cancel();
|
||||||
_countdownTimer = Timer.periodic(const Duration(seconds: 1), (timer) {
|
_countdownTimer = Timer.periodic(const Duration(seconds: 1), (timer) {
|
||||||
if (_currentCountdown != null && _currentCountdown! > Duration.zero) {
|
if (_currentCountdown != null && _currentCountdown! > Duration.zero) {
|
||||||
@ -489,7 +488,6 @@ class ScheduleBloc extends Bloc<ScheduleEvent, ScheduleState> {
|
|||||||
} else {
|
} else {
|
||||||
timer.cancel();
|
timer.cancel();
|
||||||
add(StopScheduleEvent(
|
add(StopScheduleEvent(
|
||||||
countdownCode: countdownCode,
|
|
||||||
mode: _currentCountdown == null
|
mode: _currentCountdown == null
|
||||||
? ScheduleModes.countdown
|
? ScheduleModes.countdown
|
||||||
: ScheduleModes.inching,
|
: ScheduleModes.inching,
|
||||||
@ -526,75 +524,70 @@ class ScheduleBloc extends Bloc<ScheduleEvent, ScheduleState> {
|
|||||||
try {
|
try {
|
||||||
final status =
|
final status =
|
||||||
await DevicesManagementApi().getDeviceStatus(event.deviceId);
|
await DevicesManagementApi().getDeviceStatus(event.deviceId);
|
||||||
int totalSeconds = 0;
|
print(status.status);
|
||||||
final countdownItem = status.status.firstWhere(
|
|
||||||
(item) => item.code == event.countdownCode,
|
|
||||||
orElse: () => Status(code: '', value: 0),
|
|
||||||
);
|
|
||||||
totalSeconds = (countdownItem.value as int?) ?? 0;
|
|
||||||
final countdownHours = totalSeconds ~/ 3600;
|
|
||||||
final countdownMinutes = (totalSeconds % 3600) ~/ 60;
|
|
||||||
final countdownSeconds = totalSeconds % 60;
|
|
||||||
|
|
||||||
final deviceStatus =
|
final deviceStatus =
|
||||||
WaterHeaterStatusModel.fromJson(event.deviceId, status.status);
|
WaterHeaterStatusModel.fromJson(event.deviceId, status.status);
|
||||||
final isCountdownActive = totalSeconds > 0;
|
|
||||||
final isInchingActive = !isCountdownActive &&
|
|
||||||
(deviceStatus.inchingHours > 0 || deviceStatus.inchingMinutes > 0);
|
|
||||||
|
|
||||||
final newState = state is ScheduleLoaded
|
final scheduleMode =
|
||||||
? (state as ScheduleLoaded).copyWith(
|
deviceStatus.countdownHours > 0 || deviceStatus.countdownMinutes > 0
|
||||||
scheduleMode: ScheduleModes.schedule,
|
? ScheduleModes.countdown
|
||||||
countdownHours: countdownHours,
|
: deviceStatus.inchingHours > 0 || deviceStatus.inchingMinutes > 0
|
||||||
countdownMinutes: countdownMinutes,
|
? ScheduleModes.inching
|
||||||
countdownSeconds: countdownSeconds,
|
: ScheduleModes.schedule;
|
||||||
|
final isCountdown = scheduleMode == ScheduleModes.countdown;
|
||||||
|
final isInching = scheduleMode == ScheduleModes.inching;
|
||||||
|
|
||||||
|
Duration? countdownRemaining;
|
||||||
|
var isCountdownActive = false;
|
||||||
|
var isInchingActive = false;
|
||||||
|
|
||||||
|
if (isCountdown) {
|
||||||
|
countdownRemaining = Duration(
|
||||||
|
hours: deviceStatus.countdownHours,
|
||||||
|
minutes: deviceStatus.countdownMinutes,
|
||||||
|
);
|
||||||
|
isCountdownActive = countdownRemaining > Duration.zero;
|
||||||
|
} else if (isInching) {
|
||||||
|
isInchingActive = Duration(
|
||||||
|
hours: deviceStatus.inchingHours,
|
||||||
|
minutes: deviceStatus.inchingMinutes,
|
||||||
|
) >
|
||||||
|
Duration.zero;
|
||||||
|
}
|
||||||
|
if (state is ScheduleLoaded) {
|
||||||
|
final currentState = state as ScheduleLoaded;
|
||||||
|
emit(currentState.copyWith(
|
||||||
|
scheduleMode: scheduleMode,
|
||||||
|
countdownHours: deviceStatus.countdownHours,
|
||||||
|
countdownMinutes: deviceStatus.countdownMinutes,
|
||||||
inchingHours: deviceStatus.inchingHours,
|
inchingHours: deviceStatus.inchingHours,
|
||||||
inchingMinutes: deviceStatus.inchingMinutes,
|
inchingMinutes: deviceStatus.inchingMinutes,
|
||||||
isCountdownActive: isCountdownActive,
|
isCountdownActive: isCountdownActive,
|
||||||
isInchingActive: isInchingActive,
|
isInchingActive: isInchingActive,
|
||||||
countdownRemaining: isCountdownActive
|
countdownRemaining: countdownRemaining ?? Duration.zero,
|
||||||
? Duration(seconds: totalSeconds)
|
));
|
||||||
: Duration.zero,
|
} else {
|
||||||
)
|
emit(ScheduleLoaded(
|
||||||
: ScheduleLoaded(
|
|
||||||
scheduleMode: ScheduleModes.schedule,
|
|
||||||
schedules: const [],
|
schedules: const [],
|
||||||
selectedTime: null,
|
selectedTime: null,
|
||||||
selectedDays: List.filled(7, false),
|
selectedDays: List.filled(7, false),
|
||||||
functionOn: false,
|
functionOn: false,
|
||||||
isEditing: false,
|
isEditing: false,
|
||||||
deviceId: event.deviceId,
|
deviceId: deviceId,
|
||||||
countdownHours: countdownHours,
|
scheduleMode: scheduleMode,
|
||||||
countdownMinutes: countdownMinutes,
|
countdownHours: deviceStatus.countdownHours,
|
||||||
countdownSeconds: countdownSeconds,
|
countdownMinutes: deviceStatus.countdownMinutes,
|
||||||
inchingHours: deviceStatus.inchingHours,
|
inchingHours: deviceStatus.inchingHours,
|
||||||
inchingMinutes: deviceStatus.inchingMinutes,
|
inchingMinutes: deviceStatus.inchingMinutes,
|
||||||
isCountdownActive: isCountdownActive,
|
isCountdownActive: isCountdownActive,
|
||||||
isInchingActive: isInchingActive,
|
isInchingActive: isInchingActive,
|
||||||
countdownRemaining: isCountdownActive
|
countdownRemaining: countdownRemaining ?? Duration.zero,
|
||||||
? Duration(seconds: totalSeconds)
|
|
||||||
: Duration.zero,
|
|
||||||
);
|
|
||||||
emit(newState);
|
|
||||||
|
|
||||||
if (isCountdownActive) {
|
|
||||||
_countdownTimer?.cancel();
|
|
||||||
_currentCountdown = Duration(seconds: totalSeconds);
|
|
||||||
countdownRemaining = _currentCountdown!;
|
|
||||||
|
|
||||||
if (totalSeconds > 0) {
|
|
||||||
_startCountdownTimer(
|
|
||||||
emit, Duration(seconds: totalSeconds), event.countdownCode);
|
|
||||||
} else {
|
|
||||||
add(StopScheduleEvent(
|
|
||||||
countdownCode: event.countdownCode,
|
|
||||||
mode: ScheduleModes.countdown,
|
|
||||||
deviceId: event.deviceId,
|
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
_countdownTimer?.cancel();
|
// if (isCountdownActive && countdownRemaining != null) {
|
||||||
}
|
// _startCountdownTimer(emit, countdownRemaining);
|
||||||
|
// }
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(ScheduleError('Failed to fetch device status: $e'));
|
emit(ScheduleError('Failed to fetch device status: $e'));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -91,7 +91,6 @@ class ScheduleEditEvent extends ScheduleEvent {
|
|||||||
final String time;
|
final String time;
|
||||||
final List<String> selectedDays;
|
final List<String> selectedDays;
|
||||||
final bool functionOn;
|
final bool functionOn;
|
||||||
final String deviceType;
|
|
||||||
|
|
||||||
const ScheduleEditEvent({
|
const ScheduleEditEvent({
|
||||||
required this.scheduleId,
|
required this.scheduleId,
|
||||||
@ -99,7 +98,6 @@ class ScheduleEditEvent extends ScheduleEvent {
|
|||||||
required this.time,
|
required this.time,
|
||||||
required this.selectedDays,
|
required this.selectedDays,
|
||||||
required this.functionOn,
|
required this.functionOn,
|
||||||
required this.deviceType,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -109,7 +107,6 @@ class ScheduleEditEvent extends ScheduleEvent {
|
|||||||
time,
|
time,
|
||||||
selectedDays,
|
selectedDays,
|
||||||
functionOn,
|
functionOn,
|
||||||
deviceType,
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -141,13 +138,11 @@ class ScheduleUpdateEntryEvent extends ScheduleEvent {
|
|||||||
|
|
||||||
class UpdateScheduleModeEvent extends ScheduleEvent {
|
class UpdateScheduleModeEvent extends ScheduleEvent {
|
||||||
final ScheduleModes scheduleMode;
|
final ScheduleModes scheduleMode;
|
||||||
final String countdownCode;
|
|
||||||
|
|
||||||
const UpdateScheduleModeEvent(
|
const UpdateScheduleModeEvent({required this.scheduleMode});
|
||||||
{required this.scheduleMode, required this.countdownCode});
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Object> get props => [scheduleMode, countdownCode!];
|
List<Object> get props => [scheduleMode];
|
||||||
}
|
}
|
||||||
|
|
||||||
class UpdateCountdownTimeEvent extends ScheduleEvent {
|
class UpdateCountdownTimeEvent extends ScheduleEvent {
|
||||||
@ -182,32 +177,28 @@ class StartScheduleEvent extends ScheduleEvent {
|
|||||||
final ScheduleModes mode;
|
final ScheduleModes mode;
|
||||||
final int hours;
|
final int hours;
|
||||||
final int minutes;
|
final int minutes;
|
||||||
final String countDownCode;
|
|
||||||
|
|
||||||
const StartScheduleEvent({
|
const StartScheduleEvent({
|
||||||
required this.mode,
|
required this.mode,
|
||||||
required this.hours,
|
required this.hours,
|
||||||
required this.minutes,
|
required this.minutes,
|
||||||
required this.countDownCode,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Object?> get props => [mode, hours, minutes, countDownCode];
|
List<Object?> get props => [mode, hours, minutes];
|
||||||
}
|
}
|
||||||
|
|
||||||
class StopScheduleEvent extends ScheduleEvent {
|
class StopScheduleEvent extends ScheduleEvent {
|
||||||
final ScheduleModes mode;
|
final ScheduleModes mode;
|
||||||
final String deviceId;
|
final String deviceId;
|
||||||
final String countdownCode;
|
|
||||||
|
|
||||||
const StopScheduleEvent({
|
const StopScheduleEvent({
|
||||||
required this.mode,
|
required this.mode,
|
||||||
required this.deviceId,
|
required this.deviceId,
|
||||||
required this.countdownCode,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Object?> get props => [mode, deviceId, countdownCode];
|
List<Object?> get props => [mode, deviceId];
|
||||||
}
|
}
|
||||||
|
|
||||||
class ScheduleDecrementCountdownEvent extends ScheduleEvent {
|
class ScheduleDecrementCountdownEvent extends ScheduleEvent {
|
||||||
@ -219,13 +210,11 @@ class ScheduleDecrementCountdownEvent extends ScheduleEvent {
|
|||||||
|
|
||||||
class ScheduleFetchStatusEvent extends ScheduleEvent {
|
class ScheduleFetchStatusEvent extends ScheduleEvent {
|
||||||
final String deviceId;
|
final String deviceId;
|
||||||
final String countdownCode;
|
|
||||||
|
|
||||||
const ScheduleFetchStatusEvent(
|
const ScheduleFetchStatusEvent(this.deviceId);
|
||||||
{required this.deviceId, required this.countdownCode});
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Object> get props => [deviceId, countdownCode];
|
List<Object> get props => [deviceId];
|
||||||
}
|
}
|
||||||
|
|
||||||
class DeleteScheduleEvent extends ScheduleEvent {
|
class DeleteScheduleEvent extends ScheduleEvent {
|
||||||
|
|||||||
@ -29,7 +29,7 @@ class ScheduleLoaded extends ScheduleState {
|
|||||||
final int inchingSeconds;
|
final int inchingSeconds;
|
||||||
final bool isInchingActive;
|
final bool isInchingActive;
|
||||||
final ScheduleModes scheduleMode;
|
final ScheduleModes scheduleMode;
|
||||||
final Duration countdownRemaining;
|
final Duration? countdownRemaining;
|
||||||
final int? countdownSeconds;
|
final int? countdownSeconds;
|
||||||
|
|
||||||
const ScheduleLoaded({
|
const ScheduleLoaded({
|
||||||
@ -48,7 +48,7 @@ class ScheduleLoaded extends ScheduleState {
|
|||||||
this.inchingMinutes = 0,
|
this.inchingMinutes = 0,
|
||||||
this.isInchingActive = false,
|
this.isInchingActive = false,
|
||||||
this.scheduleMode = ScheduleModes.countdown,
|
this.scheduleMode = ScheduleModes.countdown,
|
||||||
this.countdownRemaining = Duration.zero,
|
this.countdownRemaining,
|
||||||
});
|
});
|
||||||
|
|
||||||
ScheduleLoaded copyWith({
|
ScheduleLoaded copyWith({
|
||||||
|
|||||||
@ -11,7 +11,6 @@ class CountdownModeButtons extends StatelessWidget {
|
|||||||
final String deviceId;
|
final String deviceId;
|
||||||
final int hours;
|
final int hours;
|
||||||
final int minutes;
|
final int minutes;
|
||||||
final String countDownCode;
|
|
||||||
|
|
||||||
const CountdownModeButtons({
|
const CountdownModeButtons({
|
||||||
super.key,
|
super.key,
|
||||||
@ -19,7 +18,6 @@ class CountdownModeButtons extends StatelessWidget {
|
|||||||
required this.deviceId,
|
required this.deviceId,
|
||||||
required this.hours,
|
required this.hours,
|
||||||
required this.minutes,
|
required this.minutes,
|
||||||
required this.countDownCode,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -45,7 +43,6 @@ class CountdownModeButtons extends StatelessWidget {
|
|||||||
StopScheduleEvent(
|
StopScheduleEvent(
|
||||||
mode: ScheduleModes.countdown,
|
mode: ScheduleModes.countdown,
|
||||||
deviceId: deviceId,
|
deviceId: deviceId,
|
||||||
countdownCode: countDownCode,
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@ -60,7 +57,7 @@ class CountdownModeButtons extends StatelessWidget {
|
|||||||
mode: ScheduleModes.countdown,
|
mode: ScheduleModes.countdown,
|
||||||
hours: hours,
|
hours: hours,
|
||||||
minutes: minutes,
|
minutes: minutes,
|
||||||
countDownCode: countDownCode),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
backgroundColor: ColorsManager.primaryColor,
|
backgroundColor: ColorsManager.primaryColor,
|
||||||
|
|||||||
@ -75,33 +75,23 @@ class _CountdownInchingViewState extends State<CountdownInchingView> {
|
|||||||
final isCountDown = state.scheduleMode == ScheduleModes.countdown;
|
final isCountDown = state.scheduleMode == ScheduleModes.countdown;
|
||||||
final isActive =
|
final isActive =
|
||||||
isCountDown ? state.isCountdownActive : state.isInchingActive;
|
isCountDown ? state.isCountdownActive : state.isInchingActive;
|
||||||
|
final displayHours = isActive && state.countdownRemaining != null
|
||||||
final displayHours =
|
? state.countdownRemaining!.inHours
|
||||||
isActive && state.countdownRemaining != Duration.zero
|
|
||||||
? state.countdownRemaining.inHours
|
|
||||||
: (isCountDown ? state.countdownHours : state.inchingHours);
|
: (isCountDown ? state.countdownHours : state.inchingHours);
|
||||||
|
final displayMinutes = isActive && state.countdownRemaining != null
|
||||||
final displayMinutes =
|
? state.countdownRemaining!.inMinutes.remainder(60)
|
||||||
isActive && state.countdownRemaining != Duration.zero
|
|
||||||
? state.countdownRemaining.inMinutes.remainder(60)
|
|
||||||
: (isCountDown ? state.countdownMinutes : state.inchingMinutes);
|
: (isCountDown ? state.countdownMinutes : state.inchingMinutes);
|
||||||
|
final displaySeconds = isActive && state.countdownRemaining != null
|
||||||
|
? state.countdownRemaining!.inSeconds.remainder(60)
|
||||||
|
: (isCountDown ? state.countdownSeconds : state.inchingSeconds);
|
||||||
|
|
||||||
final displaySeconds =
|
_updateControllers(displayHours, displayMinutes, displaySeconds!);
|
||||||
isActive && state.countdownRemaining != Duration.zero
|
|
||||||
? state.countdownRemaining.inSeconds.remainder(60)
|
|
||||||
: (isCountDown ? (state.countdownSeconds ?? 0) : 0);
|
|
||||||
|
|
||||||
_updateControllers(displayHours, displayMinutes, displaySeconds);
|
if (displayHours == 0 && displayMinutes == 0 && displaySeconds == 0) {
|
||||||
|
|
||||||
if (isActive &&
|
|
||||||
displayHours == 0 &&
|
|
||||||
displayMinutes == 0 &&
|
|
||||||
displaySeconds == 0) {
|
|
||||||
context.read<ScheduleBloc>().add(
|
context.read<ScheduleBloc>().add(
|
||||||
StopScheduleEvent(
|
StopScheduleEvent(
|
||||||
mode: ScheduleModes.countdown,
|
mode: ScheduleModes.countdown,
|
||||||
deviceId: widget.deviceId,
|
deviceId: widget.deviceId,
|
||||||
countdownCode: '',
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -43,9 +43,7 @@ class InchingModeButtons extends StatelessWidget {
|
|||||||
onPressed: () {
|
onPressed: () {
|
||||||
context.read<ScheduleBloc>().add(
|
context.read<ScheduleBloc>().add(
|
||||||
StopScheduleEvent(
|
StopScheduleEvent(
|
||||||
deviceId: deviceId,
|
deviceId: deviceId, mode: ScheduleModes.inching),
|
||||||
mode: ScheduleModes.inching,
|
|
||||||
countdownCode: ''),
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
backgroundColor: Colors.red,
|
backgroundColor: Colors.red,
|
||||||
|
|||||||
@ -18,15 +18,11 @@ class BuildScheduleView extends StatelessWidget {
|
|||||||
super.key,
|
super.key,
|
||||||
required this.deviceUuid,
|
required this.deviceUuid,
|
||||||
required this.category,
|
required this.category,
|
||||||
required this.countdownCode,
|
|
||||||
this.code,
|
this.code,
|
||||||
required this.deviceType,
|
|
||||||
});
|
});
|
||||||
final String deviceUuid;
|
final String deviceUuid;
|
||||||
final String category;
|
final String category;
|
||||||
final String? code;
|
final String? code;
|
||||||
final String? countdownCode;
|
|
||||||
final String deviceType;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -35,8 +31,7 @@ class BuildScheduleView extends StatelessWidget {
|
|||||||
deviceId: deviceUuid,
|
deviceId: deviceUuid,
|
||||||
)
|
)
|
||||||
..add(ScheduleGetEvent(category: category))
|
..add(ScheduleGetEvent(category: category))
|
||||||
..add(ScheduleFetchStatusEvent(
|
..add(ScheduleFetchStatusEvent(deviceUuid)),
|
||||||
deviceId: deviceUuid, countdownCode: countdownCode ?? '')),
|
|
||||||
child: Dialog(
|
child: Dialog(
|
||||||
backgroundColor: Colors.white,
|
backgroundColor: Colors.white,
|
||||||
insetPadding: const EdgeInsets.all(20),
|
insetPadding: const EdgeInsets.all(20),
|
||||||
@ -57,22 +52,21 @@ class BuildScheduleView extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
const ScheduleHeader(),
|
const ScheduleHeader(),
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
if (deviceType == 'CUR_2')
|
if (category == 'CUR_2')
|
||||||
const SizedBox()
|
const SizedBox()
|
||||||
else
|
else
|
||||||
ScheduleModeSelector(
|
ScheduleModeSelector(
|
||||||
countdownCode: countdownCode ?? '',
|
|
||||||
currentMode: state.scheduleMode,
|
currentMode: state.scheduleMode,
|
||||||
),
|
),
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
if (state.scheduleMode == ScheduleModes.schedule)
|
if (state.scheduleMode == ScheduleModes.schedule)
|
||||||
ScheduleManagementUI(
|
ScheduleManagementUI(
|
||||||
deviceType: deviceType,
|
|
||||||
category: category,
|
category: category,
|
||||||
deviceUuid: deviceUuid,
|
deviceUuid: deviceUuid,
|
||||||
onAddSchedule: () async {
|
onAddSchedule: () async {
|
||||||
final entry = await ScheduleDialogHelper
|
final entry = await ScheduleDialogHelper
|
||||||
.showAddScheduleDialog(context,
|
.showAddScheduleDialog(
|
||||||
|
context,
|
||||||
schedule: ScheduleEntry(
|
schedule: ScheduleEntry(
|
||||||
category: category,
|
category: category,
|
||||||
time: '',
|
time: '',
|
||||||
@ -82,7 +76,7 @@ class BuildScheduleView extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
isEdit: false,
|
isEdit: false,
|
||||||
code: code,
|
code: code,
|
||||||
deviceType: deviceType);
|
);
|
||||||
if (entry != null) {
|
if (entry != null) {
|
||||||
context.read<ScheduleBloc>().add(
|
context.read<ScheduleBloc>().add(
|
||||||
ScheduleAddEvent(
|
ScheduleAddEvent(
|
||||||
@ -96,7 +90,6 @@ class BuildScheduleView extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
if (deviceType != 'CUR_2')
|
|
||||||
if (state.scheduleMode == ScheduleModes.countdown ||
|
if (state.scheduleMode == ScheduleModes.countdown ||
|
||||||
state.scheduleMode == ScheduleModes.inching)
|
state.scheduleMode == ScheduleModes.inching)
|
||||||
CountdownInchingView(
|
CountdownInchingView(
|
||||||
@ -105,7 +98,6 @@ class BuildScheduleView extends StatelessWidget {
|
|||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
if (state.scheduleMode == ScheduleModes.countdown)
|
if (state.scheduleMode == ScheduleModes.countdown)
|
||||||
CountdownModeButtons(
|
CountdownModeButtons(
|
||||||
countDownCode: countdownCode ?? '',
|
|
||||||
isActive: state.isCountdownActive,
|
isActive: state.isCountdownActive,
|
||||||
deviceId: deviceUuid,
|
deviceId: deviceUuid,
|
||||||
hours: state.countdownHours,
|
hours: state.countdownHours,
|
||||||
|
|||||||
@ -8,13 +8,11 @@ class ScheduleManagementUI extends StatelessWidget {
|
|||||||
final String deviceUuid;
|
final String deviceUuid;
|
||||||
final VoidCallback onAddSchedule;
|
final VoidCallback onAddSchedule;
|
||||||
final String category;
|
final String category;
|
||||||
final String deviceType;
|
|
||||||
|
|
||||||
const ScheduleManagementUI({
|
const ScheduleManagementUI({
|
||||||
super.key,
|
super.key,
|
||||||
required this.deviceUuid,
|
required this.deviceUuid,
|
||||||
required this.onAddSchedule,
|
required this.onAddSchedule,
|
||||||
required this.deviceType,
|
|
||||||
this.category = 'switch_1',
|
this.category = 'switch_1',
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -46,11 +44,7 @@ class ScheduleManagementUI extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
ScheduleTableWidget(
|
ScheduleTableWidget(deviceUuid: deviceUuid, category: category),
|
||||||
deviceUuid: deviceUuid,
|
|
||||||
category: category,
|
|
||||||
deviceType: deviceType,
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,12 +7,10 @@ import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
|||||||
|
|
||||||
class ScheduleModeSelector extends StatelessWidget {
|
class ScheduleModeSelector extends StatelessWidget {
|
||||||
final ScheduleModes currentMode;
|
final ScheduleModes currentMode;
|
||||||
final String countdownCode;
|
|
||||||
|
|
||||||
const ScheduleModeSelector({
|
const ScheduleModeSelector({
|
||||||
super.key,
|
super.key,
|
||||||
required this.currentMode,
|
required this.currentMode,
|
||||||
required this.countdownCode,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -73,8 +71,7 @@ class ScheduleModeSelector extends StatelessWidget {
|
|||||||
onChanged: (ScheduleModes? value) {
|
onChanged: (ScheduleModes? value) {
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
context.read<ScheduleBloc>().add(
|
context.read<ScheduleBloc>().add(
|
||||||
UpdateScheduleModeEvent(
|
UpdateScheduleModeEvent(scheduleMode: value),
|
||||||
scheduleMode: value, countdownCode: countdownCode),
|
|
||||||
);
|
);
|
||||||
if (value == ScheduleModes.schedule) {
|
if (value == ScheduleModes.schedule) {
|
||||||
context.read<ScheduleBloc>().add(
|
context.read<ScheduleBloc>().add(
|
||||||
|
|||||||
@ -12,13 +12,11 @@ import 'package:syncrow_web/utils/format_date_time.dart';
|
|||||||
class ScheduleTableWidget extends StatelessWidget {
|
class ScheduleTableWidget extends StatelessWidget {
|
||||||
final String deviceUuid;
|
final String deviceUuid;
|
||||||
final String category;
|
final String category;
|
||||||
final String deviceType;
|
|
||||||
|
|
||||||
const ScheduleTableWidget({
|
const ScheduleTableWidget({
|
||||||
super.key,
|
super.key,
|
||||||
required this.deviceUuid,
|
required this.deviceUuid,
|
||||||
this.category = 'switch_1',
|
this.category = 'switch_1',
|
||||||
required this.deviceType,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -27,14 +25,13 @@ class ScheduleTableWidget extends StatelessWidget {
|
|||||||
create: (_) => ScheduleBloc(
|
create: (_) => ScheduleBloc(
|
||||||
deviceId: deviceUuid,
|
deviceId: deviceUuid,
|
||||||
)..add(ScheduleGetEvent(category: category)),
|
)..add(ScheduleGetEvent(category: category)),
|
||||||
child: _ScheduleTableView(deviceType),
|
child: _ScheduleTableView(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class _ScheduleTableView extends StatelessWidget {
|
class _ScheduleTableView extends StatelessWidget {
|
||||||
final String deviceType;
|
const _ScheduleTableView();
|
||||||
const _ScheduleTableView(this.deviceType);
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -84,7 +81,7 @@ class _ScheduleTableView extends StatelessWidget {
|
|||||||
bottomLeft: Radius.circular(20),
|
bottomLeft: Radius.circular(20),
|
||||||
bottomRight: Radius.circular(20)),
|
bottomRight: Radius.circular(20)),
|
||||||
),
|
),
|
||||||
child: _buildTableBody(state.schedules, context, deviceType));
|
child: _buildTableBody(state.schedules, context));
|
||||||
}
|
}
|
||||||
if (state is ScheduleError) {
|
if (state is ScheduleError) {
|
||||||
return Center(child: Text(state.error));
|
return Center(child: Text(state.error));
|
||||||
@ -126,8 +123,7 @@ class _ScheduleTableView extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildTableBody(
|
Widget _buildTableBody(List<ScheduleModel> schedules, BuildContext context) {
|
||||||
List<ScheduleModel> schedules, BuildContext context, String deviceType) {
|
|
||||||
return SizedBox(
|
return SizedBox(
|
||||||
height: 200,
|
height: 200,
|
||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
@ -136,8 +132,7 @@ class _ScheduleTableView extends StatelessWidget {
|
|||||||
defaultVerticalAlignment: TableCellVerticalAlignment.middle,
|
defaultVerticalAlignment: TableCellVerticalAlignment.middle,
|
||||||
children: [
|
children: [
|
||||||
for (int i = 0; i < schedules.length; i++)
|
for (int i = 0; i < schedules.length; i++)
|
||||||
_buildScheduleRow(schedules[i], i, context,
|
_buildScheduleRow(schedules[i], i, context),
|
||||||
deviceType: deviceType),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -160,19 +155,25 @@ class _ScheduleTableView extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TableRow _buildScheduleRow(
|
TableRow _buildScheduleRow(
|
||||||
ScheduleModel schedule, int index, BuildContext context,
|
ScheduleModel schedule, int index, BuildContext context) {
|
||||||
{required String deviceType}) {
|
|
||||||
return TableRow(
|
return TableRow(
|
||||||
children: [
|
children: [
|
||||||
Center(
|
Center(
|
||||||
child: GestureDetector(
|
child: GestureDetector(
|
||||||
behavior: HitTestBehavior.opaque,
|
behavior: HitTestBehavior.opaque,
|
||||||
onTap: () {
|
onTap: () {
|
||||||
|
bool temp;
|
||||||
|
if (schedule.category == 'CUR_2') {
|
||||||
|
temp = schedule.function.value == 'open' ? true : false;
|
||||||
|
} else {
|
||||||
|
temp = schedule.function.value as bool;
|
||||||
|
}
|
||||||
context.read<ScheduleBloc>().add(
|
context.read<ScheduleBloc>().add(
|
||||||
ScheduleUpdateEntryEvent(
|
ScheduleUpdateEntryEvent(
|
||||||
category: schedule.category,
|
category: schedule.category,
|
||||||
scheduleId: schedule.scheduleId,
|
scheduleId: schedule.scheduleId,
|
||||||
functionOn: schedule.function.value,
|
functionOn: temp,
|
||||||
|
// schedule.function.value,
|
||||||
enable: !schedule.enable,
|
enable: !schedule.enable,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@ -194,9 +195,8 @@ class _ScheduleTableView extends StatelessWidget {
|
|||||||
child: Text(_getSelectedDays(
|
child: Text(_getSelectedDays(
|
||||||
ScheduleModel.parseSelectedDays(schedule.days)))),
|
ScheduleModel.parseSelectedDays(schedule.days)))),
|
||||||
Center(child: Text(formatIsoStringToTime(schedule.time, context))),
|
Center(child: Text(formatIsoStringToTime(schedule.time, context))),
|
||||||
if (deviceType == 'CUR_2')
|
if (schedule.category == 'CUR_2')
|
||||||
Center(
|
Center(child: Text(schedule.function.value))
|
||||||
child: Text(schedule.function.value == true ? 'open' : 'close'))
|
|
||||||
else
|
else
|
||||||
Center(child: Text(schedule.function.value ? 'On' : 'Off')),
|
Center(child: Text(schedule.function.value ? 'On' : 'Off')),
|
||||||
Center(
|
Center(
|
||||||
@ -206,14 +206,14 @@ class _ScheduleTableView extends StatelessWidget {
|
|||||||
TextButton(
|
TextButton(
|
||||||
style: TextButton.styleFrom(padding: EdgeInsets.zero),
|
style: TextButton.styleFrom(padding: EdgeInsets.zero),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
ScheduleDialogHelper.showAddScheduleDialog(context,
|
ScheduleDialogHelper.showAddScheduleDialog(
|
||||||
|
context,
|
||||||
schedule: ScheduleEntry.fromScheduleModel(schedule),
|
schedule: ScheduleEntry.fromScheduleModel(schedule),
|
||||||
isEdit: true,
|
isEdit: true,
|
||||||
deviceType: deviceType)
|
).then((updatedSchedule) {
|
||||||
.then((updatedSchedule) {
|
|
||||||
if (updatedSchedule != null) {
|
if (updatedSchedule != null) {
|
||||||
bool temp;
|
bool temp;
|
||||||
if (deviceType == 'CUR_2') {
|
if (schedule.category == 'CUR_2') {
|
||||||
updatedSchedule.function.value == 'open'
|
updatedSchedule.function.value == 'open'
|
||||||
? temp = true
|
? temp = true
|
||||||
: temp = false;
|
: temp = false;
|
||||||
@ -222,7 +222,6 @@ class _ScheduleTableView extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
context.read<ScheduleBloc>().add(
|
context.read<ScheduleBloc>().add(
|
||||||
ScheduleEditEvent(
|
ScheduleEditEvent(
|
||||||
deviceType: deviceType,
|
|
||||||
scheduleId: schedule.scheduleId,
|
scheduleId: schedule.scheduleId,
|
||||||
category: schedule.category,
|
category: schedule.category,
|
||||||
time: updatedSchedule.time,
|
time: updatedSchedule.time,
|
||||||
|
|||||||
@ -41,7 +41,7 @@ class ThreeGangGlassSwitchBloc
|
|||||||
emit(ThreeGangGlassSwitchLoading());
|
emit(ThreeGangGlassSwitchLoading());
|
||||||
try {
|
try {
|
||||||
final status = await DevicesManagementApi().getDeviceStatus(event.deviceId);
|
final status = await DevicesManagementApi().getDeviceStatus(event.deviceId);
|
||||||
_listenToChanges(event.deviceId);
|
_listenToChanges(event.deviceId, emit);
|
||||||
deviceStatus =
|
deviceStatus =
|
||||||
ThreeGangGlassStatusModel.fromJson(event.deviceId, status.status);
|
ThreeGangGlassStatusModel.fromJson(event.deviceId, status.status);
|
||||||
emit(ThreeGangGlassSwitchStatusLoaded(deviceStatus));
|
emit(ThreeGangGlassSwitchStatusLoaded(deviceStatus));
|
||||||
@ -50,28 +50,42 @@ class ThreeGangGlassSwitchBloc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StreamSubscription<DatabaseEvent>? _deviceStatusSubscription;
|
void _listenToChanges(
|
||||||
|
String deviceId,
|
||||||
void _listenToChanges(String deviceId) {
|
Emitter<ThreeGangGlassSwitchState> emit,
|
||||||
|
) {
|
||||||
try {
|
try {
|
||||||
final ref = FirebaseDatabase.instance.ref('device-status/$deviceId');
|
final ref = FirebaseDatabase.instance.ref('device-status/$deviceId');
|
||||||
_deviceStatusSubscription = ref.onValue.listen((DatabaseEvent event) async {
|
final stream = ref.onValue;
|
||||||
if (event.snapshot.value == null) return;
|
|
||||||
|
|
||||||
final usersMap = event.snapshot.value! as Map<dynamic, dynamic>;
|
stream.listen((DatabaseEvent event) {
|
||||||
|
final data = event.snapshot.value as Map<dynamic, dynamic>?;
|
||||||
|
if (data == null) return;
|
||||||
|
|
||||||
final statusList = <Status>[];
|
final statusList = <Status>[];
|
||||||
|
if (data['status'] != null) {
|
||||||
usersMap['status'].forEach((element) {
|
for (var element in data['status']) {
|
||||||
statusList.add(Status(code: element['code'], value: element['value']));
|
statusList.add(
|
||||||
});
|
Status(
|
||||||
|
code: element['code'].toString(),
|
||||||
deviceStatus =
|
value: element['value'].toString(),
|
||||||
ThreeGangGlassStatusModel.fromJson(usersMap['productUuid'], statusList);
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (statusList.isNotEmpty) {
|
||||||
|
final newStatus = ThreeGangGlassStatusModel.fromJson(deviceId, statusList);
|
||||||
|
if (newStatus != deviceStatus) {
|
||||||
|
deviceStatus = newStatus;
|
||||||
|
if (!isClosed) {
|
||||||
add(StatusUpdated(deviceStatus));
|
add(StatusUpdated(deviceStatus));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
} catch (_) {}
|
} catch (e) {
|
||||||
|
emit(ThreeGangGlassSwitchError('Failed to listen to changes: $e'));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onStatusUpdated(
|
void _onStatusUpdated(
|
||||||
@ -170,10 +184,4 @@ class ThreeGangGlassSwitchBloc
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> close() {
|
|
||||||
_deviceStatusSubscription?.cancel();
|
|
||||||
return super.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -111,8 +111,6 @@ class ThreeGangGlassSwitchControlView extends StatelessWidget
|
|||||||
child: BuildScheduleView(
|
child: BuildScheduleView(
|
||||||
category: 'switch_1',
|
category: 'switch_1',
|
||||||
deviceUuid: deviceId,
|
deviceUuid: deviceId,
|
||||||
countdownCode: 'countdown_1',
|
|
||||||
deviceType: '3GT',
|
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
},
|
},
|
||||||
@ -129,8 +127,6 @@ class ThreeGangGlassSwitchControlView extends StatelessWidget
|
|||||||
child: BuildScheduleView(
|
child: BuildScheduleView(
|
||||||
category: 'switch_2',
|
category: 'switch_2',
|
||||||
deviceUuid: deviceId,
|
deviceUuid: deviceId,
|
||||||
countdownCode: 'countdown_2',
|
|
||||||
deviceType: '3GT',
|
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
},
|
},
|
||||||
@ -147,8 +143,6 @@ class ThreeGangGlassSwitchControlView extends StatelessWidget
|
|||||||
child: BuildScheduleView(
|
child: BuildScheduleView(
|
||||||
category: 'switch_3',
|
category: 'switch_3',
|
||||||
deviceUuid: deviceId,
|
deviceUuid: deviceId,
|
||||||
countdownCode: 'countdown_3',
|
|
||||||
deviceType: '3GT',
|
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
},
|
},
|
||||||
|
|||||||
@ -102,8 +102,6 @@ class LivingRoomDeviceControlsView extends StatelessWidget
|
|||||||
child: BuildScheduleView(
|
child: BuildScheduleView(
|
||||||
deviceUuid: deviceId,
|
deviceUuid: deviceId,
|
||||||
category: 'switch_1',
|
category: 'switch_1',
|
||||||
countdownCode: 'countdown_1',
|
|
||||||
deviceType: '3G',
|
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
},
|
},
|
||||||
@ -120,8 +118,6 @@ class LivingRoomDeviceControlsView extends StatelessWidget
|
|||||||
child: BuildScheduleView(
|
child: BuildScheduleView(
|
||||||
deviceUuid: deviceId,
|
deviceUuid: deviceId,
|
||||||
category: 'switch_2',
|
category: 'switch_2',
|
||||||
countdownCode: 'countdown_2',
|
|
||||||
deviceType: '3G',
|
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
},
|
},
|
||||||
@ -138,8 +134,6 @@ class LivingRoomDeviceControlsView extends StatelessWidget
|
|||||||
child: BuildScheduleView(
|
child: BuildScheduleView(
|
||||||
deviceUuid: deviceId,
|
deviceUuid: deviceId,
|
||||||
category: 'switch_3',
|
category: 'switch_3',
|
||||||
countdownCode: 'countdown_3',
|
|
||||||
deviceType: '3G',
|
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1,20 +1,21 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'dart:developer';
|
||||||
|
|
||||||
import 'package:bloc/bloc.dart';
|
import 'package:bloc/bloc.dart';
|
||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
import 'package:firebase_database/firebase_database.dart';
|
import 'package:firebase_database/firebase_database.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart';
|
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart';
|
import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/two_g_glass_switch/models/two_gang_glass_status_model.dart';
|
import 'package:syncrow_web/pages/device_managment/two_g_glass_switch/models/two_gang_glass_status_model.dart';
|
||||||
import 'package:syncrow_web/services/batch_control_devices_service.dart';
|
import 'package:syncrow_web/services/batch_control_devices_service.dart';
|
||||||
import 'package:syncrow_web/services/control_device_service.dart';
|
import 'package:syncrow_web/services/control_device_service.dart';
|
||||||
import 'package:syncrow_web/services/devices_mang_api.dart';
|
import 'package:syncrow_web/services/devices_mang_api.dart';
|
||||||
|
|
||||||
part 'two_gang_glass_switch_event.dart';
|
part 'two_gang_glass_switch_event.dart';
|
||||||
part 'two_gang_glass_switch_state.dart';
|
part 'two_gang_glass_switch_state.dart';
|
||||||
|
|
||||||
class TwoGangGlassSwitchBloc
|
class TwoGangGlassSwitchBloc
|
||||||
extends Bloc<TwoGangGlassSwitchEvent, TwoGangGlassSwitchState> {
|
extends Bloc<TwoGangGlassSwitchEvent, TwoGangGlassSwitchState> {
|
||||||
final String deviceId;
|
final String deviceId;
|
||||||
final ControlDeviceService controlDeviceService;
|
final ControlDeviceService controlDeviceService;
|
||||||
@ -50,28 +51,29 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StreamSubscription<DatabaseEvent>? _deviceStatusSubscription;
|
|
||||||
|
|
||||||
void _listenToChanges(String deviceId) {
|
void _listenToChanges(String deviceId) {
|
||||||
try {
|
try {
|
||||||
final ref = FirebaseDatabase.instance.ref('device-status/$deviceId');
|
final ref = FirebaseDatabase.instance.ref(
|
||||||
_deviceStatusSubscription = ref.onValue.listen((DatabaseEvent event) async {
|
'device-status/$deviceId',
|
||||||
if (event.snapshot.value == null) return;
|
);
|
||||||
|
|
||||||
final usersMap = event.snapshot.value! as Map<dynamic, dynamic>;
|
ref.onValue.listen((event) {
|
||||||
|
final eventsMap = event.snapshot.value as Map<dynamic, dynamic>;
|
||||||
|
|
||||||
final statusList = <Status>[];
|
List<Status> statusList = [];
|
||||||
|
eventsMap['status'].forEach((element) {
|
||||||
usersMap['status'].forEach((element) {
|
|
||||||
statusList.add(Status(code: element['code'], value: element['value']));
|
statusList.add(Status(code: element['code'], value: element['value']));
|
||||||
});
|
});
|
||||||
|
|
||||||
deviceStatus =
|
deviceStatus = TwoGangGlassStatusModel.fromJson(deviceId, statusList);
|
||||||
TwoGangGlassStatusModel.fromJson(usersMap['productUuid'], statusList);
|
|
||||||
|
|
||||||
add(StatusUpdated(deviceStatus));
|
add(StatusUpdated(deviceStatus));
|
||||||
});
|
});
|
||||||
} catch (_) {}
|
} catch (_) {
|
||||||
|
log(
|
||||||
|
'Error listening to changes',
|
||||||
|
name: 'TwoGangGlassSwitchBloc._listenToChanges',
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onControl(
|
Future<void> _onControl(
|
||||||
@ -168,10 +170,4 @@
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> close() {
|
|
||||||
_deviceStatusSubscription?.cancel();
|
|
||||||
return super.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -102,8 +102,6 @@ class TwoGangGlassSwitchControlView extends StatelessWidget
|
|||||||
builder: (ctx) => BlocProvider.value(
|
builder: (ctx) => BlocProvider.value(
|
||||||
value: BlocProvider.of<TwoGangGlassSwitchBloc>(context),
|
value: BlocProvider.of<TwoGangGlassSwitchBloc>(context),
|
||||||
child: BuildScheduleView(
|
child: BuildScheduleView(
|
||||||
deviceType: '2GT',
|
|
||||||
countdownCode: 'countdown_1',
|
|
||||||
deviceUuid: deviceId,
|
deviceUuid: deviceId,
|
||||||
category: 'switch_1',
|
category: 'switch_1',
|
||||||
),
|
),
|
||||||
@ -120,8 +118,6 @@ class TwoGangGlassSwitchControlView extends StatelessWidget
|
|||||||
builder: (ctx) => BlocProvider.value(
|
builder: (ctx) => BlocProvider.value(
|
||||||
value: BlocProvider.of<TwoGangGlassSwitchBloc>(context),
|
value: BlocProvider.of<TwoGangGlassSwitchBloc>(context),
|
||||||
child: BuildScheduleView(
|
child: BuildScheduleView(
|
||||||
deviceType: '2GT',
|
|
||||||
countdownCode: 'countdown_2',
|
|
||||||
deviceUuid: deviceId,
|
deviceUuid: deviceId,
|
||||||
category: 'switch_2',
|
category: 'switch_2',
|
||||||
),
|
),
|
||||||
|
|||||||
@ -97,8 +97,6 @@ class TwoGangBatchControlView extends StatelessWidget
|
|||||||
child: BuildScheduleView(
|
child: BuildScheduleView(
|
||||||
category: 'switch_1',
|
category: 'switch_1',
|
||||||
deviceUuid: deviceIds.first,
|
deviceUuid: deviceIds.first,
|
||||||
countdownCode: 'countdown_1',
|
|
||||||
deviceType: '2G',
|
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
},
|
},
|
||||||
@ -116,8 +114,6 @@ class TwoGangBatchControlView extends StatelessWidget
|
|||||||
child: BuildScheduleView(
|
child: BuildScheduleView(
|
||||||
category: 'switch_2',
|
category: 'switch_2',
|
||||||
deviceUuid: deviceIds.first,
|
deviceUuid: deviceIds.first,
|
||||||
countdownCode: 'countdown_2',
|
|
||||||
deviceType: '2G',
|
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
},
|
},
|
||||||
@ -125,7 +121,10 @@ class TwoGangBatchControlView extends StatelessWidget
|
|||||||
subtitle: 'Scheduling',
|
subtitle: 'Scheduling',
|
||||||
iconPath: Assets.scheduling,
|
iconPath: Assets.scheduling,
|
||||||
),
|
),
|
||||||
|
// FirmwareUpdateWidget(
|
||||||
|
// deviceId: deviceIds.first,
|
||||||
|
// version: 12,
|
||||||
|
// ),
|
||||||
FactoryResetWidget(callFactoryReset: () {
|
FactoryResetWidget(callFactoryReset: () {
|
||||||
context.read<TwoGangSwitchBloc>().add(
|
context.read<TwoGangSwitchBloc>().add(
|
||||||
TwoGangFactoryReset(
|
TwoGangFactoryReset(
|
||||||
|
|||||||
@ -103,8 +103,6 @@ class TwoGangDeviceControlView extends StatelessWidget
|
|||||||
child: BuildScheduleView(
|
child: BuildScheduleView(
|
||||||
deviceUuid: deviceId,
|
deviceUuid: deviceId,
|
||||||
category: 'switch_1',
|
category: 'switch_1',
|
||||||
countdownCode: 'countdown_1',
|
|
||||||
deviceType: '2G',
|
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
},
|
},
|
||||||
@ -127,8 +125,6 @@ class TwoGangDeviceControlView extends StatelessWidget
|
|||||||
child: BuildScheduleView(
|
child: BuildScheduleView(
|
||||||
deviceUuid: deviceId,
|
deviceUuid: deviceId,
|
||||||
category: 'switch_2',
|
category: 'switch_2',
|
||||||
countdownCode: 'countdown_2',
|
|
||||||
deviceType: '2G',
|
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
},
|
},
|
||||||
|
|||||||
@ -18,10 +18,9 @@ class ScheduleDialogHelper {
|
|||||||
ScheduleEntry? schedule,
|
ScheduleEntry? schedule,
|
||||||
bool isEdit = false,
|
bool isEdit = false,
|
||||||
String? code,
|
String? code,
|
||||||
required String deviceType,
|
|
||||||
}) {
|
}) {
|
||||||
bool temp;
|
bool temp;
|
||||||
if (deviceType == 'CUR_2') {
|
if (schedule?.category == 'CUR_2') {
|
||||||
temp = schedule!.function.value == 'open' ? true : false;
|
temp = schedule!.function.value == 'open' ? true : false;
|
||||||
} else {
|
} else {
|
||||||
temp = schedule!.function.value;
|
temp = schedule!.function.value;
|
||||||
@ -104,7 +103,8 @@ class ScheduleDialogHelper {
|
|||||||
setState(() => selectedDays[i] = v);
|
setState(() => selectedDays[i] = v);
|
||||||
}),
|
}),
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
_buildFunctionSwitch(deviceType, ctx, functionOn!, (v) {
|
_buildFunctionSwitch(schedule!.category, ctx, functionOn!,
|
||||||
|
(v) {
|
||||||
setState(() => functionOn = v);
|
setState(() => functionOn = v);
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
@ -124,25 +124,28 @@ class ScheduleDialogHelper {
|
|||||||
child: ElevatedButton(
|
child: ElevatedButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
dynamic temp;
|
dynamic temp;
|
||||||
if (deviceType == 'CUR_2') {
|
if (schedule?.category == 'CUR_2') {
|
||||||
temp = functionOn! ? 'open' : 'close';
|
temp = functionOn! ? 'open' : 'close';
|
||||||
} else {
|
} else {
|
||||||
temp = functionOn;
|
temp = functionOn;
|
||||||
}
|
}
|
||||||
|
print(temp);
|
||||||
final entry = ScheduleEntry(
|
final entry = ScheduleEntry(
|
||||||
category: schedule?.category ?? 'switch_1',
|
category: schedule?.category ?? 'switch_1',
|
||||||
time: _formatTimeOfDayToISO(selectedTime),
|
time: _formatTimeOfDayToISO(selectedTime),
|
||||||
function: Status(
|
function: Status(
|
||||||
code: code ?? 'switch_1',
|
code: code ?? 'switch_1',
|
||||||
value: temp,
|
value: temp,
|
||||||
|
// functionOn,
|
||||||
),
|
),
|
||||||
days: _convertSelectedDaysToStrings(selectedDays),
|
days: _convertSelectedDaysToStrings(selectedDays),
|
||||||
scheduleId: schedule.scheduleId,
|
scheduleId: schedule?.scheduleId,
|
||||||
);
|
);
|
||||||
Navigator.pop(ctx, entry);
|
Navigator.pop(ctx, entry);
|
||||||
},
|
},
|
||||||
child: const Text('Save'),
|
child: const Text('Save'),
|
||||||
)),
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|||||||
@ -84,8 +84,6 @@ class WaterHeaterDeviceControlView extends StatelessWidget
|
|||||||
child: BuildScheduleView(
|
child: BuildScheduleView(
|
||||||
deviceUuid: device.uuid ?? '',
|
deviceUuid: device.uuid ?? '',
|
||||||
category: 'switch_1',
|
category: 'switch_1',
|
||||||
countdownCode: 'countdown_1',
|
|
||||||
deviceType: 'WH',
|
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user