Restructure app loading

This commit is contained in:
Misode
2020-06-04 18:11:11 +02:00
parent 3e8f375784
commit 1748b41438
3 changed files with 95 additions and 87 deletions

View File

@@ -6,77 +6,16 @@ import {
ConditionSchema,
LootTableSchema,
AdvancementSchema,
LOCALES
LOCALES,
locale
} from 'minecraft-schemas'
import Split from 'split.js'
import { SandboxSchema } from './Sandbox'
const models: {
[key: string]: DataModel
} = {
'loot-table': new DataModel(LootTableSchema),
'predicate': new DataModel(ConditionSchema),
'advancement': new DataModel(AdvancementSchema),
'sandbox': new DataModel(SandboxSchema)
}
const modelFromPath = (p: string) => p.split('/').filter(e => e.length !== 0).pop() ?? ''
const modelSelector = (document.getElementById('model-selector') as HTMLInputElement)
const defaultModel = modelFromPath(location.pathname)
let model = models[defaultModel]
const treeViewEl = document.getElementById('tree-view')!
const sourceviewEl = document.getElementById('source-view')!
const sourceviewOut = document.getElementById('source-view-output')!
Split([treeViewEl, sourceviewEl], {
sizes: [66, 34]
})
const views: {
[key: string]: IView
} = {
'tree': new TreeView(model, treeViewEl),
'source': new SourceView(model, sourceviewEl.getElementsByTagName('textarea')[0], {indentation: 2})
}
const updateModel = (newModel: string) => {
model = models[newModel]
for (const v in views) {
views[v].setModel(model)
}
modelSelector.innerHTML = Object.keys(models)
.map(m => `<option value=${m}${m === newModel ? ' selected' : ''}>${m}</option>`)
.join('')
model.invalidate()
}
updateModel(defaultModel)
modelSelector.addEventListener('change', evt => {
const newModel = modelSelector.value
updateModel(newModel)
history.pushState({model: newModel}, newModel, `../${newModel}`)
})
window.onpopstate = (evt: PopStateEvent) => {
updateModel(modelFromPath(location.pathname))
}
const sourceControlsToggle = document.getElementById('source-controls-toggle')!
const sourceControlsMenu = document.getElementById('source-controls-menu')!
sourceControlsToggle.addEventListener('click', evt => {
sourceControlsMenu.style.visibility = 'visible'
document.body.addEventListener('click', evt => {
sourceControlsMenu.style.visibility = 'hidden'
}, { capture: true, once: true })
})
const sourceControlsCopy = document.getElementById('source-controls-copy')!
const sourceControlsDownload = document.getElementById('source-controls-download')!
const sourceControlsShare = document.getElementById('source-controls-share')!
const addChecked = (el: HTMLElement) => {
el.classList.add('check')
setTimeout(() => {
@@ -84,26 +23,88 @@ const addChecked = (el: HTMLElement) => {
}, 2000)
}
sourceControlsCopy.addEventListener('click', evt => {
(sourceviewOut as HTMLTextAreaElement).select()
document.execCommand('copy');
addChecked(sourceControlsCopy)
})
Promise.all([
fetch('../locales/schema/en.json').then(r => r.json()),
fetch('../locales/app/en.json').then(r => r.json())
]).then(responses => {
LOCALES.register('en', {...responses[0], ...responses[1]})
LOCALES.language = 'en'
sourceControlsDownload.addEventListener('click', evt => {
const fileContents = encodeURIComponent(JSON.stringify(model.data, null, 2) + "\n")
const dataString = "data:text/json;charset=utf-8," + fileContents
const downloadAnchor = document.getElementById('source-controls-download-anchor')!
downloadAnchor.setAttribute("href", dataString)
downloadAnchor.setAttribute("download", "data.json")
downloadAnchor.click()
})
const modelSelector = (document.getElementById('model-selector') as HTMLInputElement)
const treeViewEl = document.getElementById('tree-view')!
const sourceViewEl = document.getElementById('source-view')!
const sourceViewOutput = (document.getElementById('source-view-output') as HTMLTextAreaElement)
const sourceControlsToggle = document.getElementById('source-controls-toggle')!
const sourceControlsMenu = document.getElementById('source-controls-menu')!
const sourceControlsCopy = document.getElementById('source-controls-copy')!
const sourceControlsDownload = document.getElementById('source-controls-download')!
fetch('../locales/schema/en.json')
.then(r => r.json())
.then(l => {
LOCALES.register('en', l)
LOCALES.language = 'en'
let selected = modelFromPath(location.pathname)
model.invalidate()
const models: { [key: string]: DataModel } = {
'loot-table': new DataModel(LootTableSchema),
'predicate': new DataModel(ConditionSchema),
'advancement': new DataModel(AdvancementSchema),
'sandbox': new DataModel(SandboxSchema)
}
const views: { [key: string]: IView } = {
'tree': new TreeView(models[selected], treeViewEl),
'source': new SourceView(models[selected], sourceViewOutput, {indentation: 2})
}
const updateModel = (newModel: string) => {
selected = newModel
for (const v in views) {
views[v].setModel(models[selected])
}
modelSelector.innerHTML = Object.keys(models)
.map(m => `<option value=${m}${m === selected ? ' selected' : ''}>
${locale(`generator.${m}`)}</option>`)
.join('')
models[selected].invalidate()
}
updateModel(selected)
Split([treeViewEl, sourceViewEl], {
sizes: [66, 34]
})
modelSelector.addEventListener('change', evt => {
const newModel = modelSelector.value
updateModel(newModel)
history.pushState({model: newModel}, newModel, `../${newModel}`)
})
window.onpopstate = (evt: PopStateEvent) => {
updateModel(modelFromPath(location.pathname))
}
sourceControlsToggle.addEventListener('click', evt => {
sourceControlsMenu.style.visibility = 'visible'
document.body.addEventListener('click', evt => {
sourceControlsMenu.style.visibility = 'hidden'
}, { capture: true, once: true })
})
sourceControlsCopy.addEventListener('click', evt => {
sourceViewOutput.select()
document.execCommand('copy');
addChecked(sourceControlsCopy)
})
sourceControlsDownload.addEventListener('click', evt => {
const fileContents = encodeURIComponent(JSON.stringify(models[selected].data, null, 2) + "\n")
const dataString = "data:text/json;charset=utf-8," + fileContents
const downloadAnchor = document.getElementById('source-controls-download-anchor')!
downloadAnchor.setAttribute("href", dataString)
downloadAnchor.setAttribute("download", "data.json")
downloadAnchor.click()
})
document.querySelectorAll('[data-i18n]').forEach(el => {
el.textContent = locale(el.attributes.getNamedItem('data-i18n')!.value)
})
document.body.style.visibility = 'initial'
})

View File

@@ -7,7 +7,7 @@
<link rel="stylesheet" href="../styles/global.css">
<link rel="stylesheet" href="../styles/nodes.css">
</head>
<body>
<body style="visibility: hidden;">
<div class="container">
<div class="header">
<select id="model-selector" class="btn"></select>
@@ -19,18 +19,18 @@
<button class="btn" id="source-controls-toggle"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M8 9a1.5 1.5 0 100-3 1.5 1.5 0 000 3zM1.5 9a1.5 1.5 0 100-3 1.5 1.5 0 000 3zm13 0a1.5 1.5 0 100-3 1.5 1.5 0 000 3z"></path></svg></button>
<button class="btn" id="source-controls-copy">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M5.75 1a.75.75 0 00-.75.75v3c0 .414.336.75.75.75h4.5a.75.75 0 00.75-.75v-3a.75.75 0 00-.75-.75h-4.5zm.75 3V2.5h3V4h-3zm-2.874-.467a.75.75 0 00-.752-1.298A1.75 1.75 0 002 3.75v9.5c0 .966.784 1.75 1.75 1.75h8.5A1.75 1.75 0 0014 13.25v-9.5a1.75 1.75 0 00-.874-1.515.75.75 0 10-.752 1.298.25.25 0 01.126.217v9.5a.25.25 0 01-.25.25h-8.5a.25.25 0 01-.25-.25v-9.5a.25.25 0 01.126-.217z"></path></svg>
<span>Copy</span>
<span data-i18n="copy"></span>
</button>
</div>
<div class="source-controls-more" id="source-controls-menu">
<button class="btn" id="source-controls-download">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.47 10.78a.75.75 0 001.06 0l3.75-3.75a.75.75 0 00-1.06-1.06L8.75 8.44V1.75a.75.75 0 00-1.5 0v6.69L4.78 5.97a.75.75 0 00-1.06 1.06l3.75 3.75zM3.75 13a.75.75 0 000 1.5h8.5a.75.75 0 000-1.5h-8.5z"></path></svg>
<span>Download</span>
<a id="source-controls-download-anchor" style="display:none;"></a>
<span data-i18n="download"></span>
<a id="source-controls-download-anchor" style="display: none;"></a>
</button>
<button class="btn" id="source-controls-share">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg>
<span>Share</span>
<span data-i18n="share"></span>
</button>
</div>
<textarea id="source-view-output" spellcheck="false" autocorrect="off" autocapitalize="off"></textarea>

View File

@@ -1,2 +1,9 @@
{
"generator.loot-table": "Loot Table",
"generator.predicate": "Predicate",
"generator.advancement": "Advancement",
"generator.sandbox": "Sandbox",
"copy": "Copy",
"download": "Download",
"share": "Share"
}