add project save handler for reals

This commit is contained in:
Reimar 2025-10-15 09:08:35 +02:00
parent bf9a06cadf
commit e3326f0076

113
src/project_save_handler.js Normal file
View File

@ -0,0 +1,113 @@
import { promptUpload } from "./prompt_upload.js";
import { downloadFile, slugify } from "./utils.js";
import { HtmlExporter } from "./html_exporter.js";
export class ProjectSaveHandler {
constructor(editor, assetEditor, assetProvider, projectName) {
this.editor = editor;
this.assetEditor = assetEditor;
this.projectName = projectName;
this.htmlExporter = new HtmlExporter(assetProvider);
this.saveName = null;
this.isSaved = true;
editor.addEventListener("change", () => {
this.isSaved = false;
});
assetEditor.addChangeListener(() => {
this.isSaved = false;
});
}
async loadFromFile() {
if (
!this.isSaved &&
!confirm(
"Your project has not been saved. Loading a new project will override your current one. Continue?",
)
) {
return;
}
const files = await promptUpload(".karlkode", false);
if (files.length === 0) {
return;
}
if (files.length > 1) {
throw new Error(
`unreachable: something went wrong ! files.length > 1 : files.length = ${files.length}`,
);
}
const items = KarlkoderCodec.de(
await fetch(URL.createObjectURL(files[0])).then((x) => x.bytes()),
);
const assets = items
.filter((x) => x.tag === "asset")
.map((x) => {
delete x.tag;
return x;
});
const code = items.find((x) => x.tag === "code");
delete code.tag;
assetEditor.importAssets(
assets.map(({ name, mime, content }) => {
const file = new File([content], name, { type: mime });
return { name, file };
}),
);
this.projectName.value = code.name;
const dec = new TextDecoder();
this.editor.setValue(dec.decode(code.content));
}
async saveFile() {
const filename = prompt("Filename?", this.getSaveFileName());
if (!filename) {
return;
}
this.saveName = filename;
this.isSaved = true;
downloadFile(
filename,
await KarlkoderCodec.en(
this.projectName.value,
this.editor.getValue(),
await assetEditor.getAssets(),
),
".karlkode",
);
}
async exportProject() {
const filename = prompt("Filename?", this.getSaveFileName());
if (!filename) {
return;
}
this.saveName = filename;
const html = await this.htmlExporter.export(this.projectName.value, this.editor.getValue());
downloadFile(filename, html, ".html", "text/html");
}
getSaveFileName() {
if (this.saveName) {
return this.saveName;
}
return slugify(this.projectName.value) || "project";
}
}