add error popups
This commit is contained in:
parent
70fb6efa41
commit
c63cada6e7
10
index.html
10
index.html
|
|
@ -183,5 +183,15 @@
|
|||
</footer>
|
||||
</section>
|
||||
</div>
|
||||
<div class="dialog hidden dialog--error" data-dialog="error:user">
|
||||
<section>
|
||||
<header>Error</header>
|
||||
<main data-text="error">
|
||||
</main>
|
||||
<footer>
|
||||
<button data-dialog-action="cancel">Close</button>
|
||||
</footer>
|
||||
</section>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ export async function buildAtlas(data) {
|
|||
}));
|
||||
|
||||
if (textures.length === 0) {
|
||||
throw new Error("Configuration processing failed - no textured blocks found");
|
||||
throw new UserError("Configuration processing failed - no textured blocks found");
|
||||
}
|
||||
|
||||
await Promise.all(textures.map(getTextureSize));
|
||||
|
|
@ -97,7 +97,7 @@ export async function buildAtlas(data) {
|
|||
let offset = 0;
|
||||
for (const t of Object.values(Object.groupBy(textures, t => t.size.toString()))) {
|
||||
if (t[0].size[0] !== t[0].size[1]) {
|
||||
throw new Error("Configuration processing failed - textures must be square");
|
||||
throw new UserError("Configuration processing failed - textures must be square");
|
||||
}
|
||||
|
||||
const dedupTextureMap = new Map();
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import { setState, STATE } from "./state.js";
|
|||
import { registerLoadCallback } from "./main.js";
|
||||
import { addEventToButton } from "./dom-utils.js";
|
||||
import { showOpenFileDialog } from "./files.js";
|
||||
import { DevError, UserError } from "./errors.js";
|
||||
|
||||
export let configuration = {};
|
||||
|
||||
|
|
@ -38,11 +39,11 @@ export async function loadConfiguration(event) {
|
|||
reader.readAsText(file);
|
||||
});
|
||||
} else {
|
||||
throw new Error("Configuration load failed - unrecognised event");
|
||||
throw new DevError("Configuration load failed - unrecognised event");
|
||||
}
|
||||
|
||||
if ((configData.designs ?? []).length > 0) {
|
||||
throw new Error("Configuration load failed - contains designs, likely not full configuration");
|
||||
throw new UserError("Configuration load failed - contains designs, not a full configuration!");
|
||||
}
|
||||
|
||||
emitEvent("config:load:end");
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ registerLoadCallback(() => {
|
|||
listenTo("dialogs:welcome", () => welcomeDialog(true));
|
||||
listenTo("fileLoad:chooseDesign", designChoiceDialog);
|
||||
listenTo("fileSave:nameDesign", designNameDialog);
|
||||
listenTo("error:user", errorDialog);
|
||||
});
|
||||
|
||||
function initializeDialog(dialogName, endEvent, { emptyValue, onDismiss } = {}) {
|
||||
|
|
@ -88,3 +89,8 @@ function designNameDialog() {
|
|||
dismiss(new FormData(e.detail.target).get("name"));
|
||||
});
|
||||
}
|
||||
|
||||
function errorDialog(e) {
|
||||
const { dialog } = initializeDialog("error:user", "error:dialog:close");
|
||||
dialog.querySelectorAll('[data-text="error"]').forEach(elem => elem.innerText = e.detail);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,15 @@
|
|||
import { emitEvent } from "./events.js";
|
||||
|
||||
export class UserError extends Error {
|
||||
constructor(message) {
|
||||
super(message);
|
||||
emitEvent("error:user", message);
|
||||
}
|
||||
}
|
||||
|
||||
export class DevError extends Error {
|
||||
constructor(message) {
|
||||
super(message);
|
||||
emitEvent("error:dev", message);
|
||||
}
|
||||
}
|
||||
|
|
@ -10,6 +10,7 @@ import {
|
|||
import { getAtlasIndexFromMetadata, getAtlasMetadata } from "./atlas.js";
|
||||
import { getSolverMetadata, resetSolver } from "./solver.js";
|
||||
import { registerLoadCallback } from "./main.js";
|
||||
import { DevError, UserError } from "./errors.js";
|
||||
|
||||
registerLoadCallback(() => {
|
||||
listenTo("file:load", () => showOpenFileDialog(({ data, filename }) => loadFile(data, filename)));
|
||||
|
|
@ -44,8 +45,8 @@ export async function loadExampleFile(filename) {
|
|||
}
|
||||
|
||||
export async function loadFile(data, name) {
|
||||
if (!data.designs) throw new Error("invalid file");
|
||||
if (data.designs.length === 0) throw new Error("no designs");
|
||||
if (!data.designs) throw new UserError("File must contain a list of designs!");
|
||||
if (data.designs.length === 0) throw new UserError("Fils must contain at least one design!");
|
||||
|
||||
let design = data.designs[0];
|
||||
if (data.designs.length > 1) {
|
||||
|
|
@ -55,7 +56,7 @@ export async function loadFile(data, name) {
|
|||
design = data.designs[res.detail];
|
||||
}
|
||||
|
||||
if (!design) throw new Error("no design");
|
||||
if (!design) throw new DevError("Must choose a design");
|
||||
|
||||
const blocks = data.configuration[design.type].blocks
|
||||
.map(block => getAtlasIndexFromMetadata(block, design.type, "blocks"));
|
||||
|
|
|
|||
|
|
@ -3,9 +3,10 @@ import "./block-picker.js";
|
|||
import { loadConfiguration } from "./configuration.js";
|
||||
import "./dialogs.js";
|
||||
import "./dom-list.js";
|
||||
import { addEventToButton, addEventToInput, debounce, getElements } from "./dom-utils.js";
|
||||
import { awaitEvent, emitEvent, listenTo } from "./events.js";
|
||||
import "./files.js"
|
||||
import { debounce, getElements } from "./dom-utils.js";
|
||||
import "./errors.js";
|
||||
import { emitEvent, listenTo } from "./events.js";
|
||||
import { loadExampleFile } from "./files.js"
|
||||
import "./js-utils.js"
|
||||
import "./menu-bar.js";
|
||||
import "./ncpf-utils.js";
|
||||
|
|
@ -16,7 +17,6 @@ import "./solver.js";
|
|||
import { getState, setState, STATE } from "./state.js";
|
||||
import "./storage.js";
|
||||
import "./tooltip.js";
|
||||
import { loadExampleFile } from "./files.js";
|
||||
|
||||
let loadCallbacks = [];
|
||||
export function registerLoadCallback(cb) {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { configuration } from "./configuration.js";
|
||||
import { objectKeepKeys } from "./js-utils.js";
|
||||
import { DevError } from "./errors.js";
|
||||
|
||||
export function checkEquivalence(a, b) {
|
||||
if (!a || !b || !a.type || !b.type || a.type !== b.type) return false;
|
||||
|
|
@ -31,7 +32,7 @@ export function checkEquivalence(a, b) {
|
|||
}
|
||||
|
||||
export function stripEntryToMinimums(entry) {
|
||||
if (!entry.type) throw new Error("must have a type");
|
||||
if (!entry.type) throw new DevError("must have a type");
|
||||
switch (entry.type) {
|
||||
case "legacy_block":
|
||||
return objectKeepKeys(entry, "type", "name", "metadata", "blockstate");
|
||||
|
|
@ -48,7 +49,7 @@ export function stripEntryToMinimums(entry) {
|
|||
elements: entry.elements.map(stripEntryToMinimums),
|
||||
};
|
||||
}
|
||||
throw new Error(`unknown entry type ${entry.type}`);
|
||||
throw new DevError(`unknown entry type ${entry.type}`);
|
||||
}
|
||||
|
||||
export function findFullEntry(type, entry, { configurationHint, all = false } = {}) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue