dart format
This commit is contained in:
@@ -5,7 +5,8 @@ import '../../../../theming/dark_app_theme.dart';
|
||||
enum CustomTimetableColors { orange, red, green, blue }
|
||||
|
||||
class TimetableColors {
|
||||
static const CustomTimetableColors defaultColor = CustomTimetableColors.orange;
|
||||
static const CustomTimetableColors defaultColor =
|
||||
CustomTimetableColors.orange;
|
||||
|
||||
static ColorModeDisplay getDisplayOptions(CustomTimetableColors color) {
|
||||
switch (color) {
|
||||
@@ -14,17 +15,24 @@ class TimetableColors {
|
||||
case CustomTimetableColors.blue:
|
||||
return ColorModeDisplay(color: Colors.blue, displayName: 'Blau');
|
||||
case CustomTimetableColors.orange:
|
||||
return ColorModeDisplay(color: Colors.orange.shade800, displayName: 'Orange');
|
||||
return ColorModeDisplay(
|
||||
color: Colors.orange.shade800,
|
||||
displayName: 'Orange',
|
||||
);
|
||||
case CustomTimetableColors.red:
|
||||
return ColorModeDisplay(color: DarkAppTheme.marianumRed, displayName: 'Rot');
|
||||
return ColorModeDisplay(
|
||||
color: DarkAppTheme.marianumRed,
|
||||
displayName: 'Rot',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
static Color getColorFromString(String color) =>
|
||||
getDisplayOptions(CustomTimetableColors.values.firstWhere(
|
||||
(e) => e.name == color,
|
||||
orElse: () => defaultColor,
|
||||
)).color;
|
||||
static Color getColorFromString(String color) => getDisplayOptions(
|
||||
CustomTimetableColors.values.firstWhere(
|
||||
(e) => e.name == color,
|
||||
orElse: () => defaultColor,
|
||||
),
|
||||
).color;
|
||||
}
|
||||
|
||||
class ColorModeDisplay {
|
||||
|
||||
@@ -42,7 +42,8 @@ class _CustomEventEditDialogState extends State<CustomEventEditDialog> {
|
||||
static const TimeOfDay _defaultEnd = TimeOfDay(hour: 9, minute: 30);
|
||||
static const int _minDurationMinutes = 15;
|
||||
|
||||
late DateTime _date = widget.existingEvent?.startDate ?? widget.initialStart ?? DateTime.now();
|
||||
late DateTime _date =
|
||||
widget.existingEvent?.startDate ?? widget.initialStart ?? DateTime.now();
|
||||
late TimeOfDay _startTime;
|
||||
late TimeOfDay _endTime;
|
||||
late bool _isAllDay;
|
||||
@@ -85,13 +86,18 @@ class _CustomEventEditDialogState extends State<CustomEventEditDialog> {
|
||||
_endTime = clamped.$2;
|
||||
}
|
||||
|
||||
static (TimeOfDay, TimeOfDay) _clampToVisibleWindow(TimeOfDay rawStart, TimeOfDay rawEnd) {
|
||||
static (TimeOfDay, TimeOfDay) _clampToVisibleWindow(
|
||||
TimeOfDay rawStart,
|
||||
TimeOfDay rawEnd,
|
||||
) {
|
||||
int toMin(TimeOfDay t) => t.hour * 60 + t.minute;
|
||||
TimeOfDay fromMin(int m) => TimeOfDay(hour: m ~/ 60, minute: m % 60);
|
||||
|
||||
final windowStart = toMin(_windowStart);
|
||||
final windowEnd = toMin(_windowEnd);
|
||||
var start = toMin(rawStart).clamp(windowStart, windowEnd - _minDurationMinutes);
|
||||
var start = toMin(
|
||||
rawStart,
|
||||
).clamp(windowStart, windowEnd - _minDurationMinutes);
|
||||
var end = toMin(rawEnd);
|
||||
if (end < start + _minDurationMinutes) end = start + _minDurationMinutes;
|
||||
if (end > windowEnd) {
|
||||
@@ -165,10 +171,7 @@ class _CustomEventEditDialogState extends State<CustomEventEditDialog> {
|
||||
context: context,
|
||||
start: _startTime,
|
||||
end: _endTime,
|
||||
disabledTime: TimeRange(
|
||||
startTime: _windowEnd,
|
||||
endTime: _windowStart,
|
||||
),
|
||||
disabledTime: TimeRange(startTime: _windowEnd, endTime: _windowStart),
|
||||
disabledColor: Colors.grey,
|
||||
paintingStyle: PaintingStyle.fill,
|
||||
interval: const Duration(minutes: 5),
|
||||
@@ -188,103 +191,118 @@ class _CustomEventEditDialogState extends State<CustomEventEditDialog> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => AlertDialog(
|
||||
insetPadding: const EdgeInsets.all(20),
|
||||
contentPadding: const EdgeInsets.all(10),
|
||||
title: Text(_isEditing ? 'Termin bearbeiten' : 'Termin hinzufügen'),
|
||||
content: SingleChildScrollView(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
ListTile(
|
||||
title: TextField(
|
||||
controller: _name,
|
||||
autofocus: true,
|
||||
decoration: const InputDecoration(labelText: 'Terminname', border: OutlineInputBorder()),
|
||||
onTapOutside: (_) => FocusBehaviour.textFieldTapOutside(context),
|
||||
),
|
||||
insetPadding: const EdgeInsets.all(20),
|
||||
contentPadding: const EdgeInsets.all(10),
|
||||
title: Text(_isEditing ? 'Termin bearbeiten' : 'Termin hinzufügen'),
|
||||
content: SingleChildScrollView(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
ListTile(
|
||||
title: TextField(
|
||||
controller: _name,
|
||||
autofocus: true,
|
||||
decoration: const InputDecoration(
|
||||
labelText: 'Terminname',
|
||||
border: OutlineInputBorder(),
|
||||
),
|
||||
ListTile(
|
||||
title: TextField(
|
||||
controller: _description,
|
||||
maxLines: 2,
|
||||
minLines: 2,
|
||||
decoration: const InputDecoration(labelText: 'Beschreibung', border: OutlineInputBorder()),
|
||||
onTapOutside: (_) => FocusBehaviour.textFieldTapOutside(context),
|
||||
),
|
||||
),
|
||||
const Divider(),
|
||||
ListTile(
|
||||
leading: const Icon(Icons.date_range_outlined),
|
||||
title: Text(Jiffy.parseFromDateTime(_date).yMMMd),
|
||||
subtitle: const Text('Datum'),
|
||||
onTap: _pickDate,
|
||||
),
|
||||
SwitchListTile(
|
||||
secondary: const Icon(Icons.today_outlined),
|
||||
title: const Text('Ganztägig'),
|
||||
value: _isAllDay,
|
||||
onChanged: (v) => setState(() => _isAllDay = v),
|
||||
),
|
||||
if (!_isAllDay)
|
||||
ListTile(
|
||||
leading: const Icon(Icons.access_time_outlined),
|
||||
title: Text('${_startTime.format(context)} - ${_endTime.format(context)}'),
|
||||
subtitle: const Text('Zeitraum'),
|
||||
onTap: _pickTimeRange,
|
||||
),
|
||||
const Divider(),
|
||||
ListTile(
|
||||
leading: const Icon(Icons.color_lens_outlined),
|
||||
title: const Text('Farbgebung'),
|
||||
trailing: DropdownButton<CustomTimetableColors>(
|
||||
value: _color,
|
||||
icon: const Icon(Icons.arrow_drop_down),
|
||||
items: CustomTimetableColors.values
|
||||
.map((e) => DropdownMenuItem<CustomTimetableColors>(
|
||||
value: e,
|
||||
enabled: e != _color,
|
||||
child: Row(
|
||||
children: [
|
||||
Icon(Icons.circle, color: TimetableColors.getDisplayOptions(e).color),
|
||||
const SizedBox(width: 10),
|
||||
Text(TimetableColors.getDisplayOptions(e).displayName),
|
||||
],
|
||||
),
|
||||
))
|
||||
.toList(),
|
||||
onChanged: (e) => setState(() => _color = e!),
|
||||
),
|
||||
),
|
||||
const Divider(),
|
||||
RRuleGenerator(
|
||||
config: RRuleGeneratorConfig(
|
||||
selectDayStyle: RRuleSelectDayStyle(
|
||||
dayStyle: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: Theme.of(context).colorScheme.secondary,
|
||||
),
|
||||
dayTextStyle: const TextStyle(color: Colors.black),
|
||||
selectedDayStyle: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: Theme.of(context).primaryColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
initialRRule: _rrule,
|
||||
locale: RRuleLocale.de_DE,
|
||||
onChange: (newValue) {
|
||||
log('Rule: $newValue');
|
||||
setState(() => _rrule = newValue);
|
||||
},
|
||||
),
|
||||
],
|
||||
onTapOutside: (_) => FocusBehaviour.textFieldTapOutside(context),
|
||||
),
|
||||
),
|
||||
),
|
||||
actions: [
|
||||
AsyncDialogAction(
|
||||
confirmLabel: _isEditing ? 'Speichern' : 'Erstellen',
|
||||
onConfirm: _save,
|
||||
ListTile(
|
||||
title: TextField(
|
||||
controller: _description,
|
||||
maxLines: 2,
|
||||
minLines: 2,
|
||||
decoration: const InputDecoration(
|
||||
labelText: 'Beschreibung',
|
||||
border: OutlineInputBorder(),
|
||||
),
|
||||
onTapOutside: (_) => FocusBehaviour.textFieldTapOutside(context),
|
||||
),
|
||||
),
|
||||
const Divider(),
|
||||
ListTile(
|
||||
leading: const Icon(Icons.date_range_outlined),
|
||||
title: Text(Jiffy.parseFromDateTime(_date).yMMMd),
|
||||
subtitle: const Text('Datum'),
|
||||
onTap: _pickDate,
|
||||
),
|
||||
SwitchListTile(
|
||||
secondary: const Icon(Icons.today_outlined),
|
||||
title: const Text('Ganztägig'),
|
||||
value: _isAllDay,
|
||||
onChanged: (v) => setState(() => _isAllDay = v),
|
||||
),
|
||||
if (!_isAllDay)
|
||||
ListTile(
|
||||
leading: const Icon(Icons.access_time_outlined),
|
||||
title: Text(
|
||||
'${_startTime.format(context)} - ${_endTime.format(context)}',
|
||||
),
|
||||
subtitle: const Text('Zeitraum'),
|
||||
onTap: _pickTimeRange,
|
||||
),
|
||||
const Divider(),
|
||||
ListTile(
|
||||
leading: const Icon(Icons.color_lens_outlined),
|
||||
title: const Text('Farbgebung'),
|
||||
trailing: DropdownButton<CustomTimetableColors>(
|
||||
value: _color,
|
||||
icon: const Icon(Icons.arrow_drop_down),
|
||||
items: CustomTimetableColors.values
|
||||
.map(
|
||||
(e) => DropdownMenuItem<CustomTimetableColors>(
|
||||
value: e,
|
||||
enabled: e != _color,
|
||||
child: Row(
|
||||
children: [
|
||||
Icon(
|
||||
Icons.circle,
|
||||
color: TimetableColors.getDisplayOptions(e).color,
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
Text(
|
||||
TimetableColors.getDisplayOptions(e).displayName,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
onChanged: (e) => setState(() => _color = e!),
|
||||
),
|
||||
),
|
||||
const Divider(),
|
||||
RRuleGenerator(
|
||||
config: RRuleGeneratorConfig(
|
||||
selectDayStyle: RRuleSelectDayStyle(
|
||||
dayStyle: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: Theme.of(context).colorScheme.secondary,
|
||||
),
|
||||
dayTextStyle: const TextStyle(color: Colors.black),
|
||||
selectedDayStyle: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: Theme.of(context).primaryColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
initialRRule: _rrule,
|
||||
locale: RRuleLocale.de_DE,
|
||||
onChange: (newValue) {
|
||||
log('Rule: $newValue');
|
||||
setState(() => _rrule = newValue);
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
),
|
||||
),
|
||||
actions: [
|
||||
AsyncDialogAction(
|
||||
confirmLabel: _isEditing ? 'Speichern' : 'Erstellen',
|
||||
onConfirm: _save,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@@ -22,57 +22,69 @@ class CustomEventsView extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('Eigene Termine'),
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: const Icon(Icons.add),
|
||||
appBar: AppBar(
|
||||
title: const Text('Eigene Termine'),
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: const Icon(Icons.add),
|
||||
onPressed: () => _openCreateDialog(context),
|
||||
),
|
||||
],
|
||||
),
|
||||
body: LoadableStateConsumer<TimetableBloc, TimetableState>(
|
||||
child: (state, _) {
|
||||
final events = state.customEvents?.events ?? const [];
|
||||
|
||||
if (events.isEmpty) {
|
||||
return PlaceholderView(
|
||||
icon: Icons.calendar_today_outlined,
|
||||
text: 'Keine Einträge vorhanden',
|
||||
button: TextButton(
|
||||
onPressed: () => _openCreateDialog(context),
|
||||
child: const Text('Termin erstellen'),
|
||||
),
|
||||
],
|
||||
),
|
||||
body: LoadableStateConsumer<TimetableBloc, TimetableState>(
|
||||
child: (state, _) {
|
||||
final events = state.customEvents?.events ?? const [];
|
||||
);
|
||||
}
|
||||
|
||||
if (events.isEmpty) {
|
||||
return PlaceholderView(
|
||||
icon: Icons.calendar_today_outlined,
|
||||
text: 'Keine Einträge vorhanden',
|
||||
button: TextButton(
|
||||
onPressed: () => _openCreateDialog(context),
|
||||
child: const Text('Termin erstellen'),
|
||||
return ListView(
|
||||
children: events
|
||||
.map(
|
||||
(e) => ListTile(
|
||||
title: Text(e.title),
|
||||
subtitle: Text(
|
||||
'${e.rrule.isNotEmpty ? "wiederholend, " : ""}'
|
||||
'beginnend ${e.startDate.formatRelative()}',
|
||||
),
|
||||
leading: CenteredLeading(
|
||||
Icon(
|
||||
e.rrule.isEmpty
|
||||
? Icons.event_outlined
|
||||
: Icons.event_repeat_outlined,
|
||||
),
|
||||
),
|
||||
trailing: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
IconButton(
|
||||
icon: const Icon(Icons.edit_outlined),
|
||||
onPressed: () => showDialog(
|
||||
context: context,
|
||||
builder: (_) =>
|
||||
CustomEventEditDialog(existingEvent: e),
|
||||
),
|
||||
),
|
||||
IconButton(
|
||||
icon: const Icon(Icons.delete_outline),
|
||||
onPressed: () =>
|
||||
showDeleteCustomEventDialog(context, e),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return ListView(
|
||||
children: events.map((e) => ListTile(
|
||||
title: Text(e.title),
|
||||
subtitle: Text(
|
||||
'${e.rrule.isNotEmpty ? "wiederholend, " : ""}'
|
||||
'beginnend ${e.startDate.formatRelative()}',
|
||||
),
|
||||
leading: CenteredLeading(Icon(e.rrule.isEmpty ? Icons.event_outlined : Icons.event_repeat_outlined)),
|
||||
trailing: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
IconButton(
|
||||
icon: const Icon(Icons.edit_outlined),
|
||||
onPressed: () => showDialog(
|
||||
context: context,
|
||||
builder: (_) => CustomEventEditDialog(existingEvent: e),
|
||||
),
|
||||
),
|
||||
IconButton(
|
||||
icon: const Icon(Icons.delete_outline),
|
||||
onPressed: () => showDeleteCustomEventDialog(context, e),
|
||||
),
|
||||
],
|
||||
),
|
||||
)).toList(),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
)
|
||||
.toList(),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user