╭ changed ───────────╮ │src/ui/Repo/Undo.zig│ ╰────────────────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭──────────╮ │← previous│ ╰──────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │392 │ │393 pub fn input(self: *View, allocator: std.mem.Allocator, key: Key, root_focus: *Focus) !void { │ │394 + // the sub header sits above whichever content the route selects │ │395 + if (self.headerActive()) { │ │396 + if (key == .arrow_down) root_focus.setFocus(self.box.children.values()[content_index].widget.getFocus().id); │ │397 + return; │ │398 + } │ │399 + if (self.data.clear) { │ │400 + if (key == .arrow_up) root_focus.setFocus(self.headerBox().getFocus().id) else try self.clearInput(key, root_focus);│ │401 + return; │ │402 + } │ │403 + if (key == .arrow_up and self.contentAtTop()) { │ │404 + root_focus.setFocus(self.headerBox().getFocus().id); │ │405 + return; │ │406 + } │ │407 try self.refreshDetail(allocator); │ │408 if (self.detailActive()) { │ │409 const details = &self.detailScroll().child.box; │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │433 } │ │434 } │ │435 │ │337 - pub fn atTop(self: *View) bool { │ │436 + // the confirm button submits the form the web renderer posts │ │437 + fn clearInput(self: *View, key: Key, root_focus: *Focus) !void { │ │438 + const center = &self.box.children.values()[content_index].widget.center; │ │439 + const button_id = center.child.box.getFocus().child_id orelse return; │ │440 + const activated = switch (key) { │ │441 + .enter => root_focus.grandchild_id == button_id, │ │442 + .mouse => |mouse| inp.leftClickOn(root_focus, button_id, mouse), │ │443 + else => false, │ │444 + }; │ │445 + if (!activated or !self.data.can_undo) return; │ │446 + if (builtin.target.cpu.arch != .wasm32 and self.session.is_terminal and self.session.host_request == null) {│ │447 + const route = ui.RoutablePage.repoUndoClearRoute(self.data.identity) orelse return error.RouteTooLong; │ │448 + self.session.host_request = .{ .undo = route.repo_undo }; │ │449 + } │ │450 + } │ │451 + │ │452 + fn contentAtTop(self: *View) bool { │ │453 const scroll = if (self.detailActive()) self.detailScroll() else self.listScroll(); │ │454 const rows = &scroll.child.box; │ │455 const id = rows.getFocus().child_id orelse return true; │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────╮ │456 return rows.children.getIndex(id) == 0 and scroll.y == 0; │ │457 + } │ │458 + │ │459 + // moving up from the sub header returns to the page's tabs │ │460 + pub fn atTop(self: *View) bool { │ │461 + return self.headerActive(); │ │462 + } │ │463 + │ │464 + // arriving from the page's tabs lands on the sub header, not the content│ │465 + pub fn focusHeader(self: *View, root_focus: *Focus) bool { │ │466 + root_focus.setFocus(self.headerBox().getFocus().id); │ │467 + return true; │ │468 } │ │469 pub fn deinit(self: *View, allocator: std.mem.Allocator) void { │ │470 self.box.deinit(allocator); │ ╰──────────────────────────────────────────────────────────────────────────────────╯