╭ changed ──────╮ │src/ui/Fork.zig│ ╰───────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │147 var box = try wgt.Box(ui.Widget).init(allocator, .{ .border_style = null, .direction = .vert }); │ │148 errdefer box.deinit(allocator); │ │149 { │ │150 - var header = try Header.View.init(allocator, &data.header, session); │ │150 + var header = try Header.View.init(allocator, &data.header, data.commits.commit_count, session); │ │151 errdefer header.deinit(allocator); │ │152 try box.children.put(allocator, header.getFocus().id, .{ .widget = .{ .fork_header = header }, .rect = null, .min_size = null });│ │153 } │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭ changed ─────────────╮ │src/ui/Fork/Header.zig│ ╰──────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │36 tabs_id: usize, │ │37 first_group_width: usize, │ │38 │ │39 - pub fn init(allocator: std.mem.Allocator, data: *const Self, session: *ui.Session) !View { │ │39 + pub fn init(allocator: std.mem.Allocator, data: *const Self, commit_count: ?u64, session: *ui.Session) !View { │ │40 var box = try wgt.Box(ui.Widget).init(allocator, .{ .border_style = .hidden, .rounded_corners = true, .direction = .horiz });│ │41 errdefer box.deinit(allocator); │ │42 │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │53 │ │54 const aa = session.page_arena.allocator(); │ │55 const identity = try std.fmt.allocPrint(aa, "{s}/{s}", .{ data.owner_name, data.name }); │ │56 + const commits_label = if (commit_count) |count| try std.fmt.allocPrint(aa, "commits ({d})", .{count}) else "commits";│ │57 var first_group_width = try data.title.width(); │ │58 │ │59 // the user's name links to their page. │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │92 ui.RoutablePage.forkCommitsRoute(identity, data.id, data.oid, 0, "") orelse return error.RouteTooLong,│ │93 }; │ │94 const tags = [_]std.meta.Tag(ui.RoutablePage){ .fork_patch, .fork_files, .fork_commits }; │ │94 - const labels = [_][]const u8{ "patch", "files", "commits" }; │ │95 + const labels = [_][]const u8{ "patch", "files", commits_label }; │ │96 var selected_tab: ?usize = null; │ │97 │ │98 for (routes, tags, labels) |route, tag, label| { │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭ changed ──────╮ │src/ui/Repo.zig│ ╰───────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │293 // build the header first so we can grab the files-tab id for the auth │ │294 // view (it focuses there after login). │ │295 { │ │296 - var header_view = try Header.View.init(allocator, &data.header, session); │ │296 + var header_view = try Header.View.init(allocator, &data.header, data.commits.commit_count, session); │ │297 errdefer header_view.deinit(allocator); │ │298 try box.children.put(allocator, header_view.getFocus().id, .{ .widget = .{ .repo_header = header_view }, .rect = null, .min_size = null });│ │299 } │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭ changed ──────────────╮ │src/ui/Repo/Commits.zig│ ╰───────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────╮ │50 // didn't name one), so the page can canonicalize its url to it. │ │51 ref_or_oid: ui.RoutablePage.RefOrOid, │ │52 ref_or_oid_value: []const u8, │ │53 +commit_count: ?u64 = null, │ │54 commits: []const Commit, │ │55 // the first oid of the next page, or null when this is the last page.│ │56 next_start: ?[]const u8, │ ╰──────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │171 } │ │172 } │ │173 │ │174 + const commit_count: ?u64 = switch (repo_kind) { │ │175 + .git => null, │ │176 + .xit => blk: { │ │177 + const head_count = repo.commitCount(io, gpa, .{ .oid = &resolved.oid }) catch break :blk null;│ │178 + const base_oid = base_oid_maybe orelse break :blk head_count; │ │179 + const base_count = repo.commitCount(io, gpa, .{ .oid = &base_oid }) catch break :blk null; │ │180 + break :blk if (head_count >= base_count) head_count - base_count else null; │ │181 + }, │ │182 + }; │ │183 + │ │184 return .{ │ │185 .location = try location.dupe(aa), │ │186 .ref_or_oid = resolved.ref_or_oid, │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────╮ │187 .ref_or_oid_value = resolved.value, │ │188 + .commit_count = commit_count, │ │189 .commits = try aa.dupe(Commit, buf[0..count]),│ │190 .next_start = next_start, │ │191 .content = try pageContent(aa, content), │ ╰───────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────╮ │199 .location = try location.dupe(aa), │ │200 .ref_or_oid = ref_or_oid, │ │201 .ref_or_oid_value = try aa.dupe(u8, value),│ │202 + .commit_count = null, │ │203 .commits = &.{}, │ │204 .next_start = null, │ │205 .content = try pageContent(aa, content), │ ╰────────────────────────────────────────────────────────╯ ╭ changed ─────────────╮ │src/ui/Repo/Header.zig│ ╰──────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │49 tabs_id: usize, │ │50 first_group_width: usize, │ │51 │ │52 - pub fn init(allocator: std.mem.Allocator, data: *const Self, session: *ui.Session) !View { │ │52 + pub fn init(allocator: std.mem.Allocator, data: *const Self, commit_count: ?u64, session: *ui.Session) !View { │ │53 var box = try wgt.Box(ui.Widget).init(allocator, .{ .border_style = .hidden, .rounded_corners = true, .direction = .horiz });│ │54 errdefer box.deinit(allocator); │ │55 │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────╮ │next →│ ╰──────╯