diff --git a/demo/public/party.css b/demo/public/party.css index c7d9524..70433af 100644 --- a/demo/public/party.css +++ b/demo/public/party.css @@ -120,3 +120,16 @@ body { text-align: center; vertical-align: center; } + +#grid { + transition: background-color 0.5s ease; +} + +.flash-animation { + animation: flashRed 0.5s ease; +} + +@keyframes flashRed { + 0% { background-color: #e55; } + 100% { background-color: white; } + } diff --git a/demo/src/app/views/websockets.zig b/demo/src/app/views/websockets.zig index 28ee8b1..04eced0 100644 --- a/demo/src/app/views/websockets.zig +++ b/demo/src/app/views/websockets.zig @@ -21,7 +21,7 @@ pub const Channel = struct { game.evaluate(); if (game.victor != null) { - try channel.publish(.{ .err = "Game is already over." }); + try channel.invoke(.game_over, .{}); return; } else { try movePlayer(channel, &game, cells, cell); diff --git a/demo/src/app/views/websockets/index.zmpl b/demo/src/app/views/websockets/index.zmpl index 5ca5202..738ce9d 100644 --- a/demo/src/app/views/websockets/index.zmpl +++ b/demo/src/app/views/websockets/index.zmpl @@ -5,13 +5,23 @@ stateChangedCallbacks: [], messageCallbacks: [], invokeCallbacks: {}, + elementMap: {}, + transformerMap: {}, + transformers: {}, onStateChanged: function(callback) { this.stateChangedCallbacks.push(callback); }, onMessage: function(callback) { this.messageCallbacks.push(callback); }, - receive: function(event, callback) { - if (Object.hasOwn(this.invokeCallbacks, event)) { - this.invokeCallbacks[event].push(callback); + transform: function(ref, callback) { + if (Object.hasOwn(this.transformers, ref)) { + this.transformers[ref].push(callback); } else { - this.invokeCallbacks[event] = [callback]; + this.transformers[ref] = [callback]; + } + }, + receive: function(ref, callback) { + if (Object.hasOwn(this.invokeCallbacks, ref)) { + this.invokeCallbacks[ref].push(callback); + } else { + this.invokeCallbacks[ref] = [callback]; } }, publish: function(data) { @@ -21,76 +31,122 @@ } }, }; - + + (() => { @if (context.request) |request| - @if (request.headers.get("host")) |host| - + const reduceState = (ref, state) => { + if (!ref.startsWith('$.')) throw new Error(`Unexpected ref format: ${ref}`); + const args = ref.split('.'); + args.shift(); + const isNumeric = (string) => [...string].every(char => '0123456789'.includes(char)); + const isObject = (object) => object && typeof object === 'object'; + return args.reduce((acc, arg) => { + if (isNumeric(arg)) { + if (acc && Array.isArray(acc) && acc.length > arg) return acc[parseInt(arg)]; + return null; + } else { + if (acc && isObject(acc)) return acc[arg]; + return null; + } + }, state); + }; + + window.addEventListener('DOMContentLoaded', () => { + document.querySelectorAll('[jetzig-connect]').forEach(element => { + const ref = element.getAttribute('jetzig-connect'); + if (!channel.elementMap[ref]) channel.elementMap[ref] = []; + const id = `jetzig-${crypto.randomUUID()}`; + element.setAttribute('jetzig-id', id); + channel.elementMap[ref].push(element); + channel.transformerMap[id] = element.getAttribute('jetzig-transform'); + }); + }); + + @// channel.websocket.addEventListener("open", (event) => { + @// // TODO + @// channel.publish("websockets", {}); + @// }); @end @end + })(); + +
🏆
Player
-
+
CPU
-
+
Tie
-
+
🏆
@@ -98,15 +154,9 @@
-
-
-
-
-
-
-
-
-
+ @for (0..9) |index| { +
+ }
@@ -118,19 +168,10 @@