diff --git a/package.json b/package.json index 6dd4a72f..8040cd61 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,8 @@ "@types/split.js": "^1.4.0", "copy-webpack-plugin": "^6.0.1", "html-webpack-plugin": "^4.3.0", - "minecraft-schemas": "^0.2.3", + "merge-jsons-webpack-plugin": "^1.0.21", + "minecraft-schemas": "^0.2.4", "split.js": "^1.5.11", "ts-loader": "^7.0.4", "typescript": "^3.9.3", diff --git a/src/app/app.ts b/src/app/app.ts index 40dcf229..6acae148 100644 --- a/src/app/app.ts +++ b/src/app/app.ts @@ -17,6 +17,7 @@ import { SandboxSchema } from './Sandbox' import { ErrorsView } from './ErrorsView' const LOCAL_STORAGE_THEME = 'theme' +const LOCAL_STORAGE_LANGUAGE = 'language' const publicPath = process.env.NODE_ENV === 'production' ? '/dev/' : '/'; @@ -33,7 +34,7 @@ const languages: { [key: string]: string } = { 'en': 'English', 'pt': 'Português', 'ru': 'Русский', - 'zh-CN': '简体中文' + 'zh-cn': '简体中文' } const models: { [key: string]: DataModel } = { @@ -73,12 +74,18 @@ const treeViewObserver = (el: HTMLElement) => { e.insertAdjacentHTML('afterbegin', ``) }) } + +const fetchLocale = async (id: string) => { + const response = await fetch(publicPath + `locales/${id}.json`) + LOCALES.register(id, await response.json()) +} +LOCALES.language = localStorage.getItem(LOCAL_STORAGE_LANGUAGE)?.toLowerCase() ?? 'en' + Promise.all([ - fetch(publicPath + 'locales/schema/en.json').then(r => r.json()), - fetch(publicPath + 'locales/app/en.json').then(r => r.json()), + fetchLocale(LOCALES.language), + ...(LOCALES.language === 'en' ? [] : [fetchLocale('en')]), RegistryFetcher(COLLECTIONS, registries) ]).then(responses => { - LOCALES.register('en', {...responses[0], ...responses[1]}) const homeLink = document.getElementById('home-link')! const homeGenerators = document.getElementById('home-generators')! @@ -137,9 +144,12 @@ Promise.all([ }) } - const updateLanguage = (key: string) => { - LOCALES.language = key - + 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) }) @@ -149,12 +159,18 @@ Promise.all([ languageSelectorMenu.insertAdjacentHTML('beforeend', `
${languages[key]}
`) languageSelectorMenu.lastChild?.addEventListener('click', evt => { - updateLanguage(key) + updateLanguage(key, true) languageSelectorMenu.style.visibility = 'hidden' }) }) - updateModel() + if (LOCALES.has(id)) { + updateModel() + } else { + fetchLocale(id).then(r => { + updateModel() + }) + } } Split([treeViewEl, sourceViewEl], { @@ -311,8 +327,7 @@ Promise.all([ modelSelector.style.display = '' panels.forEach(v => v.style.display = '') } - updateModel() - updateLanguage('en') + updateLanguage(LOCALES.language) } reload(location.pathname) document.body.style.visibility = 'initial' diff --git a/src/styles/nodes.css b/src/styles/nodes.css index 9f0a1e93..9526268d 100644 --- a/src/styles/nodes.css +++ b/src/styles/nodes.css @@ -99,7 +99,7 @@ background-color: var(--node-background-input); } -.object-node > .node-header > label.collapse { +.object-node > .node-header > .collapse { cursor: pointer; } @@ -127,7 +127,7 @@ border-bottom-left-radius: 0; } -.node-header > label.collapse.closed { +.node-header > .collapse.closed { border-bottom-left-radius: 3px; } @@ -136,24 +136,23 @@ button.selected { border-color: var(--node-selected-border); } -label.collapse { +.collapse { display: inline-flex; align-items: center; } -label.collapse svg { - margin-right: 5px; +.collapse svg { fill: var(--node-text); transition: fill var(--style-transition); } -label.collapse.closed, +.collapse.closed, button.add { background-color: var(--node-add); border-color: var(--node-add-border); } -label.collapse.open, +.collapse.open, button.remove { background-color: var(--node-remove); border-color: var(--node-remove-border); @@ -231,12 +230,14 @@ button.add svg { border-color: var(--category-predicate-border) !important; } +[data-category=function] > .node-header > label, [data-category=function] > .node-body > .node.node-header > *:first-child, [data-category=function] > .node-body > .node > .node-header > *:first-child { background-color: var(--category-function) !important; } [data-category=function] > .node-body, +[data-category=function] > .node-header > label, [data-category=function] > .node-body > .node.node-header > *:not(button), [data-category=function] > .node-body > .node > .node-header > *:not(button) { border-color: var(--category-function-border) !important; diff --git a/webpack.config.js b/webpack.config.js index 68abcfff..dc7fdd4c 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,5 +1,6 @@ const CopyWebpackPlugin = require('copy-webpack-plugin') const HtmlWebpackPlugin = require('html-webpack-plugin') +const MergeJsonWebpackPlugin = require("merge-jsons-webpack-plugin"); module.exports = (env, argv) => ({ entry: './src/app/app.ts', @@ -19,20 +20,23 @@ module.exports = (env, argv) => ({ plugins: [ new CopyWebpackPlugin({ patterns: [ - { - from: 'src/locales', - to: 'locales/app' - }, - { - from: 'node_modules/minecraft-schemas/src/locales', - to: 'locales/schema' - }, { from: 'src/styles', to: 'styles' } ] }), + new MergeJsonWebpackPlugin({ + debug: true, + output: { + groupBy: [ 'de', 'en', 'fr', 'it', 'ja', 'pt', 'ru', 'zh-cn' ].map(code => ( + { + pattern: `{./src/locales/${code}.json,./node_modules/minecraft-schemas/src/locales/${code}.json}`, + fileName: `./locales/${code}.json` + } + )) + } + }), new HtmlWebpackPlugin({ title: 'Minecraft Generators', filename: 'index.html',