╭ changed ──────────────╮ │src/ui/Repo/Commits.zig│ ╰───────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────╮ │64 // an object view or a base-bounded list searches the default branch: that │ │65 // branch's url-encoded name, when it is indexed │ │66 default_branch: []const u8 = "", │ │67 +// the repo's default branch has no commit yet, so the tab shows a placeholder│ │68 +no_commits: bool = false, │ │69 │ │70 const Self = @This(); │ │71 │ ╰──────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │129 // (NotFound -> 404); the default-branch path falls through to empty. │ │130 var resolved = (try ui.ResolvedRefOrOid(repo_kind, repo_opts).init(repo, io, aa, requested_ref_or_oid, requested_value)) orelse { │ │131 if (requested_ref_or_oid != null) return error.NotFound; │ │130 - return emptyResult(aa, handle, .branch, requested_value, content, base_oid); │ │132 + var data = try emptyResult(aa, handle, .branch, requested_value, content, base_oid); │ │133 + data.no_commits = true; │ │134 + return data; │ │135 }; │ │136 │ │137 var moment = repo.core.latestMoment() catch return emptyResult(aa, handle, resolved.ref_or_oid, resolved.value, content, base_oid);│ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │468 var outer = try wgt.Box(ui.Widget).init(allocator, .{ .border_style = null, .direction = .vert }); │ │469 errdefer outer.deinit(allocator); │ │470 │ │471 + if (data.no_commits) { │ │472 + var center = try ui.widget.initNoCommits(allocator, session, data.handle); │ │473 + errdefer center.deinit(allocator); │ │474 + outer.getFocus().child_id = center.getFocus().id; │ │475 + try outer.children.put(allocator, center.getFocus().id, .{ .widget = .{ .center = center }, .rect = null, .min_size = null }); │ │476 + return .{ .box = outer, .data = data, .session = session, .diffed_index = null }; │ │477 + } │ │478 + │ │479 // the search box and the clone url at the top. local mode has neither. │ │480 if (session.data.host_kind == .server) { │ │481 var header_view = try ui.widget.SearchHeader.init(allocator, session, data.handle, " search ", "search", data.search, data.search_available);│ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │645 │ │646 pub fn build(self: *View, allocator: std.mem.Allocator, constraint: layout.Constraint, root_focus: *Focus) !void {│ │647 self.clearGrid(); │ │648 + if (self.data.no_commits) return self.box.build(allocator, constraint, root_focus); │ │649 │ │650 // swap the diff pane to the selected commit when it changes. │ │651 try self.refreshDiff(allocator); │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────╮ │787 } │ │788 │ │789 pub fn input(self: *View, allocator: std.mem.Allocator, key: Key, root_focus: *Focus) !void {│ │790 + if (self.data.no_commits) return self.box.input(allocator, key, root_focus); │ │791 // scrolling crosses the sub header boundary the same way arrows do │ │792 const direction = inp.vertDirection(key); │ │793 if (self.headerActive()) { │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────╮ │887 │ │888 // only the header's own row sits directly below the repository header. │ │889 pub fn atTop(self: *View) bool { │ │890 + if (self.data.no_commits) return true; │ │891 const focusable = if (self.header()) |header_view| header_view.hasFocusable() else false;│ │892 return self.headerActive() or (!focusable and self.contentAtTop()); │ │893 } │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭ changed ────────────╮ │src/ui/Repo/Files.zig│ ╰─────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────╮ │71 // whether the viewed tree has a file index, so the search box shows and a │ │72 // find: route resolves. travels in the page json for the wasm view. │ │73 find_available: bool = false, │ │74 +// the repo's default branch has no commit yet, so the tab shows a placeholder│ │75 +no_commits: bool = false, │ │76 │ │77 const Self = @This(); │ │78 │ ╰──────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │131 // bad url (NotFound -> 404); the default-branch path falls through to empty. │ │132 const resolved = (try ui.ResolvedRefOrOid(repo_kind, repo_opts).init(repo, io, aa, requested_ref_or_oid, requested_value)) orelse {│ │133 if (requested_ref_or_oid != null or term != null) return error.NotFound; │ │132 - return emptyResult(aa, handle, .branch, requested_value, path); │ │134 + var data = try emptyResult(aa, handle, .branch, requested_value, path); │ │135 + data.no_commits = true; │ │136 + return data; │ │137 }; │ │138 │ │139 // read just the viewed directory of that tree or commit. building the │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │360 var outer = try wgt.Box(ui.Widget).init(allocator, .{ .border_style = null, .direction = .vert }); │ │361 errdefer outer.deinit(allocator); │ │362 │ │363 + if (data.no_commits) { │ │364 + var center = try ui.widget.initNoCommits(allocator, session, data.handle); │ │365 + errdefer center.deinit(allocator); │ │366 + outer.getFocus().child_id = center.getFocus().id; │ │367 + try outer.children.put(allocator, center.getFocus().id, .{ .widget = .{ .center = center }, .rect = null, .min_size = null }); │ │368 + return .{ .box = outer, .data = data, .session = session, .shown_index = null }; │ │369 + } │ │370 + │ │371 // the search box and the clone url at the top. local mode has neither. │ │372 if (session.data.host_kind == .server) { │ │373 var header_view = try ui.widget.SearchHeader.init(allocator, session, data.handle, " find file ", "find", data.find, data.find_available);│ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │594 │ │595 pub fn build(self: *View, allocator: std.mem.Allocator, constraint: layout.Constraint, root_focus: *Focus) !void {│ │596 self.clearGrid(); │ │597 + if (self.data.no_commits) return self.box.build(allocator, constraint, root_focus); │ │598 │ │599 // swap the detail pane to the selected entry when the selection changes. │ │600 try self.refreshDetail(allocator); │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────╮ │next →│ ╰──────╯