╭ changed ───────────────╮ │src/ui/widget/thread.zig│ ╰────────────────────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭───────────────────────────────────────────╮ │1 const std = @import("std"); │ │2 const builtin = @import("builtin"); │ │3 +const pch = @import("../../patch.zig"); │ │4 const evt = @import("../../event.zig"); │ │5 const ui = @import("../../ui.zig"); │ │6 const widget = @import("../widget.zig");│ ╰───────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────╮ │26 const SectionLabel = widget.SectionLabel; │ │27 const moveRowFocus = widget.moveRowFocus; │ │28 const wasm = builtin.target.cpu.arch == .wasm32; │ │29 + │ │30 +fn mergeBottomLabel(status: pch.Mergeability.Status) []const u8 { │ │31 + return switch (status) { │ │32 + .clean => "", │ │33 + .conflict => " conflict ", │ │34 + .unknown => " unavailable ", │ │35 + }; │ │36 +} │ │37 │ │38 // read the selected thread's conflicted fields and attribute each side to its│ │39 // event commit author │ ╰──────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │511 return listLink(page_arena, identity, status, encoded, ""); │ │512 } │ │513 │ │505 - fn addToolButton(allocator: std.mem.Allocator, row: *wgt.Box(Widget), label: []const u8, action: []const u8) !void { │ │506 - var button = try wgt.TextBox.init(allocator, label, .{ .border_style = .single, .rounded_corners = true, .wrap_kind = .none }); │ │514 + fn addToolButton(allocator: std.mem.Allocator, row: *wgt.Box(Widget), label: []const u8, bottom_label: []const u8, action: []const u8) !void { │ │515 + var button = try wgt.TextBox.init(allocator, label, .{ .border_style = .single, .rounded_corners = true, .wrap_kind = .none, .bottom_label = bottom_label });│ │516 errdefer button.deinit(allocator); │ │517 button.getFocus().mode = .all; │ │518 button.getFocus().kind = .{ .custom = action }; │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │510 - try row.children.put(allocator, button.getFocus().id, .{ .widget = .{ .text_box = button }, .rect = null, .min_size = .{ .width = try xitui.width.displayWidth(label) + 2, .height = null } }); │ │519 + try row.children.put(allocator, button.getFocus().id, .{ .widget = .{ .text_box = button }, .rect = null, .min_size = .{ .width = @max(try xitui.width.displayWidth(label), try xitui.width.displayWidth(bottom_label)) + 2, .height = null } });│ │520 } │ │521 │ │522 pub fn setEntry(self: *This, allocator: std.mem.Allocator, entry: Entry) !void { │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │542 │ │543 if (entryHasFork(entry) and self.session.data.current_page.parent() != .fork) { │ │544 const route = forkRoute(self.data.identity, entry.id) orelse return error.RouteTooLong; │ │536 - try addToolButton(allocator, row, "view fork", try std.fmt.allocPrint(pa, "a:{s}", .{try route.toUrl(self.session.page_arena)})); │ │545 + try addToolButton(allocator, row, "view fork", "", try std.fmt.allocPrint(pa, "a:{s}", .{try route.toUrl(self.session.page_arena)})); │ │546 const diff_route = ui.RoutablePage.forkDiffRoute(self.data.identity, entry.id, 0, "") orelse return error.RouteTooLong; │ │538 - try addToolButton(allocator, row, "view diff", try std.fmt.allocPrint(pa, "a:{s}", .{try diff_route.toUrl(self.session.page_arena)})); │ │547 + try addToolButton(allocator, row, "view diff", "", try std.fmt.allocPrint(pa, "a:{s}", .{try diff_route.toUrl(self.session.page_arena)}));│ │548 } │ │549 │ │550 { │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │556 if (comptime supports_merge) { │ │557 if (Data.canMerge(entry, self.session)) { │ │558 const route = mergeRoute(self.data.identity, entry.id) orelse return error.RouteTooLong; │ │550 - try addToolButton(allocator, row, "merge", try std.fmt.allocPrint(pa, "a:{s}", .{try route.toUrl(self.session.page_arena)})); │ │559 + try addToolButton(allocator, row, "merge", mergeBottomLabel(entry.mergeability.status()), try std.fmt.allocPrint(pa, "a:{s}", .{try route.toUrl(self.session.page_arena)}));│ │560 } │ │561 } │ │562 │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │563 if (supports_drafts and entryDraft(entry)) { │ │564 const route = publishRoute(self.data.identity, entry.id) orelse return error.RouteTooLong; │ │556 - try addToolButton(allocator, row, "publish", try std.fmt.allocPrint(pa, "a:{s}", .{try route.toUrl(self.session.page_arena)})); │ │565 + try addToolButton(allocator, row, "publish", "", try std.fmt.allocPrint(pa, "a:{s}", .{try route.toUrl(self.session.page_arena)})); │ │566 if (self.session.data.user_id != null) { │ │567 const edit_route = ui.RoutablePage.repoThreadEditRoute(kind, self.data.identity, entry.id) orelse return error.RouteTooLong; │ │559 - try addToolButton(allocator, row, "edit", try std.fmt.allocPrint(pa, "a:{s}", .{try edit_route.toUrl(self.session.page_arena)})); │ │568 + try addToolButton(allocator, row, "edit", "", try std.fmt.allocPrint(pa, "a:{s}", .{try edit_route.toUrl(self.session.page_arena)}));│ │569 const remove_route = ui.RoutablePage.repoThreadRemoveRoute(kind, self.data.identity, entry.id, "") orelse return error.RouteTooLong; │ │561 - try addToolButton(allocator, row, "✕", try std.fmt.allocPrint(pa, "a:{s}", .{try remove_route.toUrl(self.session.page_arena)})); │ │570 + try addToolButton(allocator, row, "✕", "", try std.fmt.allocPrint(pa, "a:{s}", .{try remove_route.toUrl(self.session.page_arena)})); │ │571 } │ │572 } else { │ │573 if (!self.session.is_terminal and !entryConflicted(entry) and (self.session.data.is_local or self.session.data.user_id != null)) { │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │576 try std.fmt.allocPrint(pa, "{s}/{s}:{s}/attach", .{ ui.file_input_prefix, @tagName(kind), entry.id }) │ │577 else │ │578 try std.fmt.allocPrint(pa, "{s}/repo/{s}/{s}:{s}/attach", .{ ui.file_input_prefix, self.data.identity, @tagName(kind), entry.id });│ │570 - try addToolButton(allocator, row, label, action); │ │579 + try addToolButton(allocator, row, label, "", action); │ │580 } │ │581 │ │582 if (supports_conflicts and entryConflicted(entry)) { │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │583 const route = resolveRoute(self.data.identity, entry.id, "") orelse return error.RouteTooLong; │ │575 - try addToolButton(allocator, row, "resolve conflict", try std.fmt.allocPrint(pa, "a:{s}", .{try route.toUrl(self.session.page_arena)})); │ │584 + try addToolButton(allocator, row, "resolve conflict", "", try std.fmt.allocPrint(pa, "a:{s}", .{try route.toUrl(self.session.page_arena)}));│ │585 } else { │ │586 if (has_status and (self.session.data.is_local or self.session.data.user_id != null)) { │ │587 if (statusChange(entryStatus(entry))) |change| { │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │588 const route = ui.RoutablePage.repoThreadCommentsRoute(kind, self.data.identity, entry.id, 0) orelse return error.RouteTooLong; │ │589 row.getFocus().kind = .{ .custom = try std.fmt.allocPrint(pa, "form:{s}/{s}", .{ try route.toUrl(self.session.page_arena), change.action }) };│ │581 - try addToolButton(allocator, row, change.action, "submit"); │ │590 + try addToolButton(allocator, row, change.action, "", "submit"); │ │591 } │ │592 } │ │593 │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────╮ │next →│ ╰──────╯