╭──────────╮ │← previous│ ╰──────────╯ ╭ changed ─────────────╮ │src/ui/Repo/Header.zig│ ╰──────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────╮ │296 errdefer auth_tab.deinit(allocator); │ │297 auth_tab.text_box.getFocus().kind = .{ .custom = auth_link }; │ │298 try tab_ids.put(allocator, auth_tab.getFocus().id, {}); │ │308 - if (std.mem.eql(u8, auth_link, current_link)) selected_tab = auth_tab.getFocus().id;│ │299 + if (current_tag == .repo_auth) selected_tab = auth_tab.getFocus().id; │ │300 try tabs_box.children.put(allocator, auth_tab.getFocus().id, .{ │ │301 .widget = .{ .auth_tab = auth_tab }, │ │302 .rect = null, │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭ changed ─────────────╮ │src/ui/Repo/Issues.zig│ ╰──────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────╮ │342 var header = try Header.init(allocator); │ │343 errdefer header.deinit(allocator); │ │344 const aa = session.page_arena.allocator(); │ │345 + const selected_index = View.viewIndex(data.view); │ │346 + const page_selected = std.meta.activeTag(session.data.current_page) == .repo_issues;│ │347 │ │348 // a list tab per status, labeled with its listing's issue count │ │349 for ([_]evt.Issue.Status{ .open, .closed }, 0..) |status, index| { │ ╰─────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │350 const route = ui.RoutablePage.repoIssuesRoute(data.identity, status, data.tag, "") orelse return error.RouteTooLong;│ │349 - const link = try std.fmt.allocPrint(aa, "ai:{s}", .{try route.toUrl(session.page_arena)}); │ │351 + const link = try ui.inPageTabLink(session, route, page_selected and selected_index == index); │ │352 var label_buf: [64]u8 = undefined; │ │353 const label = try std.fmt.bufPrint(&label_buf, "{s} ({d})", .{ @tagName(status), data.window(status).count }); │ │354 try header.addTab(allocator, label, link, index); │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │357 // tags tab, labeled with the active tag filter │ │358 { │ │359 const tags_route = ui.RoutablePage.repoThreadTagsRoute(.issue, data.identity, data.tag) orelse return error.RouteTooLong;│ │358 - const tags_link = try std.fmt.allocPrint(aa, "ai:{s}", .{try tags_route.toUrl(session.page_arena)}); │ │360 + const tags_link = try ui.inPageTabLink(session, tags_route, page_selected and selected_index == View.viewIndex(.tags)); │ │361 const label = if (data.tag.len == 0) "tags" else blk: { │ │362 const decoded = std.Uri.percentDecodeInPlace(try aa.dupe(u8, data.tag)); │ │363 break :blk try std.fmt.allocPrint(aa, "tags ({s})", .{decoded}); │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │375 .resolve => ui.RoutablePage.repoIssuesResolveRoute(data.identity, data.selected_id, data.theirs_picks) orelse return error.RouteTooLong,│ │376 else => ui.RoutablePage.repoThreadNewRoute(.issue, data.identity) orelse return error.RouteTooLong, │ │377 }; │ │376 - const link = try std.fmt.allocPrint(aa, "ai:{s}", .{try route.toUrl(session.page_arena)}); │ │378 + const link = try ui.inPageTabLink(session, route, page_selected and selected_index == View.viewIndex(.new)); │ │379 const label: []const u8 = switch (data.view) { │ │380 .edit => "edit", │ │381 .new_comment => "reply", │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │390 // conflicts tab, labeled with the conflict count │ │391 if (data.conflicts.count > 0) { │ │392 const route = ui.RoutablePage.repoIssuesConflictsRoute(data.identity, "") orelse return error.RouteTooLong; │ │391 - const link = try std.fmt.allocPrint(aa, "ai:{s}", .{try route.toUrl(session.page_arena)}); │ │393 + const link = try ui.inPageTabLink(session, route, page_selected and selected_index == View.viewIndex(.conflicts));│ │394 var label_buf: [64]u8 = undefined; │ │395 const label = try std.fmt.bufPrint(&label_buf, "conflicts ({d})", .{data.conflicts.count}); │ │396 try header.addTab(allocator, label, link, View.viewIndex(.conflicts)); │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭ changed ──────────────╮ │src/ui/Repo/Patches.zig│ ╰───────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────╮ │531 var header = try Header.init(allocator); │ │532 errdefer header.deinit(allocator); │ │533 const aa = session.page_arena.allocator(); │ │534 + const selected_index = View.viewIndex(data.view); │ │535 + const page_selected = std.meta.activeTag(session.data.current_page) == .repo_patches;│ │536 │ │537 // a list tab per status, labeled with its listing's patch count │ │538 for ([_]evt.Patch.Status{ .open, .closed, .merged }, 0..) |status, index| { │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │539 const route = ui.RoutablePage.repoPatchesRoute(data.identity, status, data.tag, "") orelse return error.RouteTooLong;│ │538 - const link = try std.fmt.allocPrint(aa, "ai:{s}", .{try route.toUrl(session.page_arena)}); │ │540 + const link = try ui.inPageTabLink(session, route, page_selected and selected_index == index); │ │541 var label_buf: [64]u8 = undefined; │ │542 const label = try std.fmt.bufPrint(&label_buf, "{s} ({d})", .{ @tagName(status), data.window(status).count }); │ │543 try header.addTab(allocator, label, link, index); │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │546 // tags tab, labeled with the active tag filter │ │547 { │ │548 const tags_route = ui.RoutablePage.repoThreadTagsRoute(.patch, data.identity, data.tag) orelse return error.RouteTooLong;│ │547 - const tags_link = try std.fmt.allocPrint(aa, "ai:{s}", .{try tags_route.toUrl(session.page_arena)}); │ │549 + const tags_link = try ui.inPageTabLink(session, tags_route, page_selected and selected_index == View.viewIndex(.tags)); │ │550 const label = if (data.tag.len == 0) "tags" else blk: { │ │551 const decoded = std.Uri.percentDecodeInPlace(try aa.dupe(u8, data.tag)); │ │552 break :blk try std.fmt.allocPrint(aa, "tags ({s})", .{decoded}); │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │564 .resolve => ui.RoutablePage.repoPatchesResolveRoute(data.identity, data.selected_id, data.theirs_picks) orelse return error.RouteTooLong,│ │565 else => ui.RoutablePage.repoThreadNewRoute(.patch, data.identity) orelse return error.RouteTooLong, │ │566 }; │ │565 - const link = try std.fmt.allocPrint(aa, "ai:{s}", .{try route.toUrl(session.page_arena)}); │ │567 + const link = try ui.inPageTabLink(session, route, page_selected and selected_index == View.viewIndex(.new)); │ │568 const label: []const u8 = switch (data.view) { │ │569 .edit => "edit", │ │570 .new_comment => "reply", │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────╮ │next →│ ╰──────╯