mirror of
https://github.com/misode/misode.github.io.git
synced 2026-04-23 23:27:09 +00:00
Sync search parameters for presets
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { render } from 'preact'
|
||||
import type { RouterOnChangeArgs } from 'preact-router'
|
||||
import { Router } from 'preact-router'
|
||||
import { useEffect, useState } from 'preact/hooks'
|
||||
import { getCurrentUrl, Router } from 'preact-router'
|
||||
import { useCallback, useEffect, useState } from 'preact/hooks'
|
||||
import config from '../config.json'
|
||||
import '../styles/global.css'
|
||||
import '../styles/nodes.css'
|
||||
@@ -10,8 +10,9 @@ import { Header } from './components'
|
||||
import { loadLocale, locale, Locales } from './Locales'
|
||||
import { Category, Changelog, Generator, Home, Sounds } from './pages'
|
||||
import type { VersionId } from './services'
|
||||
import { VersionIds } from './services'
|
||||
import { Store } from './Store'
|
||||
import { cleanUrl } from './Utils'
|
||||
import { cleanUrl, getSearchParams, setSeachParams } from './Utils'
|
||||
|
||||
const VERSIONS_IN_TITLE = 3
|
||||
|
||||
@@ -46,18 +47,28 @@ function Main() {
|
||||
document.documentElement.setAttribute('data-theme', theme)
|
||||
}, [theme])
|
||||
|
||||
const searchParams = getSearchParams(getCurrentUrl())
|
||||
const targetVersion = searchParams.get('version')
|
||||
const [version, setVersion] = useState<VersionId>(Store.getVersion())
|
||||
const changeVersion = (version: VersionId) => {
|
||||
const changeVersion = useCallback((version: VersionId) => {
|
||||
if (getSearchParams(getCurrentUrl()).has('version')) {
|
||||
setSeachParams({ version })
|
||||
}
|
||||
Analytics.setVersion(version)
|
||||
Store.setVersion(version)
|
||||
setVersion(version)
|
||||
}
|
||||
}, [targetVersion])
|
||||
useEffect(() => {
|
||||
if (VersionIds.includes(targetVersion as VersionId) && version !== targetVersion) {
|
||||
setVersion(targetVersion as VersionId)
|
||||
}
|
||||
}, [version, targetVersion])
|
||||
|
||||
const [title, setTitle] = useState<string>(locale(lang, 'title.home'))
|
||||
const changeTitle = (title: string, versions?: VersionId[]) => {
|
||||
versions ??= config.versions.map(v => v.id as VersionId)
|
||||
versions.splice(0, versions.length - VERSIONS_IN_TITLE)
|
||||
document.title = `${title} Minecraft ${versions.join(', ')}`
|
||||
const titleVersions = versions.slice(versions.length - VERSIONS_IN_TITLE)
|
||||
document.title = `${title} Minecraft ${titleVersions.join(', ')}`
|
||||
setTitle(title)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { DataModel } from '@mcschema/core'
|
||||
import { Path } from '@mcschema/core'
|
||||
import { getCurrentUrl, route } from 'preact-router'
|
||||
import rfdc from 'rfdc'
|
||||
import config from '../config.json'
|
||||
|
||||
@@ -53,11 +54,44 @@ export function cleanUrl(url: string) {
|
||||
return `/${url}/`.replaceAll('//', '/')
|
||||
}
|
||||
|
||||
export function getPath(url: string) {
|
||||
const searchIndex = url.indexOf('?')
|
||||
if (searchIndex >= 0) {
|
||||
url = url.slice(0, searchIndex)
|
||||
}
|
||||
return cleanUrl(url)
|
||||
}
|
||||
|
||||
export function getGenerator(url: string) {
|
||||
const trimmedUrl = url.replace(/^\//, '').replace(/\/$/, '').replace(/\?.*/, '')
|
||||
const trimmedUrl = getPath(url).replace(/^\//, '').replace(/\/$/, '')
|
||||
return config.generators.find(g => g.url === trimmedUrl)
|
||||
}
|
||||
|
||||
export function getSearchParams(url: string) {
|
||||
const searchIndex = url.indexOf('?')
|
||||
if (searchIndex >= 0) {
|
||||
url = url.slice(searchIndex + 1)
|
||||
return new Map(url.split('&').map<[string, string]>(param => {
|
||||
const index = param.indexOf('=')
|
||||
if (index === -1) return [param, 'true']
|
||||
return [decodeURIComponent(param.slice(0, index)), decodeURIComponent(param.slice(index + 1))]
|
||||
}))
|
||||
}
|
||||
return new Map<string, string>()
|
||||
}
|
||||
|
||||
export function setSeachParams(modifications: Record<string, string | undefined>) {
|
||||
const url = getCurrentUrl()
|
||||
const searchParams = getSearchParams(url)
|
||||
Object.entries(modifications).forEach(([key, value]) => {
|
||||
if (value === undefined) searchParams.delete(key)
|
||||
else searchParams.set(key, value)
|
||||
})
|
||||
const search = Array.from(searchParams).map(([key, value]) =>
|
||||
`${encodeURIComponent(key)}=${encodeURIComponent(value)}`)
|
||||
route(`${getPath(url)}${search.length === 0 ? '' : `?${search.join('&')}`}`, true)
|
||||
}
|
||||
|
||||
export function stringToColor(str: string): [number, number, number] {
|
||||
const h = Math.abs(hashString(str))
|
||||
return [h % 256, (h >> 8) % 256, (h >> 16) % 256]
|
||||
|
||||
@@ -8,7 +8,7 @@ import { useModel } from '../hooks'
|
||||
import { locale } from '../Locales'
|
||||
import type { BlockStateRegistry, VersionId } from '../services'
|
||||
import { checkVersion, fetchPreset, getBlockStates, getCollections, getModel } from '../services'
|
||||
import { getGenerator, message } from '../Utils'
|
||||
import { getGenerator, getSearchParams, message, setSeachParams } from '../Utils'
|
||||
|
||||
type GeneratorProps = {
|
||||
lang: string,
|
||||
@@ -40,6 +40,9 @@ export function Generator({ lang, changeTitle, version, changeVersion }: Generat
|
||||
setError(`The minimum version for this generator is ${gen.minVersion}`)
|
||||
}
|
||||
|
||||
const searchParams = getSearchParams(getCurrentUrl())
|
||||
const currentPreset = searchParams.get('preset')
|
||||
|
||||
const [model, setModel] = useState<DataModel | null>(null)
|
||||
const [blockStates, setBlockStates] = useState<BlockStateRegistry | null>(null)
|
||||
useEffect(() => {
|
||||
@@ -48,14 +51,19 @@ export function Generator({ lang, changeTitle, version, changeVersion }: Generat
|
||||
getBlockStates(version)
|
||||
.then(b => setBlockStates(b))
|
||||
getModel(version, gen.id)
|
||||
.then(m => {
|
||||
.then(async m => {
|
||||
Analytics.setGenerator(gen.id)
|
||||
if (currentPreset) {
|
||||
const preset = await loadPreset(currentPreset)
|
||||
m.reset(DataModel.wrapLists(preset), false)
|
||||
}
|
||||
setModel(m)
|
||||
})
|
||||
.catch(e => { console.error(e); setError(message(e)) })
|
||||
}, [version, gen.id])
|
||||
|
||||
useModel(model, () => {
|
||||
setSeachParams({ version: undefined, preset: undefined })
|
||||
setError(null)
|
||||
})
|
||||
|
||||
@@ -106,9 +114,18 @@ export function Generator({ lang, changeTitle, version, changeVersion }: Generat
|
||||
.catch(e => { console.error(e); setError(e.message) })
|
||||
}, [version, gen.id, presetFilter])
|
||||
|
||||
const loadPreset = (id: string) => {
|
||||
const selectPreset = (id: string) => {
|
||||
loadPreset(id).then(preset => {
|
||||
model?.reset(DataModel.wrapLists(preset), false)
|
||||
setSeachParams({ version, preset: id })
|
||||
})
|
||||
}
|
||||
|
||||
const loadPreset = async (id: string) => {
|
||||
Analytics.generatorEvent('load-preset', id)
|
||||
fetchPreset(version, gen.path ?? gen.id, id).then(preset => {
|
||||
console.log('load preset', version, gen.id, id)
|
||||
try {
|
||||
const preset = await fetchPreset(version, gen.path ?? gen.id, id)
|
||||
const seed = model?.get(new Path(['generator', 'seed']))
|
||||
if (preset?.generator?.seed !== undefined && seed !== undefined) {
|
||||
preset.generator.seed = seed
|
||||
@@ -116,8 +133,10 @@ export function Generator({ lang, changeTitle, version, changeVersion }: Generat
|
||||
preset.generator.biome_source.seed = seed
|
||||
}
|
||||
}
|
||||
model?.reset(DataModel.wrapLists(preset), false)
|
||||
})
|
||||
return preset
|
||||
} catch (e) {
|
||||
setError(message(e))
|
||||
}
|
||||
}
|
||||
|
||||
const [sourceShown, setSourceShown] = useState(window.innerWidth > 820)
|
||||
@@ -176,7 +195,7 @@ export function Generator({ lang, changeTitle, version, changeVersion }: Generat
|
||||
<BtnMenu icon="archive" label={loc('presets')} relative={false}>
|
||||
<BtnInput icon="search" large value={presetFilter} onChange={setPresetFilter} doSelect={1} placeholder={loc('search')} />
|
||||
<div class="result-list">
|
||||
{presetResults.map(preset => <Btn label={preset} onClick={() => loadPreset(preset)} />)}
|
||||
{presetResults.map(preset => <Btn label={preset} onClick={() => selectPreset(preset)} />)}
|
||||
</div>
|
||||
{presetResults.length === 0 && <Btn label={loc('no_presets')}/>}
|
||||
</BtnMenu>
|
||||
|
||||
@@ -213,7 +213,7 @@ export async function fetchPreset(version: VersionId, registry: string, id: stri
|
||||
}
|
||||
return await res.json()
|
||||
} catch (e) {
|
||||
console.warn(`Error occurred while fetching ${registry} preset ${id}:`, message(e))
|
||||
throw new Error(`Error occurred while fetching ${registry} preset ${id}: ${message(e)}`)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -91,8 +91,7 @@
|
||||
"id": "loot_table",
|
||||
"url": "loot-table",
|
||||
"path": "loot_tables",
|
||||
"schema": "loot_table",
|
||||
"maxVersion": "1.17"
|
||||
"schema": "loot_table"
|
||||
},
|
||||
{
|
||||
"id": "predicate",
|
||||
|
||||
Reference in New Issue
Block a user