File size: 1,812 Bytes
65d68f5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
"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,
  );
}