╭ changed ──────────────╮ │src/ui/Repo/Threads.zig│ ╰───────────────────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │483 return std.fmt.allocPrint(page_arena.allocator(), "a:{s}", .{try route.toUrl(page_arena)}); │ │484 } │ │485 │ │486 - fn rowLink(page_arena: *std.heap.ArenaAllocator, identity: []const u8, id: []const u8) ![]const u8 { │ │487 - const route = listRoute(identity, @enumFromInt(0), "", id) orelse return error.RouteTooLong; │ │486 + fn rowLink(page_arena: *std.heap.ArenaAllocator, data: *const Self, id: []const u8) ![]const u8 { │ │487 + const selected = std.mem.eql(u8, id, data.selected_id); │ │488 + const route = (if (selected and data.description_page) │ │489 + ui.RoutablePage.repoThreadDescriptionRoute(kind, data.identity, id) │ │490 + else if (selected) │ │491 + if (data.comment_page) |page| │ │492 + ui.RoutablePage.repoThreadCommentRoute(kind, data.identity, id, &page.selected.id, page.replies.start)│ │493 + else │ │494 + ui.RoutablePage.repoThreadCommentsRoute(kind, data.identity, id, data.comments_start) │ │495 + else │ │496 + ui.RoutablePage.repoThreadCommentsRoute(kind, data.identity, id, 0)) orelse return error.RouteTooLong; │ │497 return std.fmt.allocPrint(page_arena.allocator(), "ai:{s}", .{try route.toUrl(page_arena)}); │ │498 } │ │499 │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │702 try std.fmt.allocPrint(session.page_arena.allocator(), " {d} comments ", .{entry.comments.count}) │ │703 else │ │704 ""; │ │696 - try addRow(allocator, &list_box, entry.record.event.title, label, try rowLink(session.page_arena, data.identity, entry.id));│ │705 + try addRow(allocator, &list_box, entry.record.event.title, label, try rowLink(session.page_arena, data, entry.id)); │ │706 } │ │707 if (win.next_id) |next| │ │708 try addRow(allocator, &list_box, "next →", "", try windowLink(session.page_arena, data, status_maybe, drafts, next)); │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │1230 pub fn build(self: *This, allocator: std.mem.Allocator, constraint: layout.Constraint, root_focus: *Focus) !void {│ │1231 self.clearGrid(); │ │1232 │ │1224 - // each header tab maps 1:1 to a stack child by position. mirror the │ │1225 - // selection into the url: the view the page's window is rooted at │ │1226 - // keeps its rooted url, the others get their list route (keeping the │ │1227 - // tag filter). │ │1233 + // each header tab maps 1:1 to a stack child by position │ │1234 if (self.header().getSelectedIndex()) |index| { │ │1235 const stack = self.viewStack(); │ │1236 stack.getFocus().child_id = stack.children.keys()[index]; │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │1231 - self.session.data.current_page = (if (index == form_view_index) │ │1232 - (if (has_conflicts) switch (self.data.view) { │ │1233 - .edit => ui.RoutablePage.repoThreadEditRoute(kind, self.data.identity, self.data.selected_id), │ │1234 - .new_comment => ui.RoutablePage.repoThreadCommentNewRoute(kind, self.data.identity, self.data.selected_id, self.data.comment_id), │ │1235 - .edit_comment => ui.RoutablePage.repoThreadCommentEditRoute(kind, self.data.identity, self.data.selected_id, self.data.comment_id),│ │1236 - .remove => ui.RoutablePage.repoThreadRemoveRoute(kind, self.data.identity, self.data.selected_id, self.data.comment_id), │ │1237 - .resolve => resolveRoute(self.data.identity, self.data.selected_id, self.data.theirs_picks), │ │1238 - else => ui.RoutablePage.repoThreadNewRoute(kind, self.data.identity), │ │1239 - } else switch (self.data.view) { │ │1240 - .edit => ui.RoutablePage.repoThreadEditRoute(kind, self.data.identity, self.data.selected_id), │ │1241 - .new_comment => ui.RoutablePage.repoThreadCommentNewRoute(kind, self.data.identity, self.data.selected_id, self.data.comment_id), │ │1242 - .edit_comment => ui.RoutablePage.repoThreadCommentEditRoute(kind, self.data.identity, self.data.selected_id, self.data.comment_id),│ │1243 - .remove => ui.RoutablePage.repoThreadRemoveRoute(kind, self.data.identity, self.data.selected_id, self.data.comment_id), │ │1244 - else => ui.RoutablePage.repoThreadNewRoute(kind, self.data.identity), │ │1245 - }) │ │1246 - else if (has_conflicts and index == conflict_view_index) │ │1247 - conflictsRoute(self.data.identity, if (self.data.view == .conflicts) self.data.selected_id else "") │ │1248 - else if (has_drafts and index == drafts_view_index) │ │1249 - if (index == viewIndex(self.data.view) and self.data.selected_id.len != 0) │ │1250 - ui.RoutablePage.repoThreadCommentsRoute(kind, self.data.identity, self.data.selected_id, 0) │ │1251 - else │ │1252 - draftsRoute(self.data.identity) │ │1253 - else if (index == viewIndex(self.data.view) and self.data.selected_id.len != 0) │ │1254 - (if (self.data.description_page) │ │1255 - ui.RoutablePage.repoThreadDescriptionRoute(kind, self.data.identity, self.data.selected_id) │ │1256 - else if (self.data.comment_page) |page| │ │1257 - ui.RoutablePage.repoThreadCommentRoute(kind, self.data.identity, self.data.selected_id, &page.selected.id, page.replies.start) │ │1258 - else │ │1259 - ui.RoutablePage.repoThreadCommentsRoute(kind, self.data.identity, self.data.selected_id, self.data.comments_start)) │ │1260 - else if (index == tags_view_index) │ │1261 - ui.RoutablePage.repoThreadTagsRoute(kind, self.data.identity, self.data.tag) │ │1262 - else │ │1263 - listRoute(self.data.identity, splitStatus(index), self.data.tag, "")) orelse self.session.data.current_page; │ │1237 } │ │1238 │ │1239 if (self.selectedSplitIndex()) |i| { │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │1246 } │ │1247 } │ │1248 │ │1276 - // mirror the focused thread into the url, but only while focus is │ │1277 - // inside the split. a thread's url is the same whether or not the │ │1278 - // list is filtered, so the mirror drops the tag. │ │1279 - if (root_focus.grandchild_id) |g| { │ │1280 - if (self.resultsBox(i).getFocus().children.contains(g)) { │ │1281 - if (self.selectedThreadIndex(i)) |sel| { │ │1282 - // selecting another thread leaves the description page │ │1283 - // behind, like it leaves the tag filter behind. │ │1284 - const entry = &self.window(i).items[sel]; │ │1285 - const mirrored = if (self.data.description_page and std.mem.eql(u8, entry.id, self.data.selected_id)) │ │1286 - ui.RoutablePage.repoThreadDescriptionRoute(kind, self.data.identity, entry.id) │ │1287 - else if (self.data.comment_page) |page| │ │1288 - if (std.mem.eql(u8, entry.id, self.data.selected_id)) │ │1289 - ui.RoutablePage.repoThreadCommentRoute(kind, self.data.identity, entry.id, &page.selected.id, page.replies.start)│ │1290 - else │ │1291 - ui.RoutablePage.repoThreadCommentsRoute(kind, self.data.identity, entry.id, 0) │ │1292 - else if (std.mem.eql(u8, entry.id, self.data.selected_id)) │ │1293 - ui.RoutablePage.repoThreadCommentsRoute(kind, self.data.identity, entry.id, entry.comments.start) │ │1294 - else │ │1295 - ui.RoutablePage.repoThreadCommentsRoute(kind, self.data.identity, entry.id, 0); │ │1296 - if (mirrored) |route| self.session.data.current_page = route; │ │1297 - } │ │1298 - } │ │1299 - } │ │1300 - │ │1249 // the selected list row shows a border (the focused TextBox │ │1250 // upgrades it to a double border itself); the rest stay borderless. │ │1251 const lb = self.listBox(i); │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯