╭ changed ─╮ │src/ui.zig│ ╰──────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭──────────╮ │← previous│ ╰──────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │2752 freeArena(allocator, entry.arena); │ │2753 } │ │2754 self.history.deinit(allocator); │ │2755 + } │ │2756 + │ │2757 + // rebuild the current page in place from a current moment │ │2758 + fn rebuild(self: *Nav, allocator: std.mem.Allocator, session: *Session) !void { │ │2759 + if (session.haxy_moment == null and session.local == null) return; │ │2760 + const arena = try allocator.create(std.heap.ArenaAllocator); │ │2761 + arena.* = std.heap.ArenaAllocator.init(allocator); │ │2762 + errdefer freeArena(allocator, arena); │ │2763 + │ │2764 + const new_root = try initCurrentRoot(allocator, arena, session); │ │2765 + │ │2766 + self.root.deinit(allocator); │ │2767 + freeArena(allocator, self.arena); │ │2768 + self.root = new_root; │ │2769 + self.arena = arena; │ │2770 + self.user_id = session.userId(); │ │2771 } │ │2772 │ │2773 + // build the current page's root in `arena`, or the not-found page's when │ │2774 + // the route names nothing │ │2775 + fn initCurrentRoot(allocator: std.mem.Allocator, arena: *std.heap.ArenaAllocator, session: *Session) !Widget {│ │2776 + session.page_arena = arena; │ │2777 + const page = try arena.allocator().create(Page); │ │2778 + page.* = Page.init(arena, session, session.data.current_page) catch |err| switch (err) { │ │2779 + error.NotFound => blk: { │ │2780 + session.data.current_page = .not_found; │ │2781 + break :blk .not_found; │ │2782 + }, │ │2783 + else => |e| return e, │ │2784 + }; │ │2785 + return initRoot(allocator, page, session); │ │2786 + } │ │2787 + │ │2788 fn freeArena(allocator: std.mem.Allocator, arena: *std.heap.ArenaAllocator) void { │ │2789 arena.deinit(); │ │2790 allocator.destroy(arena); │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────╮ │2799 // refresh: rebuild the current page in place from a current moment │ │2800 if (session.refresh_requested) { │ │2801 session.refresh_requested = false; │ │2763 - if (session.haxy_moment != null or session.local != null) { │ │2764 - const arena = try allocator.create(std.heap.ArenaAllocator);│ │2765 - arena.* = std.heap.ArenaAllocator.init(allocator); │ │2766 - errdefer freeArena(allocator, arena); │ │2767 - │ │2768 - session.page_arena = arena; │ │2769 - │ │2770 - const route = session.data.current_page; │ │2771 - const page = try arena.allocator().create(Page); │ │2772 - page.* = try Page.init(arena, session, route); │ │2773 - const new_root = try initRoot(allocator, page, session); │ │2774 - │ │2775 - self.root.deinit(allocator); │ │2776 - freeArena(allocator, self.arena); │ │2777 - self.root = new_root; │ │2778 - self.arena = arena; │ │2779 - self.user_id = session.userId(); │ │2780 - } │ │2802 + try self.rebuild(allocator, session); │ │2803 return; │ │2804 } │ │2805 │ ╰──────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────╮ │2815 session.data.current_page = entry.route; │ │2816 // a page built under another login is rebuilt rather than restored│ │2817 if (!std.meta.eql(entry.user_id, session.userId())) { │ │2796 - session.refresh_requested = true; │ │2797 - return self.sync(allocator, session); │ │2818 + try self.rebuild(allocator, session); │ │2819 + return; │ │2820 } │ │2821 chooseAnsiArtForNavigation(session); │ │2822 return; │ ╰─────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │2861 arena.* = std.heap.ArenaAllocator.init(allocator); │ │2862 errdefer freeArena(allocator, arena); │ │2863 │ │2842 - session.page_arena = arena; │ │2843 - │ │2844 - const page = try arena.allocator().create(Page); │ │2845 - page.* = try Page.init(arena, session, route); │ │2846 - const new_root = try initRoot(allocator, page, session); │ │2864 + const new_root = try initCurrentRoot(allocator, arena, session); │ │2865 │ │2866 try self.history.append(allocator, .{ .root = self.root, .route = previous_route, .arena = self.arena, .user_id = self.user_id });│ │2867 // drop the oldest entry (freeing its widget tree and arena) once over cap │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────╮ │2883 .user => |*p| .{ .user = try .init(allocator, p, session) }, │ │2884 .repo => |*p| .{ .repo = try .init(allocator, p, session) }, │ │2885 .fork => |*p| .{ .fork = try .init(allocator, p, session) }, │ │2886 + .not_found => .{ .not_found = try .init(allocator, session) },│ │2887 }; │ │2888 │ │2889 chooseAnsiArtForNavigation(session); │ ╰────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────╮ │2925 // native and server-side sessions choose from the embedded collection. WASM│ │2926 // keeps the art serialized by the server instead. │ │2927 fn chooseAnsiArtForNavigation(session: *Session) void { │ │2909 - if (comptime ansi_arts.len == 0) return; │ │2928 + if (comptime ansi_art.art.len == 0) return; │ │2929 + if (session.data.current_page == .not_found) { │ │2930 + session.data.ansi_art = ansi_art.not_found; │ │2931 + return; │ │2932 + } │ │2933 const io = session.io orelse return; │ │2934 var random: usize = undefined; │ │2935 io.random(std.mem.asBytes(&random)); │ ╰──────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────╮ │2913 - session.data.ansi_art = ansi_arts[random % ansi_arts.len]; │ │2936 + session.data.ansi_art = ansi_art.art[random % ansi_art.art.len];│ │2937 } │ │2938 │ ╰──────────────────────────────────────────────────────────────────────────╯