diff --git a/Public/grid.css b/Public/grid.css
index 1059917..d2bde65 100644
--- a/Public/grid.css
+++ b/Public/grid.css
@@ -38,7 +38,7 @@ body {
display: none;
}
-#show-color-button {
+.top-button {
height: 20px;
font-family: "SF Pro Display", -apple-system, BlinkMacSystemFont, Helvetica, sans-serif;
-webkit-font-smoothing: antialiased;
@@ -47,8 +47,9 @@ body {
padding: 5px 10px;
border-radius: 8px;
cursor: pointer;
+ margin-left: 10px;
}
-#show-color-button:hover {
+.top-button:hover {
background-color: rgb(255, 174, 26);
}
diff --git a/Public/grid.html b/Public/grid.html
index 7952922..16e4fbf 100644
--- a/Public/grid.html
+++ b/Public/grid.html
@@ -20,7 +20,11 @@
-
Toggle colors
+
Toggle colors
+
Save
+
+
+
Reset
diff --git a/Public/grid.js b/Public/grid.js
index 5c4c73c..bc4ceda 100644
--- a/Public/grid.js
+++ b/Public/grid.js
@@ -188,3 +188,86 @@ function toggleColors() {
elements[i].style.paddingLeft = padding;
}
}
+
+function exportCapArrangement() {
+
+ const a = document.createElement("a");
+ a.href = URL.createObjectURL(new Blob([JSON.stringify(capPositions)], {
+ type: "application/json"
+ }));
+ a.setAttribute("download", "caps.json");
+ document.body.appendChild(a);
+ a.click();
+ document.body.removeChild(a);
+ URL.revokeObjectURL(a.href)
+}
+
+function resetCaps() {
+ // Set each cap in the data
+ for (let i = 0; i < capPositions.length; i++) {
+ setCapImageAtPosition(i+1, i);
+ }
+}
+
+function isInt(value) {
+ if (isNaN(value)) {
+ return false;
+ }
+ var x = parseFloat(value);
+ return (x | 0) === x;
+}
+
+function decodeCapFile(content) {
+ var caps = JSON.parse(content);
+ if (!Array.isArray(caps)) {
+ alert("Invalid file (not a JSON array)");
+ return;
+ }
+ const capCount = capPositions.length;
+ if (caps.length > capPositions.length) {
+ alert("Invalid file (Too many entries)");
+ return;
+ }
+ for (let i = 0; i < caps.length; i++) {
+ const cap = caps[i];
+ if (!Number.isInteger(cap)) {
+ alert("Invalid file (Not all integers)");
+ return;
+ }
+ if (cap < 1 || cap > capCount) {
+ alert("Invalid file (Not all valid cap counts)");
+ return;
+ }
+ // TODO: Check if each id is used once
+ }
+ // Set each cap in the data
+ for (let i = 0; i < caps.length; i++) {
+ const cap = caps[i];
+ setCapImageAtPosition(cap, i);
+ }
+ // Reset the remaining caps which may be missing from the loaded file
+ // since they are newer
+ for (let i = caps.length; i < capCount; i++) {
+ setCapImageAtPosition(i+1, i);
+ }
+ console.log("Cap image loaded")
+}
+
+function loadCapArrangementFile(e) {
+ console.log("File loaded")
+ var file = e.target.files[0];
+ if (!file) {
+ return;
+ }
+ var reader = new FileReader();
+ reader.onload = function(e) {
+ var contents = e.target.result;
+ document.getElementById('caps-upload').value = null;
+ decodeCapFile(contents);
+ };
+ reader.readAsText(file);
+}
+
+// Register when user selects a file
+document.getElementById('caps-upload')
+ .addEventListener('change', loadCapArrangementFile, false);