╭──────────╮ │← previous│ ╰──────────╯ ╭ changed ──────────────╮ │src/ui/Repo/Threads.zig│ ╰───────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────╮ │2501 │ │2502 if (!Event.fieldsValid(title, tags)) return; │ │2503 │ │2028 - var id_bytes: [evt.event_id_size]u8 = undefined; │ │2029 - _ = try std.fmt.hexToBytes(&id_bytes, entry.id[0 .. evt.event_id_size * 2]);│ │2504 + const id_bytes = try evt.parseEventId(entry.id); │ │2505 │ │2506 switch (src.repo_kind) { │ │2507 inline else => |repo_kind| { │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────╮ │2527 fn submitRemove(self: *This, allocator: std.mem.Allocator) !void { │ │2528 const comment = self.data.comment_id.len != 0; │ │2529 const event_id = if (comment) self.data.comment_id else self.data.selected_id;│ │2055 - var id: [evt.event_id_size]u8 = undefined; │ │2056 - _ = std.fmt.hexToBytes(&id, event_id) catch return; │ │2530 + const id = evt.parseEventId(event_id) catch return; │ │2531 try self.removeEvent(allocator, if (comment) .comment else kind, id); │ │2532 } │ │2533 │ ╰────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────╮ │2564 const entry = self.window(index).items[sel]; │ │2565 const author = (try self.session.eventAuthor()) orelse return; │ │2566 │ │2093 - const status: Status = switch (entryStatus(entry)) { │ │2094 - .open => .closed, │ │2095 - .closed => .open, │ │2096 - }; │ │2567 + const status = toggledStatus(entryStatus(entry)) orelse return; │ │2568 │ │2098 - var id_bytes: [evt.event_id_size]u8 = undefined; │ │2099 - _ = try std.fmt.hexToBytes(&id_bytes, entry.id[0 .. evt.event_id_size * 2]);│ │2569 + const id_bytes = try evt.parseEventId(entry.id); │ │2570 │ │2571 switch (src.repo_kind) { │ │2572 inline else => |repo_kind| { │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ ╭ added ────────────────╮ │src/ui/Repo/Patches.zig│ ╰───────────────────────╯ ╭ changed ──────╮ │src/ui/User.zig│ ╰───────────────╯ ╭───────────────────────────────────────╮ │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; │ ╰───────────────────────────────────────╯ ╭────────────────────────────────────────────────────╮ │11 const Grid = xitui.grid.Grid; │ │12 const Focus = xitui.focus.Focus; │ │13 const inp = @import("./input.zig"); │ │14 +const fork = @import("../fork.zig"); │ │15 │ │16 pub const Header = @import("./User/Header.zig");│ │17 pub const Settings = @import("./Settings.zig"); │ ╰────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────╮ │19 pub const Quit = @import("./Quit.zig"); │ │20 │ │21 pub const page_size = 20; // how many repos one window of the repos tab shows│ │22 + │ │23 +pub const ForkItem = struct { │ │24 + target: []const u8, │ │25 + title: []const u8, │ │26 +}; │ │27 │ │28 header: Header, │ │29 user: evt.User.Public, │ ╰─────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────╮ │30 repos: []const evt.Repo.Record, │ │31 repos_start: usize, // the repos window this page was built with, mirrored into the url│ │32 repos_next_start: ?usize, // the `start` for the "next" row, or null on the last window│ │33 +forks: []const ForkItem, │ │34 +forks_start: usize, │ │35 +forks_next_start: ?usize, │ │36 settings: Settings, │ │37 auth: Auth, │ │38 quit: Quit, │ ╰───────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────╮ │42 │ │43 pub fn init( │ │44 arena: *std.heap.ArenaAllocator, │ │45 + session: *ui.Session, │ │46 haxy_moment: evt.AdminDB.HashMap(.read_only), │ │47 name: ui.RoutablePage.Array(evt.User.name_max_len),│ │37 - start: usize, │ │48 + repos_start: usize, │ │49 + forks_start: usize, │ │50 ) !Self { │ │51 const DB = evt.AdminDB; │ │52 const hash_kind = evt.admin_repo_opts.hash; │ ╰───────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────╮ │79 │ │80 // read the window [start, start+page_size) with one seek to the start│ │81 // rank, then a sequential walk. │ │70 - const end = @min(start + page_size, count); │ │71 - var repos_iter = try user_repos.iteratorFromIndex(start); │ │72 - var i = start; │ │82 + const end = @min(repos_start + page_size, count); │ │83 + var repos_iter = try user_repos.iteratorFromIndex(repos_start); │ │84 + var i = repos_start; │ │85 while (i < end) : (i += 1) { │ │86 var kv_cursor = (try repos_iter.next()) orelse break; │ │87 const kv = try kv_cursor.readKeyValuePair(); │ ╰──────────────────────────────────────────────────────────────────────────────────────╯ ╭──────╮ │next →│ ╰──────╯