<form method="dialog">
<p>
<label>Your name:
- <input id="name" type="text">
+ <input id="name" type="text" autocomplete="off">
</label>
</p>
<div>
- <button value="cancel">Cancel</button>
- <button id="confirm" value="default">Confirm</button>
+ <button value="default">OK</button>
</div>
</form>
</dialog>
<label for="code">
Numeric code:
</label>
- <input id="code" type="text" autocomplete="off" placeholder="(Leave blank for random)" />
+ <input id="code" type="number" min="0" max="4294967295" autocomplete="off" placeholder="(Leave blank for random)" />
</div>
</div>
<div id="images">
</div>
- <ul id="comments">
- </ul>
-
- <p>
- <form action="" id="comment-form">
- <input id="comment" type="text" style="width:100%" autocomplete="off" placeholder="Add a comment" />
- </form>
- </p>
-
<audio loop="" src="/zombo_words.mp3" type="audio/mpeg"></audio>
- <button id="mute" class="fade volume">
+ <button id="mute" class="menu-button fade volume">
<div>🔊</div>
<script>
const mute = document.querySelector("#mute");
</button>
+ <button id="profile" class="menu-button">
+ <div>👤</div>
+ </button>
+
</div>
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io();
- const name = document.querySelector("#name");
+ const name_input = document.querySelector("#name");
const name_dialog = document.querySelector("#name-dialog");
+ var informed_name;
const images = document.querySelector("#images");
- const comments = document.querySelector("#comments");
- const comment_form = document.querySelector("#comment-form");
- const comment = document.querySelector("#comment");
const zombo_form = document.querySelector("#zombo-form");
const prompt = document.querySelector("#prompt");
const code = document.querySelector("#code");
const safety= document.querySelector("#safety");
const spinner = document.querySelector("#spinner");
+ const profile = document.querySelector("#profile");
var spinner_timeout;
- comment.addEventListener('focus', () => {
- /* Do nothing if name is already set. */
- if (name.value)
- return;
-
- /* Otherwise, bring up the modal dialog to set the name. */
+ profile.addEventListener('click', () => {
name_dialog.showModal();
});
name_dialog.addEventListener('close', () => {
- socket.emit('set-name', name.value);
+ socket.emit('set-name', name_input.value);
});
- comment_form.addEventListener('submit', function(e) {
- e.preventDefault();
- if (comment.value) {
- socket.emit('comment', comment.value);
- comment.value = '';
- }
- });
+ function add_comment(comments, comment) {
+ const dt = document.createElement('dt');
+ const dd = document.createElement('dd');
+ dt.textContent = comment.name + ':';
+ dd.textContent = comment.text;
+ comments.appendChild(dt);
+ comments.appendChild(dd);
+ }
- socket.on('comment', function(msg) {
- var item = document.createElement('li');
- item.textContent = msg;
- comments.appendChild(item);
+ socket.on('comment', function(comment) {
+ const comments = document.querySelector("#comments_" + comment.image_id);
+ add_comment(comments, comment);
});
socket.on('inform-name', (name) => {
- name.value = name;
+ console.log("Received inform-name event: " + name);
+
+ /* When we receive a name we store it in 3 places:
+ *
+ * * The informed_name variable (confirming what the server knows)
+ * * The name_input field (so the user will see that in their profile)
+ * * In localStorage (for use in a future session)
+ */
+ informed_name = name;
+ name_input.value = name;
+ localStorage.setItem('name', name);
});
socket.on('reset', () => {
images.replaceChildren();
+
+ /* Since the server is seeing us for the first time, let it
+ know our name (if we have one). */
+ const name = localStorage.getItem('name');
+ if (name) {
+ socket.emit('set-name', name);
+ return;
+ }
});
socket.on('image', (image) => {
const figure = document.createElement('figure');
+ figure.id = "image_" + image.id;
+
const img = document.createElement('img');
img.src = image.filename;
- const figcaption = document.createElement('figcaption');
- const caption_text = document.createTextNode(`${image.prompt} (${image.code})`);
- figcaption.appendChild(caption_text);
figure.appendChild(img);
- figure.appendChild(figcaption);
+
+ if (image.prompt && image.code) {
+ const figcaption = document.createElement('figcaption');
+ const caption_text = document.createTextNode(`${image.prompt} (${image.code}) `);
+ figcaption.appendChild(caption_text);
+
+ const reuse_button = document.createElement('button');
+ reuse_button.appendChild(document.createTextNode("Reuse"));
+ figcaption.appendChild(reuse_button);
+
+ reuse_button.addEventListener('click', () => {
+ prompt.value = image.prompt;
+ window.scrollTo(0,0);
+ });
+
+ figure.appendChild(figcaption);
+ }
+
+ const dl_comments = document.createElement('dl');
+ dl_comments.className = "comments";
+ dl_comments.id = "comments_" + image.id;
+
+ image.comments.forEach((comment) => {
+ add_comment(dl_comments, comment);
+ });
+
+ figure.appendChild(dl_comments);
+
+ const comment_form = document.createElement('form');
+ const comment_input = document.createElement('input')
+ comment_input.type = "text";
+ comment_input.className = "comment";
+ comment_input.placeholder = "Add a comment";
+ comment_form.appendChild(comment_input);
+ figure.appendChild(comment_form);
+
+ comment_input.addEventListener('focus', () => {
+ /* If the server has informed us it has our name, we are done. */
+ if (informed_name)
+ return;
+
+ /* If server has no name, check local storage. */
+ const name = localStorage.getItem('name');
+ if (name) {
+ socket.emit('set-name', name);
+ return;
+ }
+
+ /* Failing both, bring up the modal dialog to set the name. */
+ name_dialog.showModal();
+ });
+
+ comment_form.addEventListener('submit', function(e) {
+ e.preventDefault();
+ if (comment_input.value) {
+ socket.emit('comment', {image_id: image.id,
+ text: comment_input.value});
+ comment_input.value = '';
+ }
+ });
+
images.prepend(figure);
});
"An image of",
"A pencil sketch of",
"A watercolor of",
+ "A 3D rendering of",
+ "A marble statue of",
];
const subject = [
" a modern home",
" sci-fi buildings",
" pastel purple clouds",
" a Teenage Mutant Ninja Turtle",
+ " Pikachu",
];
const scenery = [
" in tropical surroundings",
" on the streets of London at night with neon lights flashing",
" that is part octopus",
" melting into a puddle",
+ " on a birthday cake",
];
const artist = [
", unreal engine 5",
", fantasy art, neon fog",
", epic lighting from above",
", trending on artstation",
+ " by Gustav Klimt",
+ " by Leonardo da Vinci",
];
prompt.value = random_from(art_type) + random_from(subject) +