summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpommicket <pommicket@gmail.com>2023-09-06 11:01:59 -0400
committerpommicket <pommicket@gmail.com>2023-09-06 11:01:59 -0400
commit8d16e2d14ea9dafaea0af6c357ce1c09fefa0fde (patch)
tree0fdb04c64f1f3e4ebaf63e39921f27552b7d0efd
parent723f9037ee407b316baa104f75191d0b385445af (diff)
multiple creations
-rw-r--r--index.html38
-rw-r--r--move.svg2
-rw-r--r--pugl.js109
-rw-r--r--style.css26
4 files changed, 139 insertions, 36 deletions
diff --git a/index.html b/index.html
index 5f2eb85..4369b6e 100644
--- a/index.html
+++ b/index.html
@@ -20,12 +20,23 @@
<div id="page">
<div id="main">
<div id="ui">
- <div id="title">
- <img src="icon.png" alt="" id="title-icon"> pugl
+ <div id="top-area">
+ <img src="icon.png" alt="" id="title-icon"> <span id="title">pugl</span>
<input placeholder="Title" id="creation-title">
- <button id="about-button" class="img-button" title="about pugl">
- <img alt="about" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMiIgaGVpZ2h0PSIzMiI+CjxlbGxpcHNlIGN4PSIxNiIgY3k9IjE2IiByeD0iMTIiIHJ5PSIxMiIgc3Ryb2tlPSIjZmZmIiBzdHJva2Utd2lkdGg9IjMiIGZpbGw9Im5vbmUiIC8+Cjx0ZXh0IGZpbGw9IiNmZmYiIHg9IjE2IiB5PSIyNCIgZm9udC13ZWlnaHQ9ImJvbGQiIGZvbnQtZmFtaWx5PSJzYW5zLXNlcmlmIiBmb250LXNpemU9IjIwcHgiIHRleHQtYW5jaG9yPSJtaWRkbGUiPj88L3RleHQ+Cjwvc3ZnPgo=">
- </button>
+ <div id="creation-buttons">
+ <button id="list-creations" class="img-button" title="list creations">
+ <img alt="list creations" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMiIgaGVpZ2h0PSIzMiI+PHBhdGggZD0iTTYgNyBMMjYgNyBNNiAxNiBMMjYgMTYgTTYgMjUgTDI2IDI1IiBzdHJva2U9IiNmZmYiIHN0cm9rZS13aWR0aD0iNCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIi8+PC9zdmc+">
+ </button>
+ <button id="about-button" class="img-button" title="about pugl">
+ <img alt="about" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMiIgaGVpZ2h0PSIzMiI+PGVsbGlwc2UgY3g9IjE2IiBjeT0iMTYiIHJ4PSIxMiIgcnk9IjEyIiBzdHJva2U9IiNmOGYiIHN0cm9rZS13aWR0aD0iMyIgZmlsbD0ibm9uZSIgLz48dGV4dCBmaWxsPSIjZjhmIiB4PSIxNiIgeT0iMjQiIGZvbnQtd2VpZ2h0PSJib2xkIiBmb250LWZhbWlseT0ic2Fucy1zZXJpZiIgZm9udC1zaXplPSIyMHB4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIj4/PC90ZXh0Pjwvc3ZnPg==">
+ </button>
+ <button id="new-creation" class="img-button" title="new creation">
+ <img alt="new creation" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMiIgaGVpZ2h0PSIzMiI+PHBhdGggZD0iTTE2IDYgTDE2IDI2IE02IDE2IEwyNiAxNiIgc3Ryb2tlPSIjOGY4IiBzdHJva2Utd2lkdGg9IjQiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIvPjwvc3ZnPg==">
+ </button>
+ <button id="delete-creation" class="img-button" title="delete creation">
+ <img alt="delete creation" src="x.svg">
+ </button>
+ </div>
</div>
<form action="#" method="dialog" id="code-form" class="ui-section inline-block">
<input type="text" placeholder="Code" id="code">
@@ -101,6 +112,23 @@
<button>close</button>
</form>
</dialog>
+ <dialog id="creations-dialog">
+ <h3>saved creations</h3>
+ <hr>
+ <div id="creations"></div>
+ <br>
+ <form method="dialog">
+ <button>close</button>
+ </form>
+ </dialog>
+ <dialog id="delete-dialog">
+ <h3>delete creation "<span id="delete-creation-title"></span>"?</h3>
+ <br>
+ <form method="dialog">
+ <button>no</button>
+ <button id="delete-creation-confirm">yes</button>
+ </form>
+ </dialog>
</div>
</body>
diff --git a/move.svg b/move.svg
index 69f4ff5..bf408e0 100644
--- a/move.svg
+++ b/move.svg
@@ -1,3 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32">
-<path d="M6 6 L26 6 M6 16 L26 16 M6 26 L26 26" stroke="#88f" stroke-width="4" stroke-linecap="round"/>
+<path d="M16 4 L16 28 M16 4 l -7 6 m 7 -6 l 7 6 M16 28 l -7 -6 m 7 6 l 7 -6" stroke="#88f" stroke-width="4" stroke-linecap="round"/>
</svg>
diff --git a/pugl.js b/pugl.js
index c4acbf5..7361fdb 100644
--- a/pugl.js
+++ b/pugl.js
@@ -1,10 +1,5 @@
'use strict';
-/*
-TODO:
-- multiple creations
-*/
-
const APP_ID = 'dh3YgVZQdX1Q';
function generate_creation_id() {
@@ -2357,6 +2352,7 @@ function export_widgets_to_local_storage() {
localStorage.setItem(`${APP_ID}-${creation_id}-description`, widget_str);
creation_metadata[creation_id] = {
lastViewed: Date.now(),
+ title: get_creation_title(),
};
localStorage.setItem(`${APP_ID}-metadata`, JSON.stringify(creation_metadata));
}
@@ -2370,13 +2366,37 @@ function load_creation(id) {
const result = import_widgets(
localStorage.getItem(`${APP_ID}-${id}-description`)
);
- if (result.error) return result;
- return true;
+ if (result.error) {
+ show_error(result.error);
+ }
}
function new_creation() {
creation_id = generate_creation_id();
- return import_widgets(null);
+ const result = import_widgets(null);
+ if (result.error) {
+ show_error(result.error);
+ }
+}
+
+function load_most_recent_or_create_new() {
+ let load = undefined;
+ if (creation_metadata) {
+ // load creation with largest lastViewed time
+ for (const id in creation_metadata) {
+ if (
+ !load ||
+ creation_metadata[id].lastViewed > creation_metadata[load].lastViewed
+ ) {
+ load = id;
+ }
+ }
+ }
+ if (load) {
+ load_creation(load);
+ } else {
+ new_creation();
+ }
}
function get_shader_source() {
@@ -2501,6 +2521,58 @@ function startup() {
document.getElementById('about-dialog').showModal();
});
+ document.getElementById('list-creations').addEventListener('click', () => {
+ const container = document.getElementById('creations');
+ container.innerHTML = '';
+ const creations_dialog = document.getElementById('creations-dialog');
+ creations_dialog.showModal();
+ for (const id in creation_metadata) {
+ const metadata = creation_metadata[id];
+ const entry = document.createElement('div');
+ entry.classList.add('creation-entry');
+ const title = document.createElement('h4');
+ title.classList.add('creation-entry-title');
+ title.appendChild(document.createTextNode(metadata.title));
+ entry.appendChild(title);
+ const lastViewed = document.createElement('div');
+ lastViewed.classList.add('creation-entry-last-viewed');
+ lastViewed.appendChild(
+ document.createTextNode(
+ 'Last viewed: ' + new Date(metadata.lastViewed).toLocaleString()
+ )
+ );
+ entry.appendChild(lastViewed);
+ entry.addEventListener('click', () => {
+ load_creation(id);
+ creations_dialog.close();
+ });
+ container.appendChild(entry);
+ }
+ });
+
+ document.getElementById('delete-creation').addEventListener('click', () => {
+ document.getElementById('delete-creation-title').innerText =
+ get_creation_title();
+ document.getElementById('delete-dialog').showModal();
+ });
+
+ document
+ .getElementById('delete-creation-confirm')
+ .addEventListener('click', () => {
+ delete creation_metadata[creation_id];
+ localStorage.removeItem(`${APP_ID}-${creation_id}-description`);
+ localStorage.setItem(
+ `${APP_ID}-metadata`,
+ JSON.stringify(creation_metadata)
+ );
+ creation_id = undefined;
+ load_most_recent_or_create_new();
+ });
+
+ document.getElementById('new-creation').addEventListener('click', () => {
+ new_creation();
+ });
+
document.getElementById('resolution-form').addEventListener('submit', () => {
render_width = resolution_x_element.value;
render_height = resolution_y_element.value;
@@ -2654,26 +2726,7 @@ void main() {
});
creation_metadata = parse_json(localStorage.getItem(`${APP_ID}-metadata`));
- let result;
- if (creation_metadata) {
- // load creation with largest lastViewed time
- let load = undefined;
- for (const id in creation_metadata) {
- if (
- !load ||
- creation_metadata[id].lastViewed > creation_metadata[load].lastViewed
- ) {
- load = id;
- }
- }
- result = load_creation(load);
- } else {
- creation_metadata = {};
- result = new_creation();
- }
- if (result.error) {
- show_error(result);
- }
+ load_most_recent_or_create_new();
frame(0.0);
diff --git a/style.css b/style.css
index e2981cb..12f5986 100644
--- a/style.css
+++ b/style.css
@@ -1,5 +1,6 @@
:root {
--color-text: #ddd;
+ --color-link: #8fc;
}
body {
@@ -15,7 +16,7 @@ dialog {
a,
a:visited {
- color: #8fc;
+ color: var(--color-link);
}
h1,
@@ -219,7 +220,7 @@ input[type='checkbox'] {
summary {
cursor: pointer;
}
-#title {
+#top-area {
vertical-align: middle;
font-weight: bold;
font-size: 0.5cm;
@@ -227,6 +228,9 @@ summary {
#title-icon {
height: 1cm;
}
+#creation-buttons {
+ margin-top: 0.2em;
+}
#resolution-form input[type='number'] {
width: 4em;
}
@@ -326,3 +330,21 @@ th {
margin: 0;
padding: 0.2em;
}
+
+.creation-entry {
+ cursor: pointer;
+ border-bottom: 2px solid white;
+ padding: 6px;
+}
+
+.creation-entry:hover {
+ background: #fff4;
+}
+
+.creation-entry-title {
+ color: var(--color-link);
+}
+
+.creation-entry-last-viewed {
+ font-style: italic;
+}