╭ changed ──────╮ │src/ui/Repo.zig│ ╰───────────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │59 const rf = ui.RoutablePage.RepoFiles.parse(name_str) orelse return error.NotFound; │ │60 const tag = std.meta.activeTag(route); │ │61 │ │62 - // page state lives in the route only for the tab it targets; the other tabs │ │63 - // open at their root/first page. a null ref kind means the files tab opens at │ │64 - // the default branch (Files.init resolves it). │ │65 - const files_ref_kind = if (tag == .repo) rf.ref_kind else null; │ │66 - const files_ref_value = if (tag == .repo) rf.ref_value else ""; │ │67 - const files_dir = if (tag == .repo) rf.dir else ""; │ │68 - // a null commits ref means the commits tab opens at the default branch │ │69 - // (Commits.init resolves it). │ │62 + // the files and commits tabs share one ref/oid: whichever the incoming route │ │63 + // names (it rides on the route's target tab), or the default branch when │ │64 + // neither tab is targeted. building both views at it keeps switching tabs │ │65 + // (even by key, without a reload) on the same ref. a null ref means the │ │66 + // default branch (Files/Commits.init resolve it). the directory and the diff │ │67 + // window only apply to their own tab. │ │68 const commits_ref = if (tag == .repo_commits) ui.RoutablePage.repoCommitsRef(name_str) else ui.RoutablePage.CommitsRef{ .ref_or_oid = null, .value = "" };│ │69 + const requested_ref_or_oid: ?ui.RoutablePage.RefOrOid = switch (tag) { │ │70 + .repo => rf.ref_kind, │ │71 + .repo_commits => commits_ref.ref_or_oid, │ │72 + else => null, │ │73 + }; │ │74 + const requested_ref_value: []const u8 = switch (tag) { │ │75 + .repo => rf.ref_value, │ │76 + .repo_commits => commits_ref.value, │ │77 + else => "", │ │78 + }; │ │79 + const files_dir = if (tag == .repo) rf.dir else ""; │ │80 // how many diff hunks the commits view's selected commit shows ("load more"). │ │81 const commits_after: usize = switch (route) { │ │82 .repo_commits => |c| c.after, │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │100 // of the repo title. │ │101 const owner = (try evt.User.readById(DB, hash_kind, haxy_moment, arena, repo.user_id)) orelse return error.NotFound; │ │102 │ │ 94 - // build files and commits first so their resolved refs (the default branch │ │103 + // build files and commits first so their resolved ref (the default branch │ │104 // when the route named none) can canonicalize each tab's mirror url to the │ │ 96 - // explicit ref it's viewing rather than leaving it bare. │ │ 97 - const files = try Files.init(arena, session, &found.event_id, rf.identity, files_ref_kind, files_ref_value, files_dir); │ │ 98 - const commits = try Commits.init(arena, session, &found.event_id, rf.identity, commits_ref.ref_or_oid, commits_ref.value, commits_after);│ │105 + // explicit ref it's viewing rather than leaving it bare. both resolve the │ │106 + // same requested ref, so they end up viewing the same one. │ │107 + const files = try Files.init(arena, session, &found.event_id, rf.identity, requested_ref_or_oid, requested_ref_value, files_dir); │ │108 + const commits = try Commits.init(arena, session, &found.event_id, rf.identity, requested_ref_or_oid, requested_ref_value, commits_after);│ │109 │ │110 // each tab mirror carries this page's route for that tab; tabs not targeted │ │111 // by the incoming route fall back to their root/first-page route. │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │113 const commits_route_name = (ui.RoutablePage.repoCommitsRoute(rf.identity, commits.ref_or_oid, commits.ref_or_oid_value, commits_after) orelse return error.NotFound).repo_commits.name;│ │114 │ │115 return .{ │ │106 - .header = try Header.init(arena, repo.name, owner.name), │ │116 + // files and commits resolve the same ref, so either's serves the header, │ │117 + // which points both tabs at it. │ │118 + .header = try Header.init(arena, repo.name, owner.name, files.ref_or_oid, files.ref_or_oid_value), │ │119 .repo = repo, │ │120 .files = files, │ │121 .commits = commits, │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯