mirror of
https://github.com/misode/misode.github.io.git
synced 2026-04-25 16:16:50 +00:00
Customized worlds (#387)
* Customized tool UI * Working version of the customized generator * Error reporting and only allow 1.20 for now
This commit is contained in:
96
src/app/pages/Customized.tsx
Normal file
96
src/app/pages/Customized.tsx
Normal file
@@ -0,0 +1,96 @@
|
||||
import { useCallback, useEffect, useErrorBoundary, useMemo, useRef, useState } from 'preact/hooks'
|
||||
import config from '../Config.js'
|
||||
import { writeZip } from '../Utils.js'
|
||||
import { BasicSettings } from '../components/customized/BasicSettings.jsx'
|
||||
import { generateCustomized } from '../components/customized/CustomizedGenerator.js'
|
||||
import { CustomizedModel } from '../components/customized/CustomizedModel.js'
|
||||
import { OresSettings } from '../components/customized/OresSettings.jsx'
|
||||
import { StructuresSettings } from '../components/customized/StructuresSettings.jsx'
|
||||
import { Btn, ErrorPanel, Footer, VersionSwitcher } from '../components/index.js'
|
||||
import { useLocale, useTitle } from '../contexts/index.js'
|
||||
import { useSearchParam } from '../hooks/index.js'
|
||||
import { stringifySource } from '../services/Source.js'
|
||||
|
||||
const Tabs = ['basic', 'structures', 'ores']
|
||||
|
||||
interface Props {
|
||||
path?: string,
|
||||
}
|
||||
export function Customized({}: Props) {
|
||||
const { locale } = useLocale()
|
||||
// const { version, changeVersion } = useVersion()
|
||||
const version = '1.20'
|
||||
const changeVersion = () => {}
|
||||
useTitle(locale('title.customized'))
|
||||
|
||||
const [errorBoundary, errorRetry] = useErrorBoundary()
|
||||
if (errorBoundary) {
|
||||
errorBoundary.message = `Something went wrong with the customized world tool: ${errorBoundary.message}`
|
||||
return <main><ErrorPanel error={errorBoundary} onDismiss={errorRetry} /></main>
|
||||
}
|
||||
|
||||
const [tab, setTab] = useSearchParam('tab')
|
||||
useEffect(() => {
|
||||
if (tab === undefined || !Tabs.includes(tab)) {
|
||||
setTab(Tabs[0], true)
|
||||
}
|
||||
}, [tab])
|
||||
|
||||
const [model, setModel] = useState(CustomizedModel.getDefault(version))
|
||||
const changeModel = useCallback((change: Partial<CustomizedModel>) => {
|
||||
setModel(m => ({ ...m, ...change }))
|
||||
}, [])
|
||||
const initialModel = useMemo(() => {
|
||||
return CustomizedModel.getDefault(version)
|
||||
}, [version])
|
||||
|
||||
const download = useRef<HTMLAnchorElement>(null)
|
||||
const [error, setError] = useState<Error | string | null>(null)
|
||||
const generate = useCallback(async () => {
|
||||
if (!download.current) return
|
||||
try {
|
||||
const pack = await generateCustomized(model, version)
|
||||
console.log('Generated customized', pack)
|
||||
const entries = Object.entries(pack).flatMap(([type, files]) => {
|
||||
const prefix = `data/minecraft/${type}/`
|
||||
return [...files.entries()].map(([name, data]) => {
|
||||
return [prefix + name + '.json', stringifySource(data, 'json')] as [string, string]
|
||||
})
|
||||
})
|
||||
const pack_format = config.versions.find(v => v.id === version)!.pack_format
|
||||
entries.push(['pack.mcmeta', stringifySource({ pack: { pack_format, description: 'Customized world from misode.github.io' } }, 'json')])
|
||||
const url = await writeZip(entries)
|
||||
download.current.setAttribute('href', url)
|
||||
download.current.setAttribute('download', 'customized.zip')
|
||||
download.current.click()
|
||||
setError(null)
|
||||
} catch (e) {
|
||||
if (e instanceof Error) {
|
||||
e.message = `Something went wrong creating the customized pack: ${e.message}`
|
||||
setError(e)
|
||||
}
|
||||
}
|
||||
}, [model, version])
|
||||
|
||||
return <main>
|
||||
<div class="container customized">
|
||||
<div class="tabs tabs-sticky">
|
||||
<span class={tab === 'basic' ? 'selected' : ''} onClick={() => setTab('basic')}>{locale('customized.basic')}</span>
|
||||
<span class={tab === 'structures' ? 'selected' : ''} onClick={() => setTab('structures')}>{locale('customized.structures')}</span>
|
||||
<span class={tab === 'ores' ? 'selected' : ''} onClick={() => setTab('ores')}>{locale('customized.ores')}</span>
|
||||
<VersionSwitcher value={version} onChange={changeVersion} allowed={['1.20']} />
|
||||
</div>
|
||||
<div class="customized-tab">
|
||||
{tab === 'basic' && <BasicSettings {...{model, initialModel, changeModel}} />}
|
||||
{tab === 'structures' && <StructuresSettings {...{model, initialModel, changeModel}} />}
|
||||
{tab === 'ores' && <OresSettings {...{model, initialModel, changeModel}} />}
|
||||
</div>
|
||||
<div class="customized-actions">
|
||||
<Btn icon="download" label="Create" class="customized-create" onClick={generate} />
|
||||
<a ref={download} style="display: none;"></a>
|
||||
</div>
|
||||
{error && <ErrorPanel error={error} onDismiss={() => setError(null)} />}
|
||||
</div>
|
||||
<Footer />
|
||||
</main>
|
||||
}
|
||||
Reference in New Issue
Block a user