folder restructuring
This commit is contained in:
@@ -0,0 +1,135 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:jiffy/jiffy.dart';
|
||||
|
||||
import '../../../state/app/infrastructure/loadableState/loadable_state.dart';
|
||||
import '../../../state/app/infrastructure/loadableState/view/loadable_state_consumer.dart';
|
||||
import '../../../state/app/infrastructure/utilityWidgets/bloc_module.dart';
|
||||
import '../../../state/app/modules/marianumDates/bloc/marianum_dates_bloc.dart';
|
||||
import '../../../state/app/modules/marianumDates/bloc/marianum_dates_event.dart';
|
||||
import '../../../state/app/modules/marianumDates/bloc/marianum_dates_state.dart';
|
||||
import '../../../widget/animated_time.dart';
|
||||
import '../../../widget/centered_leading.dart';
|
||||
import '../../../widget/debug/debug_tile.dart';
|
||||
import '../../../widget/list_view_util.dart';
|
||||
import '../timetable/custom_events/custom_event_edit_dialog.dart';
|
||||
|
||||
class MarianumDatesView extends StatelessWidget {
|
||||
const MarianumDatesView({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => BlocModule<MarianumDatesBloc, LoadableState<MarianumDatesState>>(
|
||||
create: (context) => MarianumDatesBloc(),
|
||||
autoRebuild: true,
|
||||
child: (context, bloc, state) => Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('Marianum Termine'),
|
||||
actions: [
|
||||
PopupMenuButton<bool>(
|
||||
initialValue: bloc.showPastEvents(),
|
||||
icon: const Icon(Icons.history),
|
||||
itemBuilder: (context) => [true, false].map((e) => PopupMenuItem<bool>(
|
||||
value: e,
|
||||
enabled: e != bloc.showPastEvents(),
|
||||
child: Row(
|
||||
children: [
|
||||
Icon(e ? Icons.history_outlined : Icons.history_toggle_off_outlined, color: Theme.of(context).colorScheme.onSurface),
|
||||
const SizedBox(width: 15),
|
||||
Text(e ? 'Alle anzeigen' : 'Nur zukünftige anzeigen'),
|
||||
],
|
||||
),
|
||||
)).toList(),
|
||||
onSelected: (e) => bloc.add(SetPastEventsVisible(e)),
|
||||
),
|
||||
],
|
||||
),
|
||||
body: LoadableStateConsumer<MarianumDatesBloc, MarianumDatesState>(
|
||||
child: (state, loading) => ListViewUtil.fromList<MarianumDate>(bloc.getEvents(), (event) => _MarianumDateTile(event: event)),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
class _MarianumDateTile extends StatelessWidget {
|
||||
final MarianumDate event;
|
||||
const _MarianumDateTile({required this.event});
|
||||
|
||||
String _formatSubtitle() {
|
||||
final start = Jiffy.parseFromDateTime(event.start);
|
||||
final end = Jiffy.parseFromDateTime(event.end);
|
||||
|
||||
if (event.isAllDay) {
|
||||
// iCal end is exclusive for multi-day all-day events. The feed sets
|
||||
// DTSTART == DTEND for single-day all-day events, so only subtract a
|
||||
// day when end actually advances past start.
|
||||
final inclusiveEnd = event.end.isAfter(event.start) ? end.subtract(days: 1) : end;
|
||||
final sameAllDay = start.format(pattern: 'yyyy-MM-dd') == inclusiveEnd.format(pattern: 'yyyy-MM-dd');
|
||||
return sameAllDay
|
||||
? '${start.format(pattern: 'dd.MM.yyyy')} · Ganztägig'
|
||||
: '${start.format(pattern: 'dd.MM.yyyy')} – ${inclusiveEnd.format(pattern: 'dd.MM.yyyy')} · Ganztägig';
|
||||
}
|
||||
|
||||
final sameDay = start.format(pattern: 'yyyy-MM-dd') == end.format(pattern: 'yyyy-MM-dd');
|
||||
if (sameDay) {
|
||||
if (event.start == event.end) {
|
||||
return '${start.format(pattern: 'dd.MM.yyyy')} · ${start.format(pattern: 'HH:mm')}';
|
||||
}
|
||||
return '${start.format(pattern: 'dd.MM.yyyy')} · ${start.format(pattern: 'HH:mm')} – ${end.format(pattern: 'HH:mm')}';
|
||||
}
|
||||
return '${start.format(pattern: 'dd.MM.yyyy HH:mm')} – ${end.format(pattern: 'dd.MM.yyyy HH:mm')}';
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => ListTile(
|
||||
leading: const CenteredLeading(Icon(Icons.event)),
|
||||
title: Text(event.title.isEmpty ? '(ohne Titel)' : event.title),
|
||||
subtitle: Text(_formatSubtitle()),
|
||||
onTap: () => _showDetails(context),
|
||||
trailing: IconButton(
|
||||
icon: const Icon(Icons.add_circle_outline),
|
||||
tooltip: 'In Stundenplan übernehmen',
|
||||
onPressed: () => showDialog(
|
||||
context: context,
|
||||
builder: (_) => CustomEventEditDialog(
|
||||
initialTitle: event.title,
|
||||
initialDescription: event.description,
|
||||
initialStart: event.start,
|
||||
initialEnd: event.end,
|
||||
),
|
||||
barrierDismissible: false,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
void _showDetails(BuildContext context) {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => SimpleDialog(
|
||||
title: Text(event.title.isEmpty ? '(ohne Titel)' : event.title),
|
||||
children: [
|
||||
ListTile(
|
||||
leading: const CenteredLeading(Icon(Icons.date_range_outlined)),
|
||||
title: Text(_formatSubtitle()),
|
||||
),
|
||||
if (event.description != null && event.description!.trim().isNotEmpty)
|
||||
ListTile(
|
||||
leading: const CenteredLeading(Icon(Icons.notes_outlined)),
|
||||
title: Text(event.description!.trim()),
|
||||
),
|
||||
Visibility(
|
||||
visible: !event.start.difference(DateTime.now()).isNegative,
|
||||
replacement: ListTile(
|
||||
leading: const CenteredLeading(Icon(Icons.content_paste_search_outlined)),
|
||||
title: Text(Jiffy.parseFromDateTime(event.start).fromNow()),
|
||||
),
|
||||
child: ListTile(
|
||||
leading: const CenteredLeading(Icon(Icons.timer_outlined)),
|
||||
title: AnimatedTime(callback: () => event.start.difference(DateTime.now())),
|
||||
subtitle: Text(Jiffy.parseFromDateTime(event.start).fromNow()),
|
||||
),
|
||||
),
|
||||
DebugTile(context).jsonData(event.toJson()),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user