╭ Repos.zig ────────────────────────────────────────────────────╮ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ╰───────────────────────────────────────────────────────────────╯
╭────╮ ╭ clone ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╮ │http│ ssh │ │ ╰────╯ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╯
1 const std = @import("std"); 2 const evt = @import("../../event.zig"); 3 const ui = @import("../../ui.zig"); 4 const xit = @import("xit"); 5 const rp = xit.repo; 6 const hash = xit.hash; 7 const xitui = xit.xitui; 8 const wgt = xitui.widget; 9 const layout = xitui.layout; 10 const inp = xitui.input; 11 const Grid = xitui.grid.Grid; 12 const Focus = xitui.focus.Focus; 13 14 repos: []const evt.Repo, 15 16 const Self = @This(); 17 18 pub fn init( 19 comptime repo_opts: rp.RepoOpts(.xit), 20 arena: *std.heap.ArenaAllocator, 21 haxy_moment: rp.Repo(.xit, repo_opts).DB.HashMap(.read_only), 22 ) !Self { 23 const DB = rp.Repo(.xit, repo_opts).DB; 24 25 var repos: std.ArrayList(evt.Repo) = .empty; 26 27 const event_id_to_repo_cursor = try haxy_moment.getCursor(hash.hashInt(repo_opts.hash, "event-id->repo")) orelse return error.NotFound; 28 const event_id_to_repo = try DB.HashMap(.read_only).init(event_id_to_repo_cursor); 29 30 var repos_iter = try event_id_to_repo.iterator(); 31 while (try repos_iter.next()) |kv_cursor| { 32 const kv = try kv_cursor.readKeyValuePair(); 33 const repo_map = try DB.HashMap(.read_only).init(kv.value_cursor); 34 const repo_event = try evt.read(evt.Repo, DB, repo_opts.hash, arena, repo_map); 35 try repos.append(arena.allocator(), repo_event); 36 } 37 38 return .{ 39 .repos = repos.items, 40 }; 41 } 42 43 pub const View = struct { 44 list: ui.SelectableList, 45 data: *const Self, 46 47 pub fn init(allocator: std.mem.Allocator, data: *const Self) !View { 48 var self = blk: { 49 var list = try ui.SelectableList.init(allocator); 50 errdefer list.deinit(); 51 52 break :blk View{ 53 .list = list, 54 .data = data, 55 }; 56 }; 57 errdefer self.deinit(); 58 59 var arena = std.heap.ArenaAllocator.init(allocator); 60 defer arena.deinit(); 61 const aa = arena.allocator(); 62 63 const lines = try aa.alloc([]const u8, data.repos.len); 64 for (data.repos, 0..) |repo, i| { 65 lines[i] = try std.fmt.allocPrint(aa, "{s} - {s}", .{ repo.name, repo.description }); 66 } 67 try self.list.setItems(lines); 68 69 return self; 70 } 71 72 pub fn deinit(self: *View) void { 73 self.list.deinit(); 74 } 75 76 pub fn build(self: *View, constraint: layout.Constraint, root_focus: *Focus) !void { 77 try self.list.build(constraint, root_focus); 78 } 79 80 pub fn input(self: *View, key: inp.Key, root_focus: *Focus) !void { 81 try self.list.input(key, root_focus); 82 } 83 84 pub fn clearGrid(self: *View) void { 85 self.list.clearGrid(); 86 } 87 88 pub fn getGrid(self: View) ?Grid { 89 return self.list.getGrid(); 90 } 91 92 pub fn getFocus(self: *View) *Focus { 93 return self.list.getFocus(); 94 } 95 96 pub fn getSelectedIndex(self: View) ?usize { 97 return self.list.getSelectedIndex(); 98 } 99 }; 100