╭──────────╮ │← previous│ ╰──────────╯ ╭ changed ─────────╮ │src/ui/AuthTab.zig│ ╰──────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │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 } │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭ changed ──────╮ │src/ui/Home.zig│ ╰───────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────╮ │57 │ │58 // build the header first so we can grab the users-tab focus id and │ │59 // hand it to login/logout │ │60 - var users_tab_id: usize = undefined; │ │60 { │ │61 var header_view = try Header.View.init(allocator, &data.header, session);│ │62 errdefer header_view.deinit(allocator); │ ╰─────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │64 - users_tab_id = header_view.tab_ids.keys()[0]; │ │63 try box.children.put(allocator, header_view.getFocus().id, .{ .widget = .{ .home_header = header_view }, .rect = null, .min_size = null });│ │64 } │ │65 │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │86 } │ │87 │ │88 { │ │91 - var auth_view = try Auth.View.init(allocator, &data.auth, session, users_tab_id); │ │89 + var auth_view = try Auth.View.init(allocator, &data.auth, session); │ │90 errdefer auth_view.deinit(allocator); │ │91 try stack.children.put(allocator, auth_view.getFocus().id, .{ .home_auth = auth_view });│ │92 } │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭ changed ─────────────╮ │src/ui/Home/Header.zig│ ╰──────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────╮ │93 try box.children.put(allocator, auth_tab.getFocus().id, .{ │ │94 .widget = .{ .auth_tab = auth_tab }, │ │95 .rect = null, │ │96 - .min_size = .{ .width = AuthTab.min_width, .height = null }, │ │96 + .min_size = .{ .width = auth_tab.minWidth(), .height = null },│ │97 }); │ │98 } │ │99 // other tabs │ ╰──────────────────────────────────────────────────────────────────────────────────────╯ ╭ changed ──────╮ │src/ui/Repo.zig│ ╰───────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │52 │ │53 // every repo route stores its identity as "owner/name" (or elides it in │ │54 // local mode); files and commits carry their remaining fields directly. │ │55 - const name_str: []const u8 = switch (route) { │ │56 - .repo_files => |f| f.name.slice(), │ │57 - .repo_commits => |c| c.name.slice(), │ │58 - .repo_settings, .repo_auth => |n| n.slice(), │ │59 - .repo_refs => |r| r.name.slice(), │ │60 - .repo_issues => |i| i.name.slice(), │ │61 - else => return error.UnexpectedRoute, │ │62 - }; │ │55 + const name_str = route.repoIdentity() orelse return error.UnexpectedRoute; │ │56 const repo_identity = ui.RoutablePage.RepoIdentity.parse(name_str) orelse return error.NotFound;│ │57 // the files and commits tabs share one ref/oid: whichever the incoming route │ │58 // names (it rides on the route's target tab), or the default branch when │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────╮ │236 │ │237 // build the header first so we can grab the files-tab id for the auth │ │238 // view (it focuses there after login). │ │246 - var files_tab_id: usize = undefined; │ │239 { │ │240 var header_view = try Header.View.init(allocator, &data.header, session);│ │241 errdefer header_view.deinit(allocator); │ ╰──────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │250 - files_tab_id = header_view.tab_ids.keys()[0]; │ │242 try box.children.put(allocator, header_view.getFocus().id, .{ .widget = .{ .repo_header = header_view }, .rect = null, .min_size = null });│ │243 } │ │244 │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │283 // the header has no auth tab in local mode, so keep the stack's │ │284 // children 1:1 with the tabs by skipping the auth view too. │ │285 if (!session.data.is_local) { │ │295 - var auth_view = try Auth.View.init(allocator, &data.auth, session, files_tab_id); │ │286 + var auth_view = try Auth.View.init(allocator, &data.auth, session); │ │287 errdefer auth_view.deinit(allocator); │ │288 try stack.children.put(allocator, auth_view.getFocus().id, .{ .home_auth = auth_view });│ │289 } │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────╮ │next →│ ╰──────╯