╭──────────╮ │← previous│ ╰──────────╯ ╭ changed ──────────────╮ │src/ui/Repo/Comment.zig│ ╰───────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │193 } │ │194 │ │195 if (!entry.comment.removed and (session.data.is_local or session.data.user_id != null)) { │ │199 - const route = commentsRoute(thread_kind, identity, &entry.comment.event.thread_id, &entry.id, 0) orelse return error.RouteTooLong; │ │200 - bar.getFocus().kind = .{ .custom = try std.fmt.allocPrint(session.page_arena.allocator(), "form:{s}/remove", .{try route.toUrl(session.page_arena)}) }; │ │201 - var remove = try wgt.TextBox(ui.Widget).init(allocator, "✕", .{ .border_style = .single, .rounded_corners = true, .wrap_kind = .none }); │ │196 + var remove = try linkBox(allocator, session, "✕", removeRoute(thread_kind, identity, &entry.comment.event.thread_id, &entry.id) orelse return error.RouteTooLong);│ │197 errdefer remove.deinit(allocator); │ │203 - remove.getFocus().focusable = true; │ │204 - remove.getFocus().kind = .{ .custom = "submit" }; │ │205 - remove_button_id = remove.getFocus().id; │ │198 try bar.children.put(allocator, remove.getFocus().id, .{ .widget = .{ .text_box = remove }, .rect = null, .min_size = .{ .width = 3, .height = null } }); │ │199 } │ │200 │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────╮ │214 │ │215 box.getFocus().child_id = box.children.keys()[metadata_index]; │ │216 │ │225 - return .{ │ │226 - .box = box, │ │227 - .id = idBytes(&entry.id) orelse return error.InvalidEventId,│ │228 - .remove_button_id = remove_button_id, │ │229 - }; │ │217 + return .{ .box = box }; │ │218 } │ │219 │ │220 fn metadata(self: *Item) *wgt.Box(ui.Widget) { │ ╰─────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────╮ │227 │ │228 pub fn bodyFocused(self: *Item) bool { │ │229 return self.box.getFocus().child_id == self.body().getFocus().id;│ │242 - } │ │243 - │ │244 - pub fn removeFocused(self: *Item) bool { │ │245 - const id = self.remove_button_id orelse return false; │ │246 - return self.metadata().getFocus().child_id == id; │ │230 } │ │231 │ │232 pub fn focusMetadata(self: *Item, root_focus: *Focus) void { │ ╰──────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │332 │ │333 fn commentEditRoute(kind: evt.EventKind, identity: []const u8, thread_id: []const u8, comment_id: []const u8) ?ui.RoutablePage { │ │334 return ui.RoutablePage.repoThreadCommentEditRoute(kind, identity, thread_id, comment_id); │ │335 +} │ │336 + │ │337 +fn removeRoute(kind: evt.EventKind, identity: []const u8, thread_id: []const u8, comment_id: []const u8) ?ui.RoutablePage { │ │338 + return ui.RoutablePage.repoThreadRemoveRoute(kind, identity, thread_id, comment_id); │ │339 } │ │340 │ │341 pub fn linkBox(allocator: std.mem.Allocator, session: *ui.Session, text: []const u8, route: ui.RoutablePage) !wgt.TextBox(ui.Widget) {│ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭ changed ──────────────────╮ │src/ui/Repo/Discussions.zig│ ╰───────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │305 .edit => ui.RoutablePage.repoThreadEditRoute(.discussion, data.identity, data.selected_id) orelse return error.RouteTooLong, │ │306 .new_comment => ui.RoutablePage.repoThreadCommentNewRoute(.discussion, data.identity, data.selected_id, data.comment_id) orelse return error.RouteTooLong, │ │307 .edit_comment => ui.RoutablePage.repoThreadCommentEditRoute(.discussion, data.identity, data.selected_id, data.comment_id) orelse return error.RouteTooLong,│ │308 + .remove => ui.RoutablePage.repoThreadRemoveRoute(.discussion, data.identity, data.selected_id, data.comment_id) orelse return error.RouteTooLong, │ │309 else => ui.RoutablePage.repoThreadNewRoute(.discussion, data.identity) orelse return error.RouteTooLong, │ │310 }; │ │311 const link = try std.fmt.allocPrint(aa, "ai:{s}", .{try route.toUrl(session.page_arena)}); │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────╮ │313 .edit => "edit", │ │314 .new_comment => "reply", │ │315 .edit_comment => "edit", │ │316 + .remove => "remove", │ │317 else => "new", │ │318 }; │ │319 try addTab(allocator, &box, &tab_ids, label, link);│ ╰────────────────────────────────────────────────────────────────────╯ ╭ changed ─────────────╮ │src/ui/Repo/Events.zig│ ╰──────────────────────╯ ╭─────────────────────────────────────╮ │23 view_url: ?[]const u8 = null,│ │24 }; │ │25 │ │26 -pub const Cursor = struct { │ │26 +pub const EventRef = struct { │ │27 id: []const u8, │ │28 kind: evt.EventKind, │ │29 }; │ ╰─────────────────────────────────────╯ ╭────────────────────────────────────╮ │31 pub const Window = struct { │ │32 count: usize = 0, │ │33 events: []const Item = &.{},│ │34 - next: ?Cursor = null, │ │34 + next: ?EventRef = null, │ │35 }; │ │36 │ │37 identity: []const u8, │ ╰────────────────────────────────────╯ ╭─────────────────────────────────────╮ │38 view: ui.RoutablePage.EventsView,│ │39 +selected: ?EventRef, │ │40 active: Window, │ │41 removed: Window, │ │42 header: Header, │ ╰─────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │ 94 const kind = selected_kind orelse return error.NotFound; │ │ 95 const stored_kind = (try evt.readEventKind(repo_opts.hash, kind_map, &id)) orelse return error.NotFound;│ │ 96 if (stored_kind != kind) return error.NotFound; │ │ 97 + result.selected = .{ .id = try aa.dupe(u8, selected), .kind = kind }; │ │ 98 const meta = try readMeta(repo_opts.hash, arena, haxy_moment, kind, &id); │ │ 99 result.view = if (meta.removed) .removed else .active; │ │100 root_key = evt.orderKeyDesc(meta.created_ts, &id); │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────╮ │next →│ ╰──────╯