╭ changed ─────────────────╮ │src/ui/Home/Auth/Login.zig│ ╰──────────────────────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭────────────────────────────────────────────────────────────────────────────────╮ │77 button.getFocus().focusable = true; │ │78 // the renderer distinguishes plain clickables from buttons that│ │79 // should POST to a server route by this kind. │ │80 - button.getFocus().kind = .submit_button; │ │80 + button.getFocus().kind = .{ .custom = "submit" }; │ │81 nav_ids[button_index] = button.getFocus().id; │ │82 try box.children.put(allocator, button.getFocus().id, .{ │ │83 .widget = .{ .text_box = button }, │ ╰────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │104 pub fn build(self: *View, allocator: std.mem.Allocator, constraint: layout.Constraint, root_focus: *Focus) !void {│ │105 const box = &self.center.child.box; │ │106 │ │107 - const button = &box.children.values()[button_index].widget.text_box; │ │108 - button.options.border_style = if (root_focus.grandchild_id == self.nav_ids[button_index]) │ │109 - .double │ │110 - else │ │111 - .single; │ │112 - │ │107 const failure = self.session.data.login_failure; │ │108 │ │109 const username_input = &box.children.values()[username_index].widget.text_input; │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────╮ │220 const username_input = &box.children.values()[username_index].widget.text_input; │ │221 const password_input = &box.children.values()[password_index].widget.text_input; │ │222 │ │229 - var username_buf: [256]u8 = undefined; │ │230 - const username = joinCodepoints(&username_buf, username_input.content.items) orelse {│ │231 - self.session.data.login_failure = .unknown_user; │ │232 - return; │ │233 - }; │ │223 + const username = try username_input.text(allocator); │ │224 + defer allocator.free(username); │ │225 │ │235 - var password_buf: [256]u8 = undefined; │ │236 - const password = joinCodepoints(&password_buf, password_input.content.items) orelse {│ │237 - self.session.data.login_failure = .wrong_password; │ │238 - return; │ │239 - }; │ │226 + const password = try password_input.text(allocator); │ │227 + defer allocator.free(password); │ │228 │ │229 const haxy_moment = self.session.haxy_moment orelse { │ │230 // no DB context (e.g. wasm/web rendering path); treat as unknown. │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────╮ │261 } │ │262 }; │ │263 │ │276 -// joins a list of utf-8 codepoint slices (as TextInput stores them) into a│ │277 -// flat buffer. returns null if the joined bytes don't fit. │ │278 -fn joinCodepoints(buf: []u8, codepoints: []const []const u8) ?[]const u8 { │ │279 - var len: usize = 0; │ │280 - for (codepoints) |cp| { │ │281 - if (len + cp.len > buf.len) return null; │ │282 - @memcpy(buf[len..][0..cp.len], cp); │ │283 - len += cp.len; │ │284 - } │ │285 - return buf[0..len]; │ │286 -} │ │287 - │ ╰────────────────────────────────────────────────────────────────────────────────╯