╭ changed ────────────╮ │src/ui/Home/Repos.zig│ ╰─────────────────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭──────────────────────────────────────────────────────────────────────╮ │10 const Grid = xitui.grid.Grid; │ │11 const Focus = xitui.focus.Focus; │ │12 │ │13 -// how many repos a page shows before the "load more" row appears.│ │14 -pub const page_size = 20; │ │13 +pub const page_size = 20; // how many repos one window shows │ │14 │ │15 repos: []const evt.Repo, │ │16 owner_names: []const []const u8, │ ╰──────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────╮ │18 -// the window start this page was built with, mirrored into the url. │ │19 -after: usize, │ │20 -// the `after` for the "load more" link, or null when this is the last page. │ │21 -next_after: ?usize, │ │17 +after: usize, // the window start this page was built with, mirrored into the url │ │18 +next_after: ?usize, // the `after` for the "next" row, or null when this is the last window│ │19 │ │20 const Self = @This(); │ │21 │ ╰───────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │ 86 defer arena.deinit(); │ │ 87 const aa = arena.allocator(); │ │ 88 │ │ 92 - // one row per repo, plus a trailing "load more" row when more remain. │ │ 93 - const extra: usize = if (data.next_after != null) 1 else 0; │ │ 94 - const lines = try aa.alloc([]const u8, data.repos.len + extra); │ │ 95 - const links = try aa.alloc([]const u8, data.repos.len + extra); │ │ 89 + // a leading "previous" row off the first window, one row per repo, then │ │ 90 + // a trailing "next" row when more remain. each window row navigates to the │ │ 91 + // adjacent window (full reload on web, Nav rebuild on the TUI). │ │ 92 + const lead: usize = if (data.after > 0) 1 else 0; │ │ 93 + const trail: usize = if (data.next_after != null) 1 else 0; │ │ 94 + const lines = try aa.alloc([]const u8, lead + data.repos.len + trail); │ │ 95 + const links = try aa.alloc([]const u8, lead + data.repos.len + trail); │ │ 96 + if (data.after > 0) { │ │ 97 + lines[0] = "← previous"; │ │ 98 + links[0] = try std.fmt.allocPrint(aa, "a:/repos?after={d}", .{data.after -| page_size}); │ │ 99 + } │ │100 for (data.repos, 0..) |repo, i| { │ │ 97 - lines[i] = try std.fmt.allocPrint(aa, "{s} - {s}", .{ repo.name, repo.description }); │ │101 + lines[lead + i] = try std.fmt.allocPrint(aa, "{s} - {s}", .{ repo.name, repo.description });│ │102 // clicking a repo opens its page; the "a:" prefix makes the web │ │103 // renderer emit an <a href="/repo/alice/foo"> anchor. skip the link │ │104 // when the owner is unknown so it isn't a dead route. │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │105 const owner = data.owner_names[i]; │ │102 - links[i] = if (owner.len > 0) try std.fmt.allocPrint(aa, "a:/repo/{s}/{s}", .{ owner, repo.name }) else ""; │ │106 + links[lead + i] = if (owner.len > 0) try std.fmt.allocPrint(aa, "a:/repo/{s}/{s}", .{ owner, repo.name }) else "";│ │107 } │ │108 if (data.next_after) |next_after| { │ │105 - // the load-more row navigates to the next window (full reload on web, │ │106 - // Nav rebuild on the TUI), exactly like the commits "load more". │ │107 - lines[data.repos.len] = "load more"; │ │108 - links[data.repos.len] = try std.fmt.allocPrint(aa, "a:/repos?after={d}", .{next_after}); │ │109 + lines[lead + data.repos.len] = "next →"; │ │110 + links[lead + data.repos.len] = try std.fmt.allocPrint(aa, "a:/repos?after={d}", .{next_after}); │ │111 } │ │112 try self.list.setItems(allocator, lines, links); │ │113 │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯