Skip to content

Commit c79bd23

Browse files
mikebarkminCopilot
andcommitted
fix(lessons): load grades reactively when category changes
The grade selections in lesson mode used a FutureProvider (one-shot fetch). Switching categories created a new provider instance, but any failure or the brief AsyncLoading flash appeared as empty grades with no feedback, and there was no reactive update when a grade was saved or cleared. Replace with a StreamProvider backed by a new watchSessionSelections stream method on GradeRepository. The stream uses Drift's .watch() with readsFrom, so it emits fresh data whenever grade_entries_table or students_table change. This matches the same reactive pattern used by all other lesson providers (material, homework, absence). The manual ref.invalidate calls after saveEntry / clearSessionSelection are no longer needed and have been removed. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 22cefe4 commit c79bd23

3 files changed

Lines changed: 37 additions & 18 deletions

File tree

lib/features/grades/grade_repository.dart

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,41 @@ class GradeRepository {
170170
};
171171
}
172172

173+
Stream<Map<int, String>> watchSessionSelections({
174+
required int groupId,
175+
required String sessionLabel,
176+
required DateTime date,
177+
required String categoryId,
178+
}) {
179+
final normalizedDate = DateTime(date.year, date.month, date.day);
180+
return _database
181+
.customSelect(
182+
'''
183+
SELECT g.student_id, g.value
184+
FROM grade_entries_table g
185+
JOIN students_table s ON s.id = g.student_id
186+
WHERE s.group_id = ? AND g.session_label = ? AND g.date = ? AND g.category_id = ?
187+
''',
188+
variables: [
189+
Variable.withInt(groupId),
190+
Variable.withString(sessionLabel),
191+
Variable.withDateTime(normalizedDate),
192+
Variable.withString(categoryId),
193+
],
194+
readsFrom: {
195+
_database.gradeEntriesTable,
196+
_database.studentsTable,
197+
},
198+
)
199+
.watch()
200+
.map(
201+
(rows) => {
202+
for (final row in rows)
203+
row.read<int>('student_id'): row.read<String>('value'),
204+
},
205+
);
206+
}
207+
173208
Future<void> saveEntry({
174209
required int studentId,
175210
required DateTime date,

lib/features/lessons/lesson_mode_screen.dart

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -625,14 +625,6 @@ class _LessonModeScreenState extends ConsumerState<LessonModeScreen> {
625625
categoryId: category.id,
626626
categoryName: category.name,
627627
);
628-
ref.invalidate(
629-
lessonGradeSelectionsProvider((
630-
widget.groupId,
631-
_selectedDate,
632-
sessionLabel,
633-
category.id,
634-
)),
635-
);
636628
}
637629

638630
Future<void> _clearGrade({
@@ -648,14 +640,6 @@ class _LessonModeScreenState extends ConsumerState<LessonModeScreen> {
648640
sessionLabel: sessionLabel,
649641
categoryId: category.id,
650642
);
651-
ref.invalidate(
652-
lessonGradeSelectionsProvider((
653-
widget.groupId,
654-
_selectedDate,
655-
sessionLabel,
656-
category.id,
657-
)),
658-
);
659643
}
660644

661645
Future<void> _pickGrade({

lib/features/lessons/lesson_support.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,11 +70,11 @@ final lessonEntryDatesProvider = StreamProvider.autoDispose
7070
ref.watch(lessonRepositoryProvider).watchGroupEntryDates(groupId),
7171
);
7272

73-
final lessonGradeSelectionsProvider = FutureProvider.autoDispose
73+
final lessonGradeSelectionsProvider = StreamProvider.autoDispose
7474
.family<Map<int, String>, (int, DateTime, String, String)>(
7575
(ref, args) => ref
7676
.watch(gradeRepositoryProvider)
77-
.getSessionSelections(
77+
.watchSessionSelections(
7878
groupId: args.$1,
7979
date: normalizeLessonDate(args.$2),
8080
sessionLabel: args.$3,

0 commit comments

Comments
 (0)