mirror of
https://github.com/misode/misode.github.io.git
synced 2026-04-23 07:10:41 +00:00
Bump mcschema and make changes to locales
This commit is contained in:
14
package-lock.json
generated
14
package-lock.json
generated
@@ -5,16 +5,16 @@
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"@mcschema/core": {
|
||||
"version": "0.10.0-beta.6",
|
||||
"resolved": "https://registry.npmjs.org/@mcschema/core/-/core-0.10.0-beta.6.tgz",
|
||||
"integrity": "sha512-52QcHOBuATSL9dqI3fuNMexuJFwwF9NrtILs+IzkwAt/40e7VnR29doJW8P3JkNcZ2a9BaVtw5ExfbePj9rTFg=="
|
||||
"version": "0.11.0",
|
||||
"resolved": "https://registry.npmjs.org/@mcschema/core/-/core-0.11.0.tgz",
|
||||
"integrity": "sha512-6FZxNI2PQleT/4wDIatL7PvTZRHvbD5zWzcJLl0JgvKu7G6XXmox+TNT3L7j/auGCDSSf4wq+n+MtoXYxZ/EnQ=="
|
||||
},
|
||||
"@mcschema/java-1.16": {
|
||||
"version": "0.5.9-beta.1",
|
||||
"resolved": "https://registry.npmjs.org/@mcschema/java-1.16/-/java-1.16-0.5.9-beta.1.tgz",
|
||||
"integrity": "sha512-Yh+Z6jH/GU/WgshsHfz6aRZLXGMldhaHgWfk+eWvY3f8ftrurNW+OUddCx3kwOZ4gADy5pivVhISB1yecpWKxQ==",
|
||||
"version": "0.5.12",
|
||||
"resolved": "https://registry.npmjs.org/@mcschema/java-1.16/-/java-1.16-0.5.12.tgz",
|
||||
"integrity": "sha512-o6bnFQgilAYYMLklv3buBbVRDeK3THN2FiHHaJqHiFbs+EeNpcJ0tWm/PDRgrTUnw8TIfiNft6Ro992NwWXkkg==",
|
||||
"requires": {
|
||||
"@mcschema/core": "^0.10.0-beta.3"
|
||||
"@mcschema/core": "^0.11.0"
|
||||
}
|
||||
},
|
||||
"@mcschema/locales": {
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
"author": "Misode",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@mcschema/core": "^0.10.0-beta.6",
|
||||
"@mcschema/java-1.16": "^0.5.9-beta.1",
|
||||
"@mcschema/core": "^0.11.0",
|
||||
"@mcschema/java-1.16": "^0.5.12",
|
||||
"@mcschema/locales": "^0.1.11",
|
||||
"@types/google.analytics": "0.0.40",
|
||||
"@types/split.js": "^1.4.0",
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import {
|
||||
DataModel,
|
||||
Errors,
|
||||
locale,
|
||||
} from '@mcschema/core'
|
||||
import { AbstractView } from './AbstractView'
|
||||
import { locale } from './locales'
|
||||
|
||||
export class ErrorsView extends AbstractView {
|
||||
target: HTMLElement
|
||||
|
||||
@@ -1,12 +1,5 @@
|
||||
import Split from 'split.js'
|
||||
import {
|
||||
Base,
|
||||
DataModel,
|
||||
locale,
|
||||
LOCALES,
|
||||
ModelPath,
|
||||
Path,
|
||||
} from '@mcschema/core'
|
||||
import { Base, DataModel, ModelPath, Path } from '@mcschema/core'
|
||||
import { getCollections, getSchemas } from '@mcschema/java-1.16'
|
||||
import { VisualizerView } from './visualization/VisualizerView'
|
||||
import { RegistryFetcher } from './RegistryFetcher'
|
||||
@@ -16,6 +9,7 @@ import { ErrorsView } from './ErrorsView'
|
||||
import config from '../config.json'
|
||||
import { BiomeNoiseVisualizer } from './visualization/BiomeNoiseVisualizer'
|
||||
import { Mounter } from './Mounter'
|
||||
import { getLanguage, hasLocale, locale, registerLocale, setLanguage } from './locales'
|
||||
|
||||
const LOCAL_STORAGE_THEME = 'theme'
|
||||
const LOCAL_STORAGE_LANGUAGE = 'language'
|
||||
@@ -92,9 +86,9 @@ const treeViewNodeInjector = (path: ModelPath, mounter: Mounter) => {
|
||||
|
||||
const fetchLocale = async (id: string) => {
|
||||
const response = await fetch(publicPath + `locales/${id}.json`)
|
||||
LOCALES.register(id, await response.json())
|
||||
registerLocale(id, await response.json())
|
||||
}
|
||||
LOCALES.language = localStorage.getItem(LOCAL_STORAGE_LANGUAGE)?.toLowerCase() ?? 'en'
|
||||
setLanguage(localStorage.getItem(LOCAL_STORAGE_LANGUAGE)?.toLowerCase())
|
||||
|
||||
const homeLink = document.getElementById('home-link')!
|
||||
const homeGenerators = document.getElementById('home-generators')!
|
||||
@@ -151,8 +145,8 @@ const views = {
|
||||
const COLLECTIONS = getCollections()
|
||||
|
||||
Promise.all([
|
||||
fetchLocale(LOCALES.language),
|
||||
...(LOCALES.language === 'en' ? [] : [fetchLocale('en')]),
|
||||
fetchLocale(getLanguage()),
|
||||
...(getLanguage() === 'en' ? [] : [fetchLocale('en')]),
|
||||
RegistryFetcher(COLLECTIONS, config.registries)
|
||||
]).then(responses => {
|
||||
|
||||
@@ -182,29 +176,29 @@ Promise.all([
|
||||
}
|
||||
selectedModel.textContent = title
|
||||
document.title = title
|
||||
}
|
||||
|
||||
const updateLanguage = (id: string, store = false) => {
|
||||
LOCALES.language = id
|
||||
if (store) {
|
||||
localStorage.setItem(LOCAL_STORAGE_LANGUAGE, id)
|
||||
}
|
||||
|
||||
document.querySelectorAll('[data-i18n]').forEach(el => {
|
||||
el.textContent = locale(el.attributes.getNamedItem('data-i18n')!.value)
|
||||
})
|
||||
}
|
||||
|
||||
const updateLanguage = (id: string, store = false) => {
|
||||
setLanguage(id)
|
||||
if (store) {
|
||||
localStorage.setItem(LOCAL_STORAGE_LANGUAGE, id)
|
||||
}
|
||||
|
||||
languageSelectorMenu.innerHTML = ''
|
||||
config.languages.forEach(lang => {
|
||||
languageSelectorMenu.insertAdjacentHTML('beforeend',
|
||||
`<div class="btn${lang.code === LOCALES.language ? ' selected' : ''}">${lang.name}</div>`)
|
||||
`<div class="btn${lang.code === getLanguage() ? ' selected' : ''}">${lang.name}</div>`)
|
||||
languageSelectorMenu.lastChild?.addEventListener('click', evt => {
|
||||
updateLanguage(lang.code, true)
|
||||
languageSelectorMenu.style.visibility = 'hidden'
|
||||
})
|
||||
})
|
||||
|
||||
if (LOCALES.has(id)) {
|
||||
if (hasLocale(id)) {
|
||||
updateModel()
|
||||
} else {
|
||||
fetchLocale(id).then(r => {
|
||||
@@ -392,7 +386,7 @@ Promise.all([
|
||||
}
|
||||
}
|
||||
|
||||
updateLanguage(LOCALES.language)
|
||||
updateLanguage(getLanguage())
|
||||
}
|
||||
reload(location.pathname, false)
|
||||
document.body.style.visibility = 'initial'
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { locale, Hook, ModelPath, Path, StringHookParams, ValidationOption, EnumOption, INode, DataModel, MapNode, StringNode } from '@mcschema/core'
|
||||
import { Hook, ModelPath, Path, StringHookParams, ValidationOption, EnumOption, INode, DataModel, MapNode, StringNode } from '@mcschema/core'
|
||||
import { errorLocale, helpLocale, locale, pathLocale, segmentedLocale } from '../locales'
|
||||
import { Mounter } from '../Mounter'
|
||||
import { hexId } from '../utils'
|
||||
|
||||
@@ -39,12 +40,12 @@ export const renderHtml: Hook<[any, Mounter], [string, string, string]> = {
|
||||
const pathWithChoiceContext = config?.choiceContext ? new Path([], [config.choiceContext]) : config?.context ? new Path([], [config.context]) : path
|
||||
const inject = choices.map(c => {
|
||||
if (c.type === choice.type) {
|
||||
return `<button class="selected" disabled>${pathWithChoiceContext.push(c.type).locale()}</button>`
|
||||
return `<button class="selected" disabled>${pathLocale(pathWithChoiceContext.push(c.type))}</button>`
|
||||
}
|
||||
const buttonId = mounter.registerClick(el => {
|
||||
path.model.set(path, c.change ? c.change(value) : c.node.default())
|
||||
})
|
||||
return `<button data-id="${buttonId}">${pathWithChoiceContext.push(c.type).locale()}</button>`
|
||||
return `<button data-id="${buttonId}">${pathLocale(pathWithChoiceContext.push(c.type))}</button>`
|
||||
}).join('')
|
||||
|
||||
const [prefix, suffix, body] = choice.node.hook(this, pathWithContext, value, mounter)
|
||||
@@ -67,14 +68,14 @@ export const renderHtml: Hook<[any, Mounter], [string, string, string]> = {
|
||||
if (Array.isArray(value)) {
|
||||
body = value.map((childValue, index) => {
|
||||
const removeId = mounter.registerClick(el => path.model.set(path.push(index), undefined))
|
||||
const childPath = path.push(index).localePush('entry')
|
||||
const childPath = path.push(index).contextPush('entry')
|
||||
const category = children.category(childPath)
|
||||
const [cPrefix, cSuffix, cBody] = children.hook(this, childPath, childValue, mounter)
|
||||
return `<div class="node-entry"><div class="node ${children.type(childPath)}-node" ${category ? `data-category="${category}"` : ''} ${childPath.error()} ${childPath.help()}>
|
||||
return `<div class="node-entry"><div class="node ${children.type(childPath)}-node" ${category ? `data-category="${category}"` : ''} ${errorLocale(childPath)} ${helpLocale(childPath)}>
|
||||
<div class="node-header">
|
||||
<button class="remove" data-id="${removeId}"></button>
|
||||
${cPrefix}
|
||||
<label>${path.localePush('entry').locale([`${index}`])}</label>
|
||||
<label>${pathLocale(path.contextPush('entry'), [`${index}`])}</label>
|
||||
${cSuffix}
|
||||
</div>
|
||||
${cBody ? `<div class="node-body">${cBody}</div>` : ''}
|
||||
@@ -109,7 +110,7 @@ export const renderHtml: Hook<[any, Mounter], [string, string, string]> = {
|
||||
const childPath = path.modelPush(key)
|
||||
const category = children.category(childPath)
|
||||
const [cPrefix, cSuffix, cBody] = children.hook(this, childPath, value[key], mounter)
|
||||
return `<div class="node-entry"><div class="node ${children.type(childPath)}-node" ${category ? `data-category="${category}"` : ''} ${childPath.error()} ${childPath.help()}>
|
||||
return `<div class="node-entry"><div class="node ${children.type(childPath)}-node" ${category ? `data-category="${category}"` : ''} ${errorLocale(childPath)} ${helpLocale(childPath)}>
|
||||
<div class="node-header">
|
||||
<button class="remove" data-id="${removeId}"></button>
|
||||
${cPrefix}
|
||||
@@ -159,10 +160,10 @@ export const renderHtml: Hook<[any, Mounter], [string, string, string]> = {
|
||||
const childPath = getChildModelPath(path, k)
|
||||
const category = field.category(childPath)
|
||||
const [cPrefix, cSuffix, cBody] = field.hook(this, childPath, value[k], mounter)
|
||||
return `<div class="node ${field.type(childPath)}-node" ${category ? `data-category="${category}"` : ''} ${childPath.error()} ${childPath.help()}>
|
||||
return `<div class="node ${field.type(childPath)}-node" ${category ? `data-category="${category}"` : ''} ${errorLocale(childPath)} ${helpLocale(childPath)}>
|
||||
<div class="node-header">
|
||||
${cPrefix}
|
||||
<label>${childPath.locale()}</label>
|
||||
<label>${pathLocale(childPath)}</label>
|
||||
${cSuffix}
|
||||
</div>
|
||||
${cBody ? `<div class="node-body">${cBody}</div>` : ''}
|
||||
@@ -207,7 +208,7 @@ function rawString({ node, getValues, config }: { node: INode } & StringHookPara
|
||||
&& typeof config.params.pool === 'string'
|
||||
&& values.length > 0) {
|
||||
const contextPath = new Path(path.getArray(), [config.params.pool])
|
||||
if (contextPath.localePush(values[0]).strictLocale()) {
|
||||
if (segmentedLocale(contextPath.contextPush(values[0]).getContext())) {
|
||||
return selectRaw(node, contextPath, values, inputId)
|
||||
}
|
||||
}
|
||||
@@ -225,7 +226,7 @@ function selectRaw(node: INode, contextPath: Path, values: string[], inputId?: s
|
||||
return `<select data-id="${inputId}">
|
||||
${node.optional() ? `<option value="">${locale('unset')}</option>` : ''}
|
||||
${values.map(v =>
|
||||
`<option value="${v}">${contextPath.localePush(v).locale()}</option>`
|
||||
`<option value="${v}">${pathLocale(contextPath.contextPush(v))}</option>`
|
||||
).join('')}
|
||||
</select>`
|
||||
}
|
||||
|
||||
72
src/app/locales.ts
Normal file
72
src/app/locales.ts
Normal file
@@ -0,0 +1,72 @@
|
||||
import { ModelPath, Path } from '@mcschema/core'
|
||||
|
||||
interface Locale {
|
||||
[key: string]: string
|
||||
}
|
||||
|
||||
const Locales: {
|
||||
[key: string]: Locale
|
||||
} = {}
|
||||
|
||||
let language = 'en'
|
||||
|
||||
export function registerLocale(code: string, locale: Locale) {
|
||||
Locales[code] = locale
|
||||
}
|
||||
|
||||
export function hasLocale(code: string) {
|
||||
return Locales[code] !== undefined
|
||||
}
|
||||
|
||||
export function setLanguage(code: string | undefined) {
|
||||
language = code ?? language
|
||||
}
|
||||
|
||||
export function getLanguage() {
|
||||
return language
|
||||
}
|
||||
|
||||
export function resolveLocaleParams(value: string, params?: string[]): string | undefined {
|
||||
return value?.replace(/%\d+%/g, match => {
|
||||
const index = parseInt(match.slice(1, -1))
|
||||
return params?.[index] !== undefined ? params[index] : match
|
||||
})
|
||||
}
|
||||
|
||||
export function locale(key: string, params?: string[]): string {
|
||||
const value: string | undefined = Locales[language][key] ?? Locales.en[key]
|
||||
return resolveLocaleParams(value, params) ?? key
|
||||
}
|
||||
|
||||
export function segmentedLocale(segments: string[], params?: string[], depth = 5, minDepth = 1): string | undefined {
|
||||
return [language, 'en'].reduce((prev: string | undefined, code) => {
|
||||
if (prev !== undefined) return prev
|
||||
|
||||
const array = segments.slice(-depth);
|
||||
while (array.length >= minDepth) {
|
||||
const locale = resolveLocaleParams(Locales[code][array.join('.')], params)
|
||||
if (locale !== undefined) return locale
|
||||
array.shift()
|
||||
}
|
||||
|
||||
return undefined
|
||||
}, undefined)
|
||||
}
|
||||
|
||||
export function pathLocale(path: Path, params?: string[]): string {
|
||||
// return path.getContext().slice(-5).join('.')
|
||||
return segmentedLocale(path.getContext(), params)
|
||||
?? path.getContext()[path.getContext().length - 1] ?? ''
|
||||
}
|
||||
|
||||
export function errorLocale(p: ModelPath, exact = true): string {
|
||||
const errors = p.model.errors.get(p, exact)
|
||||
if (errors.length === 0) return ''
|
||||
return `data-error="${locale(errors[0].error, errors[0].params)}"`
|
||||
}
|
||||
|
||||
export function helpLocale(path: ModelPath): string {
|
||||
const res = segmentedLocale(path.contextPush('help').getContext(), [], 6)
|
||||
if (res === undefined) return ''
|
||||
return `data-help="${res}"`
|
||||
}
|
||||
Reference in New Issue
Block a user