mirror of
https://github.com/misode/misode.github.io.git
synced 2026-04-25 16:16:50 +00:00
Refactor projects to use indexeddb
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import { route } from 'preact-router'
|
||||
import { useCallback, useEffect, useErrorBoundary, useMemo, useRef, useState } from 'preact/hooks'
|
||||
import type { Method } from '../../Analytics.js'
|
||||
import { Analytics } from '../../Analytics.js'
|
||||
import type { ConfigGenerator } from '../../Config.js'
|
||||
import config from '../../Config.js'
|
||||
@@ -8,8 +9,9 @@ import { useSpyglass, watchSpyglassUri } from '../../contexts/Spyglass.jsx'
|
||||
import { AsyncCancel, useActiveTimeout, useAsync, useSearchParam } from '../../hooks/index.js'
|
||||
import type { VersionId } from '../../services/index.js'
|
||||
import { checkVersion, fetchDependencyMcdoc, fetchPreset, fetchRegistries, getSnippet, shareSnippet } from '../../services/index.js'
|
||||
import { DEPENDENCY_URI } from '../../services/Spyglass.js'
|
||||
import { Store } from '../../Store.js'
|
||||
import { cleanUrl, genPath, safeJsonParse } from '../../Utils.js'
|
||||
import { cleanUrl, genPath } from '../../Utils.js'
|
||||
import { Ad, Btn, BtnMenu, ErrorPanel, FileCreation, FileRenaming, Footer, HasPreview, Octicon, PreviewPanel, ProjectCreation, ProjectDeletion, ProjectPanel, SearchList, SourcePanel, TextInput, Tree, VersionSwitcher } from '../index.js'
|
||||
import { getRootDefault } from './McdocHelpers.js'
|
||||
|
||||
@@ -23,7 +25,7 @@ export function SchemaGenerator({ gen, allowedVersions }: Props) {
|
||||
const { locale } = useLocale()
|
||||
const { version, changeVersion, changeTargetVersion } = useVersion()
|
||||
const { service } = useSpyglass()
|
||||
const { projects, project, file, updateProject, updateFile, closeFile } = useProject()
|
||||
const { project, projectUri, setProjectUri, updateProject } = useProject()
|
||||
const [error, setError] = useState<Error | string | null>(null)
|
||||
const [errorBoundary, errorRetry] = useErrorBoundary()
|
||||
if (errorBoundary) {
|
||||
@@ -34,9 +36,21 @@ export function SchemaGenerator({ gen, allowedVersions }: Props) {
|
||||
useEffect(() => Store.visitGenerator(gen.id), [gen.id])
|
||||
|
||||
const uri = useMemo(() => {
|
||||
// TODO: return different uri when project file is open
|
||||
return service?.getUnsavedFileUri(gen)
|
||||
}, [service, version, gen])
|
||||
if (!service) {
|
||||
return undefined
|
||||
}
|
||||
if (projectUri) {
|
||||
const category = projectUri.endsWith('/pack.mcmeta')
|
||||
? 'pack_mcmeta'
|
||||
: service.dissectUri(projectUri)?.category
|
||||
if (category === gen.id) {
|
||||
return projectUri
|
||||
} else {
|
||||
setProjectUri(undefined)
|
||||
}
|
||||
}
|
||||
return service.getUnsavedFileUri(gen)
|
||||
}, [service, version, gen, projectUri])
|
||||
|
||||
const [currentPreset, setCurrentPreset] = useSearchParam('preset')
|
||||
const [sharedSnippetId, setSharedSnippetId] = useSearchParam(SHARE_KEY)
|
||||
@@ -75,20 +89,13 @@ export function SchemaGenerator({ gen, allowedVersions }: Props) {
|
||||
Analytics.openSnippet(gen.id, sharedSnippetId, version)
|
||||
ignoreChange.current = true
|
||||
text = snippet.text
|
||||
} else if (file) {
|
||||
if (project.version && project.version !== version) {
|
||||
changeVersion(project.version, false)
|
||||
return AsyncCancel
|
||||
}
|
||||
ignoreChange.current = true
|
||||
text = JSON.stringify(file.data, null, 2)
|
||||
}
|
||||
if (!service || !uri) {
|
||||
return AsyncCancel
|
||||
}
|
||||
if (gen.dependency) {
|
||||
const dependency = await fetchDependencyMcdoc(gen.dependency)
|
||||
const dependencyUri = `file:///project/mcdoc/${gen.dependency}.mcdoc`
|
||||
const dependencyUri = `${DEPENDENCY_URI}${gen.dependency}.mcdoc`
|
||||
await service.writeFile(dependencyUri, dependency)
|
||||
}
|
||||
if (text !== undefined) {
|
||||
@@ -104,24 +111,18 @@ export function SchemaGenerator({ gen, allowedVersions }: Props) {
|
||||
const docAndNode = await service.openFile(uri)
|
||||
Analytics.setGenerator(gen.id)
|
||||
return docAndNode
|
||||
}, [gen.id, version, sharedSnippetId, currentPreset, project.name, file?.id, service])
|
||||
}, [gen.id, version, sharedSnippetId, currentPreset, project.name, service, uri])
|
||||
|
||||
const { doc } = docAndNode ?? {}
|
||||
|
||||
watchSpyglassUri(uri, ({ doc }) => {
|
||||
watchSpyglassUri(uri, () => {
|
||||
if (!ignoreChange.current) {
|
||||
setCurrentPreset(undefined, true)
|
||||
setSharedSnippetId(undefined, true)
|
||||
}
|
||||
if (file) {
|
||||
const data = safeJsonParse(doc.getText())
|
||||
if (data !== undefined) {
|
||||
updateFile(gen.id, file.id, { id: file.id, data })
|
||||
}
|
||||
}
|
||||
ignoreChange.current = false
|
||||
setError(null)
|
||||
}, [updateFile])
|
||||
}, [])
|
||||
|
||||
const reset = async () => {
|
||||
if (!service || !uri) {
|
||||
@@ -304,9 +305,9 @@ export function SchemaGenerator({ gen, allowedVersions }: Props) {
|
||||
const [projectShown, setProjectShown] = useState(Store.getProjectPanelOpen() ?? window.innerWidth > 1000)
|
||||
const toggleProjectShown = useCallback(() => {
|
||||
if (projectShown) {
|
||||
Analytics.hideProject(gen.id, projects.length, project.files.length, 'menu')
|
||||
Analytics.hideProject('menu')
|
||||
} else {
|
||||
Analytics.showProject(gen.id, projects.length, project.files.length, 'menu')
|
||||
Analytics.showProject('menu')
|
||||
}
|
||||
Store.setProjectPanelOpen(!projectShown)
|
||||
setProjectShown(!projectShown)
|
||||
@@ -314,13 +315,13 @@ export function SchemaGenerator({ gen, allowedVersions }: Props) {
|
||||
|
||||
const [projectCreating, setProjectCreating] = useState(false)
|
||||
const [projectDeleting, setprojectDeleting] = useState(false)
|
||||
const [fileSaving, setFileSaving] = useState<string | undefined>(undefined)
|
||||
const [fileRenaming, setFileRenaming] = useState<{ type: string, id: string } | undefined>(undefined)
|
||||
const [fileSaving, setFileSaving] = useState<Method | undefined>(undefined)
|
||||
const [fileRenaming, setFileRenaming] = useState<string | undefined>(undefined)
|
||||
|
||||
const onNewFile = useCallback(() => {
|
||||
closeFile()
|
||||
setProjectUri(undefined)
|
||||
// TODO: create new file with default contents
|
||||
}, [closeFile])
|
||||
}, [setProjectUri])
|
||||
|
||||
return <>
|
||||
<main class={`${previewShown ? 'has-preview' : ''} ${projectShown ? 'has-project' : ''}`}>
|
||||
@@ -379,11 +380,11 @@ export function SchemaGenerator({ gen, allowedVersions }: Props) {
|
||||
</div>
|
||||
</div>
|
||||
<div class={`popup-project${projectShown ? ' shown' : ''}`}>
|
||||
<ProjectPanel onError={setError} onDeleteProject={() => setprojectDeleting(true)} onRename={setFileRenaming} onCreate={() => setProjectCreating(true)} />
|
||||
<ProjectPanel onError={setError} onRename={setFileRenaming} onDeleteProject={() => setprojectDeleting(true)} onCreateProject={() => setProjectCreating(true)} />
|
||||
</div>
|
||||
{projectCreating && <ProjectCreation onClose={() => setProjectCreating(false)} />}
|
||||
{projectDeleting && <ProjectDeletion onClose={() => setprojectDeleting(false)} />}
|
||||
{docAndNode && fileSaving && <FileCreation id={gen.id} docAndNode={docAndNode} method={fileSaving} onClose={() => setFileSaving(undefined)} />}
|
||||
{fileRenaming && <FileRenaming id={fileRenaming.type } name={fileRenaming.id} onClose={() => setFileRenaming(undefined)} />}
|
||||
{docAndNode && fileSaving && <FileCreation gen={gen} docAndNode={docAndNode} method={fileSaving} onCreate={(uri) => {setFileSaving(undefined); setProjectUri(uri)}} onClose={() => setFileSaving(undefined)} />}
|
||||
{fileRenaming && <FileRenaming uri={fileRenaming} onClose={() => setFileRenaming(undefined)} />}
|
||||
</>
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user