╭ changed ─────────────╮ │src/ui/Repo/Issues.zig│ ╰──────────────────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭──────────╮ │← previous│ ╰──────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │636 var tag_iter = evt.Issue.tagIterator(entry.issue.tags); │ │637 while (tag_iter.next()) |tag| { │ │638 if (tag.len == 0) continue; │ │505 - try items.append(allocator, .{ .text = tag, .link = try tagLink(self.session.page_arena, self.data.identity, tag) }); │ │639 + try items.append(allocator, .{ .text = tag, .link = try tagLink(self.session.page_arena, self.data.identity, splitStatus(index), tag) });│ │640 } │ │641 if (items.items.len > 0) { │ │642 var tf = try ui.TagFlow.init(allocator); │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │649 // the description as a focusable word-wrapped text box. its hidden │ │650 // border reserves the space the border occupies when focused, so │ │651 // focusing doesn't shift layout. │ │518 - self.description_id = blk: { │ │652 + self.description_id[index] = blk: { │ │653 var tb = try wgt.TextBox(ui.Widget).init(allocator, entry.issue.description, .{ .border_style = .hidden, .rounded_corners = true, .wrap_kind = .word });│ │654 errdefer tb.deinit(allocator); │ │655 tb.getFocus().focusable = true; │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────╮ │658 }; │ │659 │ │660 // select the description by default │ │527 - inner.getFocus().child_id = self.description_id; │ │661 + inner.getFocus().child_id = self.description_id[index]; │ │662 │ │663 // reset the scroll to the top for the newly-shown issue: directly on the│ │664 // terminal (the wasm offset), and via a version bump on the web (so the │ ╰──────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────╮ │665 // renderer's scroll id changes and JS drops the preserved position).│ │532 - const sc = self.detailScroll(); │ │666 + const sc = self.detailScroll(index); │ │667 sc.x = 0; │ │668 sc.y = 0; │ │669 sc.getFocus().version +%= 1; │ ╰──────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │671 │ │672 pub fn input(self: *View, allocator: std.mem.Allocator, key: Key, root_focus: *Focus) !void { │ │673 if (self.headerActive()) { │ │540 - // down from the tabs re-enters the split; other keys move the tabs. │ │674 + // down from the tabs re-enters the stack if the selected view has │ │675 + // something to focus; other keys move the tabs. │ │676 if (inp.vertDirection(key) == .down) { │ │542 - root_focus.setFocus(self.box.children.keys()[stack_index]); │ │677 + const enterable = if (self.viewStack().getSelected()) |selected| switch (selected.*) {│ │678 + .tag_flow => |*tf| tf.text_boxes.items.len > 0, │ │679 + else => true, │ │680 + } else false; │ │681 + if (enterable) root_focus.setFocus(self.box.children.keys()[stack_index]); │ │682 } else { │ │683 try self.header().input(allocator, key, root_focus); │ │684 } │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────╮ │686 } │ │687 if (self.tagsViewActive()) { │ │688 self.tagsViewInput(key, root_focus); │ │550 - } else if (self.detailActive()) { │ │551 - try self.detailInput(key, root_focus); │ │689 + return; │ │690 + } │ │691 + const i = self.selectedSplitIndex() orelse return;│ │692 + if (self.detailActive(i)) { │ │693 + try self.detailInput(i, key, root_focus); │ │694 } else { │ │553 - try self.listInput(key, root_focus); │ │695 + try self.listInput(i, key, root_focus); │ │696 } │ │697 } │ │698 │ ╰───────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────╮ │714 } │ │715 } │ │716 │ │575 - fn listInput(self: *View, key: Key, root_focus: *Focus) !void { │ │717 + fn listInput(self: *View, index: usize, key: Key, root_focus: *Focus) !void {│ │718 // up/down (and the scroll wheel) move the selection a row; page up/down │ │719 // jump a fixed amount. right/Enter cross into the detail pane. up from │ │720 // the top row crosses into the header tabs. │ ╰──────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │579 - if (inp.rowDelta(key, @intCast(self.listBox().children.count()))) |delta| { │ │580 - const lb = self.listBox(); │ │721 + if (inp.rowDelta(key, @intCast(self.listBox(index).children.count()))) |delta| { │ │722 + const lb = self.listBox(index); │ │723 const at_top = if (lb.getFocus().child_id) |cid| lb.children.getIndex(cid) == 0 else true;│ │724 if (delta < 0 and at_top) return self.focusHeader(root_focus); │ │583 - ui.moveRowFocus(lb, self.listScroll(), root_focus, delta); │ │725 + ui.moveRowFocus(lb, self.listScroll(index), root_focus, delta); │ │726 return; │ │727 } │ │728 switch (key) { │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────╮ │587 - .enter, .arrow_right => try self.focusDetail(root_focus), │ │729 + .enter, .arrow_right => try self.focusDetail(index, root_focus),│ │730 else => {}, │ │731 } │ │732 } │ ╰─────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────╮ │733 │ │592 - fn detailInput(self: *View, key: Key, root_focus: *Focus) !void { │ │593 - if (self.tagsFocused()) { │ │594 - try self.tagsInput(key, root_focus); │ │734 + fn detailInput(self: *View, index: usize, key: Key, root_focus: *Focus) !void {│ │735 + if (self.tagsFocused(index)) { │ │736 + try self.tagsInput(index, key, root_focus); │ │737 } else { │ │596 - try self.descriptionInput(key, root_focus); │ │738 + try self.descriptionInput(index, key, root_focus); │ │739 } │ │740 } │ │741 │ ╰────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────╮ │next →│ ╰──────╯