╭ changed ───────────────╮ │src/ui/widget/thread.zig│ ╰────────────────────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────╮ │1271 const title_field_index: usize = 0; │ │1272 const tags_field_index: usize = 1; │ │1273 const description_field_index: usize = 2; │ │1274 - const target_branch_field_index: usize = 3; │ │1275 - const submit_field_index: usize = 3 + @as(usize, @intFromBool(supports_drafts));│ │1274 + const source_field_index: usize = 3; │ │1275 const comment_author_field_index: usize = 0; │ │1276 const comment_body_field_index: usize = 1; │ │1277 const comment_submit_field_index: usize = 2; │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │1657 try box.children.put(allocator, description.getFocus().id, .{ .widget = .{ .text_input = description }, .rect = null, .min_size = null }); │ │1658 } │ │1659 │ │1660 + if (supports_drafts and record == null) { │ │1661 + var source = try Data.Source.init(allocator, session, if (saved_fields) |saved| saved.source_branch else "", if (saved_fields) |saved| saved.branch_source else (session.data.host_kind == .local));│ │1662 + errdefer source.deinit(allocator); │ │1663 + try box.children.put(allocator, source.getFocus().id, .{ .widget = .{ .patch_source = source }, .rect = null, .min_size = .{ .width = null, .height = 3 } }); │ │1664 + } │ │1665 + │ │1666 if (supports_drafts) { │ │1667 var target = try wgt.TextInput.init(allocator, .{ .label = " target branch ", .name = "target_branch", .visible_width = null, .rounded_corners = true, .render_content = session.is_terminal }); │ │1668 errdefer target.deinit(allocator); │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │2130 const failure = if (self.session.formFeedback(feedback_tag)) |saved| saved.failure else null; │ │2131 form.children.values()[title_field_index].widget.text_input.options.label = if (failure == .required_title) " title (required) " else " title "; │ │2132 if (comptime supports_drafts) { │ │2128 - const invalid_target = failure == .invalid_target_branch; │ │2129 - form.children.values()[target_branch_field_index].widget.text_input.options.label = if (invalid_target) " target branch (not found) " else " target branch "; │ │2133 + if (form.children.values()[source_field_index].widget == .patch_source) { │ │2134 + const source = &form.children.values()[source_field_index].widget.patch_source; │ │2135 + source.field().options.label = if (failure == .invalid_source_branch) " source branch (not found) " else if (failure == .unrelated_branches) " source branch (unrelated) " else " source branch "; │ │2136 + const submit = &form.children.values()[form.children.count() - 1].widget.submit_button; │ │2137 + try submit.setLabel(allocator, if (source.existing) "submit patch" else "submit draft"); │ │2138 + } │ │2139 + const target_branch_field_index = form.children.count() - 2; │ │2140 + form.children.values()[target_branch_field_index].widget.text_input.options.label = │ │2141 + if (failure == .invalid_target_branch) " target branch (not found) " else if (self.data.view == .edit and failure == .unrelated_branches) " target branch (unrelated to source) " else if (self.data.view == .edit and failure == .invalid_source_branch) " target branch (source branch not found) " else " target branch ";│ │2142 } │ │2143 } │ │2144 if (self.formBox()) |form| { │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────╮ │2242 const form = self.threadForm() orelse return; │ │2243 const cid = form.getFocus().child_id orelse return; │ │2244 const cur = form.children.getIndex(cid) orelse return; │ │2245 + const submit_field_index = form.children.count() - 1; │ │2246 + const child = &form.children.values()[cur]; │ │2247 │ │2248 if (cur == description_field_index) { │ │2235 - const child = &form.children.values()[cur]; │ │2249 if (try multilineKeepsKey(&child.widget.text_input, allocator, key))│ │2250 return child.widget.input(allocator, key, root_focus); │ │2251 } │ ╰──────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────╮ │2252 │ │2253 switch (key) { │ │2241 - .arrow_up, .back_tab => if (cur > 0) │ │2254 + .arrow_up, .back_tab => return if (cur > 0) │ │2255 root_focus.setFocus(form.children.keys()[cur - 1])│ │2256 else │ │2257 self.focusHeader(root_focus), │ ╰────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │2245 - .arrow_down, .tab => if (cur < submit_field_index) { │ │2246 - root_focus.setFocus(form.children.keys()[cur + 1]); │ │2247 - }, │ │2248 - .enter => if (cur == submit_field_index) try self.submitForm(allocator), │ │2258 + .arrow_down, .tab => return if (cur < submit_field_index) root_focus.setFocus(form.children.keys()[cur + 1]), │ │2259 + .enter => if (cur == submit_field_index) return self.submitForm(allocator), │ │2260 .mouse => |mouse| if (cur == submit_field_index) { │ │2250 - const submit = &form.children.values()[cur].widget.submit_button; │ │2251 - if (inp.leftClickOn(root_focus, submit.buttonId(), mouse)) try self.submitForm(allocator); │ │2261 + if (inp.leftClickOn(root_focus, child.widget.submit_button.buttonId(), mouse)) return self.submitForm(allocator);│ │2262 }, │ │2253 - else => try form.children.values()[cur].widget.input(allocator, key, root_focus), │ │2263 + else => {}, │ │2264 } │ │2265 + try child.widget.input(allocator, key, root_focus); │ │2266 } │ │2267 │ │2268 fn commentFormInput(self: *This, allocator: std.mem.Allocator, key: Key, root_focus: *Focus) !void { │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │2524 const author = (try self.session.eventAuthor()) orelse return; │ │2525 │ │2526 const form = self.threadForm() orelse return; │ │2527 + const target_branch_field_index = form.children.count() - 2; │ │2528 const title_input = &form.children.values()[title_field_index].widget.text_input; │ │2529 const tags_input = &form.children.values()[tags_field_index].widget.text_input; │ │2530 const description_input = &form.children.values()[description_field_index].widget.text_input;│ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │2544 } │ │2545 │ │2546 if (comptime supports_drafts) { │ │2535 - const event_id_hex = Data.createDraft(self.data, self.session, allocator, title, tags, description, target_branch) catch |err| switch (err) {│ │2536 - error.InvalidFields => { │ │2537 - try self.rememberThreadFeedback(.invalid_target_branch, title, tags, description, target_branch); │ │2538 - return; │ │2539 - }, │ │2540 - else => |other| return other, │ │2547 + const source = &form.children.values()[source_field_index].widget.patch_source; │ │2548 + const source_branch = if (source.existing) try source.field().text(allocator) else null; │ │2549 + defer if (source_branch) |branch| allocator.free(branch); │ │2550 + const event_id_hex = Data.create(self.data, self.session, allocator, title, tags, description, target_branch, source_branch) catch |err| { │ │2551 + const failure = FeedbackFailure.fromError(err) orelse return err; │ │2552 + try self.rememberThreadFeedback(failure, title, tags, description, target_branch); │ │2553 + return; │ │2554 }; │ │2555 title_input.clear(allocator); │ │2556 tags_input.clear(allocator); │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │2604 const entry = self.data.selectedThread() orelse return; │ │2605 │ │2606 const form = self.threadForm() orelse return; │ │2607 + const target_branch_field_index = form.children.count() - 2; │ │2608 const title_input = &form.children.values()[title_field_index].widget.text_input; │ │2609 const tags_input = &form.children.values()[tags_field_index].widget.text_input; │ │2610 const description_input = &form.children.values()[description_field_index].widget.text_input;│ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │2626 │ │2627 if (comptime supports_drafts) { │ │2628 if (entryDraft(entry.*)) { │ │2615 - self.data.editDraft(self.session, allocator, entry.id, title, tags, description, target_branch) catch |err| switch (err) {│ │2616 - error.InvalidFields => { │ │2617 - try self.rememberThreadFeedback(.invalid_target_branch, title, tags, description, target_branch); │ │2618 - return; │ │2619 - }, │ │2620 - else => |other| return other, │ │2629 + self.data.editDraft(self.session, allocator, entry.id, title, tags, description, target_branch) catch |err| { │ │2630 + const failure = FeedbackFailure.fromError(err) orelse return err; │ │2631 + try self.rememberThreadFeedback(failure, title, tags, description, target_branch); │ │2632 + return; │ │2633 }; │ │2634 const route = listRoute(self.data.identity, entryStatus(entry.*), "", entry.id) orelse return; │ │2635 try self.session.navigate(route); │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────╮ │next →│ ╰──────╯