Files
Client/lib/view/pages/timetable/data/lesson_period_schedule.dart
T

156 lines
4.3 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import 'package:flutter/material.dart';
import '../../../../api/marianumconnect/queries/timetable_get_timegrid/timetable_get_timegrid_response.dart';
import '../../../../state/app/modules/timetable/bloc/timetable_state.dart';
class LessonPeriod {
final String name;
final TimeOfDay start;
final TimeOfDay end;
final bool isBreak;
const LessonPeriod({
required this.name,
required this.start,
required this.end,
this.isBreak = false,
});
Duration get duration => Duration(
minutes: (end.hour * 60 + end.minute) - (start.hour * 60 + start.minute),
);
int get _startMinutes => start.hour * 60 + start.minute;
}
class LessonPeriodSchedule {
final List<LessonPeriod> periods;
const LessonPeriodSchedule(this.periods);
static LessonPeriodSchedule? fromApi(TimetableGetTimegridResponse response) {
// The Marianum-Connect endpoint returns one entry per (weekday, unit). The
// school's bell schedule is identical MonFri, so we pick Monday as the
// canonical day and fall back to the first available weekday if Monday is
// missing.
final monday = response.result
.where((u) => u.dayOfWeek == McDayOfWeek.monday)
.toList();
final source = monday.isNotEmpty ? monday : response.result;
if (source.isEmpty) return null;
final periods =
source
.map(
(u) => LessonPeriod(
name: u.label,
start: TimeOfDay(
hour: u.startTime.hour,
minute: u.startTime.minute,
),
end: TimeOfDay(
hour: u.endTime.hour,
minute: u.endTime.minute,
),
),
)
.toList()
..sort((a, b) => a._startMinutes.compareTo(b._startMinutes));
return LessonPeriodSchedule(periods);
}
static LessonPeriodSchedule fallback() => const LessonPeriodSchedule([
LessonPeriod(
name: '0',
start: TimeOfDay(hour: 7, minute: 10),
end: TimeOfDay(hour: 7, minute: 53),
),
LessonPeriod(
name: '1',
start: TimeOfDay(hour: 7, minute: 55),
end: TimeOfDay(hour: 8, minute: 40),
),
LessonPeriod(
name: '2',
start: TimeOfDay(hour: 8, minute: 40),
end: TimeOfDay(hour: 9, minute: 25),
),
LessonPeriod(
name: '3',
start: TimeOfDay(hour: 9, minute: 30),
end: TimeOfDay(hour: 10, minute: 15),
),
LessonPeriod(
name: '4',
start: TimeOfDay(hour: 10, minute: 35),
end: TimeOfDay(hour: 11, minute: 20),
),
LessonPeriod(
name: '5',
start: TimeOfDay(hour: 11, minute: 25),
end: TimeOfDay(hour: 12, minute: 10),
),
LessonPeriod(
name: '6',
start: TimeOfDay(hour: 12, minute: 15),
end: TimeOfDay(hour: 13, minute: 0),
),
LessonPeriod(
name: '7',
start: TimeOfDay(hour: 13, minute: 5),
end: TimeOfDay(hour: 13, minute: 50),
),
LessonPeriod(
name: '8',
start: TimeOfDay(hour: 14, minute: 5),
end: TimeOfDay(hour: 14, minute: 50),
),
LessonPeriod(
name: '9',
start: TimeOfDay(hour: 14, minute: 50),
end: TimeOfDay(hour: 15, minute: 35),
),
LessonPeriod(
name: '10',
start: TimeOfDay(hour: 15, minute: 40),
end: TimeOfDay(hour: 16, minute: 25),
),
LessonPeriod(
name: '11',
start: TimeOfDay(hour: 16, minute: 25),
end: TimeOfDay(hour: 17, minute: 10),
),
]);
static LessonPeriodSchedule fromState(TimetableState state) {
final fromApi = state.timegrid != null
? LessonPeriodSchedule.fromApi(state.timegrid!)
: null;
return (fromApi ?? fallback()).withSyntheticBreaks();
}
LessonPeriodSchedule withSyntheticBreaks() {
final result = <LessonPeriod>[];
for (var i = 0; i < periods.length; i++) {
final current = periods[i];
result.add(current);
if (i + 1 >= periods.length) continue;
final next = periods[i + 1];
final gapMinutes =
next._startMinutes - (current.end.hour * 60 + current.end.minute);
if (gapMinutes >= 10) {
result.add(
LessonPeriod(
name: 'Pause',
start: current.end,
end: next.start,
isBreak: true,
),
);
}
}
return LessonPeriodSchedule(result);
}
}