╭ changed ───────────────╮ │src/ui/widget/thread.zig│ ╰────────────────────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭──────────╮ │← previous│ ╰──────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │594 const route = ui.RoutablePage.repoThreadEditRoute(kind, self.data.identity, entry.id) orelse return error.RouteTooLong; │ │586 - try addToolButton(allocator, row, "edit", try std.fmt.allocPrint(pa, "a:{s}", .{try route.toUrl(self.session.page_arena)})); │ │595 + try addToolButton(allocator, row, "edit", "", try std.fmt.allocPrint(pa, "a:{s}", .{try route.toUrl(self.session.page_arena)}));│ │596 } │ │597 │ │598 if (self.session.data.is_local or self.session.data.user_id != null) { │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │599 const route = ui.RoutablePage.repoThreadRemoveRoute(kind, self.data.identity, entry.id, "") orelse return error.RouteTooLong;│ │591 - try addToolButton(allocator, row, "✕", try std.fmt.allocPrint(pa, "a:{s}", .{try route.toUrl(self.session.page_arena)})); │ │600 + try addToolButton(allocator, row, "✕", "", try std.fmt.allocPrint(pa, "a:{s}", .{try route.toUrl(self.session.page_arena)}));│ │601 } │ │602 } │ │603 │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │1206 var any_repo = try rp.AnyRepo(repo_kind, .{}).open(io, allocator, source.localInitOpts()); │ │1207 defer any_repo.deinit(io, allocator); │ │1208 switch (any_repo) { │ │1200 - inline else => |*repo| try Event.update(repo_kind, repo.self_repo_opts, io, allocator, repo, &id, .{ .status = status }, author),│ │1209 + inline else => |*repo| { │ │1210 + try Event.update(repo_kind, repo.self_repo_opts, io, allocator, repo, &id, .{ .status = status }, author); │ │1211 + if (comptime kind == .patch and repo_kind == .xit) { │ │1212 + if (!self.session.data.is_local) pch.refreshMergeability(repo.self_repo_opts, io, allocator, repo, id); │ │1213 + } │ │1214 + }, │ │1215 } │ │1216 }, │ │1217 } │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │1449 var button_count: usize = 1; │ │1450 if (confirmation_kind == .merge) { │ │1451 if (comptime supports_merge) { │ │1452 + const availability = if (data.selectedThread()) |entry| │ │1453 + if (Data.canMerge(entry.*, session)) entry.mergeability else pch.Mergeability{} │ │1454 + else │ │1455 + pch.Mergeability{}; │ │1456 + buttons[0].bottom_label = mergeBottomLabel(availability.source); │ │1457 + if (availability.source != .clean) buttons[0].action = ""; │ │1458 buttons[1] = .{ │ │1459 .label = "squash and merge patch", │ │1440 - .action = try std.fmt.allocPrint(aa, "{s}{s}/squash", .{ ui.submit_action_prefix, page_url }), │ │1460 + .bottom_label = mergeBottomLabel(availability.squash), │ │1461 + .action = if (availability.squash == .clean) try std.fmt.allocPrint(aa, "{s}{s}/squash", .{ ui.submit_action_prefix, page_url }) else "",│ │1462 }; │ │1463 button_count += 1; │ │1464 } else unreachable; │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────╮ │1715 │ │1716 const ConfirmationButton = struct {│ │1717 label: []const u8, │ │1718 + bottom_label: []const u8 = "", │ │1719 action: []const u8 = "submit", │ │1720 }; │ │1721 │ ╰─────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │1729 try box.children.put(allocator, prompt.getFocus().id, .{ .widget = .{ .text = prompt }, .rect = null, .min_size = null }); │ │1730 │ │1731 for (buttons, 0..) |options, index| { │ │1710 - var button = try wgt.TextBox.init(allocator, options.label, .{ .border_style = .single, .rounded_corners = true, .wrap_kind = .none }); │ │1732 + var button = try wgt.TextBox.init(allocator, options.label, .{ .border_style = .single, .rounded_corners = true, .wrap_kind = .none, .bottom_label = options.bottom_label });│ │1733 errdefer button.deinit(allocator); │ │1734 button.getFocus().mode = .all; │ │1735 button.getFocus().kind = .{ .custom = options.action }; │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │2445 error.InvalidFields => return, │ │2446 else => |e| return e, │ │2447 }; │ │2448 + if (comptime kind == .patch and repo_kind == .xit) { │ │2449 + if (!self.session.data.is_local) pch.refreshMergeability(repo.self_repo_opts, io, allocator, repo, id_bytes);│ │2450 + } │ │2451 }, │ │2452 } │ │2453 }, │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │2654 }, │ │2655 else => |other| return other, │ │2656 }; │ │2657 + if (comptime kind == .patch and repo_kind == .xit) { │ │2658 + if (!self.session.data.is_local) pch.refreshMergeability(repo.self_repo_opts, io, allocator, repo, id_bytes);│ │2659 + } │ │2660 } else if (has_status) │ │2661 try Event.update(repo_kind, repo.self_repo_opts, io, allocator, repo, &id_bytes, .{ .fields = .{ │ │2662 .title = title, │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │2703 .merge => if (comptime supports_merge) { │ │2704 if (comptime wasm) return; │ │2705 const entry = self.data.selectedThread() orelse return; │ │2678 - try self.data.mergePatch(self.session, allocator, entry.id, button_index > 1); │ │2706 + const revision: pch.MergeRevision = if (button_index > 1) .squash else .source; │ │2707 + if (!Data.canMerge(entry.*, self.session) or entry.mergeability.get(revision) != .clean) return; │ │2708 + self.data.mergePatch(self.session, allocator, entry.id, revision) catch |err| switch (err) { │ │2709 + error.MergeConflict, error.MergeCheckUnavailable, error.PatchOutOfDate, error.PatchDataUnavailable => {│ │2710 + const route = listRoute(self.data.identity, entryStatus(entry.*), "", entry.id) orelse return; │ │2711 + try self.session.navigate(route); │ │2712 + return; │ │2713 + }, │ │2714 + else => return err, │ │2715 + }; │ │2716 const merged = std.meta.stringToEnum(Status, "merged") orelse return; │ │2717 const route = listRoute(self.data.identity, merged, "", entry.id) orelse return; │ │2718 try self.session.navigate(route); │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯