╭─────────────╮ │scroll to top│ ╰─────────────╯ ╭ Repos.zig ────────────────────────────────────────────────────╮ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ╰───────────────────────────────────────────────────────────────╯
╭────╮ ╭ clone ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╮ │http│ ssh │ │ ╰────╯ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╯
78 var list = try ui.FlowBox.Scroll.init(allocator, .{}); 79 errdefer list.deinit(allocator); 80 81 break :blk View{ 82 .list = list, 83 .data = data, 84 }; 85 }; 86 errdefer self.deinit(allocator); 87 88 var arena = std.heap.ArenaAllocator.init(allocator); 89 defer arena.deinit(); 90 const aa = arena.allocator(); 91 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); 96 for (data.repos, 0..) |repo, i| { 97 lines[i] = try std.fmt.allocPrint(aa, "{s} - {s}", .{ repo.name, repo.description }); 98 // clicking a repo opens its page; the "a:" prefix makes the web 99 // renderer emit an <a href="/repo/alice/foo"> anchor. skip the link 100 // when the owner is unknown so it isn't a dead route. 101 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 ""; 103 } 104 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 } 110 try self.list.setItems(allocator, lines, links); 111 112 return self; 113 } 114 115 pub fn deinit(self: *View, allocator: std.mem.Allocator) void { 116 self.list.deinit(allocator); 117 } 118 119 pub fn build(self: *View, allocator: std.mem.Allocator, constraint: layout.Constraint, root_focus: *Focus) !void { 120 try self.list.build(allocator, constraint, root_focus); 121 } 122 123 pub fn input(self: *View, allocator: std.mem.Allocator, key: inp.Key, root_focus: *Focus) !void { 124 try self.list.input(allocator, key, root_focus); 125 } 126 127 pub fn clearGrid(self: *View) void { 128 self.list.clearGrid(); 129 } 130 131 pub fn getGrid(self: View) ?Grid { 132 return self.list.getGrid(); 133 } 134 135 pub fn getFocus(self: *View) *Focus { 136 return self.list.getFocus(); 137 } 138 139 pub fn getSelectedIndex(self: View) ?usize { 140 return self.list.getSelectedIndex(); 141 } 142 }; 143