fix: clear internal state across projects switching
This commit is contained in:
@ -1,62 +0,0 @@
|
||||
import { PATHS } from '@src/lib/paths'
|
||||
import type { IndexLoaderData } from '@src/lib/types'
|
||||
import { useRouteLoaderData } from 'react-router-dom'
|
||||
import { addPlaceHoldersForNewFileAndFolder } from '@src/components/Explorer/utils'
|
||||
import { ProjectExplorer } from '@src/components/Explorer/ProjectExplorer'
|
||||
import { useFolders } from '@src/machines/systemIO/hooks'
|
||||
import { useState, useEffect } from 'react'
|
||||
import type { Project } from '@src/lib/project'
|
||||
|
||||
export const ModelingProjectExplorer = ({
|
||||
createFilePressed,
|
||||
createFolderPressed,
|
||||
refreshExplorerPressed,
|
||||
collapsePressed
|
||||
}:{
|
||||
createFilePressed:number
|
||||
createFolderPressed: number
|
||||
refreshExplorerPressed: number
|
||||
collapsePressed: number
|
||||
}) => {
|
||||
const projects = useFolders()
|
||||
const loaderData = useRouteLoaderData(PATHS.FILE) as IndexLoaderData
|
||||
const [theProject, setTheProject] = useState<Project | null>(null)
|
||||
const { project } = loaderData
|
||||
useEffect(() => {
|
||||
// Have no idea why the project loader data doesn't have the children from the ls on disk
|
||||
// That means it is a different object or cached incorrectly?
|
||||
if (!project) {
|
||||
return
|
||||
}
|
||||
|
||||
// You need to find the real project in the storage from the loader information since the loader Project is not hydrated
|
||||
const theProject = projects.find((p) => {
|
||||
return p.name === project.name
|
||||
})
|
||||
|
||||
if (!theProject) {
|
||||
return
|
||||
}
|
||||
|
||||
// Duplicate the state to not edit the raw data
|
||||
const duplicated = JSON.parse(JSON.stringify(theProject))
|
||||
addPlaceHoldersForNewFileAndFolder(duplicated.children, theProject.path)
|
||||
setTheProject(duplicated)
|
||||
}, [projects])
|
||||
|
||||
return (
|
||||
<>
|
||||
{theProject ? (
|
||||
<ProjectExplorer
|
||||
project={theProject}
|
||||
createFilePressed={createFilePressed}
|
||||
createFolderPressed={createFolderPressed}
|
||||
refreshExplorerPressed={refreshExplorerPressed}
|
||||
collapsePressed={collapsePressed}
|
||||
></ProjectExplorer>
|
||||
) : (
|
||||
<div></div>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
@ -49,7 +49,7 @@ export const ProjectExplorer = ({
|
||||
createFilePressed,
|
||||
createFolderPressed,
|
||||
refreshExplorerPressed,
|
||||
collapsePressed
|
||||
collapsePressed,
|
||||
}: {
|
||||
project: Project
|
||||
createFilePressed: number
|
||||
@ -75,7 +75,7 @@ export const ProjectExplorer = ({
|
||||
const activeIndexRef = useRef(activeIndex)
|
||||
const selectedRowRef = useRef(selectedRow)
|
||||
const isRenamingRef = useRef(isRenaming)
|
||||
|
||||
const previousProject = useRef(project)
|
||||
|
||||
// fake row is used for new files or folders, you should not be able to have multiple fake rows for creation
|
||||
const [fakeRow, setFakeRow] = useState<{
|
||||
@ -87,13 +87,12 @@ export const ProjectExplorer = ({
|
||||
* External state handlers since the callback logic lives here.
|
||||
* If code wants to externall trigger creating a file pass in a new timestamp.
|
||||
*/
|
||||
useEffect(()=>{
|
||||
useEffect(() => {
|
||||
if (createFilePressed <= 0) {
|
||||
return
|
||||
}
|
||||
|
||||
const row =
|
||||
rowsToRenderRef.current[activeIndexRef.current] || null
|
||||
const row = rowsToRenderRef.current[activeIndexRef.current] || null
|
||||
setFakeRow({ entry: row, isFile: true })
|
||||
if (row?.key) {
|
||||
// If the file tree had the folder opened make the new one open.
|
||||
@ -101,24 +100,23 @@ export const ProjectExplorer = ({
|
||||
newOpenedRows[row?.key] = true
|
||||
setOpenedRows(newOpenedRows)
|
||||
}
|
||||
},[createFilePressed])
|
||||
}, [createFilePressed])
|
||||
|
||||
useEffect(()=>{
|
||||
useEffect(() => {
|
||||
if (createFolderPressed <= 0) {
|
||||
return
|
||||
}
|
||||
const row =
|
||||
rowsToRenderRef.current[activeIndexRef.current] || null
|
||||
setFakeRow({ entry: row, isFile: false })
|
||||
if (row?.key) {
|
||||
// If the file tree had the folder opened make the new one open.
|
||||
const newOpenedRows = { ...openedRowsRef.current }
|
||||
newOpenedRows[row?.key] = true
|
||||
setOpenedRows(newOpenedRows)
|
||||
}
|
||||
const row = rowsToRenderRef.current[activeIndexRef.current] || null
|
||||
setFakeRow({ entry: row, isFile: false })
|
||||
if (row?.key) {
|
||||
// If the file tree had the folder opened make the new one open.
|
||||
const newOpenedRows = { ...openedRowsRef.current }
|
||||
newOpenedRows[row?.key] = true
|
||||
setOpenedRows(newOpenedRows)
|
||||
}
|
||||
}, [createFolderPressed])
|
||||
|
||||
useEffect(()=>{
|
||||
useEffect(() => {
|
||||
if (refreshExplorerPressed <= 0) {
|
||||
return
|
||||
}
|
||||
@ -127,18 +125,14 @@ export const ProjectExplorer = ({
|
||||
systemIOActor.send({
|
||||
type: SystemIOMachineEvents.readFoldersFromProjectDirectory,
|
||||
})
|
||||
},[
|
||||
refreshExplorerPressed
|
||||
])
|
||||
}, [refreshExplorerPressed])
|
||||
|
||||
useEffect(()=>{
|
||||
if (collapsePressed <= 0) {
|
||||
useEffect(() => {
|
||||
if (collapsePressed <= 0) {
|
||||
return
|
||||
}
|
||||
setOpenedRows({})
|
||||
},[
|
||||
collapsePressed
|
||||
])
|
||||
setOpenedRows({})
|
||||
}, [collapsePressed])
|
||||
|
||||
const setSelectedRowWrapper = (row: FileExplorerEntry | null) => {
|
||||
setSelectedRow(row)
|
||||
@ -159,11 +153,18 @@ export const ProjectExplorer = ({
|
||||
setActiveIndex(domIndex)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
// TODO What to do when a different project comes in? Clear old state.
|
||||
// Clear openedRows
|
||||
// Clear rowsToRender
|
||||
// Clear selected information
|
||||
useEffect(() => {
|
||||
/**
|
||||
* You are loading a new project, clear the internal state!
|
||||
*/
|
||||
if (previousProject.current.name !== project.name) {
|
||||
setOpenedRows({})
|
||||
setSelectedRow(null)
|
||||
setActiveIndex(NOTHING_IS_SELECTED)
|
||||
setRowsToRender([])
|
||||
setContextMenuRow(null)
|
||||
setIsRenaming(false)
|
||||
}
|
||||
|
||||
// gotcha: sync state
|
||||
openedRowsRef.current = openedRows
|
||||
@ -404,6 +405,7 @@ export const ProjectExplorer = ({
|
||||
|
||||
setRowsToRender(requestedRowsToRender)
|
||||
rowsToRenderRef.current = requestedRowsToRender
|
||||
previousProject.current = project
|
||||
}, [project, openedRows, fakeRow, activeIndex])
|
||||
|
||||
// Handle clicks and keyboard presses within the global DOM level
|
||||
|
||||
@ -18,10 +18,18 @@ import type { useKclContext } from '@src/lang/KclProvider'
|
||||
import { kclErrorsByFilename } from '@src/lang/errors'
|
||||
import { editorManager } from '@src/lib/singletons'
|
||||
import type { settingsMachine } from '@src/machines/settingsMachine'
|
||||
import { ProjectExplorer} from '@src/components/Explorer/ProjectExplorer'
|
||||
import { ModelingProjectExplorer } from '@src/components/Explorer/ModelingProjectExplorer'
|
||||
import { ProjectExplorer } from '@src/components/Explorer/ProjectExplorer'
|
||||
import { FileExplorerHeaderActions } from '@src/components/Explorer/FileExplorerHeaderActions'
|
||||
|
||||
import { PATHS } from '@src/lib/paths'
|
||||
import type { IndexLoaderData } from '@src/lib/types'
|
||||
import { useRouteLoaderData } from 'react-router-dom'
|
||||
import { addPlaceHoldersForNewFileAndFolder } from '@src/components/Explorer/utils'
|
||||
import { ProjectExplorer } from '@src/components/Explorer/ProjectExplorer'
|
||||
import { useFolders } from '@src/machines/systemIO/hooks'
|
||||
import { useState, useEffect } from 'react'
|
||||
import type { Project } from '@src/lib/project'
|
||||
|
||||
export type SidebarType =
|
||||
| 'code'
|
||||
| 'debug'
|
||||
@ -130,9 +138,36 @@ export const sidebarPanes: SidebarPane[] = [
|
||||
icon: 'folder',
|
||||
sidebarName: 'Project Files',
|
||||
Content: (props: { id: SidebarType; onClose: () => void }) => {
|
||||
|
||||
const projects = useFolders()
|
||||
const loaderData = useRouteLoaderData(PATHS.FILE) as IndexLoaderData
|
||||
const [theProject, setTheProject] = useState<Project | null>(null)
|
||||
const { project } = loaderData
|
||||
useEffect(() => {
|
||||
// Have no idea why the project loader data doesn't have the children from the ls on disk
|
||||
// That means it is a different object or cached incorrectly?
|
||||
if (!project) {
|
||||
return
|
||||
}
|
||||
|
||||
// You need to find the real project in the storage from the loader information since the loader Project is not hydrated
|
||||
const theProject = projects.find((p) => {
|
||||
return p.name === project.name
|
||||
})
|
||||
|
||||
if (!theProject) {
|
||||
return
|
||||
}
|
||||
|
||||
// Duplicate the state to not edit the raw data
|
||||
const duplicated = JSON.parse(JSON.stringify(theProject))
|
||||
addPlaceHoldersForNewFileAndFolder(duplicated.children, theProject.path)
|
||||
setTheProject(duplicated)
|
||||
}, [projects, loaderData])
|
||||
|
||||
const [createFilePressed, setCreateFilePressed] = useState<number>(0)
|
||||
const [createFolderPressed, setCreateFolderPressed] = useState<number>(0)
|
||||
const [refreshFolderPressed, setRefresFolderPressed] = useState<number>(0)
|
||||
const [refreshExplorerPressed, setRefresFolderPressed] = useState<number>(0)
|
||||
const [collapsePressed, setCollapsedPressed] = useState<number>(0)
|
||||
|
||||
return (
|
||||
@ -140,7 +175,7 @@ export const sidebarPanes: SidebarPane[] = [
|
||||
<ModelingPaneHeader
|
||||
id={props.id}
|
||||
icon="folder"
|
||||
title={'huh'}
|
||||
title={`${theProject?.name || ''}`}
|
||||
Menu={
|
||||
<FileExplorerHeaderActions
|
||||
onCreateFile={() => {
|
||||
@ -152,19 +187,24 @@ export const sidebarPanes: SidebarPane[] = [
|
||||
onRefreshExplorer={() => {
|
||||
setRefresFolderPressed(performance.now())
|
||||
}}
|
||||
onCollapseExplorer={() => {
|
||||
onCollapseExplorer={() => {
|
||||
setCollapsedPressed(performance.now())
|
||||
}}
|
||||
></FileExplorerHeaderActions>
|
||||
}
|
||||
onClose={props.onClose}
|
||||
/>
|
||||
<ModelingProjectExplorer
|
||||
createFilePressed={createFilePressed}
|
||||
createFolderPressed={createFolderPressed}
|
||||
refreshExplorerPressed={refreshFolderPressed}
|
||||
collapsePressed={collapsePressed}
|
||||
/>
|
||||
{theProject ? (
|
||||
<ProjectExplorer
|
||||
project={theProject}
|
||||
createFilePressed={createFilePressed}
|
||||
createFolderPressed={createFolderPressed}
|
||||
refreshExplorerPressed={refreshExplorerPressed}
|
||||
collapsePressed={collapsePressed}
|
||||
></ProjectExplorer>
|
||||
) : (
|
||||
<div></div>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user