╭──────────╮ │← previous│ ╰──────────╯ ╭ changed ──────────────╮ │src/ui/Repo/Commits.zig│ ╰───────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │565 const cut_short = commit.message_truncated and kind == .preview; │ │566 var tb = try messageBox(allocator, commit.message, if (cut_short) " click or press enter to see more " else ""); │ │567 errdefer tb.deinit(allocator); │ │568 - if (cut_short) tb.getFocus().kind = .{ .custom = try messageLink(self.session.page_arena, self.data.identity, commit.oid) };│ │568 + if (cut_short) tb.getFocus().kind = .{ .custom = try messageLink(self.session.page_arena, self.data.location, commit.oid) };│ │569 try box.children.put(allocator, tb.getFocus().id, .{ .widget = .{ .text_box = tb }, .rect = null, .min_size = null }); │ │570 } │ │571 │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │770 .enter => if (self.selectedCommitIndex() != null) │ │771 try self.focusDiff(root_focus) │ │772 else if (self.data.next_start) |next| { │ │773 - if (ui.RoutablePage.repoCommitsRoute(self.data.identity, .object, next, 0, "")) |route|│ │773 + if (self.data.location.commitsRoute(.object, next, 0, "")) |route| │ │774 try self.session.navigate(route); │ │775 }, │ │776 .arrow_right => try self.focusDiff(root_focus), │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │953 }; │ │954 │ │955 // the "a:" navigation link for the commits page walking from commit `oid` within │ │956 -// `identity`, windowing the selected commit's diff from hunk `start`, filtered │ │956 +// `location`, windowing the selected commit's diff from hunk `start`, filtered │ │957 // to `path` ("" = every file). │ │958 -fn commitsLink(page_arena: *std.heap.ArenaAllocator, identity: []const u8, oid: []const u8, start: usize, path: []const u8) ![]const u8 { │ │959 - const route = ui.RoutablePage.repoCommitsRoute(identity, .object, oid, start, path) orelse return error.RouteTooLong; │ │958 +fn commitsLink(page_arena: *std.heap.ArenaAllocator, location: ui.RoutablePage.RepoLocation, oid: []const u8, start: usize, path: []const u8) ![]const u8 {│ │959 + const route = location.commitsRoute(.object, oid, start, path) orelse return error.RouteTooLong; │ │960 const url = try route.toUrl(page_arena); │ │961 return std.fmt.allocPrint(page_arena.allocator(), "a:{s}", .{url}); │ │962 } │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │963 │ │964 // the "a:" link to the files tab at commit `oid` (an object ref), at its root │ │965 -// directory, within `identity` ("owner/name"). │ │966 -fn filesObjectLink(page_arena: *std.heap.ArenaAllocator, identity: []const u8, oid: []const u8) ![]const u8 { │ │967 - const route = ui.RoutablePage.repoFilesRoute(identity, .object, oid, "", 0) orelse return error.RouteTooLong; │ │965 +// directory, within `location`. │ │966 +fn filesObjectLink(page_arena: *std.heap.ArenaAllocator, location: ui.RoutablePage.RepoLocation, oid: []const u8) ![]const u8 {│ │967 + const route = location.filesRoute(.object, oid, "", 0) orelse return error.RouteTooLong; │ │968 const url = try route.toUrl(page_arena); │ │969 return std.fmt.allocPrint(page_arena.allocator(), "a:{s}", .{url}); │ │970 } │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │971 │ │972 // the in-page "ai:" anchor for selecting a commit with its current pane content │ │973 // and window. the href is only followed with js off. │ │974 -fn commitRowLink(page_arena: *std.heap.ArenaAllocator, identity: []const u8, commit: Commit, content: Content) ![]const u8 { │ │974 +fn commitRowLink(page_arena: *std.heap.ArenaAllocator, location: ui.RoutablePage.RepoLocation, commit: Commit, content: Content) ![]const u8 {│ │975 const route = (switch (content) { │ │976 - .message => ui.RoutablePage.repoCommitMessageRoute(identity, .object, commit.oid), │ │977 - .diff => |diff| ui.RoutablePage.repoCommitsRoute(identity, .object, commit.oid, commit.window_start, diff.path), │ │976 + .message => location.commitMessageRoute(.object, commit.oid), │ │977 + .diff => |diff| location.commitsRoute(.object, commit.oid, commit.window_start, diff.path), │ │978 }) orelse return error.RouteTooLong; │ │979 const url = try route.toUrl(page_arena); │ │980 return std.fmt.allocPrint(page_arena.allocator(), "ai:{s}", .{url}); │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │981 } │ │982 │ │983 // the "a:" link to the page showing `oid`'s message on its own. │ │984 -fn messageLink(page_arena: *std.heap.ArenaAllocator, identity: []const u8, oid: []const u8) ![]const u8 { │ │985 - const route = ui.RoutablePage.repoCommitMessageRoute(identity, .object, oid) orelse return error.RouteTooLong; │ │984 +fn messageLink(page_arena: *std.heap.ArenaAllocator, location: ui.RoutablePage.RepoLocation, oid: []const u8) ![]const u8 {│ │985 + const route = location.commitMessageRoute(.object, oid) orelse return error.RouteTooLong; │ │986 const url = try route.toUrl(page_arena); │ │987 return std.fmt.allocPrint(page_arena.allocator(), "a:{s}", .{url}); │ │988 } │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │1003 box: wgt.Box(ui.Widget), │ │1004 data: *const Header, │ │1005 │ │1006 - pub fn init(allocator: std.mem.Allocator, data: *const Header, session: *ui.Session, identity: []const u8) !Header.View { │ │1006 + pub fn init(allocator: std.mem.Allocator, data: *const Header, session: *ui.Session, location: ui.RoutablePage.RepoLocation) !Header.View {│ │1007 var box = try wgt.Box(ui.Widget).init(allocator, .{ .border_style = null, .direction = .horiz }); │ │1008 errdefer box.deinit(allocator); │ │1009 │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │1010 - if (!session.data.is_local and (session.data.git_http_port != null or session.data.git_ssh_port != null)) { │ │1011 - var clone_url = try ui.widget.CopyableText.initClone(allocator, session, identity); │ │1012 - errdefer clone_url.deinit(allocator); │ │1013 - const min_width = clone_url.minWidth(); │ │1014 - box.getFocus().child_id = clone_url.getFocus().id; │ │1015 - try box.children.put(allocator, clone_url.getFocus().id, .{ .widget = .{ .copyable_text = clone_url }, .rect = null, .min_size = .{ .width = min_width, .height = 3 }, .max_size = .{ .width = min_width, .height = 3 } }); │ │1010 + if (!session.data.is_local) { │ │1011 + if (try ui.widget.CopyableText.initClone(allocator, session, location)) |value| { │ │1012 + var clone_url = value; │ │1013 + errdefer clone_url.deinit(allocator); │ │1014 + const min_width = clone_url.minWidth(); │ │1015 + box.getFocus().child_id = clone_url.getFocus().id; │ │1016 + try box.children.put(allocator, clone_url.getFocus().id, .{ .widget = .{ .copyable_text = clone_url }, .rect = null, .min_size = .{ .width = min_width, .height = 3 }, .max_size = .{ .width = min_width, .height = 3 } });│ │1017 + } │ │1018 } │ │1019 │ │1020 var spacer = try ui.widget.Spacer.init(allocator); │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭ changed ────────────╮ │src/ui/Repo/Files.zig│ ╰─────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────╮ │40 loaded: bool = false, │ │41 }; │ │42 │ │43 -// "owner/name", so the view can build /repo/owner/name/files/... links. │ │44 -identity: []const u8, │ │43 +// where links and clone commands for this repository are rooted. │ │44 +location: ui.RoutablePage.RepoLocation, │ │45 // the resolved ref this listing is read at (the default branch when the route│ │46 // didn't name one), so the view's directory links stay pinned to it. │ │47 ref_or_oid: ui.RoutablePage.RefOrOid, │ ╰──────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────╮ │69 repo: *rp.Repo(repo_kind, repo_opts), │ │70 io: std.Io, │ │71 gpa: std.mem.Allocator, │ │72 - identity: []const u8, │ │72 + location: ui.RoutablePage.RepoLocation, │ │73 requested_ref_or_oid: ?ui.RoutablePage.RefOrOid,│ │74 requested_value: []const u8, │ │75 path: []const u8, │ ╰────────────────────────────────────────────────────────╯ ╭──────╮ │next →│ ╰──────╯