╭ changed ───────────────────╮ │src/ui/UserNotifications.zig│ ╰────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │73 try session.navigate(session.data.current_page.pageRoot()); │ │74 } │ │75 │ │76 +const repos_label = "view repos"; │ │77 const logout_label = "logout"; │ │78 │ │79 // the notifications and user settings sub tabs over their content, with the logout button across from them│ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────╮ │81 box: wgt.Box(ui.Widget), │ │82 data: *const Self, │ │83 session: *ui.Session, │ │83 - // the sub tabs' ids then the logout button's, in header order │ │84 - control_ids: [3]usize, │ │84 + // the sub tabs' ids then the repos and logout buttons', in header order│ │85 + control_ids: [4]usize, │ │86 // the sub tab whose content shows │ │87 view_index: usize, │ │88 │ ╰────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │89 const header_index = 0; │ │90 const content_index = 1; │ │90 - const logout_index = 2; │ │91 + // the sub tabs come first in `control_ids` │ │92 + const tab_count = 2; │ │93 + const repos_index = 2; │ │94 + const logout_index = 3; │ │95 │ │96 // `user_route` is the page's user tab route │ │97 pub fn init(allocator: std.mem.Allocator, data: *const Self, session: *ui.Session, user_route: ui.RoutablePage) !View {│ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │ 98 var box = try wgt.Box(ui.Widget).init(allocator, .{ .border = null, .direction = .vert }); │ │ 99 errdefer box.deinit(allocator); │ │100 │ │ 97 - var control_ids: [3]usize = undefined; │ │101 + var control_ids: [4]usize = undefined; │ │102 const settings_route = user_route.withUserTab(.{ .view = .settings }); │ │103 { │ │104 var header = try wgt.Box(ui.Widget).init(allocator, .{ .border = null, .direction = .horiz });│ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │113 control_ids[index] = tab.getFocus().id; │ │114 try header.children.put(allocator, tab.getFocus().id, .{ .widget = .{ .text_box = tab }, .rect = null, .min_size = .{ .width = label.len + 2, .height = null } });│ │115 } │ │112 - // the spacer pushes the logout button to the right edge │ │116 + // the spacer pushes the buttons to the right edge │ │117 { │ │118 var spacer = try ui.widget.Spacer.init(allocator); │ │119 errdefer spacer.deinit(allocator); │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │120 try header.children.put(allocator, spacer.getFocus().id, .{ .widget = .{ .spacer = spacer }, .rect = null, .min_size = null }); │ │121 } │ │122 { │ │123 + var button = try wgt.TextBox.init(allocator, repos_label, .{ .border = .single, .round_corners = true, .wrap_kind = .none }); │ │124 + errdefer button.deinit(allocator); │ │125 + button.getFocus().mode = .all; │ │126 + button.getFocus().kind = .{ .custom = try ui.userLink(session.page_arena, session.data.user_name orelse unreachable) }; │ │127 + control_ids[repos_index] = button.getFocus().id; │ │128 + try header.children.put(allocator, button.getFocus().id, .{ .widget = .{ .text_box = button }, .rect = null, .min_size = .{ .width = repos_label.len + 2, .height = 3 } });│ │129 + } │ │130 + { │ │131 // the form kind makes the web renderer post the button to the logout route │ │132 header.getFocus().kind = .{ .custom = try session.page_arena.allocator().print("form:{s}/logout", .{try settings_route.toUrl(session.page_arena)}) }; │ │133 var button = try wgt.TextBox.init(allocator, logout_label, .{ .border = .single, .round_corners = true, .wrap_kind = .none }); │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │210 self.clearGrid(); │ │211 const header = self.headerBox(); │ │212 // focusing a sub tab shows its content, while the logout button leaves it │ │201 - if (header.getFocus().child_id) |child_id| if (std.mem.indexOfScalar(usize, self.control_ids[0..logout_index], child_id)) |index| {│ │213 + if (header.getFocus().child_id) |child_id| if (std.mem.indexOfScalar(usize, self.control_ids[0..tab_count], child_id)) |index| { │ │214 self.view_index = index; │ │215 }; │ │204 - for (self.control_ids[0..logout_index], 0..) |id, index| { │ │216 + for (self.control_ids[0..tab_count], 0..) |id, index| { │ │217 const tab = header.children.getPtr(id) orelse unreachable; │ │218 ui.widget.markSelected(&tab.widget.text_box, index == self.view_index); │ │219 } │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯