You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

149 lines
5.7 KiB
JavaScript

import { openDB } from 'indexed-pdb'
import * as tic from './ticparse.js'
import * as filesize from 'filesize';
import {select, selectAll} from "d3-selection";
import * as CodeMirror from 'codemirror';
import 'codemirror/mode/lua/lua.js';
import 'codemirror/mode/javascript/javascript.js';
import 'codemirror/addon/fold/foldcode.js';
import 'codemirror/addon/fold/foldgutter.js';
//require('codemirror/addon/fold/foldcode.js');
//require('codemirror/addon/fold/foldgutter.js');
//require('codemirror/addon/fold/markdown-fold.js')
//require("codemirror/theme/monokai.css")
var current_item,
current_filename,
current_cart;
const DB_NAME = "/com.nesbox.tic/TIC-80",
DB_STORE = "FILE_DATA",
TIC_SPECIALS = ["TIC", "SCN", "OVR", "btn", "btnp", "clip", "cls", "circ", "circb", "exit", "fget", "font", "fset", "key", "keyp", "line", "map", "memcpy", "memset", "mget", "mouse", "mset", "music", "peek", "peek4", "pix", "pmem", "poke", "poke4", "print", "rect", "rectb", "reset", "sfx", "spr", "sync", "time", "tstamp", "trace", "tri", "textri"],
listing = select("#listing"),
table = listing.append("table"),
thead = table.append("thead").append("tr"),
tbody = table.append("tbody"),
CM_OPTS = {
// mode: {'name': 'lua', 'specials': TIC_SPECIALS, 'fold': true},
mode: {'name': 'javascript'},
theme: 'default',
lineNumbers: true,
lineWrapping: true,
extraKeys: {"Ctrl-S": function(cm){ save(); }},
foldGutter: true,
gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"]
},
code = CodeMirror(document.getElementById("code"), CM_OPTS);
listing.append("button").html("save").on("click", (e, d) => {
if (current_filename) { save(); }
});
listing.append("button").html("save as...").on("click", (e, d) => {
if (current_filename) {
var save_filename = prompt("key", current_filename);
if (save_filename) {
current_filename = save_filename;
save();
}
}
});
listing.append("input").attr("type", "file").on("change", function (e, d) {
console.log("filechange", this.files);
if (this.files.length == 1) {
this.files[0].arrayBuffer().then(result => {
console.log("file", result);
var file_cart = tic.parsetic(result);
console.log("file_cart", file_cart);
})
// reader.readAsArrayBuffer(this.files[0]);
}
});
thead.selectAll("th").data(["name", "size", "time", " "]).enter().append("th").html(d => d);
async function save() {
current_cart.code.text = code.getValue();
console.log("code", current_cart.code.text);
current_item.contents = current_cart.tobuffer();
current_item.timestamp = new Date();
console.log("save", current_item);
return await save_key(DB_NAME+"/"+current_filename, current_item);
}
function filename_from_key (key) {
if (key.startsWith(DB_NAME+"/")) { return key.substr((DB_NAME+"/").length); }
}
(async () => {
try {
const db = await openDB(DB_NAME);
var objectStore = db.transaction([DB_STORE], "readonly").objectStore(DB_STORE);
var files = [];
await objectStore.openCursor().then(function push_item(cursor) {
if (!cursor) { return }
var filename = filename_from_key(cursor.key);
if (filename && !filename.startsWith(".")) {
// console.log(cursor.value.contents);
var blob = new Blob([cursor.value.contents]);
// console.log("blob", blob, {type: "application/octet-stream"});
var objecturl = URL.createObjectURL(blob);
files.push({
key: cursor.key,
filename: filename,
size: cursor.value.contents.length,
timestamp: cursor.value.timestamp,
objecturl: objecturl
});
}
return cursor.continue().then(push_item)
})
// console.log("files", files);
let tr = tbody.selectAll("tr").data(files).enter().append("tr");
tr.append("td").append("a").attr("href", "#").html(d => d.filename).on("click", async (e, d) => {
e.preventDefault();
var filename = filename_from_key(d.key);
if (filename) {
current_filename = filename;
current_item = await load_key(DB_NAME+"/"+current_filename);
console.log("loaded item", current_item);
current_cart = tic.parsetic(current_item.contents);
console.log("current_cart", current_cart);
code.setValue(current_cart.code.text);
}
});
tr.append("td").html(d => filesize(d.size));
tr.append("td").html(d => d.timestamp.toLocaleString());
tr.append("td").append("a").attr("href", d=>d.objecturl).attr("download", d=>d.filename).html("download");
} catch (error) {
console.log(error, 'any error during the process');
}
})()
function compareBuffers (a, b) {
var ad = new DataView(a.buffer),
bd = new DataView(b.buffer);
if (ad.byteLength != bd.byteLength) { return false; }
for (var i=0; i<ad.byteLength; i++) {
if (ad.getUint8(i, 1) != bd.getUint8(i, 1)) { return false;}
}
return true;
}
async function load_key (key) {
const db = await openDB(DB_NAME),
objectStore = db.transaction([DB_STORE], "readonly").objectStore(DB_STORE);
return await objectStore.get(key);
}
async function save_key (key, item) {
const db = await openDB(DB_NAME),
objectStore = db.transaction([DB_STORE], "readwrite").objectStore(DB_STORE);
return await objectStore.put(item, key);
}