DocDoeAI / src /hooks /useStudentActivity.ts
asnannp's picture
deploy: sync backend to Space root (learn-lesson HF cache fix)
65d68f5
Raw History Blame Contribute Delete
1.81 kB
"use client";
import { useSyncExternalStore } from "react";
import { STUDENT_ACTIVITY_EVENT } from "@/lib/student-activity";
// =============================================================================
// Live activity subscription. student-activity.ts already dispatches
// STUDENT_ACTIVITY_EVENT on every write (and localStorage fires `storage` in
// other tabs); this turns those signals into a React subscription so any
// surface β€” Home's "pick up where you left off", Progress, Notes, Quizzes β€”
// re-reads the moment the student does something, in this tab or another,
// without a full reload. Without it the ledger felt static: act on one page,
// come back to another, see stale numbers.
// =============================================================================
let version = 0;
const listeners = new Set<() => void>();
function bump(): void {
version += 1;
for (const listener of listeners) listener();
}
let wired = false;
function ensureWired(): void {
if (wired || typeof window === "undefined") return;
wired = true;
window.addEventListener(STUDENT_ACTIVITY_EVENT, bump);
window.addEventListener("storage", (event) => {
// Cross-tab: another tab wrote a docdoe:* key.
if (!event.key || event.key.startsWith("docdoe:")) bump();
});
}
function subscribe(onChange: () => void): () => void {
ensureWired();
listeners.add(onChange);
return () => {
listeners.delete(onChange);
};
}
/**
* Returns a version token that increments whenever saved activity, notes, or
* quizzes change. Use it as an effect dependency to re-read the ledger, e.g.
* `useEffect(() => setEvents(listActivities()), [version])`.
*/
export function useStudentActivityVersion(): number {
return useSyncExternalStore(
subscribe,
() => version,
() => 0,
);
}