╭──────────╮ │← previous│ ╰──────────╯ ╭ changed ─────────────╮ │src/ui/Repo/Issues.zig│ ╰──────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │1739 fn toolRowInput(self: *View, allocator: std.mem.Allocator, index: usize, key: Key, root_focus: *Focus) !void { │ │1740 const row = self.toolRow(index); │ │1741 const cur = if (row.getFocus().child_id) |cid| row.children.getIndex(cid) orelse return else return; │ │1715 - const on_status = cur == button_in_row_index and self.statusButton(index) != null; │ │1742 + const on_status = if (self.status_button_id[index]) |id| row.getFocus().child_id == id else false; │ │1743 switch (key) { │ │1717 - .arrow_left => if (cur > button_in_row_index) root_focus.setFocus(row.children.keys()[cur - 1]) else try self.focusList(index, root_focus),│ │1744 + .arrow_left => if (cur > first_in_row_index) root_focus.setFocus(row.children.keys()[cur - 1]) else try self.focusList(index, root_focus), │ │1745 .arrow_right => if (cur + 1 < row.children.count()) root_focus.setFocus(row.children.keys()[cur + 1]), │ │1746 .arrow_up => self.focusHeader(root_focus), │ │1747 .arrow_down => { │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │1749 self.detailScroll(index).y = 0; │ │1750 }, │ │1751 .enter => if (on_status) try self.toggleIssueStatus(allocator, index), │ │1725 - .mouse => |mouse| if (self.statusButton(index)) |button| { │ │1726 - if (inp.leftClickOn(root_focus, button.getFocus().id, mouse)) try self.toggleIssueStatus(allocator, index);│ │1752 + .mouse => |mouse| if (self.status_button_id[index]) |id| { │ │1753 + if (inp.leftClickOn(root_focus, id, mouse)) try self.toggleIssueStatus(allocator, index); │ │1754 }, │ │1755 else => {}, │ │1756 } │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────╮ │2443 } │ │2444 } │ │2445 │ │2419 - const button_in_row_index: usize = 1; │ │2446 const title_child_index: usize = 0; │ │2447 const tags_child_index: usize = 2; │ │2448 + │ │2449 + // the tool row's first child after the spacer that pushes it right│ │2450 + const first_in_row_index: usize = 1; │ │2451 │ │2452 fn tagFlow(self: *View, index: usize) ?*ui.TagFlow { │ │2453 const inner = self.detailInner(index); │ ╰─────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────╮ │2464 return inner.children.getIndex(cid) == tags_child_index and self.tagFlow(index) != null;│ │2465 } │ │2466 │ │2438 - // the open/close button inside the detail frame's tool row, identified │ │2439 - // by its posting kind; a logged-out session's or conflicted issue's row │ │2440 - // has none. │ │2441 - fn statusButton(self: *View, index: usize) ?*wgt.TextBox(ui.Widget) { │ │2442 - const row = self.toolRow(index); │ │2443 - if (row.children.count() <= button_in_row_index) return null; │ │2444 - switch (row.children.values()[button_in_row_index].widget) { │ │2445 - .text_box => |*tb| switch (tb.box.focus.kind) { │ │2446 - .custom => |custom| if (std.mem.eql(u8, custom, "submit")) return tb, │ │2447 - else => {}, │ │2448 - }, │ │2449 - else => {}, │ │2450 - } │ │2451 - return null; │ │2452 - } │ │2453 - │ │2467 fn toolRowFocused(self: *View, index: usize) bool { │ │2468 const outer = self.detailOuter(index); │ │2469 const cid = outer.getFocus().child_id orelse return false; │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭ added ───────────────────╮ │src/ui/Repo/Attachment.zig│ ╰──────────────────────────╯ ╭ changed ──╮ │src/web.zig│ ╰───────────╯ ╭──────────────────────────────────────────────────────╮ │2 const builtin = @import("builtin"); │ │3 const xit = @import("xit"); │ │4 const rp = xit.repo; │ │5 +const obj = xit.object; │ │6 +const hash = xit.hash; │ │7 const evt = @import("./event.zig"); │ │8 const serve_common = @import("./serve_common.zig");│ │9 const ui = @import("./ui.zig"); │ ╰──────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │100 if (method == .POST) { │ │101 switch (host) { │ │102 .remote => |remote| { │ │101 - const PostRoute = enum { login, logout, ansi, new, edit, open, close, resolve }; │ │103 + const PostRoute = enum { login, logout, ansi, new, edit, open, close, resolve, attach };│ │104 inline for (@typeInfo(PostRoute).@"enum".fields) |field| { │ │105 const suffix = "/" ++ field.name; │ │106 if (std.mem.endsWith(u8, path, suffix)) { │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │114 .open => handleIssueStatus(io, request, allocator, base, host, .open), │ │115 .close => handleIssueStatus(io, request, allocator, base, host, .closed),│ │116 .resolve => handleIssueResolve(io, request, allocator, base, host), │ │117 + .attach => handleAttach(io, request, allocator, base, host), │ │118 }; │ │119 } │ │120 } │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────╮ │121 }, │ │122 .local => |local| { │ │120 - const PostRoute = enum { new, edit, open, close, resolve, sync }; │ │123 + const PostRoute = enum { new, edit, open, close, resolve, sync, attach };│ │124 inline for (@typeInfo(PostRoute).@"enum".fields) |field| { │ │125 const suffix = "/" ++ field.name; │ │126 if (std.mem.endsWith(u8, path, suffix)) { │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │132 .close => handleIssueStatus(io, request, allocator, base, host, .closed),│ │133 .resolve => handleIssueResolve(io, request, allocator, base, host), │ │134 .sync => handleSync(io, request, allocator, base, local), │ │135 + .attach => handleAttach(io, request, allocator, base, host), │ │136 }; │ │137 } │ │138 } │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────╮ │next →│ ╰──────╯