@@ -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+
103108export 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