Skip to content

Commit fefc7df

Browse files
committed
support image widgets
1 parent bb68b59 commit fefc7df

File tree

2 files changed

+59
-53
lines changed

2 files changed

+59
-53
lines changed

src/config.ts

Lines changed: 55 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import JSZip from "jszip";
2+
13
type TextWidget = {
24
type: "title" | "heading" | "text";
35
text: string;
@@ -71,61 +73,65 @@ export class ConfigClass {
7173
this.file = config_object as { config: ConfigDefinition };
7274
this.widgets = this.file.config?.widgets || [];
7375
}
76+
}
77+
78+
export async function getWidgetsHtml(configObject: ConfigClass, zip: JSZip) {
79+
let htmlWidgets = await Promise.all(
80+
configObject.widgets.map(async (element, index) => {
81+
const type = element.type;
82+
83+
if (!(type in typeTemplateMap)) {
84+
console.error("No template found for type", type);
85+
return;
86+
}
87+
88+
// Create the thing
89+
let template = document.getElementById(typeTemplateMap[type]) as HTMLTemplateElement;
90+
let clone = template.content.cloneNode(true) as DocumentFragment;
91+
92+
const widgetText = clone.querySelector(".widget-text") as HTMLElement | null;
93+
const inputElement = clone.querySelector(".widget-input") as HTMLInputElement | null;
94+
95+
if ("text" in element && widgetText) widgetText.innerText = element.text;
96+
97+
if (type === "switch") {
98+
(clone.querySelector(".widget-switch-input") as HTMLInputElement).checked = !(
99+
element.default === "disabled"
100+
);
101+
} else if (type === "slider" || type === "number" || type === "value") {
102+
if (element.value.default) inputElement!.valueAsNumber = element.value.default;
103+
if (element.value.range) {
104+
inputElement!.min = element.value.range[0].toString();
105+
inputElement!.max = element.value.range[1].toString();
106+
}
107+
if (element.value.step) {
108+
inputElement!.step = element.value.step.toString();
109+
}
74110

75-
public get_widgets_html() {
76-
let html_widgets = this.widgets
77-
.map((element, index) => {
78-
const type = element.type;
111+
let suffix = "";
79112

80-
if (!(type in typeTemplateMap)) {
81-
console.error("No template found for type", type);
82-
return;
113+
if ("suffix" in element.value && element.value.suffix) {
114+
suffix = element.value.suffix;
115+
} else if (element.value.type === "percent") {
116+
suffix = " (%)";
83117
}
84118

85-
// Create the thing
86-
let template = document.getElementById(typeTemplateMap[type]) as HTMLTemplateElement;
87-
let clone = template.content.cloneNode(true) as DocumentFragment;
88-
89-
const widgetText = clone.querySelector(".widget-text") as HTMLElement | null;
90-
const inputElement = clone.querySelector(".widget-input") as HTMLInputElement | null;
91-
92-
if ("text" in element && widgetText) widgetText.innerText = element.text;
93-
94-
if (type === "switch") {
95-
(clone.querySelector(".widget-switch-input") as HTMLInputElement).checked = !(
96-
element.default === "disabled"
97-
);
98-
} else if (type === "slider" || type === "number" || type === "value") {
99-
if (element.value.default) inputElement!.valueAsNumber = element.value.default;
100-
if (element.value.range) {
101-
inputElement!.min = element.value.range[0].toString();
102-
inputElement!.max = element.value.range[1].toString();
103-
}
104-
if (element.value.step) {
105-
inputElement!.step = element.value.step.toString();
106-
}
107-
108-
let suffix = "";
109-
110-
if ("suffix" in element.value && element.value.suffix) {
111-
suffix = element.value.suffix;
112-
} else if (element.value.type === "percent") {
113-
suffix = " (%)";
114-
}
115-
116-
if (suffix && widgetText) widgetText.innerText += suffix;
117-
} else if (type === "image") {
118-
(clone.querySelector(".widget-image") as HTMLImageElement).src = "";
119+
if (suffix && widgetText) widgetText.innerText += suffix;
120+
} else if (type === "image") {
121+
const imageFile = await zip.file(element.file)?.async("blob");
122+
if (imageFile) {
123+
(clone.querySelector(".widget-image") as HTMLImageElement).src =
124+
URL.createObjectURL(imageFile);
119125
}
126+
}
120127

121-
// Set input ID
122-
if (inputElement) inputElement.id = "widget-input-" + index.toString();
128+
// Set input ID
129+
if (inputElement) inputElement.id = "widget-input-" + index.toString();
123130

124-
return clone;
125-
})
126-
.filter((element) => element !== undefined);
131+
return clone;
132+
})
133+
);
127134

128-
// Return array of HTML elements
129-
return html_widgets;
130-
}
135+
// Return array of HTML elements
136+
return htmlWidgets.filter((element) => element !== undefined);
131137
}

src/datapack.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import JSZip from "jszip";
2-
import { ConfigClass } from "./config";
2+
import { ConfigClass, getWidgetsHtml } from "./config";
33

44
export interface Datapack {
55
id: string;
@@ -51,7 +51,7 @@ export async function loadDatapack(file: File): Promise<Datapack | string> {
5151

5252
let configObject = new ConfigClass(config);
5353

54-
writeConfigWidgetsToDocument(configObject);
54+
writeConfigWidgetsToDocument(configObject, zip);
5555

5656
return {
5757
id: mcmeta.pack.id || file.name,
@@ -91,8 +91,8 @@ function detectModules(datapackZip: JSZip): Set<Module> {
9191
return modules;
9292
}
9393

94-
function writeConfigWidgetsToDocument(configObject: ConfigClass) {
95-
const widgets: Array<DocumentFragment> = configObject.get_widgets_html();
94+
async function writeConfigWidgetsToDocument(configObject: ConfigClass, zip: JSZip) {
95+
const widgets: Array<DocumentFragment> = await getWidgetsHtml(configObject, zip);
9696
const screen = document.getElementById("config-screen")!;
9797
widgets.forEach((element) => {
9898
screen.appendChild(element);

0 commit comments

Comments
 (0)