This commit is contained in:
Bob Farrell 2025-05-06 19:41:33 +01:00
parent c887b25ef8
commit ae3ed05a7d
6 changed files with 26 additions and 9 deletions

View File

@ -9,6 +9,12 @@ pub fn index(request: *jetzig.Request) !jetzig.View {
return request.render(.ok); return request.render(.ok);
} }
pub fn get(id: []const u8, request: *jetzig.Request) !jetzig.View {
var root = try request.data(.object);
try root.put("join_token", id);
return request.renderTemplate("websockets/index", .ok);
}
pub const Channel = struct { pub const Channel = struct {
pub fn open(channel: jetzig.channels.Channel) !void { pub fn open(channel: jetzig.channels.Channel) !void {
var state = try channel.state("game"); var state = try channel.state("game");
@ -17,8 +23,8 @@ pub const Channel = struct {
} }
pub const Actions = struct { pub const Actions = struct {
pub fn join(channel: jetzig.channels.Channel, token: []const u8) !void { pub fn join(channel: jetzig.channels.Channel, join_token: []const u8) !void {
try channel.connect("game", token); try channel.connect("game", join_token);
} }
pub fn move(channel: jetzig.channels.Channel, cell: usize) !void { pub fn move(channel: jetzig.channels.Channel, cell: usize) !void {

View File

@ -3,6 +3,10 @@
<div id="party-container"></div> <div id="party-container"></div>
@if ($.join_token) |join_token|
<a href="#" jetzig-click="join" data-join-token="{{join_token}}">Join Game</a>
@end
<jetzig-scope name="game"> <jetzig-scope name="game">
<div id="results-wrapper"> <div id="results-wrapper">
<span class="trophy">&#127942;</span> <span class="trophy">&#127942;</span>
@ -45,9 +49,10 @@
</div> </div>
<h4>Share this link to invite another player</h4> <h4>Share this link to invite another player</h4>
<div jetzig-connect="$.__connect_url__"></div> <div jetzig-connect="$.__connection_url__"></div>
</jetzig-scope> </jetzig-scope>
<script> <script>
Jetzig.channel.receive("victor", data => { Jetzig.channel.receive("victor", data => {
triggerPartyAnimation(); triggerPartyAnimation();

View File

@ -116,7 +116,8 @@ pub fn RoutedChannel(Routes: type) type {
const connection_key = try std.fmt.allocPrint(channel.allocator, "{s}:{s}", .{ channel.websocket.session_id, connection_id }); const connection_key = try std.fmt.allocPrint(channel.allocator, "{s}:{s}", .{ channel.websocket.session_id, connection_id });
const channel_state = try channel.websocket.channels.get(channel.data, connection_key) orelse blk: { const channel_state = try channel.websocket.channels.get(channel.data, connection_key) orelse blk: {
const channel_state = try channel.data.object(); const channel_state = try channel.data.object();
try channel_state.put("__connection_key__", try std.fmt.allocPrint(channel.allocator, "http://{s}{s}?key={s}", .{ channel.host, channel.path, connection_key })); // TODO - store this in a way that won't clobber the key with each new state.
try channel_state.put("__connection_url__", try std.fmt.allocPrint(channel.allocator, "http://{s}{s}?key={s}", .{ channel.host, channel.path, connection_key }));
try channel.websocket.channels.put(connection_key, channel_state); try channel.websocket.channels.put(connection_key, channel_state);
break :blk channel_state; break :blk channel_state;
}; };

View File

@ -481,7 +481,7 @@ pub fn RoutedServer(Routes: type) type {
) ![]const u8 { ) ![]const u8 {
try addTemplateConstants(view, route); try addTemplateConstants(view, route);
var template_context = jetzig.TemplateContext{ .request = request }; var template_context = jetzig.TemplateContext{ .request = request, .route = route };
template_context.middleware.context = &template_context; template_context.middleware.context = &template_context;
if (request.getLayout(route)) |layout_name| { if (request.getLayout(route)) |layout_name| {

View File

@ -15,18 +15,19 @@ pub const Blocks = struct {
} }
pub fn footer(context: jetzig.TemplateContext, writer: anytype) !void { pub fn footer(context: jetzig.TemplateContext, writer: anytype) !void {
const route = context.route orelse return;
const request = context.request orelse return; const request = context.request orelse return;
const host = request.headers.getLower("host") orelse return; const host = request.headers.getLower("host") orelse return;
try writer.print( try writer.print(
\\<script> \\<script>
\\ (() => {{ \\ (() => {{
\\ window.addEventListener('DOMContentLoaded', () => {{ \\ window.addEventListener('DOMContentLoaded', () => {{
\\ Jetzig.channel.init("{s}", "{s}"); \\ Jetzig.channel.init("{s}", "/{s}");
\\ }}); \\ }});
\\ }})(); \\ }})();
\\</script> \\</script>
\\ \\
, .{ host, request.path.base_path }); , .{ host, route.view_name });
} }
}; };

View File

@ -104,9 +104,9 @@ const Jetzig = window.Jetzig;
element.addEventListener('click', () => { element.addEventListener('click', () => {
const args = []; const args = [];
action.spec.params.forEach(param => { action.spec.params.forEach(param => {
const arg = element.dataset[param.name]; const arg = element.dataset[transformParam(param.name)];
if (arg === undefined) { if (arg === undefined) {
throw new Error(`Expected 'data-${param.name}' attribute for '${action.name}' click handler.`); throw new Error(`Expected 'data-${param.name}' HTML attribute for '${action.spec.name}' click handler.`);
} else { } else {
args.push(element.dataset[param.name]); args.push(element.dataset[param.name]);
} }
@ -119,6 +119,10 @@ const Jetzig = window.Jetzig;
}); });
}; };
const transformParam = (param) => param.toLowerCase()
.replace(/([-_][a-z])/g,
group => group.toUpperCase().replace('-', '').replace('_', ''));
const initScopes = (channel) => { const initScopes = (channel) => {
document.querySelectorAll('jetzig-scope').forEach(element => { document.querySelectorAll('jetzig-scope').forEach(element => {
channel.scopeWrappers.push(element); channel.scopeWrappers.push(element);