Skip to content

Commit

Permalink
Fix #637 unsupported project storage undefined on first load
Browse files Browse the repository at this point in the history
  • Loading branch information
misode committed Nov 27, 2024
1 parent 5c874e3 commit dc72614
Show file tree
Hide file tree
Showing 6 changed files with 33 additions and 25 deletions.
8 changes: 1 addition & 7 deletions src/app/components/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { getCurrentUrl, Link, route } from 'preact-router'
import config from '../Config.js'
import { useLocale, useProject, useTheme, useTitle, useVersion } from '../contexts/index.js'
import { useLocale, useTheme, useTitle, useVersion } from '../contexts/index.js'
import { checkVersion } from '../services/index.js'
import { cleanUrl, getGenerator } from '../Utils.js'
import { Btn, BtnMenu, Icons, Octicon } from './index.js'
Expand All @@ -15,7 +15,6 @@ export function Header() {
const { lang, locale, changeLocale: changeLanguage } = useLocale()
const { theme, changeTheme } = useTheme()
const { version } = useVersion()
const { projects, project, changeProject } = useProject()
const { title } = useTitle()
const url = getCurrentUrl()
const gen = getGenerator(url)
Expand All @@ -31,11 +30,6 @@ export function Header() {
<Btn label={locale(`generator.${g.id}`)} active={g.id === gen.id} onClick={() => route(cleanUrl(g.url))} />
)}
</BtnMenu>}
{!gen && url.match(/\/?project\/?$/) && <BtnMenu icon="chevron_down" tooltip={locale('switch_project')}>
{projects.map(p =>
<Btn label={p.name} active={p.name === project.name} onClick={() => changeProject(p.name)} />
)}
</BtnMenu>}
</div>
<nav>
<ul>
Expand Down
3 changes: 3 additions & 0 deletions src/app/components/generator/FileCreation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ export function FileCreation({ docAndNode, gen, method }: Props) {
}

const doSave = useCallback(() => {
if (!project) {
return
}
if (!fileId.match(/^([a-z0-9_.-]+:)?[a-z0-9/_.-]+$/)) {
setError('Invalid resource location')
return
Expand Down
7 changes: 5 additions & 2 deletions src/app/components/generator/ProjectDeletion.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,16 @@ export function ProjectDeletion() {
const { project, deleteProject } = useProject()

const doSave = useCallback(() => {
if (!project) {
return
}
Analytics.deleteProject('menu')
deleteProject(project.name)
deleteProject(project!.name)
hideModal()
}, [deleteProject, hideModal])

return <Modal class="file-modal">
<p>{locale('project.delete_confirm.1', project.name)}</p>
<p>{project && locale('project.delete_confirm.1', project.name)}</p>
<p><b>{locale('project.delete_confirm.2')}</b></p>
<div class="button-group">
<Btn icon="trashcan" label={locale('project.delete')} onClick={doSave} class="danger" />
Expand Down
17 changes: 11 additions & 6 deletions src/app/components/generator/ProjectPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,22 @@ export function ProjectPanel() {
const { projects, project, projectUri, setProjectUri, changeProject } = useProject()
const { client, service } = useSpyglass()

const projectRoot = getProjectRoot(project)
const projectRoot = project ? getProjectRoot(project) : undefined

const [entries, setEntries] = useState<string[]>()
useEffect(() => {
setEntries(undefined)
if (!projectRoot) {
return
}
client.fs.readdir(projectRoot).then(entries => {
setEntries(entries.flatMap(e => {
return e.isFile() ? [e.name.slice(projectRoot.length)] : []
}))
})
}, [projectRoot])
useEffect(() => {
if (!service) {
if (!service || !projectRoot) {
return
}
service.watchTree(projectRoot, setEntries)
Expand All @@ -44,7 +47,9 @@ export function ProjectPanel() {
const download = useRef<HTMLAnchorElement>(null)

const onDownload = async () => {
if (!download.current || entries === undefined) return
if (!download.current || entries === undefined || !project) {
return
}
const zipEntries = await Promise.all(entries.map(async e => {
const data = await client.fs.readFile(projectRoot + e)
return [e, data] as [string, Uint8Array]
Expand Down Expand Up @@ -139,13 +144,13 @@ export function ProjectPanel() {

return <div class="panel-content">
<div class="project-controls">
<BtnMenu icon="chevron_down" label={project.name} tooltip={locale('switch_project')} tooltipLoc="se">
{projects.map(p => <Btn label={p.name} active={p.name === project.name} onClick={() => changeProject(p.name)} />)}
<BtnMenu icon="chevron_down" label={project ? project.name : locale('loading')} tooltip={locale('switch_project')} tooltipLoc="se">
{projects.map(p => <Btn label={p.name} active={p.name === project?.name} onClick={() => changeProject(p.name)} />)}
</BtnMenu>
<BtnMenu icon="kebab_horizontal" >
<Btn icon="file_zip" label={locale('project.download')} onClick={onDownload} />
<Btn icon="plus_circle" label={locale('project.new')} onClick={onCreateProject} />
{project.name !== DRAFT_PROJECT.name && <Btn icon="trashcan" label={locale('project.delete')} onClick={onDeleteProject} />}
{(project && project.name !== DRAFT_PROJECT.name) && <Btn icon="trashcan" label={locale('project.delete')} onClick={onDeleteProject} />}
</BtnMenu>
</div>
<div class="project-files">
Expand Down
4 changes: 2 additions & 2 deletions src/app/components/generator/SchemaGenerator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ export function SchemaGenerator({ gen, allowedVersions }: Props) {
ignoreChange.current = false
Analytics.setGenerator(gen.id)
return docAndNode
}, [gen.id, version, sharedSnippetId, currentPreset, project.name, service, uri])
}, [gen.id, version, sharedSnippetId, currentPreset, service, uri])

const { doc } = docAndNode ?? {}

Expand Down Expand Up @@ -216,7 +216,7 @@ export function SchemaGenerator({ gen, allowedVersions }: Props) {
const selectVersion = (version: VersionId) => {
setSharedSnippetId(undefined, true)
changeVersion(version)
if (project.name !== DRAFT_PROJECT.name && project.version !== version) {
if (project && project.name !== DRAFT_PROJECT.name && project.version !== version) {
updateProject({ version })
}
}
Expand Down
19 changes: 11 additions & 8 deletions src/app/contexts/Project.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export const DRAFT_PROJECT: ProjectMeta = {

interface ProjectContext {
projects: ProjectMeta[],
project: ProjectMeta,
project: ProjectMeta | undefined,
projectUri: string | undefined,
setProjectUri: (uri: string | undefined) => void,
createProject: (project: ProjectMeta) => void,
Expand All @@ -71,7 +71,7 @@ export function ProjectProvider({ children }: { children: ComponentChildren }) {
const [projects, setProjects] = useState<ProjectMeta[]>(Store.getProjects())
const [openProject, setOpenProject] = useState<string>(Store.getOpenProject())

const { value: project} = useAsync(async () => {
const { value: project } = useAsync(async () => {
const project = projects.find(p => p.name === openProject)
if (!project) {
if (openProject !== undefined && openProject !== DRAFT_PROJECT.name) {
Expand Down Expand Up @@ -105,9 +105,12 @@ export function ProjectProvider({ children }: { children: ComponentChildren }) {
return SpyglassClient.FS.writeFile(uri, file.data)
}))
}
changeProjects(projects.map(p => p === project ? { ...p, storage: { type: 'indexeddb', rootUri: projectRoot } } : p))
const newProject: ProjectMeta = { ...project, storage: { type: 'indexeddb', rootUri: projectRoot } }
changeProjects(projects.map(p => p === project ? newProject : p))
return newProject
} catch (e) {
console.error(`Something went wrong upgrading project ${openProject}: ${message(e)}`)
setOpenProject(DRAFT_PROJECT.name)
return DRAFT_PROJECT
}
}
Expand Down Expand Up @@ -148,7 +151,7 @@ export function ProjectProvider({ children }: { children: ComponentChildren }) {

const value: ProjectContext = {
projects,
project: project ?? DRAFT_PROJECT,
project,
projectUri,
setProjectUri,
createProject,
Expand All @@ -166,13 +169,13 @@ export function getProjectRoot(project: ProjectMeta) {
if (project.storage?.type === 'indexeddb') {
return project.storage.rootUri
}
if (project.name === DRAFT_PROJECT.name) {
return DRAFTS_URI
}
throw new Error(`Unsupported project storage ${project.storage?.type}`)
}

export async function getWorldgenProjectData(project: ProjectMeta): Promise<ProjectData> {
export async function getWorldgenProjectData(project: ProjectMeta | undefined): Promise<ProjectData> {
if (!project) {
return {}
}
const projectRoot = getProjectRoot(project)
const categories = ['worldgen/noise_settings', 'worldgen/noise', 'worldgen/density_function']
const result: ProjectData = Object.fromEntries(categories.map(c => [c, {}]))
Expand Down

0 comments on commit dc72614

Please sign in to comment.