11import { useState , useEffect } from "react" ;
22import App from "../App" ;
33import { LoadingScreen } from "./LoadingScreen" ;
4+ import { useProjectManagement } from "../hooks/useProjectManagement" ;
45import { useWorkspaceStoreRaw } from "../stores/WorkspaceStore" ;
56import { useGitStatusStoreRaw } from "../stores/GitStatusStore" ;
67import { usePersistedState } from "../hooks/usePersistedState" ;
78import type { WorkspaceSelection } from "./ProjectSidebar" ;
89import { AppProvider } from "../contexts/AppContext" ;
9- import { ProjectProvider , useProjectContext } from "../contexts/ProjectContext" ;
1010import { WorkspaceProvider , useWorkspaceContext } from "../contexts/WorkspaceContext" ;
1111
1212/**
@@ -20,38 +20,42 @@ import { WorkspaceProvider, useWorkspaceContext } from "../contexts/WorkspaceCon
2020 * the need for conditional guards in effects.
2121 */
2222export function AppLoader ( ) {
23- return (
24- < ProjectProvider >
25- < AppLoaderMiddle />
26- </ ProjectProvider >
27- ) ;
28- }
29-
30- function AppLoaderMiddle ( ) {
3123 // Workspace selection - restored from localStorage immediately
3224 const [ selectedWorkspace , setSelectedWorkspace ] = usePersistedState < WorkspaceSelection | null > (
3325 "selectedWorkspace" ,
3426 null
3527 ) ;
3628
37- const { refreshProjects } = useProjectContext ( ) ;
29+ // Load projects
30+ const projectManagement = useProjectManagement ( ) ;
3831
39- // Wrap with WorkspaceProvider
32+ // Render App with WorkspaceProvider wrapping it
4033 return (
4134 < WorkspaceProvider
4235 selectedWorkspace = { selectedWorkspace }
4336 onSelectedWorkspaceUpdate = { setSelectedWorkspace }
44- onProjectsUpdate = { refreshProjects }
37+ onProjectsUpdate = { projectManagement . setProjects }
4538 >
4639 < AppLoaderInner
40+ projects = { projectManagement . projects }
41+ setProjects = { projectManagement . setProjects }
42+ addProject = { projectManagement . addProject }
43+ removeProject = { projectManagement . removeProject }
4744 selectedWorkspace = { selectedWorkspace }
4845 setSelectedWorkspace = { setSelectedWorkspace }
4946 />
5047 </ WorkspaceProvider >
5148 ) ;
5249}
5350
51+ /**
52+ * Inner component that has access to WorkspaceContext
53+ */
5454function AppLoaderInner ( props : {
55+ projects : ReturnType < typeof useProjectManagement > [ "projects" ] ;
56+ setProjects : ReturnType < typeof useProjectManagement > [ "setProjects" ] ;
57+ addProject : ReturnType < typeof useProjectManagement > [ "addProject" ] ;
58+ removeProject : ReturnType < typeof useProjectManagement > [ "removeProject" ] ;
5559 selectedWorkspace : WorkspaceSelection | null ;
5660 setSelectedWorkspace : ( workspace : WorkspaceSelection | null ) => void ;
5761} ) {
@@ -73,17 +77,13 @@ function AppLoaderInner(props: {
7377 } else {
7478 setStoresSynced ( false ) ;
7579 }
76- } , [
77- workspaceContext . loading ,
78- workspaceContext . workspaceMetadata ,
79- workspaceStore ,
80- gitStatusStore ,
81- ] ) ;
80+ } , [ workspaceContext . loading , workspaceContext . workspaceMetadata , workspaceStore , gitStatusStore ] ) ;
8281
8382 // Restore workspace from URL hash (runs once when stores are synced)
8483 const [ hasRestoredFromHash , setHasRestoredFromHash ] = useState ( false ) ;
8584
8685 useEffect ( ( ) => {
86+ const { setSelectedWorkspace } = props ;
8787 // Wait until stores are synced before attempting restoration
8888 if ( ! storesSynced ) return ;
8989
@@ -99,7 +99,7 @@ function AppLoaderInner(props: {
9999
100100 if ( metadata ) {
101101 // Restore from hash (overrides localStorage)
102- props . setSelectedWorkspace ( {
102+ setSelectedWorkspace ( {
103103 workspaceId : metadata . id ,
104104 projectPath : metadata . projectPath ,
105105 projectName : metadata . projectName ,
@@ -114,11 +114,12 @@ function AppLoaderInner(props: {
114114 // Check for launch project from server (for --add-project flag)
115115 // This only applies in server mode
116116 useEffect ( ( ) => {
117+ const { selectedWorkspace, setSelectedWorkspace } = props ;
117118 // Wait until stores are synced and hash restoration is complete
118119 if ( ! storesSynced || ! hasRestoredFromHash ) return ;
119120
120121 // Skip if we already have a selected workspace (from localStorage or URL hash)
121- if ( props . selectedWorkspace ) return ;
122+ if ( selectedWorkspace ) return ;
122123
123124 // Only check once
124125 const checkLaunchProject = async ( ) => {
@@ -136,7 +137,7 @@ function AppLoaderInner(props: {
136137 if ( projectWorkspaces . length > 0 ) {
137138 // Select the first workspace in the project
138139 const metadata = projectWorkspaces [ 0 ] ;
139- props . setSelectedWorkspace ( {
140+ setSelectedWorkspace ( {
140141 workspaceId : metadata . id ,
141142 projectPath : metadata . projectPath ,
142143 projectName : metadata . projectName ,
@@ -158,8 +159,14 @@ function AppLoaderInner(props: {
158159 // Render App with all initialized data via context
159160 return (
160161 < AppProvider
162+ projects = { props . projects }
163+ setProjects = { props . setProjects }
164+ addProject = { props . addProject }
165+ removeProject = { props . removeProject }
161166 workspaceMetadata = { workspaceContext . workspaceMetadata }
162- setWorkspaceMetadata = { workspaceContext . setWorkspaceMetadata }
167+ setWorkspaceMetadata = { ( ) => {
168+ /* no-op now since WorkspaceContext handles it */
169+ } }
163170 createWorkspace = { workspaceContext . createWorkspace }
164171 removeWorkspace = { workspaceContext . removeWorkspace }
165172 renameWorkspace = { workspaceContext . renameWorkspace }
0 commit comments