]> git.cworth.org Git - zombocom-ai/blob - index.html
Send along the user's name with each comment made
[zombocom-ai] / index.html
1 <!DOCTYPE html>
2 <html>
3
4 <head>
5   <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
6   <title>ZOMBO</title>
7   <link href="/zombo.css" rel="stylesheet" type="text/css">
8   <meta name="viewport" content="width=device-width,initial-scale=1">
9   <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
10   <meta name="HandheldFriendly" content="true">
11 </head>
12
13 <body>
14   <div id="content">
15
16     <div id="header" align="center">
17       <p>
18         <br>
19       </p>
20
21       <p>
22         <img src="/zombocom.png" alt="Zombocom" longdesc="http://zombo.com" width="1199" height="217">
23       </p>
24     </div>
25
26     <p>
27       Welcome to Zombocom. You can do anything at Zombocom, anything at
28       all. The only limit is yourself!
29     </p>
30
31     <dialog id="name-dialog">
32       <form method="dialog">
33         <p>
34           <label>Your name:
35             <input id="name" type="text">
36           </label>
37         </p>
38         <div>
39           <button value="cancel">Cancel</button>
40           <button id="confirm" value="default">Confirm</button>
41         </div>
42       </form>
43     </dialog>
44
45     <p>
46       <div id="spinner" align="center">
47         <div class="animate-flicker">
48           <p>
49             <img src="/pngwheel.png" class="rotate thefade">
50           </p>
51         </div>
52       </div>
53
54       <form action="" id="zombo-form">
55         <div class="form-row large">
56           <label for="prompt">
57             What can you imagine?
58           </label>
59           <button id="safety" type="button">Safety prompt</button>
60           <textarea id="prompt" rows="4" width="100%" autocomplete="off" required></textarea>
61         </div>
62
63         <div class="form-row small left">
64           <div class="labeled-row">
65             <label for="code">
66               Numeric code:
67             </label>
68             <input id="code" type="text" autocomplete="off" placeholder="(Leave blank for random)" />
69           </div>
70         </div>
71
72         <div class="form-row large">
73           <button id="generate" type="submit">Make the infinite possible</button>
74         </div>
75       </form>
76     </p>
77
78     <div id="images">
79     </div>
80
81     <dl id="comments">
82     </dl>
83
84     <p>
85       <form action="" id="comment-form">
86         <input id="comment" type="text" style="width:100%" autocomplete="off" placeholder="Add a comment" />
87       </form>
88     </p>
89
90     <audio loop="" src="/zombo_words.mp3" type="audio/mpeg"></audio>
91     <button id="mute" class="menu-button fade volume">
92       <div>🔊</div>
93       <script>
94 const mute = document.querySelector("#mute");
95 const icon = document.querySelector("#mute > div");
96 const audio = document.querySelector("audio");
97
98 mute.addEventListener("click", () => {
99   if (audio.paused) {
100       audio.volume = 0.2;
101       audio.play();
102       icon.innerHTML = "🔈";
103   } else {
104       audio.pause();
105       icon.innerHTML = "🔊";
106   }
107   mute.classList.add("fade");
108 });
109       </script>
110
111     </button>
112
113     <button id="profile" class="menu-button">
114       <div>👤</div>
115     </button>
116
117   </div>
118
119   <script src="/socket.io/socket.io.js"></script>
120   <script>
121     var socket = io();
122
123     const name = document.querySelector("#name");
124     const name_dialog = document.querySelector("#name-dialog");
125     const images = document.querySelector("#images");
126     const comments = document.querySelector("#comments");
127     const comment_form = document.querySelector("#comment-form");
128     const comment = document.querySelector("#comment");
129     const zombo_form = document.querySelector("#zombo-form");
130     const prompt = document.querySelector("#prompt");
131     const code = document.querySelector("#code");
132     const safety= document.querySelector("#safety");
133     const spinner = document.querySelector("#spinner");
134     const profile = document.querySelector("#profile");
135     var spinner_timeout;
136
137     comment.addEventListener('focus', () => {
138         /* Do nothing if name is already set. */
139         if (name.value)
140             return;
141
142         /* Otherwise, bring up the modal dialog to set the name. */
143         name_dialog.showModal();
144     });
145
146     profile.addEventListener('click', () => {
147         name_dialog.showModal();
148     });
149
150     name_dialog.addEventListener('close', () => {
151         socket.emit('set-name', name.value);
152     });
153
154     comment_form.addEventListener('submit', function(e) {
155         e.preventDefault();
156         if (comment.value) {
157             socket.emit('comment', comment.value);
158             comment.value = '';
159         }
160     });
161
162     socket.on('comment', function(comment) {
163         const dt = document.createElement('dt');
164         const dd = document.createElement('dd');
165         dt.textContent = comment.name;
166         dd.textContent = comment.text;
167         comments.appendChild(dt);
168         comments.appendChild(dd);
169     });
170
171     socket.on('inform-name', (name) => {
172         console.log("Received inform-name event: " + name);
173         name.value = name;
174     });
175
176     socket.on('reset', () => {
177         images.replaceChildren();
178     });
179
180     socket.on('image', (image) => {
181         const figure = document.createElement('figure');
182         const img = document.createElement('img');
183         img.src = image.filename;
184         const figcaption = document.createElement('figcaption');
185         const caption_text = document.createTextNode(`${image.prompt} (${image.code})`);
186         figcaption.appendChild(caption_text);
187         figure.appendChild(img);
188         figure.appendChild(figcaption);
189         images.prepend(figure);
190     });
191
192     function hide_spinner() {
193         zombo_form.style.display = "grid";
194         spinner.style.display = "none";
195     }
196
197     zombo_form.addEventListener('submit', function(e) {
198         e.preventDefault();
199         /* Hide the form and show spinner while generation is happening. */
200         zombo_form.style.display = "none";
201         spinner.style.display = "block";
202         spinner_timeout = setTimeout(hide_spinner, 60000);
203         socket.emit('generate', {"prompt": prompt.value, "code": code.value});
204         prompt.value = '';
205     });
206
207     socket.on('generation-done', () => {
208         /* Re-display the form and hide spinner now that generation is over. */
209         clearTimeout(spinner_timeout);
210         hide_spinner();
211     });
212
213     function random_from(items) {
214         return items[Math.floor(Math.random()*items.length)];
215     }
216
217     safety.addEventListener("click", () => {
218         const art_type = [
219             "A portrait of",
220             "A hyperrealistic photograph of",
221             "A matte painting of",
222             "Epic fantasy card art of",
223             "Professional oil painting of",
224             "An image of",
225             "A pencil sketch of",
226             "A watercolor of",
227         ];
228         const subject = [
229             " a modern home",
230             " crashing waves",
231             " a Porsche 911 Carrera",
232             " a Halo spartan",
233             " a cute cat",
234             " a mad scientist",
235             " an elfin princess",
236             " sci-fi buildings",
237             " pastel purple clouds",
238             " a Teenage Mutant Ninja Turtle",
239         ];
240         const scenery = [
241             " in tropical surroundings",
242             " in space",
243             " in an ocean storm",
244             " in a snowy forest",
245             " in a cardboard box",
246             " holding an axe",
247             " in an epic landscape",
248             " in a haunted forest",
249             " riding a motorbike",
250             " in a futuristic city at night",
251             " in a dystopian landscape, foggy",
252             " in the land of snow",
253             " that looks like a watermelon",
254             " on the streets of London at night with neon lights flashing",
255             " that is part octopus",
256             " melting into a puddle",
257         ];
258         const artist = [
259             ", unreal engine 5",
260             ", concept art",
261             ", graphic novel",
262             " by Vincent Van Gogh",
263             " by Claude Monet",
264             " by Johannes Vermeer",
265             ", fantasy art, neon fog",
266             ", epic lighting from above",
267             ", trending on artstation",
268         ];
269
270         prompt.value = random_from(art_type) + random_from(subject) +
271             random_from(scenery) + random_from(artist);
272         return false;
273     });
274
275   </script>
276 </body>
277 </html>