╭ changed ──────╮ │src/ui/Fork.zig│ ╰───────────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │162 { │ │163 var stack = try wgt.Stack(ui.Widget).init(allocator); │ │164 errdefer stack.deinit(allocator); │ │165 - if (data.patch.repo_source == null) { │ │166 - var fallback = try initFallback(allocator, &data.patch, session); │ │167 - errdefer fallback.deinit(allocator); │ │168 - try stack.children.put(allocator, fallback.getFocus().id, .{ .scroll = fallback }); │ │169 - } else { │ │170 - var patch_view = try Patches.View.initDetail(allocator, &data.patch, session); │ │171 - errdefer patch_view.deinit(allocator); │ │172 - try stack.children.put(allocator, patch_view.getFocus().id, .{ .repo_patches = patch_view }); │ │173 - } │ │165 + const selected = data.patch.selectedThread() orelse return error.NotFound; │ │166 + var patch_detail = try Patches.Detail.init(allocator, &data.patch, session, selected.*, .{ .actions = data.patch.repo_source != null });│ │167 + errdefer patch_detail.deinit(allocator); │ │168 + try stack.children.put(allocator, patch_detail.getFocus().id, .{ .repo_patch_detail = patch_detail }); │ │169 { │ │170 var files = try Files.View.init(allocator, &data.files, session); │ │171 errdefer files.deinit(allocator); │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │195 } │ │196 box.getFocus().child_id = box.children.keys()[header_index]; │ │197 return .{ .box = box }; │ │203 - } │ │204 - │ │205 - fn initFallback(allocator: std.mem.Allocator, data: *const Patches, session: *ui.Session) !wgt.Scroll(ui.Widget) { │ │206 - const entry = data.selectedThread() orelse return error.NotFound; │ │207 - var content = try wgt.Box(ui.Widget).init(allocator, .{ .border_style = null, .direction = .vert }); │ │208 - errdefer content.deinit(allocator); │ │209 - { │ │210 - var text_box = try wgt.TextBox.init(allocator, entry.record.event.title, .{ .border_style = .single, .rounded_corners = true, .wrap_kind = .word, .label = " title " });│ │211 - errdefer text_box.deinit(allocator); │ │212 - text_box.getFocus().focusable = true; │ │213 - try content.children.put(allocator, text_box.getFocus().id, .{ .widget = .{ .text_box = text_box }, .rect = null, .min_size = null }); │ │214 - } │ │215 - { │ │216 - var author = try ui.authorBox(allocator, session.page_arena, entry.author); │ │217 - errdefer author.deinit(allocator); │ │218 - try content.children.put(allocator, author.getFocus().id, .{ .widget = .{ .text_box = author }, .rect = null, .min_size = null }); │ │219 - } │ │220 - inline for (.{ │ │221 - .{ entry.record.event.tags, " tags " }, │ │222 - .{ entry.record.event.description, " description " }, │ │223 - }) |field| { │ │224 - var text_box = try wgt.TextBox.init(allocator, field[0], .{ .border_style = .single, .rounded_corners = true, .wrap_kind = .word, .label = field[1] }); │ │225 - errdefer text_box.deinit(allocator); │ │226 - text_box.getFocus().focusable = true; │ │227 - try content.children.put(allocator, text_box.getFocus().id, .{ .widget = .{ .text_box = text_box }, .rect = null, .min_size = null }); │ │228 - } │ │229 - content.getFocus().child_id = content.children.keys()[0]; │ │230 - return wgt.Scroll(ui.Widget).init(allocator, .{ .box = content }, .{ .direction = .vert, .web_native = !session.is_terminal, .fill = true }); │ │198 } │ │199 │ │200 pub fn deinit(self: *View, allocator: std.mem.Allocator) void { │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────╮ │220 .fork_header => try child.input(allocator, key, root_focus), │ │221 .stack => if (stack.getSelected()) |selected| { │ │222 const at_top = switch (selected.*) { │ │256 - .repo_patches => |*view| view.atTop(root_focus), │ │223 + .repo_patch_detail => |*view| view.atTop(root_focus), │ │224 .repo_files => |*view| view.getSelectedIndex() == 0, │ │225 .repo_commits => |*view| view.getSelectedIndex() == 0, │ │226 .home_settings => |*view| view.getSelectedIndex() == 0,│ ╰────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │227 .home_auth => |*view| view.getSelectedIndex() == 0, │ │228 .quit => |*view| view.getSelectedIndex() == 0, │ │262 - .scroll => |*scroll| scroll.y == 0, │ │229 else => false, │ │230 }; │ │231 if (at_top) next_index = header_index else try child.input(allocator, key, root_focus);│ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────╮ │235 .down => switch (child.*) { │ │236 .fork_header => { │ │237 if (stack.getSelected()) |selected| switch (selected.*) { │ │272 - .repo_patches => |*view| if (view.focusDetail(root_focus)) return, │ │238 + .repo_patch_detail => |*view| if (view.focusFirst(root_focus)) return,│ │239 .repo_files => |*view| if (view.focusCloneUrl(root_focus)) return, │ │240 .repo_commits => |*view| if (view.focusCloneUrl(root_focus)) return, │ │241 else => {}, │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────╯