Fix #178 ability to restore last backup

This commit is contained in:
Misode
2022-04-08 01:30:14 +02:00
parent ee713cfe00
commit 5d22048bc8
4 changed files with 33 additions and 4 deletions

View File

@@ -12,6 +12,7 @@ export namespace Store {
export const ID_HIGHLIGHTING = 'output_highlighting'
export const ID_SOUNDS_VERSION = 'minecraft_sounds_version'
export const ID_PROJECTS = 'misode_projects'
export const ID_BACKUPS = 'misode_generator_backups'
export function getLanguage() {
return localStorage.getItem(ID_LANGUAGE) ?? 'en'
@@ -53,6 +54,11 @@ export namespace Store {
return [DRAFT_PROJECT]
}
export function getBackup(id: string): object | undefined {
const backups = JSON.parse(localStorage.getItem(ID_BACKUPS) ?? '{}')
return backups[id]
}
export function setLanguage(language: string | undefined) {
if (language) localStorage.setItem(ID_LANGUAGE, language)
}
@@ -84,4 +90,14 @@ export namespace Store {
export function setProjects(projects: Project[] | undefined) {
if (projects) localStorage.setItem(ID_PROJECTS, JSON.stringify(projects))
}
export function setBackup(id: string, data: object | undefined) {
const backups = JSON.parse(localStorage.getItem(ID_BACKUPS) ?? '{}')
if (data === undefined) {
delete backups[id]
} else {
backups[id] = data
}
localStorage.setItem(ID_BACKUPS, JSON.stringify(backups))
}
}

View File

@@ -1,7 +1,8 @@
import type { DataModel } from '@mcschema/core'
import type { Inputs } from 'preact/hooks'
import { useEffect } from 'preact/hooks'
export function useModel(model: DataModel | undefined | null, invalidated: (model: DataModel) => unknown) {
export function useModel(model: DataModel | undefined | null, invalidated: (model: DataModel) => unknown, inputs?: Inputs) {
const listener = {
invalidated() {
if (model) {
@@ -15,5 +16,5 @@ export function useModel(model: DataModel | undefined | null, invalidated: (mode
return () => {
model?.removeListener(listener)
}
}, [model])
}, [model, ...inputs ?? []])
}

View File

@@ -1,6 +1,6 @@
import { DataModel, Path } from '@mcschema/core'
import { getCurrentUrl, route } from 'preact-router'
import { useEffect, useErrorBoundary, useState } from 'preact/hooks'
import { useEffect, useErrorBoundary, useMemo, useState } from 'preact/hooks'
import config from '../../config.json'
import { Analytics } from '../Analytics'
import { Ad, Btn, BtnMenu, ErrorPanel, HasPreview, Octicon, PreviewPanel, SearchList, SourcePanel, TextInput, Tree } from '../components'
@@ -9,6 +9,7 @@ import { useActiveTimeout, useModel } from '../hooks'
import { getOutput } from '../schema/transformOutput'
import type { BlockStateRegistry, VersionId } from '../services'
import { checkVersion, fetchPreset, getBlockStates, getCollections, getModel, getSnippet, shareSnippet, SHARE_KEY } from '../services'
import { Store } from '../Store'
import { cleanUrl, deepEqual, getGenerator, getSearchParams, message, setSeachParams } from '../Utils'
interface Props {
@@ -74,6 +75,14 @@ export function Generator({}: Props) {
model.reset(DataModel.wrapLists(snippet.data), false)
}
const backup = useMemo(() => Store.getBackup(gen.id), [gen.id])
const loadBackup = () => {
if (backup !== undefined) {
model?.reset(DataModel.wrapLists(backup), false)
}
}
const [model, setModel] = useState<DataModel | null>(null)
const [blockStates, setBlockStates] = useState<BlockStateRegistry | null>(null)
useEffect(() => {
@@ -99,9 +108,10 @@ export function Generator({}: Props) {
const [dirty, setDirty] = useState(false)
useModel(model, () => {
setSeachParams({ version: undefined, preset: undefined, [SHARE_KEY]: undefined })
Store.setBackup(gen.id, DataModel.unwrapLists(model?.data))
setError(null)
setDirty(true)
})
}, [gen.id])
const [fileRename, setFileRename] = useState('')
const [fileSaved, doSave] = useActiveTimeout()
@@ -319,6 +329,7 @@ export function Generator({}: Props) {
<BtnMenu icon="repo" label={project.name} relative={false}>
<Btn icon="arrow_left" label={locale('project.go_to')} onClick={() => route('/project')} />
{file && <Btn icon="file" label={locale('project.new_file')} onClick={closeFile} />}
{backup !== undefined && <Btn icon="history" label={locale('restore_backup')} onClick={loadBackup} />}
<SearchList searchPlaceholder={locale(project.name === 'Drafts' ? 'project.search_drafts' : 'project.search')} noResults={locale('project.no_files')} values={project.files.filter(f => f.type === gen.id).map(f => f.id)} onSelect={(id) => openFile(gen.id, id)} />
</BtnMenu>
<TextInput class="btn btn-input" placeholder={locale('project.unsaved_file')} value={fileRename} onChange={setFileRename} onEnter={doFileRename} onBlur={doFileRename} />