╭ changed ─╮ │src/ui.zig│ ╰──────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │11 const Key = xitui.input.Key; │ │12 const Grid = xitui.grid.Grid; │ │13 const Focus = xitui.focus.Focus; │ │14 -const ansi_arts: []const []const u8 = if (builtin.cpu.arch == .wasm32) &.{} else @import("ansi_art").art;│ │14 +// the random page art and the not-found page's fixed art. wasm receives its art │ │15 +// from the server, so it links none. │ │16 +const ansi_art = if (builtin.cpu.arch == .wasm32) struct { │ │17 + const art: []const []const u8 = &.{}; │ │18 + const not_found: []const u8 = ""; │ │19 +} else @import("ansi_art"); │ │20 const evt = @import("./event.zig"); │ │21 const inp = @import("./ui/input.zig"); │ │22 │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────╮ │28 pub const SubTitle = @import("./ui/SubTitle.zig"); │ │29 pub const Quit = @import("./ui/Quit.zig"); │ │30 pub const Unauthorized = @import("./ui/Unauthorized.zig");│ │31 +pub const NotFound = @import("./ui/NotFound.zig"); │ │32 pub const NewRepo = @import("./ui/NewRepo.zig"); │ │33 pub const widget = @import("./ui/widget.zig"); │ │34 pub const Widget = widget.Widget; │ ╰──────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────╮ │65 user, │ │66 repo, │ │67 fork, │ │68 + not_found, │ │69 }; │ │70 │ │71 pub const Page = union(PageKind) {│ ╰──────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────╮ │73 user: User, │ │74 repo: Repo, │ │75 fork: Fork, │ │76 + not_found, │ │77 │ │78 pub fn init(arena: *std.heap.ArenaAllocator, session: *Session, route: RoutablePage) !Page {│ │79 // the repo page can build without a moment in local mode; the home and │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │100 .fork_patch, .fork_diff, .fork_files, .fork_commits, .fork_new_repo, .fork_auth => .{ .fork = try Fork.init(arena, session, route) },│ │101 else => return error.UnexpectedRoute, │ │102 }, │ │103 + .not_found => .not_found, │ │104 }; │ │105 } │ │106 }; │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────╮ │191 fork_commits: ForkCommitsRoute, │ │192 fork_new_repo: ForkRoute, │ │193 fork_auth: ForkRoute, │ │194 + not_found, │ │195 │ │196 pub const default: RoutablePage = .home_about;│ │197 │ ╰───────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────╮ │1046 }, │ │1047 .home_new_repo => "/new-repo", │ │1048 .home_auth => "/auth", │ │1049 + .not_found => "/not-found", │ │1050 .user_repos => |u| blk: { │ │1051 var out: std.Io.Writer.Allocating = .init(arena.allocator()); │ │1052 try out.writer.print(user_segment ++ "{s}/repos", .{u.name.slice()});│ ╰───────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────╮ │1430 const f = self.forkRoute() orelse break :blk self; │ │1431 break :blk forkPatchRoute(f.name.slice(), f.id.slice()) orelse self;│ │1432 }, │ │1433 + .not_found => self, │ │1434 }; │ │1435 } │ │1436 │ ╰──────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │1440 .user_repos, .user_forks, .user_new_repo, .user_auth => .user, │ │1441 .repo_files, .repo_commits, .repo_diff, .repo_refs, .repo_issues, .repo_patches, .repo_discussions, .repo_events, .repo_undo, .repo_new_repo, .repo_auth => .repo,│ │1442 .fork_patch, .fork_diff, .fork_files, .fork_commits, .fork_new_repo, .fork_auth => .fork, │ │1443 + .not_found => .not_found, │ │1444 }; │ │1445 } │ │1446 │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────╮ │2736 allocator.destroy(arena); │ │2737 } │ │2738 │ │2726 - session.page_arena = arena; │ │2727 - const route = session.data.current_page; │ │2728 - │ │2729 - const page = try arena.allocator().create(Page); │ │2730 - page.* = try Page.init(arena, session, route); │ │2739 return .{ │ │2732 - .root = try initRoot(allocator, page, session), │ │2740 + .root = try initCurrentRoot(allocator, arena, session),│ │2741 .arena = arena, │ │2742 .user_id = session.userId(), │ │2743 .history = .empty, │ ╰─────────────────────────────────────────────────────────────────────────╯ ╭──────╮ │next →│ ╰──────╯