App import/export from the editor.

git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@4786 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
2024-01-21 23:56:36 +00:00
parent ab519342e8
commit ad2b49b838
4 changed files with 97 additions and 0 deletions

View File

@ -1029,6 +1029,97 @@ function removeFile() {
}
}
async function appExport() {
let JsZip = (await import('/static/jszip.min.js')).default;
let owner = window.location.pathname.split('/')[1].replace('~', '');
let name = window.location.pathname.split('/')[2];
let zip = new JsZip();
zip.file(`${name}.json`, JSON.stringify({
type: "tildefriends-app",
emoji: gApp.emoji || '📦',
}));
for (let file of Object.keys(gFiles)) {
zip.file(`${name}/${file}`, gFiles[file].buffer ?? gFiles[file].doc.doc.toString());
}
let content = await zip.generateAsync({
type: 'blob',
compression: 'DEFLATE',
});
let a = document.createElement('a');
a.href = URL.createObjectURL(content);
a.download = `${owner}_${name}.zip`;
a.click();
}
async function save_file_to_blob_id(name, file) {
console.log(`Saving ${name}.`);
let response = await fetch('/save', {
method: 'POST',
headers: {
'Content-Type': 'application/binary',
},
body: file,
});
if (!response.ok) {
throw new Error('Saving "' + name + '": ' + response.status + ' ' + response.statusText);
}
let blob_id = await response.text();
if (blob_id.charAt(0) == '/') {
blob_id = blob_id.substr(1);
}
return blob_id;
}
async function appImport() {
let JsZip = (await import('/static/jszip.min.js')).default;
let input = document.createElement('input');
input.type = 'file';
input.click();
input.onchange = async function() {
try {
for (let file of input.files) {
if (file.type != 'application/zip') {
console.log('This does not look like a .zip.');
continue;
}
let buffer = await file.arrayBuffer();
let zip = new JsZip();
await zip.loadAsync(buffer);
let app_object;
let app_name;
for (let [name, object] of Object.entries(zip.files)) {
if (name.endsWith('.json') && name.indexOf('/') == -1) {
try {
let parsed = JSON.parse(await object.async('text'));
if (parsed.type == 'tildefriends-app') {
app_object = parsed;
app_name = name.substring(0, name.length - '.json'.length);
break;
}
} catch (e) {
console.log(e);
}
}
}
if (app_object) {
app_object.files = {};
for (let [name, object] of Object.entries(zip.files)) {
if (!name.startsWith(app_name + '/') || name.endsWith('/')) {
continue;
}
app_object.files[name.substring(app_name.length + '/'.length)] = await save_file_to_blob_id(name, await object.async('arrayBuffer'));
}
let path = '/' + await save_file_to_blob_id(`${app_name}.json`, JSON.stringify(app_object)) + '/';
console.log('Redirecting to:', path);
window.location.pathname = path;
}
}
} catch (e) {
alert(e.toString());
}
}
}
window.addEventListener("load", function() {
window.addEventListener("hashchange", hashChange);
window.addEventListener("focus", focus);
@ -1040,6 +1131,8 @@ window.addEventListener("load", function() {
document.getElementById('save').addEventListener('click', () => save());
document.getElementById('icon').addEventListener('click', () => changeIcon());
document.getElementById('delete').addEventListener('click', () => deleteApp());
document.getElementById('export').addEventListener('click', () => appExport());
document.getElementById('import').addEventListener('click', () => appImport());
document.getElementById('trace_button').addEventListener('click', function(event) {
event.preventDefault();
trace();