╭ changed ───────────────╮ │src/ui/widget/thread.zig│ ╰────────────────────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭──────────╮ │← previous│ ╰──────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │1544 const route = draftsRoute(data.identity) orelse return error.RouteTooLong; │ │1545 return std.fmt.allocPrint(page_arena.allocator(), "a:{s}", .{try route.toUrl(page_arena)}); │ │1546 } │ │1547 - return listLink(page_arena, data.identity, status_maybe orelse @enumFromInt(0), data.tag, id, data.search orelse ""); │ │1547 + return listLink(page_arena, data.identity, status_maybe orelse @enumFromInt(0), data.label, id, data.search orelse ""); │ │1548 } │ │1549 │ │1550 - fn tagLink(page_arena: *std.heap.ArenaAllocator, identity: []const u8, status: Status, tag: []const u8, search: []const u8) ![]const u8 { │ │1551 - const encoded = try ui.urlEncodeRef(page_arena.allocator(), tag); │ │1550 + fn labelLink(page_arena: *std.heap.ArenaAllocator, identity: []const u8, status: Status, label: []const u8, search: []const u8) ![]const u8 {│ │1551 + const encoded = try ui.urlEncodeRef(page_arena.allocator(), label); │ │1552 return listLink(page_arena, identity, status, encoded, "", search); │ │1553 } │ │1554 │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │1578 try stack.children.put(allocator, split.getFocus().id, .{ .box = split }); │ │1579 } │ │1580 │ │1581 - // the tags view │ │1581 + // the labels view │ │1582 { │ │1583 - var tf = try TagFlow.init(allocator); │ │1583 + var tf = try WordFlow.init(allocator); │ │1584 errdefer tf.deinit(allocator); │ │1585 - var items: std.ArrayList(TagFlow.Item) = .empty; │ │1585 + var items: std.ArrayList(WordFlow.Item) = .empty; │ │1586 defer items.deinit(allocator); │ │1587 // when filtered, the first item clears the filter │ │1588 - if (data.tag.len != 0) │ │1588 + if (data.label.len != 0) │ │1589 try items.append(allocator, .{ .text = "✕", .link = try listLink(session.page_arena, data.identity, @enumFromInt(0), "", "", data.search orelse "") }); │ │1590 - for (data.tags) |tag| │ │1591 - try items.append(allocator, .{ .text = tag, .link = try tagLink(session.page_arena, data.identity, @enumFromInt(0), tag, data.search orelse "") }); │ │1590 + for (data.labels) |label| │ │1591 + try items.append(allocator, .{ .text = label, .link = try labelLink(session.page_arena, data.identity, @enumFromInt(0), label, data.search orelse "") });│ │1592 try tf.setItems(allocator, items.items); │ │1593 - try stack.children.put(allocator, tf.getFocus().id, .{ .tag_flow = tf }); │ │1593 + try stack.children.put(allocator, tf.getFocus().id, .{ .word_flow = tf }); │ │1594 } │ │1595 │ │1596 // the new-thread form, or — on an edit, comment, or resolve url — that form in │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │1812 } │ │1813 │ │1814 { │ │1815 - var tags = try wgt.TextInput.init(allocator, .{ .label = " tags (separate with spaces) ", .name = "tags", .visible_width = null, .rounded_corners = true, .render_content = session.is_terminal }); │ │1816 - errdefer tags.deinit(allocator); │ │1817 - tags.getFocus().mode = .all; │ │1815 + var labels = try wgt.TextInput.init(allocator, .{ .label = " labels (separate with spaces) ", .name = "labels", .visible_width = null, .rounded_corners = true, .render_content = session.is_terminal });│ │1816 + errdefer labels.deinit(allocator); │ │1817 + labels.getFocus().mode = .all; │ │1818 if (saved_fields) |saved| │ │1819 - try tags.setContent(allocator, saved.tags) │ │1819 + try labels.setContent(allocator, saved.labels) │ │1820 else if (record) |r| │ │1821 - try tags.setContent(allocator, r.event.tags); │ │1822 - try box.children.put(allocator, tags.getFocus().id, .{ .widget = .{ .text_input = tags }, .rect = null, .min_size = .{ .width = null, .height = 3 } }); │ │1821 + try labels.setContent(allocator, r.event.labels); │ │1822 + try box.children.put(allocator, labels.getFocus().id, .{ .widget = .{ .text_input = labels }, .rect = null, .min_size = .{ .width = null, .height = 3 } }); │ │1823 } │ │1824 │ │1825 { │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────╮ │1949 try addLabel(allocator, &box, "title conflict:"); │ │1950 try addFieldConflict(allocator, &box, session, data, "title", fc); │ │1951 } │ │1952 - if (conflict.tags) |*fc| { │ │1953 - try addLabel(allocator, &box, "tags conflict:"); │ │1954 - try addFieldConflict(allocator, &box, session, data, "tags", fc); │ │1952 + if (conflict.labels) |*fc| { │ │1953 + try addLabel(allocator, &box, "labels conflict:"); │ │1954 + try addFieldConflict(allocator, &box, session, data, "labels", fc);│ │1955 } │ │1956 if (comptime @hasField(Data.Conflict, "status")) { │ │1957 if (conflict.status) |*fc| { │ ╰─────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────╮ │2147 return &self.viewStack().children.values()[index].box; │ │2148 } │ │2149 │ │2150 - // the tags view's flow inside the stack. │ │2151 - fn tagsView(self: *This) *TagFlow { │ │2152 - return &self.viewStack().children.values()[tags_view_index].tag_flow; │ │2150 + // the labels view's flow inside the stack. │ │2151 + fn labelsView(self: *This) *WordFlow { │ │2152 + return &self.viewStack().children.values()[labels_view_index].word_flow;│ │2153 } │ │2154 │ │2155 // the non-confirmation form inside the stack │ ╰──────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────╮ │2228 return stack.children.getIndex(cid); │ │2229 } │ │2230 │ │2231 - // the stack's selected master-detail split (null when the tags view or the │ │2231 + // the stack's selected master-detail split (null when the labels view or the│ │2232 // new-thread form shows). │ │2233 fn selectedSplitIndex(self: *This) ?usize { │ │2234 const idx = self.stackSelectedIndex() orelse return null; │ ╰───────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────╮ │2246 return self.box.children.getIndex(cid) == header_index;│ │2247 } │ │2248 │ │2249 - fn tagsViewActive(self: *This) bool { │ │2249 + fn labelsViewActive(self: *This) bool { │ │2250 if (self.headerActive()) return false; │ │2251 - return self.stackSelectedIndex() == tags_view_index; │ │2251 + return self.stackSelectedIndex() == labels_view_index; │ │2252 } │ │2253 │ │2254 fn formViewActive(self: *This) bool { │ ╰─────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │2357 // the query; other keys move within the sub-header. │ │2358 if (inp.vertDirection(key) == .down) { │ │2359 const enterable = if (self.viewStack().getSelected()) |selected| switch (selected.*) {│ │2360 - .tag_flow => |*tf| tf.text_boxes.items.len > 0, │ │2360 + .word_flow => |*tf| tf.text_boxes.items.len > 0, │ │2361 // nothing focusable in the unauthorized view │ │2362 .unauthorized => false, │ │2363 else => true, │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────╮ │2373 } │ │2374 return; │ │2375 } │ │2376 - if (self.tagsViewActive()) { │ │2377 - self.tagsViewInput(key, root_focus); │ │2376 + if (self.labelsViewActive()) { │ │2377 + self.labelsViewInput(key, root_focus);│ │2378 return; │ │2379 } │ │2380 if (self.formViewActive()) { │ ╰────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────╮ │2399 } │ │2400 } │ │2401 │ │2402 - // navigate to the typed query's results, keeping the tag filter and the │ │2402 + // navigate to the typed query's results, keeping the label filter and the│ │2403 // status list the page shows. an empty box clears a filtered page and │ │2404 // does nothing on any other one. │ │2405 fn submitSearch(self: *This, text: []const u8) !void { │ ╰────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────╮ │next →│ ╰──────╯