From 7bf3eaca039d353d89b42950ab73013677ad1626 Mon Sep 17 00:00:00 2001 From: Armand <4831c0@proton.me> Date: Thu, 4 Sep 2025 17:34:14 +0200 Subject: [PATCH] tt: empty classes --- firka/lib/helpers/extensions.dart | 41 ++++++ firka/lib/l10n | 2 +- .../ui/phone/pages/home/home_timetable.dart | 14 ++- firka/lib/ui/phone/widgets/lesson.dart | 119 +++++++++++++++--- firka/lib/ui/phone/widgets/tt_day.dart | 4 +- 5 files changed, 157 insertions(+), 23 deletions(-) diff --git a/firka/lib/helpers/extensions.dart b/firka/lib/helpers/extensions.dart index a7d6a38..98023eb 100644 --- a/firka/lib/helpers/extensions.dart +++ b/firka/lib/helpers/extensions.dart @@ -4,6 +4,47 @@ import '../l10n/app_localizations.dart'; import 'api/model/timetable.dart'; import 'debug_helper.dart'; +extension TimetableExtension on Iterable { + List getAllSeqs(Lesson reference) { + List lessons = List.empty(growable: true); + + for (var lesson in this) { + if (lesson.lessonNumber == null) continue; + + if (lessons.firstWhereOrNull( + (lesson2) => lesson.lessonNumber == lesson2.lessonNumber) == + null) { + final ref = reference.start; + final newStart = DateTime(ref.year, ref.month, ref.day, + lesson.start.hour, lesson.start.minute, lesson.start.second); + final newEnd = DateTime(ref.year, ref.month, ref.day, lesson.end.hour, + lesson.end.minute, lesson.end.second); + final lessonCopy = Lesson( + uid: lesson.uid, + date: lesson.date, + start: newStart, + end: newEnd, + name: lesson.name, + type: lesson.type, + state: lesson.state, + canStudentEditHomework: lesson.canStudentEditHomework, + isHomeworkComplete: lesson.isHomeworkComplete, + attachments: lesson.attachments, + lessonNumber: lesson.lessonNumber, + isDigitalLesson: lesson.isDigitalLesson, + digitalSupportDeviceTypeList: lesson.digitalSupportDeviceTypeList, + createdAt: lesson.createdAt, + lastModifiedAt: lesson.lastModifiedAt); + lessons.add(lessonCopy); + } + } + + lessons.sort((l1, l2) => l1.lessonNumber! - l2.lessonNumber!); + + return lessons; + } +} + extension IterableExtensionMap on Iterable> { Map toMap() { var map = {}; diff --git a/firka/lib/l10n b/firka/lib/l10n index b98899c..47c41a0 160000 --- a/firka/lib/l10n +++ b/firka/lib/l10n @@ -1 +1 @@ -Subproject commit b98899c06375f7ab256da8eb911dc62f0c4268e1 +Subproject commit 47c41a04d1dd364eaefd45d32519419129eeb003 diff --git a/firka/lib/ui/phone/pages/home/home_timetable.dart b/firka/lib/ui/phone/pages/home/home_timetable.dart index cc96bed..09a7da0 100644 --- a/firka/lib/ui/phone/pages/home/home_timetable.dart +++ b/firka/lib/ui/phone/pages/home/home_timetable.dart @@ -89,11 +89,13 @@ class _HomeTimetableScreen extends State { if (idx >= 0) { final todaysLessons = lessons?.where((lesson) => lesson.start.isAfter(todayMid) && - lesson.end.isBefore(todayMid.add(Duration(hours: 23, minutes: 59)))); - + lesson.end + .isBefore(todayMid.add(Duration(hours: 23, minutes: 59)))); + if (todaysLessons != null && todaysLessons.isNotEmpty) { - final lastLessonToday = todaysLessons.reduce((a, b) => a.end.isAfter(b.end) ? a : b); - + final lastLessonToday = + todaysLessons.reduce((a, b) => a.end.isAfter(b.end) ? a : b); + if (now.isAfter(lastLessonToday.end)) { int nextIdx = idx + 1; if (nextIdx < dates.length) { @@ -190,8 +192,8 @@ class _HomeTimetableScreen extends State { test.date.isBefore(date.add(Duration(hours: 23, minutes: 59)))) .toList(); - ttDays.add(TimeTableDayWidget( - widget.data, date, lessonsOnDate, eventsOnDate, testsOnDate)); + ttDays.add(TimeTableDayWidget(widget.data, date, lessons!, + lessonsOnDate, eventsOnDate, testsOnDate)); } return Scaffold( diff --git a/firka/lib/ui/phone/widgets/lesson.dart b/firka/lib/ui/phone/widgets/lesson.dart index 92446dc..bf86944 100644 --- a/firka/lib/ui/phone/widgets/lesson.dart +++ b/firka/lib/ui/phone/widgets/lesson.dart @@ -13,13 +13,14 @@ import '../../widget/firka_icon.dart'; class LessonWidget extends StatelessWidget { final AppInitialization data; + final List week; final int? lessonNo; final Lesson lesson; final Test? test; final Lesson? nextLesson; - const LessonWidget( - this.data, this.lessonNo, this.lesson, this.test, this.nextLesson, + const LessonWidget(this.data, this.week, this.lessonNo, this.lesson, + this.test, this.nextLesson, {super.key}); @override @@ -147,24 +148,112 @@ class LessonWidget extends StatelessWidget { if (nextLesson != null) { elements.add(SizedBox(height: 4)); var breakMins = nextLesson!.start.difference(lesson.end).inMinutes; + var seqSchedule = week.getAllSeqs(lesson); if (data.settings .group("settings") .subGroup("timetable_toast") .boolean("breaks")) { - elements.add(FirkaCard( - left: [ - Text(data.l10n.breakTxt, - style: appStyle.fonts.B_14SB - .apply(color: appStyle.colors.textSecondary)) - ], - right: [ - Text( - "$breakMins ${breakMins == 1 ? data.l10n.starting_min : data.l10n.starting_min_plural}", - style: appStyle.fonts.B_14R - .apply(color: appStyle.colors.textTertiary)) - ], - )); + if (breakMins > 45) { + final breakEnd = lesson.end.add(Duration(minutes: breakMins)); + final emptyClass = seqSchedule.firstWhereOrNull((lesson2) => + lesson2.start.isAfter(lesson.end) && + lesson2.end.isBefore(breakEnd)); + + if (emptyClass != null) { + final preBreak = emptyClass.start.difference(lesson.end).inMinutes; + final postBreak = breakEnd.difference(emptyClass.end).inMinutes; + elements.add(FirkaCard( + left: [ + Text(data.l10n.breakTxt, + style: appStyle.fonts.B_14SB + .apply(color: appStyle.colors.textSecondary)) + ], + right: [ + Text( + "$preBreak ${preBreak == 1 ? data.l10n.starting_min : data.l10n.starting_min_plural}", + style: appStyle.fonts.B_14R + .apply(color: appStyle.colors.textTertiary)) + ], + )); + elements.add(FirkaCard( + left: [ + Card( + shadowColor: Colors.transparent, + color: bgColor, + child: Padding( + padding: EdgeInsets.all(4), + child: Text(emptyClass.lessonNumber.toString(), + style: appStyle.fonts.B_12R.apply(color: secondary)), + ), + ), + Card( + shadowColor: Colors.transparent, + color: bgColor, + child: Padding( + padding: EdgeInsetsGeometry.all(4), + child: FirkaIconWidget( + FirkaIconType.majesticonsLocal, 'cupFilled', + color: wearStyle.colors.accent, size: 24), + ), + ), + SizedBox(width: 8), + Text(data.l10n.empty_class, + style: appStyle.fonts.B_16SB + .apply(color: appStyle.colors.textPrimary)), + ], + right: [ + Text( + isDismissed + ? data.l10n.class_dismissed + : "${emptyClass.start.toLocal().format(data.l10n, FormatMode.hmm)} - ${emptyClass.end.toLocal().format(data.l10n, FormatMode.hmm)}", + style: appStyle.fonts.B_14R + .apply(color: appStyle.colors.textPrimary)) + ], + )); + elements.add(FirkaCard( + left: [ + Text(data.l10n.breakTxt, + style: appStyle.fonts.B_14SB + .apply(color: appStyle.colors.textSecondary)) + ], + right: [ + Text( + "$postBreak ${postBreak == 1 ? data.l10n.starting_min : data.l10n.starting_min_plural}", + style: appStyle.fonts.B_14R + .apply(color: appStyle.colors.textTertiary)) + ], + )); + } else { + elements.add(FirkaCard( + left: [ + Text(data.l10n.breakTxt, + style: appStyle.fonts.B_14SB + .apply(color: appStyle.colors.textSecondary)) + ], + right: [ + Text( + "$breakMins ${breakMins == 1 ? data.l10n.starting_min : data.l10n.starting_min_plural}", + style: appStyle.fonts.B_14R + .apply(color: appStyle.colors.textTertiary)) + ], + )); + } + } else { + elements.add(FirkaCard( + left: [ + Text(data.l10n.breakTxt, + style: appStyle.fonts.B_14SB + .apply(color: appStyle.colors.textSecondary)) + ], + right: [ + Text( + "$breakMins ${breakMins == 1 ? data.l10n.starting_min : data.l10n.starting_min_plural}", + style: appStyle.fonts.B_14R + .apply(color: appStyle.colors.textTertiary)) + ], + )); + } elements.add(SizedBox(height: 4)); } } diff --git a/firka/lib/ui/phone/widgets/tt_day.dart b/firka/lib/ui/phone/widgets/tt_day.dart index 91d4ef7..751b1c5 100644 --- a/firka/lib/ui/phone/widgets/tt_day.dart +++ b/firka/lib/ui/phone/widgets/tt_day.dart @@ -11,12 +11,13 @@ import 'lesson.dart'; class TimeTableDayWidget extends StatelessWidget { final AppInitialization data; final DateTime date; + final List week; final List lessons; final List events; final List tests; const TimeTableDayWidget( - this.data, this.date, this.lessons, this.events, this.tests, + this.data, this.date, this.week, this.lessons, this.events, this.tests, {super.key}); @override @@ -45,6 +46,7 @@ class TimeTableDayWidget extends StatelessWidget { Lesson? nextLesson = lessons.length > i + 1 ? lessons[i + 1] : null; ttBody.add(LessonWidget( data, + week, lessons.getLessonNo(lesson), lesson, tests.firstWhereOrNull(