watchSemesters method

Stream<List<Semester>> watchSemesters()

Watches available semesters for the authenticated student.

Emits cached data immediately, then triggers a background network fetch if data is empty or stale. The stream re-emits automatically when the DB is updated.

Network errors during background refresh are absorbed — the stream continues showing stale (or empty) data rather than erroring.

Implementation

Stream<List<Semester>> watchSemesters() async* {
  const ttl = Duration(days: 3);

  final query = _database.select(_database.semesters)
    ..where((s) => s.inCourseSemesterList.equals(true))
    ..orderBy([
      (s) => OrderingTerm.desc(s.year),
      (s) => OrderingTerm.desc(s.term),
    ]);

  await for (final semesters in query.watch()) {
    if (semesters.isEmpty) {
      try {
        await refreshSemesters();
      } catch (_) {
        // Absorb: yield empty below so UI exits loading state
      }
    }

    yield semesters;

    final user = await _database.select(_database.users).getSingleOrNull();
    final age = switch (user?.semestersFetchedAt) {
      final t? => DateTime.now().difference(t),
      null => ttl,
    };
    if (age >= ttl) {
      try {
        await refreshSemesters();
      } catch (_) {
        // Absorb: stale data is shown via stream
      }
    }
  }
}