╭ changed ──────────────╮ │src/ui/Repo/Threads.zig│ ╰───────────────────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭──────────╮ │← previous│ ╰──────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │1836 self.focusDetailEdge(index, root_focus, false); │ │1837 self.detailScroll(index).y = 0; │ │1838 }, │ │1401 - .enter => if (on_status) try self.toggleStatus(allocator, index), │ │1402 - .mouse => |mouse| if (self.status_button_id[index]) |id| { │ │1403 - if (inp.leftClickOn(root_focus, id, mouse)) try self.toggleStatus(allocator, index); │ │1839 + .enter => if (on_primary) try self.primaryAction(allocator, index), │ │1840 + .mouse => |mouse| if (self.primary_button_id[index]) |id| { │ │1841 + if (inp.leftClickOn(root_focus, id, mouse)) try self.primaryAction(allocator, index);│ │1842 }, │ │1843 else => {}, │ │1844 } │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │1845 + } │ │1846 + │ │1847 + fn primaryAction(self: *This, allocator: std.mem.Allocator, index: usize) !void { │ │1848 + const selected = self.detailed_index[index] orelse return; │ │1849 + const entry = self.window(index).items[selected]; │ │1850 + if (has_drafts and entryDraft(entry)) │ │1851 + try self.postDraft(allocator, index) │ │1852 + else │ │1853 + try self.toggleStatus(allocator, index); │ │1854 + } │ │1855 + │ │1856 + fn postDraft(self: *This, allocator: std.mem.Allocator, index: usize) !void { │ │1857 + if (!has_drafts or comptime wasm) return; │ │1858 + const selected = self.detailed_index[index] orelse return; │ │1859 + const entry = self.window(index).items[selected]; │ │1860 + if (!entryDraft(entry) or !entry.revision_ready) return; │ │1861 + try self.data.postDraft(self.session, allocator, entry.id); │ │1862 + const route = listRoute(self.data.identity, @enumFromInt(0), "", entry.id) orelse return;│ │1863 + try self.session.navigate(route); │ │1864 } │ │1865 │ │1866 fn titleInput(self: *This, index: usize, key: Key, root_focus: *Focus) !void { │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────╮ │2321 else => {}, │ │2322 }; │ │2323 │ │1867 - var id_bytes: [evt.event_id_size]u8 = undefined; │ │1868 - _ = try std.fmt.hexToBytes(&id_bytes, entry.id[0 .. evt.event_id_size * 2]);│ │2324 + const id_bytes = try evt.parseEventId(entry.id); │ │2325 │ │2326 switch (src.repo_kind) { │ │2327 inline else => |repo_kind| { │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │2328 var any_repo = try rp.AnyRepo(repo_kind, .{}).open(io, allocator, src.localInitOpts()); │ │2329 defer any_repo.deinit(io, allocator); │ │2330 switch (any_repo) { │ │1875 - inline else => |*repo| Event.update(repo_kind, repo.self_repo_opts, io, allocator, repo, &id_bytes, .{ .resolve = .{ │ │1876 - .title = title, │ │1877 - .tags = tags, │ │1878 - .hunks = hunks.items, │ │1879 - } }, author) catch |err| switch (err) { │ │1880 - // leave the form up for correction │ │1881 - error.InvalidFields => return, │ │1882 - else => |e| return e, │ │2331 + inline else => |*repo| { │ │2332 + const change: Event.Update = if (comptime kind == .patch) │ │2333 + .{ .resolve = .{ │ │2334 + .title = title, │ │2335 + .tags = tags, │ │2336 + .hunks = hunks.items, │ │2337 + .theirs = self.data.theirs_picks, │ │2338 + } } │ │2339 + else │ │2340 + .{ .resolve = .{ │ │2341 + .title = title, │ │2342 + .tags = tags, │ │2343 + .hunks = hunks.items, │ │2344 + } }; │ │2345 + Event.update(repo_kind, repo.self_repo_opts, io, allocator, repo, &id_bytes, change, author) catch |err| switch (err) {│ │2346 + // leave the form up for correction │ │2347 + error.InvalidFields => return, │ │2348 + else => |e| return e, │ │2349 + }; │ │2350 }, │ │2351 } │ │2352 }, │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │2384 defer any_repo.deinit(io, allocator); │ │2385 switch (any_repo) { │ │2386 inline else => |*repo| if (editing) { │ │1920 - var comment_id: [evt.event_id_size]u8 = undefined; │ │1921 - _ = std.fmt.hexToBytes(&comment_id, self.data.comment_id) catch return; │ │2387 + const comment_id = evt.parseEventId(self.data.comment_id) catch return; │ │2388 try evt.Comment.update(repo_kind, repo.self_repo_opts, io, allocator, repo, &thread_id, &comment_id, body, author);│ │2389 event_id_hex = std.fmt.bytesToHex(comment_id, .lower); │ │2390 } else { │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │2433 │ │2434 if (!Event.fieldsValid(title, tags)) return; │ │2435 │ │2436 + if (comptime kind == .patch) { │ │2437 + const event_id_hex = try Data.createDraft(self.data, self.session, allocator, title, tags, description);│ │2438 + title_input.clear(allocator); │ │2439 + tags_input.clear(allocator); │ │2440 + description_input.clear(allocator); │ │2441 + const route = commentsRoute(self.data.identity, &event_id_hex, 0) orelse return; │ │2442 + try self.session.navigate(route); │ │2443 + return; │ │2444 + } │ │2445 + │ │2446 var id_bytes: [evt.event_id_size]u8 = undefined; │ │2447 io.random(&id_bytes); │ │2448 const event_id_hex = std.fmt.bytesToHex(id_bytes, .lower); │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────╮ │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| { │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯