mirror of
https://github.com/Iconica-Development/flutter_availability.git
synced 2025-05-18 20:53:45 +02:00
fix: allow clearing the duration from the pause dialog
This commit is contained in:
parent
020d7a71f8
commit
134f827f3a
6 changed files with 51 additions and 36 deletions
|
@ -7,7 +7,7 @@ class BreakViewModel {
|
|||
const BreakViewModel({
|
||||
this.startTime,
|
||||
this.endTime,
|
||||
this.duration,
|
||||
this.submittedDuration,
|
||||
});
|
||||
|
||||
/// Create a [BreakViewModel] from a [AvailabilityBreakModel]
|
||||
|
@ -17,7 +17,7 @@ class BreakViewModel {
|
|||
BreakViewModel(
|
||||
startTime: TimeOfDay.fromDateTime(data.startTime),
|
||||
endTime: TimeOfDay.fromDateTime(data.endTime),
|
||||
duration: data.duration,
|
||||
submittedDuration: data.submittedDuration,
|
||||
);
|
||||
|
||||
/// The start time for this break
|
||||
|
@ -26,20 +26,18 @@ class BreakViewModel {
|
|||
/// The end time for this break
|
||||
final TimeOfDay? endTime;
|
||||
|
||||
/// The full duration of the actual break.
|
||||
/// The full duration of the actual break. This is filled in by the users and
|
||||
/// stays null if the user has not filled it in.
|
||||
///
|
||||
/// This is allowed to diverge from the difference between [startTime] and
|
||||
/// [endTime] to indicate that the break is somewhere between [startTime] and
|
||||
/// [endTime]
|
||||
final Duration? duration;
|
||||
final Duration? submittedDuration;
|
||||
|
||||
/// Get the duration in minutes
|
||||
/// Get the duration of the break
|
||||
/// If the duration is null, return the difference between the start and end
|
||||
/// time in minutes
|
||||
int get durationInMinutes =>
|
||||
duration?.inMinutes ??
|
||||
((endTime!.hour * 60 + endTime!.minute) -
|
||||
(startTime!.hour * 60 + startTime!.minute));
|
||||
Duration get duration => submittedDuration ?? toBreak().duration;
|
||||
|
||||
/// Returns true if the break is valid
|
||||
/// The start is before the end and the duration is equal or lower than the
|
||||
|
@ -54,11 +52,11 @@ class BreakViewModel {
|
|||
if (startDateTime.isAfter(endDateTime)) {
|
||||
return false;
|
||||
}
|
||||
if (duration == null) {
|
||||
if (submittedDuration == null) {
|
||||
return true;
|
||||
}
|
||||
var actualDuration = endDateTime.difference(startDateTime);
|
||||
return duration! <= actualDuration;
|
||||
return submittedDuration! <= actualDuration;
|
||||
}
|
||||
|
||||
/// Whether the save/next button should be enabled
|
||||
|
@ -66,21 +64,22 @@ class BreakViewModel {
|
|||
|
||||
/// Convert to [AvailabilityBreakModel] for saving
|
||||
AvailabilityBreakModel toBreak() => AvailabilityBreakModel(
|
||||
startTime: DateTime(0, 0, 0, startTime!.hour, startTime!.minute),
|
||||
endTime: DateTime(0, 0, 0, endTime!.hour, endTime!.minute),
|
||||
duration: duration,
|
||||
startTime:
|
||||
DateTime(0, 0, 0, startTime?.hour ?? 0, startTime?.minute ?? 0),
|
||||
endTime: DateTime(0, 0, 0, endTime?.hour ?? 0, endTime?.minute ?? 0),
|
||||
submittedDuration: submittedDuration,
|
||||
);
|
||||
|
||||
/// Create a copy with new values
|
||||
BreakViewModel copyWith({
|
||||
TimeOfDay? startTime,
|
||||
TimeOfDay? endTime,
|
||||
Duration? duration,
|
||||
Duration? submittedDuration,
|
||||
}) =>
|
||||
BreakViewModel(
|
||||
startTime: startTime ?? this.startTime,
|
||||
endTime: endTime ?? this.endTime,
|
||||
duration: duration ?? this.duration,
|
||||
submittedDuration: submittedDuration ?? this.submittedDuration,
|
||||
);
|
||||
|
||||
/// compareto method to order two breaks based on their start time
|
||||
|
@ -92,4 +91,11 @@ class BreakViewModel {
|
|||
other.startTime!.minute;
|
||||
return difference;
|
||||
}
|
||||
|
||||
/// Clear the duration of the break
|
||||
BreakViewModel clearDuration() => BreakViewModel(
|
||||
startTime: startTime,
|
||||
endTime: endTime,
|
||||
submittedDuration: null,
|
||||
);
|
||||
}
|
||||
|
|
|
@ -67,7 +67,7 @@ class DurationInputField extends StatelessWidget {
|
|||
final Duration? initialValue;
|
||||
|
||||
///
|
||||
final void Function(Duration) onDurationChanged;
|
||||
final void Function(Duration?) onDurationChanged;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
@ -79,6 +79,8 @@ class DurationInputField extends StatelessWidget {
|
|||
var duration = int.tryParse(value);
|
||||
if (duration != null) {
|
||||
onDurationChanged(Duration(minutes: duration));
|
||||
} else {
|
||||
onDurationChanged(null);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -146,7 +146,7 @@ class BreakDisplay extends StatelessWidget {
|
|||
breakModel.endTime!,
|
||||
);
|
||||
|
||||
var breakDuration = breakModel.durationInMinutes;
|
||||
var breakDuration = breakModel.duration.inMinutes;
|
||||
|
||||
return InkWell(
|
||||
onTap: onClick,
|
||||
|
@ -246,9 +246,14 @@ class _AvailabilityBreakSelectionDialogState
|
|||
var translations = options.translations;
|
||||
var spacing = options.spacing;
|
||||
|
||||
void onUpdateDuration(Duration duration) {
|
||||
void onUpdateDuration(Duration? duration) {
|
||||
setState(() {
|
||||
_breakViewModel = _breakViewModel.copyWith(duration: duration);
|
||||
if (duration != null) {
|
||||
_breakViewModel =
|
||||
_breakViewModel.copyWith(submittedDuration: duration);
|
||||
} else {
|
||||
_breakViewModel = _breakViewModel.clearDuration();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -317,7 +322,7 @@ class _AvailabilityBreakSelectionDialogState
|
|||
Expanded(
|
||||
flex: 2,
|
||||
child: DurationInputField(
|
||||
initialValue: _breakViewModel.duration,
|
||||
initialValue: _breakViewModel.submittedDuration,
|
||||
onDurationChanged: onUpdateDuration,
|
||||
),
|
||||
),
|
||||
|
|
|
@ -60,8 +60,8 @@ class AvailabilityBreakModel {
|
|||
const AvailabilityBreakModel({
|
||||
required this.startTime,
|
||||
required this.endTime,
|
||||
Duration? duration,
|
||||
}) : _duration = duration;
|
||||
this.submittedDuration,
|
||||
});
|
||||
|
||||
/// Parses a break from a map.
|
||||
///
|
||||
|
@ -74,7 +74,7 @@ class AvailabilityBreakModel {
|
|||
DateTime.fromMillisecondsSinceEpoch((map["startTime"] ?? 0) as int),
|
||||
endTime:
|
||||
DateTime.fromMillisecondsSinceEpoch((map["endTime"] ?? 0) as int),
|
||||
duration: map["duration"] != null
|
||||
submittedDuration: map["duration"] != null
|
||||
? Duration(minutes: map["duration"] as int)
|
||||
: null,
|
||||
);
|
||||
|
@ -83,35 +83,36 @@ class AvailabilityBreakModel {
|
|||
///
|
||||
/// If duration is not the same as the difference between [startTime] and
|
||||
/// [endTime], the [startTime] is considered the start of the period of which
|
||||
/// a break of [_duration] can be held.
|
||||
/// a break of [submittedDuration] can be held.
|
||||
final DateTime startTime;
|
||||
|
||||
/// The end time for this break
|
||||
///
|
||||
/// If duration is not the same as the difference between [startTime] and
|
||||
/// [endTime], the [endTime] is considered the end of the period of which
|
||||
/// a break of [_duration] can be held.
|
||||
/// a break of [submittedDuration] can be held.
|
||||
final DateTime endTime;
|
||||
|
||||
/// The full duration of the actual break.
|
||||
/// The full duration of the actual break. This is filled in by the users and
|
||||
/// stays null if the user has not filled it in.
|
||||
///
|
||||
/// This is allowed to diverge from the difference between [startTime] and
|
||||
/// [endTime] to indicate that the break is somewhere between [startTime] and
|
||||
/// [endTime]
|
||||
final Duration? _duration;
|
||||
final Duration? submittedDuration;
|
||||
|
||||
/// Results in the set duration, or the difference between [startTime] and
|
||||
/// [endTime] if no duration is set.
|
||||
Duration get duration => _duration ?? period;
|
||||
Duration get duration => submittedDuration ?? period;
|
||||
|
||||
/// The period in which the break will take place.
|
||||
///
|
||||
/// Will be the same as [duration] if the initial [_duration] is null
|
||||
/// Will be the same as [duration] if the initial [submittedDuration] is null
|
||||
Duration get period => endTime.difference(startTime);
|
||||
|
||||
/// Whether the duration of the break matches the difference between
|
||||
/// [startTime] and [endTime]
|
||||
bool get isTight => _duration == null || _duration == period;
|
||||
bool get isTight => submittedDuration == null || submittedDuration == period;
|
||||
|
||||
/// Copies the current properties into a new instance of
|
||||
/// [AvailabilityBreakModel], except for the properties provided
|
||||
|
@ -119,12 +120,12 @@ class AvailabilityBreakModel {
|
|||
AvailabilityBreakModel copyWith({
|
||||
DateTime? startTime,
|
||||
DateTime? endTime,
|
||||
Duration? duration,
|
||||
Duration? submittedDuration,
|
||||
}) =>
|
||||
AvailabilityBreakModel(
|
||||
startTime: startTime ?? this.startTime,
|
||||
endTime: endTime ?? this.endTime,
|
||||
duration: duration ?? _duration,
|
||||
submittedDuration: submittedDuration ?? this.submittedDuration,
|
||||
);
|
||||
|
||||
/// Returns a map variant of this object.
|
||||
|
@ -135,6 +136,6 @@ class AvailabilityBreakModel {
|
|||
Map<String, dynamic> toMap() => <String, dynamic>{
|
||||
"startTime": startTime.millisecondsSinceEpoch,
|
||||
"endTime": endTime.millisecondsSinceEpoch,
|
||||
"duration": _duration?.inMinutes,
|
||||
"duration": submittedDuration?.inMinutes,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -331,7 +331,8 @@ class DayTemplateData implements TemplateData {
|
|||
AvailabilityBreakModel(
|
||||
startTime: date.mergeTime(templateBreak.startTime),
|
||||
endTime: date.mergeTime(templateBreak.endTime),
|
||||
duration: templateBreak.isTight ? null : templateBreak.duration,
|
||||
submittedDuration:
|
||||
templateBreak.isTight ? null : templateBreak.duration,
|
||||
),
|
||||
],
|
||||
],
|
||||
|
|
|
@ -12,7 +12,7 @@ void main() {
|
|||
AvailabilityBreakModel(
|
||||
startTime: asTime(startHour),
|
||||
endTime: asTime(startHour + 1),
|
||||
duration: const Duration(minutes: 30),
|
||||
submittedDuration: const Duration(minutes: 30),
|
||||
);
|
||||
|
||||
DayTemplateData createTemplate(int startHour) => DayTemplateData(
|
||||
|
|
Loading…
Reference in a new issue