simplified code across the app and consolidated duplicated helpers

This commit is contained in:
2026-09-27 17:29:54 +02:00
parent 3e856d0b1c
commit ee1240f71a
155 changed files with 1772 additions and 2546 deletions
@@ -3,6 +3,7 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncfusion_flutter_calendar/calendar.dart';
import '../../../../api/marianumconnect/queries/timetable_get_element_week/timetable_element_type.dart';
import '../../../../api/marianumconnect/queries/timetable_get_subjects/timetable_get_subjects_response.dart';
import '../../../../api/marianumconnect/queries/timetable_get_week/timetable_get_week_response.dart';
import '../../../../extensions/date_time.dart';
import '../../../../extensions/text.dart';
@@ -31,12 +32,11 @@ class LessonSheet {
// ändern, ohne dass sich der fremde Plan aktualisiert — daher nur im
// eigenen Plan anbieten. Die Einfärbung (eigene Farben) bleibt.
final bloc = context.read<TimetableBloc>();
final subjects = state.subjects?.result ?? const <McSubject>[];
McSubject? subjectFor(String shortName) =>
subjects.where((s) => s.shortName == shortName).firstOrNull;
final subjectShort = lesson.subjects.firstOrNull;
final subjectEntry = subjectShort == null
? null
: state.subjects?.result
.where((s) => s.shortName == subjectShort)
.firstOrNull;
final subjectEntry = subjectShort == null ? null : subjectFor(subjectShort);
final headerLong = subjectEntry?.longName;
// Bei Stunden ohne Fach (Pausenaufsicht etc.) den Lesson-Type-Titel
// einsetzen — sonst stünde im Header nur ein generisches "?".
@@ -85,9 +85,7 @@ class LessonSheet {
icon: Icons.book_outlined,
label: 'Fächer',
entries: lesson.subjects
.map(
(s) => _line(s, longname: _subjectLongName(state.subjects, s)),
)
.map((s) => _line(s, longname: subjectFor(s)?.longName))
.toList(),
),
_roomTile(context, lesson),
@@ -120,14 +118,10 @@ class LessonSheet {
);
}
final entries = lesson.rooms
.map((name) => (main: _line(name), sub: null as String?))
.toList();
return _listTileWithSubs(
return _listTile(
icon: Icons.room,
label: lesson.rooms.length == 1 ? 'Raum' : 'Räume',
entries: entries,
entries: lesson.rooms.map(_line).toList(),
trailing: trailing,
);
}
@@ -229,43 +223,6 @@ class LessonSheet {
);
}
static Widget _listTileWithSubs({
required IconData icon,
required String label,
required List<({String main, String? sub})> entries,
Widget? trailing,
}) {
if (entries.length == 1) {
final e = entries.first;
return ListTile(
leading: Icon(icon),
title: Text('$label: ${e.main}'),
subtitle: e.sub != null ? Text(e.sub!) : null,
trailing: trailing,
);
}
return ListTile(
leading: Icon(icon),
title: Text(label),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: entries
.expand<Widget>(
(e) => [
Text(e.main),
if (e.sub != null)
Padding(
padding: const EdgeInsets.only(left: 12),
child: Text(e.sub!),
),
],
)
.toList(),
),
trailing: trailing,
);
}
static Widget _listTile({
required IconData icon,
required String label,
@@ -347,15 +304,6 @@ class LessonSheet {
return parts.join(' ');
}
static String? _subjectLongName(dynamic subjects, String shortName) {
if (subjects == null) return null;
final list = subjects.result as Iterable<dynamic>;
for (final s in list) {
if (s.shortName == shortName) return s.longName as String?;
}
return null;
}
static IconData _iconForStatus(String status) {
switch (status) {
case 'CANCELLED':