╭ changed ───────────────╮ │src/ui/widget/thread.zig│ ╰────────────────────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │933 try addToolButton(allocator, row, "publish", "", try pa.print("a:{s}", .{try route.toUrl(self.session.page_arena)})); │ │934 const edit_route = ui.RoutablePage.repoThreadEditRoute(kind, self.data.identity, entry.id) orelse return error.RouteTooLong; │ │935 try addToolButton(allocator, row, "edit", "", try pa.print("a:{s}", .{try edit_route.toUrl(self.session.page_arena)})); │ │936 - const remove_route = ui.RoutablePage.repoThreadRemoveRoute(kind, self.data.identity, entry.id, "") orelse return error.RouteTooLong; │ │936 + const remove_route = ui.RoutablePage.repoThreadRemoveRoute(kind, self.data.identity, entry.id, "", "") orelse return error.RouteTooLong;│ │937 try addToolButton(allocator, row, "✕", "", try pa.print("a:{s}", .{try remove_route.toUrl(self.session.page_arena)})); │ │938 } else { │ │939 if (!self.session.is_terminal and !entryConflicted(entry)) { │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │974 try addToolButton(allocator, row, "edit", "", try pa.print("a:{s}", .{try route.toUrl(self.session.page_arena)})); │ │975 } │ │976 │ │977 - const route = ui.RoutablePage.repoThreadRemoveRoute(kind, self.data.identity, entry.id, "") orelse return error.RouteTooLong; │ │977 + const route = ui.RoutablePage.repoThreadRemoveRoute(kind, self.data.identity, entry.id, "", "") orelse return error.RouteTooLong;│ │978 try addToolButton(allocator, row, "✕", "", try pa.print("a:{s}", .{try route.toUrl(self.session.page_arena)})); │ │979 } │ │980 } │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │1212 }, │ │1213 .box => |*row| if (isAssigneeRow(row)) { │ │1214 try self.assigneeInput(allocator, row, key, root_focus); │ │1215 - } else if (Attachment.removeId(row)) |attachment_id| { │ │1216 - if (self.removableRowInput(row, key, root_focus)) try self.removeEvent(allocator, .attach, attachment_id); │ │1215 + } else if (Attachment.isRow(row)) { │ │1216 + _ = self.removableRowInput(row, key, root_focus); │ │1217 } else if (unassignEmail(row)) |encoded| { │ │1218 if (self.removableRowInput(row, key, root_focus)) try self.unassign(allocator, std.Uri.percentDecodeInPlace(try self.session.page_arena.allocator().dupe(u8, encoded)));│ │1219 } else self.commentInput(key, root_focus), │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │1956 if (session.data.host_kind == .local or data.viewer != null) { │ │1957 if (confirmation(data.view)) |confirmation_kind| { │ │1958 const aa = session.page_arena.allocator(); │ │1959 + // an attachment's ✕ links here with the attachment in the route │ │1960 + const attachment_id = session.data.current_page.threadAttachment(); │ │1961 const route = switch (confirmation_kind) { │ │1960 - .remove => ui.RoutablePage.repoThreadRemoveRoute(kind, data.identity, data.selected_id, data.comment_id), │ │1962 + .remove => ui.RoutablePage.repoThreadRemoveRoute(kind, data.identity, data.selected_id, data.comment_id, attachment_id),│ │1963 .publish => publishRoute(data.identity, data.selected_id), │ │1964 .merge => mergeRoute(data.identity, data.selected_id), │ │1965 } orelse return error.RouteTooLong; │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │1966 const page_url = try route.toUrl(session.page_arena); │ │1967 const action = try aa.print("form:{s}", .{page_url}); │ │1966 - const event_name = if (data.comment_id.len == 0) thread_name else "comment"; │ │1967 - var label_buf: ["remove ".len + @max(thread_name.len, "comment".len)]u8 = undefined; │ │1968 + const event_name = if (attachment_id.len != 0) "attachment" else if (data.comment_id.len == 0) thread_name else "comment";│ │1969 + var label_buf: ["remove ".len + @max(thread_name.len, "attachment".len)]u8 = undefined; │ │1970 var buttons: [2]widget.ConfirmationButton = undefined; │ │1971 buttons[0] = .{ .label = switch (confirmation_kind) { │ │1972 .remove => try std.fmt.bufPrint(&label_buf, "remove {s}", .{event_name}), │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │3288 } │ │3289 │ │3290 fn submitRemove(self: *This, allocator: std.mem.Allocator) !void { │ │3291 + const attachment_id = self.session.data.current_page.threadAttachment(); │ │3292 + if (attachment_id.len != 0) return self.removeEvent(allocator, .attach, evt.parseEventId(attachment_id) catch return);│ │3293 const comment = self.data.comment_id.len != 0; │ │3294 const event_id = if (comment) self.data.comment_id else self.data.selected_id; │ │3295 const id = evt.parseEventId(event_id) catch return; │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯