╭──────────╮ │← previous│ ╰──────────╯ ╭ changed ──╮ │src/web.zig│ ╰───────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────╮ │304 }); │ │305 } │ │306 │ │307 -fn handleAnsi(request: *std.http.Server.Request) !void { │ │308 - // TODO: persist the flip in the logged-in user's server-side session so it │ │309 - // survives this redirect and subsequent GETs. │ │310 - // │ │307 +fn handleAnsi( │ │308 + io: std.Io, │ │309 + request: *std.http.Server.Request, │ │310 + allocator: std.mem.Allocator, │ │311 + admin_repo_path: []const u8, │ │312 + session_store: SessionStore, │ │313 +) !void { │ │314 + var user_id: [evt.event_id_size]u8 = undefined; │ │315 + if (getCookieValue(request, cookie_name)) |token| { │ │316 + if (session_store.lookup(token, &user_id)) { │ │317 + const repo_opts: rp.RepoOpts(.xit) = .{}; │ │318 + const Repo = rp.Repo(.xit, repo_opts); │ │319 + var repo = try Repo.open(io, allocator, .{ .path = admin_repo_path });│ │320 + defer repo.deinit(io, allocator); │ │321 + │ │322 + try evt.User.toggleAnsi(repo_opts, io, allocator, &repo, &user_id); │ │323 + } │ │324 + } │ │325 + │ │326 // like logout, this is a bodyless POST, so close the connection rather than │ │327 // letting the keep-alive path try to discard a body that isn't framed. │ │328 try request.respond("", .{ │ ╰───────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │544 │ │545 try out.appendSlice(allocator, "<form action=\""); │ │546 try appendEscapedHtml(allocator, &out, action_url); │ │532 - try out.appendSlice(allocator, "\" method=\"post\">"); │ │547 + try out.appendSlice(allocator, "\" method=\"post\""); │ │548 + // an empty action must not POST — block it and send the input to the TUI instead │ │549 + if (action_url.len == 0) try out.appendSlice(allocator, " onsubmit=\"event.preventDefault();sendEnter(this);\"");│ │550 + try out.appendSlice(allocator, ">"); │ │551 │ │552 // form.focus.children was populated by addChild, which flattens the │ │553 // whole subtree into one map — so descendants (inputs + the submit │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │663 │ │664 // --- helpers -------------------------------------------------------------- │ │665 │ │648 -fn openHaxyMoment( │ │649 - comptime repo_opts: rp.RepoOpts(.xit), │ │650 - repo: *rp.Repo(.xit, repo_opts), │ │651 -) !rp.Repo(.xit, repo_opts).DB.HashMap(.read_only) { │ │652 - const DB = rp.Repo(.xit, repo_opts).DB; │ │653 - const history = try DB.ArrayList(.read_only).init(repo.core.db.rootCursor().readOnly()); │ │654 - const moment_cursor = try history.getCursor(-1) orelse return error.NotFound; │ │655 - const moment = try DB.HashMap(.read_only).init(moment_cursor); │ │656 - const last_object_id_cursor = try moment.getCursor(hash.hashInt(repo_opts.hash, "haxy-last-object-id")) orelse return error.NotFound;│ │657 - var last_object_id: [hash.byteLen(repo_opts.hash)]u8 = undefined; │ │658 - _ = try last_object_id_cursor.readBytes(&last_object_id); │ │659 - const haxy_cursor = try moment.getCursor(hash.hashInt(repo_opts.hash, "haxy")) orelse return error.NotFound; │ │660 - const haxy = try DB.ArrayList(.read_only).init(haxy_cursor); │ │661 - const haxy_moments_cursor = try haxy.getCursor(-1) orelse return error.NotFound; │ │662 - const haxy_moments = try DB.HashMap(.read_only).init(haxy_moments_cursor); │ │663 - const haxy_moment_cursor = try haxy_moments.getCursor(hash.bytesToInt(repo_opts.hash, &last_object_id)) orelse return error.NotFound;│ │664 - return try DB.HashMap(.read_only).init(haxy_moment_cursor); │ │665 -} │ │666 - │ │666 fn getCookieValue(request: *std.http.Server.Request, name: []const u8) ?[]const u8 { │ │667 var iter = request.iterateHeaders(); │ │668 while (iter.next()) |header| { │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯