mirror of
https://github.com/SyncrowIOT/web.git
synced 2025-07-16 01:56:24 +00:00
Add countdown functionality and device type support across device management views
This commit is contained in:
@ -11,6 +11,7 @@ class CountdownModeButtons extends StatelessWidget {
|
||||
final String deviceId;
|
||||
final int hours;
|
||||
final int minutes;
|
||||
final String countDownCode;
|
||||
|
||||
const CountdownModeButtons({
|
||||
super.key,
|
||||
@ -18,6 +19,7 @@ class CountdownModeButtons extends StatelessWidget {
|
||||
required this.deviceId,
|
||||
required this.hours,
|
||||
required this.minutes,
|
||||
required this.countDownCode,
|
||||
});
|
||||
|
||||
@override
|
||||
@ -43,6 +45,7 @@ class CountdownModeButtons extends StatelessWidget {
|
||||
StopScheduleEvent(
|
||||
mode: ScheduleModes.countdown,
|
||||
deviceId: deviceId,
|
||||
countdownCode: countDownCode,
|
||||
),
|
||||
);
|
||||
},
|
||||
@ -54,10 +57,10 @@ class CountdownModeButtons extends StatelessWidget {
|
||||
onPressed: () {
|
||||
context.read<ScheduleBloc>().add(
|
||||
StartScheduleEvent(
|
||||
mode: ScheduleModes.countdown,
|
||||
hours: hours,
|
||||
minutes: minutes,
|
||||
),
|
||||
mode: ScheduleModes.countdown,
|
||||
hours: hours,
|
||||
minutes: minutes,
|
||||
countDownCode: countDownCode),
|
||||
);
|
||||
},
|
||||
backgroundColor: ColorsManager.primaryColor,
|
||||
|
@ -75,23 +75,33 @@ class _CountdownInchingViewState extends State<CountdownInchingView> {
|
||||
final isCountDown = state.scheduleMode == ScheduleModes.countdown;
|
||||
final isActive =
|
||||
isCountDown ? state.isCountdownActive : state.isInchingActive;
|
||||
final displayHours = isActive && state.countdownRemaining != null
|
||||
? state.countdownRemaining!.inHours
|
||||
: (isCountDown ? state.countdownHours : state.inchingHours);
|
||||
final displayMinutes = isActive && state.countdownRemaining != null
|
||||
? state.countdownRemaining!.inMinutes.remainder(60)
|
||||
: (isCountDown ? state.countdownMinutes : state.inchingMinutes);
|
||||
final displaySeconds = isActive && state.countdownRemaining != null
|
||||
? state.countdownRemaining!.inSeconds.remainder(60)
|
||||
: (isCountDown ? state.countdownSeconds : state.inchingSeconds);
|
||||
|
||||
_updateControllers(displayHours, displayMinutes, displaySeconds!);
|
||||
final displayHours =
|
||||
isActive && state.countdownRemaining != Duration.zero
|
||||
? state.countdownRemaining.inHours
|
||||
: (isCountDown ? state.countdownHours : state.inchingHours);
|
||||
|
||||
if (displayHours == 0 && displayMinutes == 0 && displaySeconds == 0) {
|
||||
final displayMinutes =
|
||||
isActive && state.countdownRemaining != Duration.zero
|
||||
? state.countdownRemaining.inMinutes.remainder(60)
|
||||
: (isCountDown ? state.countdownMinutes : state.inchingMinutes);
|
||||
|
||||
final displaySeconds =
|
||||
isActive && state.countdownRemaining != Duration.zero
|
||||
? state.countdownRemaining.inSeconds.remainder(60)
|
||||
: (isCountDown ? (state.countdownSeconds ?? 0) : 0);
|
||||
|
||||
_updateControllers(displayHours, displayMinutes, displaySeconds);
|
||||
|
||||
if (isActive &&
|
||||
displayHours == 0 &&
|
||||
displayMinutes == 0 &&
|
||||
displaySeconds == 0) {
|
||||
context.read<ScheduleBloc>().add(
|
||||
StopScheduleEvent(
|
||||
mode: ScheduleModes.countdown,
|
||||
deviceId: widget.deviceId,
|
||||
countdownCode: '',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -43,7 +43,9 @@ class InchingModeButtons extends StatelessWidget {
|
||||
onPressed: () {
|
||||
context.read<ScheduleBloc>().add(
|
||||
StopScheduleEvent(
|
||||
deviceId: deviceId, mode: ScheduleModes.inching),
|
||||
deviceId: deviceId,
|
||||
mode: ScheduleModes.inching,
|
||||
countdownCode: ''),
|
||||
);
|
||||
},
|
||||
backgroundColor: Colors.red,
|
||||
|
@ -18,11 +18,15 @@ class BuildScheduleView extends StatelessWidget {
|
||||
super.key,
|
||||
required this.deviceUuid,
|
||||
required this.category,
|
||||
required this.countdownCode,
|
||||
this.code,
|
||||
required this.deviceType,
|
||||
});
|
||||
final String deviceUuid;
|
||||
final String category;
|
||||
final String? code;
|
||||
final String? countdownCode;
|
||||
final String deviceType;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@ -31,7 +35,8 @@ class BuildScheduleView extends StatelessWidget {
|
||||
deviceId: deviceUuid,
|
||||
)
|
||||
..add(ScheduleGetEvent(category: category))
|
||||
..add(ScheduleFetchStatusEvent(deviceUuid)),
|
||||
..add(ScheduleFetchStatusEvent(
|
||||
deviceId: deviceUuid, countdownCode: countdownCode ?? '')),
|
||||
child: Dialog(
|
||||
backgroundColor: Colors.white,
|
||||
insetPadding: const EdgeInsets.all(20),
|
||||
@ -52,28 +57,32 @@ class BuildScheduleView extends StatelessWidget {
|
||||
children: [
|
||||
const ScheduleHeader(),
|
||||
const SizedBox(height: 20),
|
||||
ScheduleModeSelector(
|
||||
currentMode: state.scheduleMode,
|
||||
),
|
||||
if (deviceType == 'CUR_2')
|
||||
const SizedBox()
|
||||
else
|
||||
ScheduleModeSelector(
|
||||
countdownCode: countdownCode ?? '',
|
||||
currentMode: state.scheduleMode,
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
if (state.scheduleMode == ScheduleModes.schedule)
|
||||
ScheduleManagementUI(
|
||||
deviceType: deviceType,
|
||||
category: category,
|
||||
deviceUuid: deviceUuid,
|
||||
onAddSchedule: () async {
|
||||
final entry = await ScheduleDialogHelper
|
||||
.showAddScheduleDialog(
|
||||
context,
|
||||
schedule: ScheduleEntry(
|
||||
category: category,
|
||||
time: '',
|
||||
function: Status(
|
||||
code: code.toString(), value: null),
|
||||
days: [],
|
||||
),
|
||||
isEdit: false,
|
||||
code: code,
|
||||
);
|
||||
.showAddScheduleDialog(context,
|
||||
schedule: ScheduleEntry(
|
||||
category: category,
|
||||
time: '',
|
||||
function: Status(
|
||||
code: code.toString(), value: null),
|
||||
days: [],
|
||||
),
|
||||
isEdit: false,
|
||||
code: code,
|
||||
deviceType: deviceType);
|
||||
if (entry != null) {
|
||||
context.read<ScheduleBloc>().add(
|
||||
ScheduleAddEvent(
|
||||
@ -87,14 +96,16 @@ class BuildScheduleView extends StatelessWidget {
|
||||
}
|
||||
},
|
||||
),
|
||||
if (state.scheduleMode == ScheduleModes.countdown ||
|
||||
state.scheduleMode == ScheduleModes.inching)
|
||||
CountdownInchingView(
|
||||
deviceId: deviceUuid,
|
||||
),
|
||||
if (deviceType != 'CUR_2')
|
||||
if (state.scheduleMode == ScheduleModes.countdown ||
|
||||
state.scheduleMode == ScheduleModes.inching)
|
||||
CountdownInchingView(
|
||||
deviceId: deviceUuid,
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
if (state.scheduleMode == ScheduleModes.countdown)
|
||||
CountdownModeButtons(
|
||||
countDownCode: countdownCode ?? '',
|
||||
isActive: state.isCountdownActive,
|
||||
deviceId: deviceUuid,
|
||||
hours: state.countdownHours,
|
||||
|
@ -5,14 +5,16 @@ import 'package:syncrow_web/utils/color_manager.dart';
|
||||
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
||||
|
||||
class ScheduleManagementUI extends StatelessWidget {
|
||||
final String deviceUuid;
|
||||
final String deviceUuid;
|
||||
final VoidCallback onAddSchedule;
|
||||
final String category;
|
||||
final String deviceType;
|
||||
|
||||
const ScheduleManagementUI({
|
||||
super.key,
|
||||
required this.deviceUuid,
|
||||
required this.onAddSchedule,
|
||||
required this.deviceType,
|
||||
this.category = 'switch_1',
|
||||
});
|
||||
|
||||
@ -44,7 +46,11 @@ class ScheduleManagementUI extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
ScheduleTableWidget(deviceUuid: deviceUuid, category: category),
|
||||
ScheduleTableWidget(
|
||||
deviceUuid: deviceUuid,
|
||||
category: category,
|
||||
deviceType: deviceType,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
@ -7,10 +7,12 @@ import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
||||
|
||||
class ScheduleModeSelector extends StatelessWidget {
|
||||
final ScheduleModes currentMode;
|
||||
final String countdownCode;
|
||||
|
||||
const ScheduleModeSelector({
|
||||
super.key,
|
||||
required this.currentMode,
|
||||
required this.countdownCode,
|
||||
});
|
||||
|
||||
@override
|
||||
@ -71,7 +73,8 @@ class ScheduleModeSelector extends StatelessWidget {
|
||||
onChanged: (ScheduleModes? value) {
|
||||
if (value != null) {
|
||||
context.read<ScheduleBloc>().add(
|
||||
UpdateScheduleModeEvent(scheduleMode: value),
|
||||
UpdateScheduleModeEvent(
|
||||
scheduleMode: value, countdownCode: countdownCode),
|
||||
);
|
||||
if (value == ScheduleModes.schedule) {
|
||||
context.read<ScheduleBloc>().add(
|
||||
|
@ -12,11 +12,13 @@ import 'package:syncrow_web/utils/format_date_time.dart';
|
||||
class ScheduleTableWidget extends StatelessWidget {
|
||||
final String deviceUuid;
|
||||
final String category;
|
||||
final String deviceType;
|
||||
|
||||
const ScheduleTableWidget({
|
||||
super.key,
|
||||
required this.deviceUuid,
|
||||
this.category = 'switch_1',
|
||||
required this.deviceType,
|
||||
});
|
||||
|
||||
@override
|
||||
@ -25,13 +27,14 @@ class ScheduleTableWidget extends StatelessWidget {
|
||||
create: (_) => ScheduleBloc(
|
||||
deviceId: deviceUuid,
|
||||
)..add(ScheduleGetEvent(category: category)),
|
||||
child: _ScheduleTableView(),
|
||||
child: _ScheduleTableView(deviceType),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _ScheduleTableView extends StatelessWidget {
|
||||
const _ScheduleTableView();
|
||||
final String deviceType;
|
||||
const _ScheduleTableView(this.deviceType);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@ -81,7 +84,7 @@ class _ScheduleTableView extends StatelessWidget {
|
||||
bottomLeft: Radius.circular(20),
|
||||
bottomRight: Radius.circular(20)),
|
||||
),
|
||||
child: _buildTableBody(state.schedules, context));
|
||||
child: _buildTableBody(state.schedules, context, deviceType));
|
||||
}
|
||||
if (state is ScheduleError) {
|
||||
return Center(child: Text(state.error));
|
||||
@ -123,7 +126,8 @@ class _ScheduleTableView extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildTableBody(List<ScheduleModel> schedules, BuildContext context) {
|
||||
Widget _buildTableBody(
|
||||
List<ScheduleModel> schedules, BuildContext context, String deviceType) {
|
||||
return SizedBox(
|
||||
height: 200,
|
||||
child: SingleChildScrollView(
|
||||
@ -132,7 +136,8 @@ class _ScheduleTableView extends StatelessWidget {
|
||||
defaultVerticalAlignment: TableCellVerticalAlignment.middle,
|
||||
children: [
|
||||
for (int i = 0; i < schedules.length; i++)
|
||||
_buildScheduleRow(schedules[i], i, context),
|
||||
_buildScheduleRow(schedules[i], i, context,
|
||||
deviceType: deviceType),
|
||||
],
|
||||
),
|
||||
),
|
||||
@ -155,25 +160,19 @@ class _ScheduleTableView extends StatelessWidget {
|
||||
}
|
||||
|
||||
TableRow _buildScheduleRow(
|
||||
ScheduleModel schedule, int index, BuildContext context) {
|
||||
ScheduleModel schedule, int index, BuildContext context,
|
||||
{required String deviceType}) {
|
||||
return TableRow(
|
||||
children: [
|
||||
Center(
|
||||
child: GestureDetector(
|
||||
behavior: HitTestBehavior.opaque,
|
||||
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(
|
||||
ScheduleUpdateEntryEvent(
|
||||
category: schedule.category,
|
||||
scheduleId: schedule.scheduleId,
|
||||
functionOn: temp,
|
||||
// schedule.function.value,
|
||||
functionOn: schedule.function.value,
|
||||
enable: !schedule.enable,
|
||||
),
|
||||
);
|
||||
@ -195,10 +194,11 @@ class _ScheduleTableView extends StatelessWidget {
|
||||
child: Text(_getSelectedDays(
|
||||
ScheduleModel.parseSelectedDays(schedule.days)))),
|
||||
Center(child: Text(formatIsoStringToTime(schedule.time, context))),
|
||||
schedule.category == 'CUR_2'
|
||||
? Center(
|
||||
child: Text(schedule.function.value == true ? 'open' : 'close'))
|
||||
: Center(child: Text(schedule.function.value ? 'On' : 'Off')),
|
||||
if (deviceType == 'CUR_2')
|
||||
Center(
|
||||
child: Text(schedule.function.value == true ? 'open' : 'close'))
|
||||
else
|
||||
Center(child: Text(schedule.function.value ? 'On' : 'Off')),
|
||||
Center(
|
||||
child: Wrap(
|
||||
runAlignment: WrapAlignment.center,
|
||||
@ -206,18 +206,28 @@ class _ScheduleTableView extends StatelessWidget {
|
||||
TextButton(
|
||||
style: TextButton.styleFrom(padding: EdgeInsets.zero),
|
||||
onPressed: () {
|
||||
ScheduleDialogHelper.showAddScheduleDialog(
|
||||
context,
|
||||
schedule: ScheduleEntry.fromScheduleModel(schedule),
|
||||
isEdit: true,
|
||||
).then((updatedSchedule) {
|
||||
ScheduleDialogHelper.showAddScheduleDialog(context,
|
||||
schedule: ScheduleEntry.fromScheduleModel(schedule),
|
||||
isEdit: true,
|
||||
deviceType: deviceType)
|
||||
.then((updatedSchedule) {
|
||||
if (updatedSchedule != null) {
|
||||
bool temp;
|
||||
if (deviceType == 'CUR_2') {
|
||||
updatedSchedule.function.value == 'open'
|
||||
? temp = true
|
||||
: temp = false;
|
||||
} else {
|
||||
temp = updatedSchedule.function.value;
|
||||
}
|
||||
print('deviceType $deviceType');
|
||||
context.read<ScheduleBloc>().add(
|
||||
ScheduleEditEvent(
|
||||
deviceType: deviceType,
|
||||
scheduleId: schedule.scheduleId,
|
||||
category: schedule.category,
|
||||
time: updatedSchedule.time,
|
||||
functionOn: updatedSchedule.function.value,
|
||||
functionOn: temp,
|
||||
selectedDays: updatedSchedule.days),
|
||||
);
|
||||
}
|
||||
|
Reference in New Issue
Block a user