╭ changed ─────────────╮ │src/ui/Repo/Issues.zig│ ╰──────────────────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭──────────╮ │← previous│ ╰──────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │1857 sc.clampToContent(); │ │1858 } │ │1859 │ │1814 - fn commentInput(self: *View, index: usize, key: Key, root_focus: *Focus) !void { │ │1860 + fn commentInput(self: *View, allocator: std.mem.Allocator, index: usize, key: Key, root_focus: *Focus) !void { │ │1861 + const item = self.focusedComment(index, root_focus); │ │1862 switch (key) { │ │1863 .arrow_left => if (!self.moveCommentHorizontal(index, root_focus, false)) return self.focusList(index, root_focus),│ │1864 .arrow_right => _ = self.moveCommentHorizontal(index, root_focus, true), │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │1865 .arrow_up => _ = self.moveDetailVertical(index, root_focus, false), │ │1866 .arrow_down => _ = self.moveDetailVertical(index, root_focus, true), │ │1867 + .enter => if (item) |comment| if (comment.removeFocused()) try self.removeComment(allocator, comment),│ │1868 + .mouse => |mouse| if (item) |comment| if (comment.remove_button_id) |id| { │ │1869 + if (inp.leftClickOn(root_focus, id, mouse)) try self.removeComment(allocator, comment); │ │1870 + }, │ │1871 else => return, │ │1872 } │ │1873 } │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────╮ │1874 │ │1875 + fn focusedComment(self: *View, index: usize, root_focus: *Focus) ?*Comment.Item { │ │1876 + const child_index = self.focusedDetailChild(index, root_focus) orelse return null;│ │1877 + return switch (self.detailInner(index).children.values()[child_index].widget) { │ │1878 + .repo_comment => |*comment| comment, │ │1879 + else => null, │ │1880 + }; │ │1881 + } │ │1882 + │ │1883 // page the detail scroll, then focus the first or last visible widget. │ │1884 fn pageDetail(self: *View, index: usize, root_focus: *Focus, delta: isize) void { │ │1885 if (!self.session.is_terminal) return; │ ╰────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │2443 try self.session.navigate(route); │ │2444 } │ │2445 │ │2446 + fn removeIssue(self: *View, allocator: std.mem.Allocator, index: usize) !void { │ │2447 + const sel = self.detailed_index[index] orelse return; │ │2448 + const entry = self.window(index).issues[sel]; │ │2449 + │ │2450 + var id_bytes: [evt.event_id_size]u8 = undefined; │ │2451 + _ = std.fmt.hexToBytes(&id_bytes, entry.id) catch return; │ │2452 + try self.removeEvent(allocator, .issue, id_bytes); │ │2453 + } │ │2454 + │ │2455 + fn removeComment(self: *View, allocator: std.mem.Allocator, comment: *Comment.Item) !void { │ │2456 + try self.removeEvent(allocator, .comment, comment.id); │ │2457 + } │ │2458 + │ │2459 + fn removeEvent(self: *View, allocator: std.mem.Allocator, kind: evt.EventKind, id: [evt.event_id_size]u8) !void { │ │2460 + if (comptime wasm) return; │ │2461 + const io = self.session.io orelse return; │ │2462 + const src = self.data.repo_source orelse return; │ │2463 + const author = (try self.session.eventAuthor()) orelse return; │ │2464 + │ │2465 + switch (src.repo_kind) { │ │2466 + inline else => |repo_kind| { │ │2467 + var any_repo = try rp.AnyRepo(repo_kind, .{}).open(io, allocator, src.localInitOpts()); │ │2468 + defer any_repo.deinit(io, allocator); │ │2469 + switch (any_repo) { │ │2470 + inline else => |*repo| try evt.remove(repo_kind, repo.self_repo_opts, io, allocator, repo, &id, kind, author),│ │2471 + } │ │2472 + }, │ │2473 + } │ │2474 + │ │2475 + const id_hex = std.fmt.bytesToHex(id, .lower); │ │2476 + const route = ui.RoutablePage.repoEventsRoute(self.data.identity, .removed, kind, &id_hex) orelse return; │ │2477 + try self.session.navigate(route); │ │2478 + } │ │2479 + │ │2480 // flip the shown issue's status by re-emitting its event, then reload the │ │2481 // page rooted at the issue so the view reflects the change. this is the │ │2482 // terminal path; the web posts the button's form to the status route. │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯