╭──────────╮ │← previous│ ╰──────────╯ ╭ changed ─╮ │src/ui.zig│ ╰──────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │502 const a_prefix = "a:"; │ │503 if (!std.mem.startsWith(u8, custom, a_prefix)) return null; │ │504 const route = RoutablePage.fromUrl(custom[a_prefix.len..]) orelse return null; │ │453 - if (route.parent() == current.parent()) return null; │ │454 - return route; │ │505 + // a link to a different parent page always navigates; within the repo page, │ │506 + // a files-directory link navigates while settings/auth tab links stay │ │507 + // in-page (header-handled). │ │508 + if (route.parent() != current.parent() or RoutablePage.repoDirChanged(route, current)) return route;│ │509 + return null; │ │510 } │ │511 │ │512 // native-TUI navigation │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────╮ │528 const max_history: usize = 16; │ │529 │ │530 pub fn init(allocator: std.mem.Allocator, session: *Session) !Nav {│ │476 - const moment = session.haxy_moment orelse unreachable; │ │531 const arena = try allocator.create(std.heap.ArenaAllocator); │ │532 arena.* = std.heap.ArenaAllocator.init(allocator); │ │533 errdefer { │ ╰────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────╮ │539 const route = session.data.current_page; │ │540 │ │541 const page = try arena.allocator().create(Page); │ │488 - page.* = try Page.init(arena, moment, route); │ │542 + page.* = try Page.init(arena, session, route); │ │543 return .{ │ │544 .root = try initRoot(allocator, page, session),│ │545 .route = route, │ ╰────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────╮ │606 return; │ │607 } │ │608 │ │555 - if (session.data.current_page.parent() != self.route.parent()) { │ │556 - const moment = session.haxy_moment orelse return; │ │609 + // forward navigation: a different parent page, or — within the repo page │ │610 + // — a different files directory (each directory is its own page, while │ │611 + // settings/auth tab switches stay in-page and are not pushed here). │ │612 + const cp = session.data.current_page; │ │613 + if (cp.parent() != self.route.parent() or RoutablePage.repoDirChanged(cp, self.route)) {│ │614 + if (session.haxy_moment == null) return; │ │615 const arena = try allocator.create(std.heap.ArenaAllocator); │ │616 arena.* = std.heap.ArenaAllocator.init(allocator); │ │617 errdefer freeArena(allocator, arena); │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │620 const route = session.data.current_page; │ │621 │ │622 const page = try arena.allocator().create(Page); │ │565 - page.* = try Page.init(arena, moment, route); │ │623 + page.* = try Page.init(arena, session, route); │ │624 const new_root = try initRoot(allocator, page, session); │ │625 │ │626 try self.history.append(allocator, .{ .root = self.root, .route = self.route, .arena = self.arena });│ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────╮ │681 home_header: Home.Header.View, │ │682 user_header: User.Header.View, │ │683 repo_header: Repo.Header.View, │ │684 + repo_files: Repo.Files.View, │ │685 home_users: Home.Users.View, │ │686 home_repos: Home.Repos.View, │ │687 auth_tab: Home.Header.AuthTab.View,│ ╰────────────────────────────────────────────╯ ╭ changed ──────╮ │src/ui/Repo.zig│ ╰───────────────╯ ╭────────────────────────────────────────────────────╮ │10 const Focus = xitui.focus.Focus; │ │11 │ │12 pub const Header = @import("./Repo/Header.zig");│ │13 +pub const Files = @import("./Repo/Files.zig"); │ │14 pub const Settings = @import("./Settings.zig"); │ │15 pub const Auth = @import("./Auth.zig"); │ │16 pub const Quit = @import("./Quit.zig"); │ ╰────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────╮ │17 + │ │18 +const Array = ui.RoutablePage.Array(ui.RoutablePage.repo_route_max_len);│ │19 │ │20 header: Header, │ │21 repo: evt.Repo, │ ╰────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────╮ │22 +files: Files, │ │23 settings: Settings,│ │24 auth: Auth, │ │25 quit: Quit, │ ╰───────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────╮ │22 -route_name: ui.RoutablePage.Array(ui.RoutablePage.repo_name_max_len), │ │26 +// the full files route this page renders ("owner/name" or "owner/name/files/<dir>"),│ │27 +// mirrored into current_page when the files tab is selected. │ │28 +route_name: Array, │ │29 +// "owner/name" alone, mirrored when the settings/auth tab is selected. │ │30 +identity: Array, │ │31 │ │32 const Self = @This(); │ │33 │ ╰─────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────╮ │next →│ ╰──────╯