╭──────────╮ │← previous│ ╰──────────╯ ╭ changed ─────────────╮ │src/ui/Repo/Header.zig│ ╰──────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │254 │ │255 // patches tab, unless it is off │ │256 if (page.repo.event.patch_role != null) { │ │260 - var text_box = try wgt.TextBox.init(allocator, patches_tab_label, .{ .border = .single, .round_corners = true, .wrap_kind = .none, .bottom_label = .{ .text = patches_bottom_label } });│ │257 + var text_box = try wgt.TextBox.init(allocator, patches_tab_label, .{ .border = .single, .round_corners = true, .wrap_kind = .none }); │ │258 errdefer text_box.deinit(allocator); │ │259 text_box.getFocus().mode = .all; │ │260 text_box.getFocus().kind = .{ .custom = patches_link }; │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭ changed ─────────────╮ │src/ui/Repo/Issues.zig│ ╰──────────────────────╯ ╭─────────────────────────────────────────────────────────╮ │ 9 const Comment = @import("Comment.zig"); │ │10 const Attachment = @import("Attachment.zig"); │ │11 const thread = ui.widget.thread; │ │12 +const srch_thrd = @import("../../search_thread.zig");│ │13 │ │14 const wasm = builtin.target.cpu.arch == .wasm32; │ │15 │ ╰─────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────╮ │81 │ │82 // "owner:name", so the view can build /owner:name/issues/... links. │ │83 identity: []const u8, │ │83 -// the url-encoded label the lists are filtered to ("" = unfiltered). │ │84 -label: []const u8, │ │85 -// the url-encoded name or email the lists are filtered to, as typed ("" = unfiltered).│ │86 -assignee: []const u8, │ │87 -// false when the assignee names no user or no assigned issue, which lists nothing │ │88 -assignee_found: bool = true, │ │84 // the decoded query the lists are filtered to, or null when unfiltered. │ │85 search: ?[]const u8 = null, │ │86 +// whether an assignee term names no user, which lists nothing │ │87 +assignee_unknown: bool = false, │ │88 // the hex event id of the issue its status's window is rooted at ("" = the │ │89 // first window), mirrored into the url. │ │90 selected_id: []const u8, │ ╰───────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │128 return event.status; │ │129 } │ │130 │ │134 -pub fn listRoute(identity: []const u8, status: Status, label: []const u8, selected: []const u8) ?ui.RoutablePage {│ │135 - return ui.RoutablePage.repoIssuesRoute(identity, status, label, selected); │ │131 +pub fn listRoute(identity: []const u8, status: Status, selected: []const u8) ?ui.RoutablePage { │ │132 + return ui.RoutablePage.repoIssuesRoute(identity, status, selected); │ │133 } │ │134 │ │135 pub fn conflictsRoute(identity: []const u8, selected: []const u8) ?ui.RoutablePage { │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │170 } │ │171 │ │172 // an empty listing, for the wasm / no-repo paths. │ │176 -pub fn emptyResult(aa: std.mem.Allocator, identity: []const u8, label: []const u8, assignee: []const u8, search: []const u8, selected_id: []const u8, comment_id: []const u8, comments_start: usize, theirs_picks: []const u8, view: ui.RoutablePage.IssuesView) !Self {│ │173 +pub fn emptyResult(aa: std.mem.Allocator, identity: []const u8, search: []const u8, selected_id: []const u8, comment_id: []const u8, comments_start: usize, theirs_picks: []const u8, view: ui.RoutablePage.IssuesView) !Self { │ │174 return .{ │ │175 .identity = try aa.dupe(u8, identity), │ │179 - .label = try aa.dupe(u8, label), │ │180 - .assignee = try aa.dupe(u8, assignee), │ │176 .search = if (search.len == 0) null else std.Uri.percentDecodeInPlace(try aa.dupe(u8, search)), │ │177 .selected_id = try aa.dupe(u8, selected_id), │ │178 .comment_id = try aa.dupe(u8, comment_id), │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────╮ │193 }; │ │194 } │ │195 │ │201 -// read one window per status of an opened repo's issues (filtered to `label` │ │202 -// and `assignee` when set), ordered by creation (newest first). the window of │ │196 +// read one window per status of an opened repo's issues (filtered to the │ │197 +// search when set), ordered by creation (newest first). the window of │ │198 // the issue `selected_id` names starts at it ("" = the beginning). a git repo reads the│ │199 // event db next to it (synced from the events branch on each page build); a │ │200 // xit repo reads its own db. │ ╰─────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────╮ │208 // in local mode, which has no users) │ │209 admin_moment: ?evt.AdminDB.HashMap(.read_only),│ │210 identity: []const u8, │ │216 - label: []const u8, │ │217 - assignee: []const u8, │ │211 search: []const u8, │ │212 selected_id: []const u8, │ │213 comment_id: []const u8, │ ╰────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │216 view: ui.RoutablePage.IssuesView, │ │217 viewer: ?ui.Viewer, │ │218 ) !Self { │ │226 - var empty = try emptyResult(arena.allocator(), identity, label, assignee, search, selected_id, comment_id, comments_start, theirs_picks, view);│ │219 + var empty = try emptyResult(arena.allocator(), identity, search, selected_id, comment_id, comments_start, theirs_picks, view); │ │220 // the early returns below still let the viewer write │ │221 empty.viewer = viewer; │ │222 │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────╮ │223 const aa = arena.allocator(); │ │224 const DB = evt.EventDB(repo_opts.hash); │ │225 + // an explicitly named issue that doesn't exist is a bad url (NotFound ->│ │226 + // 404); the bare route falls through to an empty listing. │ │227 const rooted = empty.selected_id.len != 0; │ │233 - const labeled = empty.label.len != 0; │ │234 - // an explicitly named issue or label that doesn't exist is a bad url │ │235 - // (NotFound -> 404); the bare route falls through to an empty listing. │ │236 - const strict = rooted or labeled; │ │228 │ │229 // a repo with no consumed events has no moment yet. │ │230 const gpa = arena.child_allocator; │ ╰──────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────╮ │236 return empty │ │237 else │ │238 evt.currentMoment(repo_opts, repo)) catch {│ │248 - if (strict) return error.NotFound; │ │239 + if (rooted) return error.NotFound; │ │240 return empty; │ │241 }; │ │242 │ ╰────────────────────────────────────────────────────────╯ ╭──────╮ │next →│ ╰──────╯