implemented custom subject colors for the timetable and unified the color palette system

This commit is contained in:
2026-07-12 21:30:08 +02:00
parent a7111844b1
commit fe2b3c43b2
23 changed files with 916 additions and 89 deletions
@@ -1,31 +1,39 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncfusion_flutter_calendar/calendar.dart';
import '../../../../api/marianumconnect/queries/timetable_get_week/timetable_get_week_response.dart';
import '../../../../extensions/date_time.dart';
import '../../../../extensions/text.dart';
import '../../../../routing/app_routes.dart';
import '../../../../state/app/modules/timetable/bloc/timetable_bloc.dart';
import '../../../../state/app/modules/timetable/bloc/timetable_state.dart';
import '../../../../widget/debug/debug_tile.dart';
import '../../../../widget/details_bottom_sheet.dart';
import '../data/lesson_type_label.dart';
import '../subject_colors/subject_color_picker.dart';
class LessonSheet {
static void show(
BuildContext context,
TimetableState? state,
Appointment appointment,
McTimetableEntry lesson,
) {
McTimetableEntry lesson, {
bool canEditSubjectColor = false,
}) {
if (state == null) return;
// In Fremdansichten würde der Farb-Button die eigene, globale Fach-Farbe
// ä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 subjectShort = lesson.subjects.firstOrNull;
final headerLong = subjectShort == null
final subjectEntry = subjectShort == null
? null
: state.subjects?.result
.where((s) => s.shortName == subjectShort)
.firstOrNull
?.longName;
.firstOrNull;
final headerLong = subjectEntry?.longName;
// Bei Stunden ohne Fach (Pausenaufsicht etc.) den Lesson-Type-Titel
// einsetzen — sonst stünde im Header nur ein generisches "?".
final headerTitle = subjectShort != null
@@ -50,6 +58,18 @@ class LessonSheet {
headerLongName.isNotEmpty ? '$timeRange\n$headerLongName' : timeRange,
),
isThreeLine: headerLongName.isNotEmpty,
trailing: canEditSubjectColor && subjectShort != null
? TimetableColorHeaderButton(
initialColorName: subjectEntry?.color,
pickerTitle: (headerLong != null && headerLong.isNotEmpty)
? 'Farbe: $headerLong'
: 'Farbe: $subjectShort',
pickerSubtitle: 'Nur reguläre Stunden werden eingefärbt',
onSelected: (option) =>
bloc.setSubjectColor(subjectShort, option.name),
onReset: () => bloc.clearSubjectColor(subjectShort),
)
: null,
),
children: (_) => <Widget>[
ListTile(