Skip to content

Commit 577d179

Browse files
refactor: key workspace state by term path
Co-authored-by: Rahul Chalamala <rchalamala@users.noreply.github.com>
1 parent 4cafe78 commit 577d179

1 file changed

Lines changed: 50 additions & 28 deletions

File tree

src/hooks/useWorkspaceState.ts

Lines changed: 50 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -100,38 +100,51 @@ export interface WorkspaceStateAPI {
100100
updateAvailableTimes: (dayIdx: number, isStart: boolean, day: Date) => void;
101101
}
102102

103+
interface PersistedWorkspaceState {
104+
workspaces: Workspace[];
105+
workspaceIdx: number;
106+
}
107+
103108
export function useWorkspaceState(
104109
termPath: string,
105110
indexedCourses: CourseIndex,
106111
): WorkspaceStateAPI {
107-
const [workspaces, setWorkspaces] = useState<Workspace[]>(() =>
108-
loadPersistedWorkspaceState(termPath).workspaces,
109-
);
110-
const [workspaceIdx, setWorkspaceIdxRaw] = useState<number>(() =>
111-
loadPersistedWorkspaceState(termPath).workspaceIdx,
112+
const [workspaceStateByTerm, setWorkspaceStateByTerm] = useState<
113+
Record<string, PersistedWorkspaceState>
114+
>(() => ({
115+
[termPath]: loadPersistedWorkspaceState(termPath),
116+
}));
117+
118+
const { workspaces, workspaceIdx } =
119+
workspaceStateByTerm[termPath] ?? loadPersistedWorkspaceState(termPath);
120+
121+
const updateTermState = useCallback(
122+
(
123+
updater: (currentState: PersistedWorkspaceState) => PersistedWorkspaceState,
124+
) => {
125+
setWorkspaceStateByTerm((prev) => {
126+
const currentState = prev[termPath] ?? loadPersistedWorkspaceState(termPath);
127+
const nextState = updater(currentState);
128+
return {
129+
...prev,
130+
[termPath]: {
131+
...nextState,
132+
workspaceIdx: clampWorkspaceIdx(
133+
nextState.workspaces,
134+
nextState.workspaceIdx,
135+
),
136+
},
137+
};
138+
});
139+
},
140+
[termPath],
112141
);
113-
const [loadedTermPath, setLoadedTermPath] = useState(termPath);
114-
115-
useEffect(() => {
116-
if (loadedTermPath === termPath) {
117-
return;
118-
}
119-
120-
const persistedState = loadPersistedWorkspaceState(termPath);
121-
setWorkspaces(persistedState.workspaces);
122-
setWorkspaceIdxRaw(persistedState.workspaceIdx);
123-
setLoadedTermPath(termPath);
124-
}, [loadedTermPath, termPath]);
125142

126143
// Persist to localStorage on every change
127144
useEffect(() => {
128-
if (loadedTermPath !== termPath) {
129-
return;
130-
}
131-
132145
saveWorkspaces(termPath, workspaces);
133146
saveWorkspaceIdx(termPath, workspaceIdx);
134-
}, [loadedTermPath, termPath, workspaces, workspaceIdx]);
147+
}, [termPath, workspaces, workspaceIdx]);
135148

136149
// Derived state for the active workspace
137150
const activeWorkspace = workspaces[workspaceIdx];
@@ -147,9 +160,16 @@ export function useWorkspaceState(
147160
// Helper: update the active workspace in the workspaces array
148161
const updateActive = useCallback(
149162
(updated: Workspace) => {
150-
setWorkspaces((prev) => setArrayIdx(prev, workspaceIdx, updated));
163+
updateTermState((currentState) => ({
164+
...currentState,
165+
workspaces: setArrayIdx(
166+
currentState.workspaces,
167+
currentState.workspaceIdx,
168+
updated,
169+
),
170+
}));
151171
},
152-
[workspaceIdx],
172+
[updateTermState],
153173
);
154174

155175
/* ---- Mutations ---- */
@@ -275,11 +295,13 @@ export function useWorkspaceState(
275295

276296
const setWorkspace = useCallback(
277297
(idx: number) => {
278-
if (idx >= 0 && idx < workspaces.length) {
279-
setWorkspaceIdxRaw(idx);
280-
}
298+
updateTermState((currentState) =>
299+
idx >= 0 && idx < currentState.workspaces.length
300+
? { ...currentState, workspaceIdx: idx }
301+
: currentState,
302+
);
281303
},
282-
[workspaces.length],
304+
[updateTermState],
283305
);
284306

285307
const updateAvailableTimes = useCallback(

0 commit comments

Comments
 (0)