refactored timetable
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
const double kCalendarStartHour = 7.5;
|
||||
const double kCalendarEndHour = 17.25;
|
||||
const Duration kCalendarTimeInterval = Duration(minutes: 30);
|
||||
const double kCalendarViewHeaderHeight = 60;
|
||||
|
||||
/// Minimum pixels per hour. Below this, the grid scrolls vertically rather
|
||||
/// than compressing further.
|
||||
const double kCalendarMinPxPerHour = 56;
|
||||
@@ -3,12 +3,14 @@ import 'package:flutter/material.dart';
|
||||
import 'lesson_status.dart';
|
||||
|
||||
class LessonColor {
|
||||
static const Color regular = Color.fromARGB(255, 153, 51, 51);
|
||||
static const Color ongoing = Color.fromARGB(255, 200, 51, 51);
|
||||
static const Color cancelled = Color(0xff000000);
|
||||
static const Color irregular = Color(0xff8F19B3);
|
||||
static const Color teacherChanged = Color(0xFF29639B);
|
||||
static const Color parseFallback = Color(0xff404040);
|
||||
|
||||
static Color forStatus(LessonStatus status, ColorScheme scheme) {
|
||||
static Color forStatus(LessonStatus status) {
|
||||
switch (status) {
|
||||
case LessonStatus.cancelled:
|
||||
return cancelled;
|
||||
@@ -18,14 +20,9 @@ class LessonColor {
|
||||
return teacherChanged;
|
||||
case LessonStatus.past:
|
||||
case LessonStatus.regular:
|
||||
return scheme.primary;
|
||||
return regular;
|
||||
case LessonStatus.ongoing:
|
||||
return Color.from(
|
||||
alpha: scheme.primary.a,
|
||||
red: 200 / 255,
|
||||
green: scheme.primary.g,
|
||||
blue: scheme.primary.b,
|
||||
);
|
||||
return ongoing;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../../../../api/webuntis/queries/getTimegridUnits/getTimegridUnitsResponse.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(GetTimegridUnitsResponse response) {
|
||||
final canonical = response.result.firstWhere(
|
||||
(d) => d.day == 1,
|
||||
orElse: () => response.result.isNotEmpty ? response.result.first : GetTimegridUnitsResponseDay(0, []),
|
||||
);
|
||||
if (canonical.timeUnits.isEmpty) return null;
|
||||
|
||||
final periods = canonical.timeUnits
|
||||
.map((u) => LessonPeriod(
|
||||
name: u.name,
|
||||
start: _fromHHMM(u.startTime),
|
||||
end: _fromHHMM(u.endTime),
|
||||
))
|
||||
.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);
|
||||
}
|
||||
|
||||
static TimeOfDay _fromHHMM(int hhmm) => TimeOfDay(
|
||||
hour: hhmm ~/ 100,
|
||||
minute: hhmm % 100,
|
||||
);
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:syncfusion_flutter_calendar/calendar.dart';
|
||||
|
||||
import '../../../../api/mhsl/customTimetableEvent/customTimetableEvent.dart';
|
||||
@@ -20,7 +19,6 @@ class TimetableAppointmentFactory {
|
||||
final GetRoomsResponse rooms;
|
||||
final GetSubjectsResponse subjects;
|
||||
final TimetableSettings settings;
|
||||
final ColorScheme colorScheme;
|
||||
final DateTime now;
|
||||
|
||||
TimetableAppointmentFactory({
|
||||
@@ -29,7 +27,6 @@ class TimetableAppointmentFactory {
|
||||
required this.rooms,
|
||||
required this.subjects,
|
||||
required this.settings,
|
||||
required this.colorScheme,
|
||||
required this.now,
|
||||
});
|
||||
|
||||
@@ -54,7 +51,7 @@ class TimetableAppointmentFactory {
|
||||
subject: _subjectName(lesson),
|
||||
location: _locationLabel(lesson),
|
||||
notes: lesson.activityType,
|
||||
color: LessonColor.forStatus(status, colorScheme),
|
||||
color: LessonColor.forStatus(status),
|
||||
);
|
||||
} catch (_) {
|
||||
return Appointment(
|
||||
|
||||
Reference in New Issue
Block a user