╭ changed ─────────╮ │src/ui/AuthTab.zig│ ╰──────────────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭───────────────────────────────────────╮ │1 const std = @import("std"); │ │2 +const evt = @import("../event.zig");│ │3 const ui = @import("../ui.zig"); │ │4 const xit = @import("xit"); │ │5 const xitui = xit.xitui; │ ╰───────────────────────────────────────╯ ╭──────────────────────────────────────────────────╮ │10 const Focus = xitui.focus.Focus; │ │11 │ │12 const Self = @This(); │ │12 - │ │13 -pub const min_width: usize = "logout".len + 2;│ │13 │ │14 pub fn init() Self { │ │15 return .{}; │ ╰──────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │18 pub const View = struct { │ │19 text_box: wgt.TextBox(ui.Widget), │ │20 session: *ui.Session, │ │21 + // backs the tab's text, which borrows it. sized for the longest name, so │ │22 + // build never allocates. │ │23 + text_buf: [logout_prefix.len + evt.User.name_max_len]u8, │ │24 │ │25 + const logout_prefix = "logout "; │ │26 + │ │27 pub fn init(allocator: std.mem.Allocator, session: *ui.Session) !View { │ │28 var text_box = try wgt.TextBox(ui.Widget).init(allocator, "login", .{ .border_style = .single, .rounded_corners = true, .wrap_kind = .none });│ │29 errdefer text_box.deinit(allocator); │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────╮ │32 return .{ │ │33 .text_box = text_box, │ │34 .session = session, │ │35 + .text_buf = undefined,│ │36 }; │ │37 } │ │38 │ ╰──────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │39 pub fn deinit(self: *View, allocator: std.mem.Allocator) void { │ │40 self.text_box.deinit(allocator); │ │41 + } │ │42 + │ │43 + // the action the tab performs, naming whoever is logged in │ │44 + fn text(self: *View) []const u8 { │ │45 + if (self.session.data.user_id == null) return "login"; │ │46 + const name = self.session.data.user_name orelse return "logout"; │ │47 + // validateName caps the name, so the buffer always fits it │ │48 + return std.fmt.bufPrint(&self.text_buf, logout_prefix ++ "{s}", .{name}) catch unreachable; │ │49 } │ │50 │ │51 + // what the tab's text needs, plus its border │ │52 + pub fn minWidth(self: *View) usize { │ │53 + return self.text().len + 2; │ │54 + } │ │55 + │ │56 pub fn build(self: *View, allocator: std.mem.Allocator, constraint: layout.Constraint, root_focus: *Focus) !void {│ │39 - // update the displayed label based on session state. the inner Text │ │57 + // update the displayed text based on session state. the inner Text │ │58 // widget's content is just a slice, so we can repoint it without │ │59 // re-allocating. │ │60 if (self.text_box.box.children.values().len > 0) { │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────╮ │61 const text_widget = &self.text_box.box.children.values()[0].widget.text; │ │44 - text_widget.content = if (self.session.data.user_id != null) "logout" else "login";│ │62 + text_widget.content = self.text(); │ │63 } │ │64 try self.text_box.build(allocator, constraint, root_focus); │ │65 } │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────╯