╭ changed ─────────────╮ │src/ui/Home/Header.zig│ ╰──────────────────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │ 69 }; │ │ 70 var selected_tab: ?usize = null; │ │ 71 │ │ 72 - // tabs │ │ 73 - for ( │ │ 74 - [_][]const u8{ "users", "repos", "", "settings", "" }, │ │ 75 - [_][]const u8{ "ai:/users", "ai:/repos", "", "ai:/settings", "ai:/auth" }, │ │ 76 - ) |name, focus_name| { │ │ 77 - // spacer │ │ 78 - if (focus_name.len == 0) { │ │ 79 - var spacer = try ui.Spacer.init(allocator); │ │ 80 - errdefer spacer.deinit(allocator); │ │ 81 - try box.children.put(allocator, spacer.getFocus().id, .{ │ │ 82 - .widget = .{ .spacer = spacer }, │ │ 83 - .rect = null, │ │ 84 - .min_size = null, │ │ 85 - }); │ │ 86 - } │ │ 87 - // auth │ │ 88 - else if (std.mem.eql(u8, "ai:/auth", focus_name)) { │ │ 89 - var auth_tab = try AuthTab.View.init(allocator, session); │ │ 90 - errdefer auth_tab.deinit(allocator); │ │ 91 - try tab_ids.put(allocator, auth_tab.getFocus().id, {}); │ │ 92 - if (std.mem.eql(u8, focus_name, current_link)) selected_tab = auth_tab.getFocus().id; │ │ 93 - try box.children.put(allocator, auth_tab.getFocus().id, .{ │ │ 94 - .widget = .{ .auth_tab = auth_tab }, │ │ 95 - .rect = null, │ │ 96 - .min_size = .{ .width = auth_tab.minWidth(), .height = null }, │ │ 97 - }); │ │ 98 - } │ │ 99 - // other tabs │ │100 - else { │ │101 - var text_box = try wgt.TextBox(ui.Widget).init(allocator, name, .{ .border_style = .single, .rounded_corners = true, .wrap_kind = .none }); │ │102 - errdefer text_box.deinit(allocator); │ │103 - text_box.getFocus().focusable = true; │ │104 - text_box.getFocus().kind = .{ .custom = focus_name }; │ │105 - try tab_ids.put(allocator, text_box.getFocus().id, {}); │ │106 - if (std.mem.eql(u8, focus_name, current_link)) selected_tab = text_box.getFocus().id; │ │107 - try box.children.put(allocator, text_box.getFocus().id, .{ │ │108 - .widget = .{ .text_box = text_box }, │ │109 - .rect = null, │ │110 - .min_size = .{ .width = name.len + 2, .height = null }, │ │111 - }); │ │112 - } │ │ 72 + // users tab │ │ 73 + { │ │ 74 + var text_box = try wgt.TextBox(ui.Widget).init(allocator, "users", .{ .border_style = .single, .rounded_corners = true, .wrap_kind = .none }); │ │ 75 + errdefer text_box.deinit(allocator); │ │ 76 + text_box.getFocus().focusable = true; │ │ 77 + text_box.getFocus().kind = .{ .custom = "ai:/users" }; │ │ 78 + try tab_ids.put(allocator, text_box.getFocus().id, {}); │ │ 79 + if (std.mem.eql(u8, "ai:/users", current_link)) selected_tab = text_box.getFocus().id; │ │ 80 + try box.children.put(allocator, text_box.getFocus().id, .{ │ │ 81 + .widget = .{ .text_box = text_box }, │ │ 82 + .rect = null, │ │ 83 + .min_size = .{ .width = "users".len + 2, .height = null }, │ │ 84 + }); │ │ 85 + } │ │ 86 + │ │ 87 + // repos tab │ │ 88 + { │ │ 89 + var text_box = try wgt.TextBox(ui.Widget).init(allocator, "repos", .{ .border_style = .single, .rounded_corners = true, .wrap_kind = .none }); │ │ 90 + errdefer text_box.deinit(allocator); │ │ 91 + text_box.getFocus().focusable = true; │ │ 92 + text_box.getFocus().kind = .{ .custom = "ai:/repos" }; │ │ 93 + try tab_ids.put(allocator, text_box.getFocus().id, {}); │ │ 94 + if (std.mem.eql(u8, "ai:/repos", current_link)) selected_tab = text_box.getFocus().id; │ │ 95 + try box.children.put(allocator, text_box.getFocus().id, .{ │ │ 96 + .widget = .{ .text_box = text_box }, │ │ 97 + .rect = null, │ │ 98 + .min_size = .{ .width = "repos".len + 2, .height = null }, │ │ 99 + }); │ │100 } │ │101 │ │102 + // spacer pushes settings + auth to the right │ │103 + { │ │104 + var spacer = try ui.Spacer.init(allocator); │ │105 + errdefer spacer.deinit(allocator); │ │106 + try box.children.put(allocator, spacer.getFocus().id, .{ │ │107 + .widget = .{ .spacer = spacer }, │ │108 + .rect = null, │ │109 + .min_size = null, │ │110 + }); │ │111 + } │ │112 + │ │113 + // settings tab. settings are account preferences, so it needs a login. │ │114 + if (session.data.user_id != null) { │ │115 + var text_box = try wgt.TextBox(ui.Widget).init(allocator, "settings", .{ .border_style = .single, .rounded_corners = true, .wrap_kind = .none }); │ │116 + errdefer text_box.deinit(allocator); │ │117 + text_box.getFocus().focusable = true; │ │118 + text_box.getFocus().kind = .{ .custom = "ai:/settings" }; │ │119 + try tab_ids.put(allocator, text_box.getFocus().id, {}); │ │120 + if (std.mem.eql(u8, "ai:/settings", current_link)) selected_tab = text_box.getFocus().id; │ │121 + try box.children.put(allocator, text_box.getFocus().id, .{ │ │122 + .widget = .{ .text_box = text_box }, │ │123 + .rect = null, │ │124 + .min_size = .{ .width = "settings".len + 2, .height = null }, │ │125 + }); │ │126 + } │ │127 + │ │128 + // auth tab (login / logout) │ │129 + { │ │130 + var auth_tab = try AuthTab.View.init(allocator, session); │ │131 + errdefer auth_tab.deinit(allocator); │ │132 + try tab_ids.put(allocator, auth_tab.getFocus().id, {}); │ │133 + if (std.mem.eql(u8, "ai:/auth", current_link)) selected_tab = auth_tab.getFocus().id; │ │134 + try box.children.put(allocator, auth_tab.getFocus().id, .{ │ │135 + .widget = .{ .auth_tab = auth_tab }, │ │136 + .rect = null, │ │137 + .min_size = .{ .width = auth_tab.minWidth(), .height = null }, │ │138 + }); │ │139 + } │ │140 + │ │141 // quit tab │ │142 if (session.is_terminal) { │ │143 var text_box = try wgt.TextBox(ui.Widget).init(allocator, ui.Quit.tab_label, .{ .border_style = .single, .rounded_corners = true, .wrap_kind = .none });│ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────╮ │168 for (self.box.children.keys(), self.box.children.values()) |id, *child| { │ │169 const tb: ?*wgt.TextBox(ui.Widget) = switch (child.widget) { │ │170 .text_box => |*x| x, │ │145 - .auth_tab => |*at| &at.text_box, │ │171 + .auth_tab => |*at| blk: { │ │172 + // the label tracks login state per frame, so the width must too│ │173 + child.min_size = .{ .width = at.minWidth(), .height = null }; │ │174 + break :blk &at.text_box; │ │175 + }, │ │176 else => null, │ │177 }; │ │178 if (tb) |t| { │ ╰─────────────────────────────────────────────────────────────────────────────────────────╯