chore: first attempt of purging projects context provider
This commit is contained in:
@ -2,7 +2,6 @@ import { AppStateProvider } from '@src/AppState'
|
||||
import LspProvider from '@src/components/LspProvider'
|
||||
import { MachineManagerProvider } from '@src/components/MachineManagerProvider'
|
||||
import { OpenInDesktopAppHandler } from '@src/components/OpenInDesktopAppHandler'
|
||||
import { ProjectsContextProvider } from '@src/components/ProjectsContextProvider'
|
||||
import { SystemIOMachineLogicListener } from '@src/components/Providers/SystemIOProviderDesktop'
|
||||
import { RouteProvider } from '@src/components/RouteProvider'
|
||||
import { KclContextProvider } from '@src/lang/KclProvider'
|
||||
@ -17,11 +16,9 @@ function RootLayout() {
|
||||
}
|
||||
}, [])
|
||||
return (
|
||||
<div>
|
||||
<OpenInDesktopAppHandler>
|
||||
<RouteProvider>
|
||||
<LspProvider>
|
||||
<ProjectsContextProvider>
|
||||
<KclContextProvider>
|
||||
<AppStateProvider>
|
||||
<MachineManagerProvider>
|
||||
@ -30,11 +27,9 @@ function RootLayout() {
|
||||
</MachineManagerProvider>
|
||||
</AppStateProvider>
|
||||
</KclContextProvider>
|
||||
</ProjectsContextProvider>
|
||||
</LspProvider>
|
||||
</RouteProvider>
|
||||
</OpenInDesktopAppHandler>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -48,7 +48,7 @@ const createRouter = isDesktop() ? createHashRouter : createBrowserRouter
|
||||
const router = createRouter([
|
||||
{
|
||||
id: PATHS.INDEX,
|
||||
element: <RootLayout />,
|
||||
element: <RootLayout/>,
|
||||
children: [
|
||||
{
|
||||
path: PATHS.INDEX,
|
||||
|
@ -1,20 +1,24 @@
|
||||
import { PATHS } from '@src/lib/paths'
|
||||
import { systemIOActor } from '@src/machines/appMachine'
|
||||
import { useSelector } from '@xstate/react'
|
||||
import { systemIOActor, useSettings } from '@src/machines/appMachine'
|
||||
import {
|
||||
useProjectDirectoryPath,
|
||||
useRequestedFileName,
|
||||
useRequestedProjectName,
|
||||
useState as useSystemIOState,
|
||||
} from '@src/machines/systemIO/hooks'
|
||||
import { SystemIOMachineEvents } from '@src/machines/systemIO/utils'
|
||||
import { useEffect } from 'react'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
export const useRequestedProjectName = () =>
|
||||
useSelector(systemIOActor, (state) => state.context.requestedProjectName)
|
||||
export const useRequestedFileName = () =>
|
||||
useSelector(systemIOActor, (state) => state.context.requestedFileName)
|
||||
export const useProjectDirectoryPath = () =>
|
||||
useSelector(systemIOActor, (state) => state.context.projectDirectoryPath)
|
||||
import { projectsCommandBarConfig } from '@src/lib/commandBarConfigs/projectsCommandConfig'
|
||||
import useStateMachineCommands from '@src/hooks/useStateMachineCommands'
|
||||
|
||||
export function SystemIOMachineLogicListener() {
|
||||
const requestedProjectName = useRequestedProjectName()
|
||||
const requestedFileName = useRequestedFileName()
|
||||
const projectDirectoryPath = useProjectDirectoryPath()
|
||||
const navigate = useNavigate()
|
||||
const settings = useSettings()
|
||||
const state = useSystemIOState()
|
||||
|
||||
// Handle global project name navigation
|
||||
useEffect(() => {
|
||||
@ -46,5 +50,27 @@ export function SystemIOMachineLogicListener() {
|
||||
navigate(requestedPath)
|
||||
}, [requestedFileName])
|
||||
|
||||
// Reload all folders when the project directory path changes
|
||||
useEffect(() => {
|
||||
systemIOActor.send({
|
||||
type: SystemIOMachineEvents.setProjectDirectoryPath,
|
||||
data: {
|
||||
requestedProjectDirectoryPath:
|
||||
settings.app.projectDirectory.current || '',
|
||||
},
|
||||
})
|
||||
}, [settings.app.projectDirectory.current])
|
||||
|
||||
// Implement setting the default project folder name
|
||||
useEffect(() => {
|
||||
systemIOActor.send({
|
||||
type: SystemIOMachineEvents.setDefaultProjectFolderName,
|
||||
data: {
|
||||
requestedDefaultProjectFolderName:
|
||||
settings.projects.defaultProjectName.current || '',
|
||||
},
|
||||
})
|
||||
}, [settings.projects.defaultProjectName.current])
|
||||
|
||||
return null
|
||||
}
|
||||
|
@ -1,10 +1,8 @@
|
||||
import { useSelector } from '@xstate/react'
|
||||
import { createActor, setup, spawnChild } from 'xstate'
|
||||
|
||||
import { readAppSettingsFile } from '@src/lib/desktop'
|
||||
import { isDesktop } from '@src/lib/isDesktop'
|
||||
import { createSettings } from '@src/lib/settings/initialSettings'
|
||||
import { reportRejection } from '@src/lib/trap'
|
||||
import { authMachine } from '@src/machines/authMachine'
|
||||
import type { EngineStreamActor } from '@src/machines/engineStreamMachine'
|
||||
import {
|
||||
@ -15,7 +13,6 @@ import { ACTOR_IDS } from '@src/machines/machineConstants'
|
||||
import { settingsMachine } from '@src/machines/settingsMachine'
|
||||
import { systemIOMachineDesktop } from '@src/machines/systemIO/systemIOMachineDesktop'
|
||||
import { systemIOMachineWeb } from '@src/machines/systemIO/systemIOMachineWeb'
|
||||
import { SystemIOMachineEvents } from '@src/machines/systemIO/utils'
|
||||
const { AUTH, SETTINGS, SYSTEM_IO, ENGINE_STREAM } = ACTOR_IDS
|
||||
const appMachineActors = {
|
||||
[AUTH]: authMachine,
|
||||
@ -85,24 +82,6 @@ export const useSettings = () =>
|
||||
// TODO: Debugging
|
||||
export const systemIOActor = appActor.getSnapshot().children.systemIO!
|
||||
|
||||
async function initializeActors() {
|
||||
if (isDesktop()) {
|
||||
const appSettings = await readAppSettingsFile()
|
||||
const projectDirectorySettting = appSettings.settings?.project?.directory
|
||||
systemIOActor.send({
|
||||
type: SystemIOMachineEvents.setProjectDirectoryPath,
|
||||
data: {
|
||||
requestedProjectDirectoryPath: projectDirectorySettting || '',
|
||||
},
|
||||
})
|
||||
systemIOActor.send({
|
||||
type: SystemIOMachineEvents.readFoldersFromProjectDirectory,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
initializeActors().catch(reportRejection)
|
||||
|
||||
window.systemIOActor = systemIOActor
|
||||
export const engineStreamActor = appActor.system.get(
|
||||
ENGINE_STREAM
|
||||
|
11
src/machines/systemIO/hooks.ts
Normal file
11
src/machines/systemIO/hooks.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import { systemIOActor } from '@src/machines/appMachine'
|
||||
import { useSelector } from '@xstate/react'
|
||||
export const useRequestedProjectName = () =>
|
||||
useSelector(systemIOActor, (state) => state.context.requestedProjectName)
|
||||
export const useRequestedFileName = () =>
|
||||
useSelector(systemIOActor, (state) => state.context.requestedFileName)
|
||||
export const useProjectDirectoryPath = () =>
|
||||
useSelector(systemIOActor, (state) => state.context.projectDirectoryPath)
|
||||
export const useFolders = () =>
|
||||
useSelector(systemIOActor, (state) => state.context.folders)
|
||||
export const useState = () => useSelector(systemIOActor, (state) => state)
|
@ -62,5 +62,17 @@ describe('systemIOMachine - XState', () => {
|
||||
expect(context.projectDirectoryPath).toBe(kclSamplesPath)
|
||||
})
|
||||
})
|
||||
describe('when setting default project folder name', () => {
|
||||
it('should set a new default project folder name', async () => {
|
||||
const expected = 'coolcoolcoolProjectName'
|
||||
const actor = createActor(systemIOMachineDesktop).start()
|
||||
actor.send({
|
||||
type: SystemIOMachineEvents.setDefaultProjectFolderName,
|
||||
data: { requestedDefaultProjectFolderName: expected },
|
||||
})
|
||||
let context = actor.getSnapshot().context
|
||||
expect(context.defaultProjectFolderName).toBe(expected)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -58,6 +58,10 @@ export const systemIOMachine = setup({
|
||||
requestedFileName: string
|
||||
requestedCode: string
|
||||
}
|
||||
}
|
||||
| {
|
||||
type: SystemIOMachineEvents.setDefaultProjectFolderName
|
||||
data: { requestedDefaultProjectFolderName: string }
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
@ -91,6 +95,12 @@ export const systemIOMachine = setup({
|
||||
}
|
||||
},
|
||||
}),
|
||||
[SystemIOMachineActions.setDefaultProjectFolderName]: assign({
|
||||
defaultProjectFolderName: ({ event }) => {
|
||||
assertEvent(event, SystemIOMachineEvents.setDefaultProjectFolderName)
|
||||
return event.data.requestedDefaultProjectFolderName
|
||||
},
|
||||
}),
|
||||
},
|
||||
actors: {
|
||||
[SystemIOMachineActors.readFoldersFromProjectDirectory]: fromPromise(
|
||||
@ -133,7 +143,8 @@ export const systemIOMachine = setup({
|
||||
requestedProjectName: string
|
||||
requestedFileName: string
|
||||
requestedCode: string
|
||||
}
|
||||
|
||||
}
|
||||
}) => {}
|
||||
),
|
||||
},
|
||||
@ -182,6 +193,9 @@ export const systemIOMachine = setup({
|
||||
[SystemIOMachineEvents.createKCLFile]: {
|
||||
target: SystemIOMachineStates.creatingKCLFile,
|
||||
},
|
||||
[SystemIOMachineEvents.setDefaultProjectFolderName]: {
|
||||
actions: [SystemIOMachineActions.setDefaultProjectFolderName],
|
||||
},
|
||||
},
|
||||
},
|
||||
[SystemIOMachineStates.readingFolders]: {
|
||||
|
@ -32,6 +32,7 @@ export enum SystemIOMachineEvents {
|
||||
renameProject = 'rename project',
|
||||
deleteProject = 'delete project',
|
||||
createKCLFile = 'create kcl file',
|
||||
setDefaultProjectFolderName = 'set default project folder name',
|
||||
}
|
||||
|
||||
export enum SystemIOMachineActions {
|
||||
@ -39,6 +40,7 @@ export enum SystemIOMachineActions {
|
||||
setProjectDirectoryPath = 'set project directory path',
|
||||
setRequestedProjectName = 'set requested project name',
|
||||
setRequestedFileName = 'set requested file name',
|
||||
setDefaultProjectFolderName = 'set default project folder name',
|
||||
}
|
||||
|
||||
export const NO_PROJECT_DIRECTORY = ''
|
||||
|
@ -15,7 +15,6 @@ import {
|
||||
} from '@src/components/ProjectSearchBar'
|
||||
import { useCreateFileLinkQuery } from '@src/hooks/useCreateFileLinkQueryWatcher'
|
||||
import { useMenuListener } from '@src/hooks/useMenu'
|
||||
import { useProjectsContext } from '@src/hooks/useProjectsContext'
|
||||
import { isDesktop } from '@src/lib/isDesktop'
|
||||
import { PATHS } from '@src/lib/paths'
|
||||
import { markOnce } from '@src/lib/performance'
|
||||
@ -27,14 +26,22 @@ import {
|
||||
getSortIcon,
|
||||
} from '@src/lib/sorting'
|
||||
import { reportRejection } from '@src/lib/trap'
|
||||
import { authActor, useSettings } from '@src/machines/appMachine'
|
||||
import { authActor, systemIOActor, useSettings } from '@src/machines/appMachine'
|
||||
import { commandBarActor } from '@src/machines/commandBarMachine'
|
||||
import {
|
||||
useFolders,
|
||||
useState as useSystemIOState,
|
||||
} from '@src/machines/systemIO/hooks'
|
||||
import {
|
||||
SystemIOMachineEvents,
|
||||
SystemIOMachineStates,
|
||||
} from '@src/machines/systemIO/utils'
|
||||
import type { WebContentSendPayload } from '@src/menu/channels'
|
||||
|
||||
// This route only opens in the desktop context for now,
|
||||
// as defined in Router.tsx, so we can use the desktop APIs and types.
|
||||
const Home = () => {
|
||||
const { state, send } = useProjectsContext()
|
||||
const state = useSystemIOState()
|
||||
const [readWriteProjectDir, setReadWriteProjectDir] = useState<{
|
||||
value: boolean
|
||||
error: unknown
|
||||
@ -156,40 +163,13 @@ const Home = () => {
|
||||
}
|
||||
)
|
||||
const ref = useRef<HTMLDivElement>(null)
|
||||
|
||||
const projects = state?.context.projects ?? []
|
||||
const projects = useFolders()
|
||||
const [searchParams, setSearchParams] = useSearchParams()
|
||||
const { searchResults, query, setQuery } = useProjectSearch(projects)
|
||||
const sort = searchParams.get('sort_by') ?? 'modified:desc'
|
||||
|
||||
const isSortByModified = sort?.includes('modified') || !sort || sort === null
|
||||
|
||||
// Update the default project name and directory in the home machine
|
||||
// when the settings change
|
||||
useEffect(() => {
|
||||
send({
|
||||
type: 'assign',
|
||||
data: {
|
||||
defaultProjectName: settings.projects.defaultProjectName.current,
|
||||
defaultDirectory: settings.app.projectDirectory.current,
|
||||
},
|
||||
})
|
||||
|
||||
// Must be a truthy string, not '' or null or undefined
|
||||
if (settings.app.projectDirectory.current) {
|
||||
window.electron
|
||||
.canReadWriteDirectory(settings.app.projectDirectory.current)
|
||||
.then((res) => {
|
||||
setReadWriteProjectDir(res)
|
||||
})
|
||||
.catch(reportRejection)
|
||||
}
|
||||
}, [
|
||||
settings.app.projectDirectory.current,
|
||||
settings.projects.defaultProjectName.current,
|
||||
send,
|
||||
])
|
||||
|
||||
async function handleRenameProject(
|
||||
e: FormEvent<HTMLFormElement>,
|
||||
project: Project
|
||||
@ -204,17 +184,20 @@ const Home = () => {
|
||||
}
|
||||
|
||||
if (newProjectName !== project.name) {
|
||||
send({
|
||||
type: 'Rename project',
|
||||
data: { oldName: project.name, newName: newProjectName as string },
|
||||
systemIOActor.send({
|
||||
type: SystemIOMachineEvents.renameProject,
|
||||
data: {
|
||||
requestedProjectName: String(newProjectName),
|
||||
projectName: project.name,
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
async function handleDeleteProject(project: Project) {
|
||||
send({
|
||||
type: 'Delete project',
|
||||
data: { name: project.name || '' },
|
||||
systemIOActor.send({
|
||||
type: SystemIOMachineEvents.deleteProject,
|
||||
data: { requestedProjectName: project.name },
|
||||
})
|
||||
}
|
||||
/** Type narrowing function of unknown error to a string */
|
||||
@ -345,7 +328,7 @@ const Home = () => {
|
||||
data-testid="home-section"
|
||||
className="flex-1 overflow-y-auto pr-2 pb-24"
|
||||
>
|
||||
{state?.matches('Reading projects') ? (
|
||||
{state?.matches(SystemIOMachineStates.readingFolders) ? (
|
||||
<Loading>Loading your Projects...</Loading>
|
||||
) : (
|
||||
<>
|
||||
|
Reference in New Issue
Block a user