╭──────────╮ │← previous│ ╰──────────╯ ╭ changed ──────╮ │src/ui/Home.zig│ ╰───────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │69 errdefer stack.deinit(allocator); │ │70 │ │71 { │ │72 - var users_view = try Users.View.init(allocator, &data.users); │ │72 + var users_view = try Users.View.init(allocator, &data.users, !session.is_terminal); │ │73 errdefer users_view.deinit(allocator); │ │74 try stack.children.put(allocator, users_view.getFocus().id, .{ .home_users = users_view });│ │75 } │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │76 │ │77 { │ │78 - var repos_view = try Repos.View.init(allocator, &data.repos); │ │78 + var repos_view = try Repos.View.init(allocator, &data.repos, !session.is_terminal); │ │79 errdefer repos_view.deinit(allocator); │ │80 try stack.children.put(allocator, repos_view.getFocus().id, .{ .home_repos = repos_view });│ │81 } │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭ changed ────────────╮ │src/ui/Home/Repos.zig│ ╰─────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────╮ │70 list: ui.FlowBox.Scroll, │ │71 data: *const Self, │ │72 │ │73 - pub fn init(allocator: std.mem.Allocator, data: *const Self) !View { │ │73 + pub fn init(allocator: std.mem.Allocator, data: *const Self, web_native: bool) !View {│ │74 var self = blk: { │ │75 - var list = try ui.FlowBox.Scroll.init(allocator, .{}); │ │75 + var list = try ui.FlowBox.Scroll.init(allocator, .{}, web_native); │ │76 errdefer list.deinit(allocator); │ │77 │ │78 break :blk View{ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ ╭ changed ────────────╮ │src/ui/Home/Users.zig│ ╰─────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────╮ │64 list: ui.FlowBox.Scroll, │ │65 data: *const Self, │ │66 │ │67 - pub fn init(allocator: std.mem.Allocator, data: *const Self) !View { │ │67 + pub fn init(allocator: std.mem.Allocator, data: *const Self, web_native: bool) !View { │ │68 var self = blk: { │ │69 - var list = try ui.FlowBox.Scroll.init(allocator, .{ .cell_height = 1 }); │ │69 + var list = try ui.FlowBox.Scroll.init(allocator, .{ .cell_height = 1 }, web_native);│ │70 errdefer list.deinit(allocator); │ │71 │ │72 break :blk View{ │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭ changed ──────────────╮ │src/ui/Repo/Commits.zig│ ╰───────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │310 try addRow(allocator, &list_box, "next →", try commitsLink(session.page_arena, data.identity, next, 0)); │ │311 } │ │312 if (list_box.children.count() > 0) list_box.getFocus().child_id = list_box.children.keys()[0]; │ │313 - break :blk try wgt.Scroll(ui.Widget).init(allocator, .{ .box = list_box }, .{ .direction = .vert }); │ │313 + break :blk try wgt.Scroll(ui.Widget).init(allocator, .{ .box = list_box }, .{ .direction = .vert, .web_native = !session.is_terminal }); │ │314 }; │ │315 errdefer list_scroll.deinit(allocator); │ │316 try box.children.put(allocator, list_scroll.getFocus().id, .{ .widget = .{ .scroll = list_scroll }, .rect = null, .min_size = .{ .width = list_max_width, .height = null }, .max_size = .{ .width = list_max_width, .height = null } });│ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │322 var diff_scroll = blk2: { │ │323 var diff_inner = try wgt.Box(ui.Widget).init(allocator, .{ .border_style = null, .direction = .vert }); │ │324 errdefer diff_inner.deinit(allocator); │ │325 - break :blk2 try wgt.Scroll(ui.Widget).init(allocator, .{ .box = diff_inner }, .{ .direction = .both }); │ │325 + break :blk2 try wgt.Scroll(ui.Widget).init(allocator, .{ .box = diff_inner }, .{ .direction = .both, .web_native = !session.is_terminal });│ │326 }; │ │327 errdefer diff_scroll.deinit(allocator); │ │328 var outer = try wgt.Box(ui.Widget).init(allocator, .{ .border_style = .hidden, .direction = .vert }); │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │472 const both_panes_fit = if (constraint.max_size.width) |w| w >= list_max_width + diff_min_width else true; │ │473 self.box.children.values()[list_index].max_size = if (both_panes_fit) .{ .width = list_max_width, .height = null } else null;│ │474 │ │475 - // web browsers provide scrolling, so let every widget grow to │ │476 - // its natural size instead of clipping inside the diff scroll │ │477 - const build_constraint = if (self.session.is_terminal) constraint else layout.Constraint{ │ │478 - .min_size = .{ .width = null, .height = null }, │ │479 - .max_size = .{ .width = null, .height = null }, │ │480 - }; │ │481 - try self.box.build(allocator, build_constraint, root_focus); │ │475 + // the web bounds the layout to the browser viewport like the terminal; │ │476 + // each Scroll's web-native mode hands its full content to a real │ │477 + // scrollable element, so we no longer build unbounded here. │ │478 + try self.box.build(allocator, constraint, root_focus); │ │479 │ │480 // if the diff pane is selected but focus is still elsewhere in this view, │ │481 // the pane was too narrow to lay out when focus crossed over. it's laid │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │514 } │ │515 if (commit.has_more) try self.addNavLink(allocator, inner, "next →", commit.oid, commit.window_start + diff_page);│ │516 │ │517 + // reset the scroll to the top for the newly-shown commit: directly on the │ │518 + // terminal (the wasm offset), and via a version bump on the web (so the │ │519 + // renderer's scroll id changes and JS drops the preserved position). │ │520 const sc = self.diffScroll(); │ │521 sc.x = 0; │ │522 sc.y = 0; │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │523 + sc.getFocus().version +%= 1; │ │524 } │ │525 │ │526 pub fn input(self: *View, allocator: std.mem.Allocator, key: inp.Key, root_focus: *Focus) !void {│ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────╮ │537 // jump a fixed amount. right/Enter cross into the diff pane. Enter/clicks │ │538 // on the "next" row become navigation in the host before reaching here. │ │539 switch (key) { │ │539 - .arrow_right, .enter => try self.focusDiff(root_focus), │ │540 + .enter => if (self.selectedCommitIndex() != null) │ │541 + try self.focusDiff(root_focus) │ │542 + else if (self.data.next_start) |next| { │ │543 + if (ui.RoutablePage.repoCommitsRoute(self.data.identity, next, 0)) |route|│ │544 + try self.session.navigate(route); │ │545 + }, │ │546 + .arrow_right => try self.focusDiff(root_focus), │ │547 .arrow_down => try self.moveSelection(root_focus, 1), │ │548 .arrow_up => try self.moveSelection(root_focus, -1), │ │549 .page_down => try self.moveSelection(root_focus, page_rows), │ ╰───────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────╮ │next →│ ╰──────╯