╭ changed ──────╮ │src/ui/Repo.zig│ ╰───────────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭─────────────────────────────────────────────────────────────╮ │209 .repo_events => |e| e.view, │ │210 else => .active, │ │211 }; │ │212 + const events_moment: ?u64 = switch (route) { │ │213 + .repo_events => |e| e.moment, │ │214 + else => null, │ │215 + }; │ │216 const events_selected: []const u8 = switch (route) {│ │217 .repo_events => |*e| e.selected.slice(), │ │218 else => "", │ ╰─────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │265 // a server shows events to whoever it shows undo to, so the route follows │ │266 if (route == .repo_events and session.data.host_kind != .local and !undo_allowed) return error.NotFound;│ │267 const undo_index = if (route == .repo_undo) route.repo_undo.index else null; │ │264 - var undo_data: ?Undo = null; │ │268 + // an unreadable repo still shows the tab, like every other tab │ │269 + var undo_data: ?Undo = if (undo_allowed) .{ .identity = repo_identity.identity } else null; │ │270 const files, const changes, const refs, var issues, var patches, var discussions, const events = blk: { │ │271 read: { │ │272 const io = session.io orelse break :read; │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │283 try evt.consume(.local, .repo, repo_kind, opened.self_repo_opts, io, gpa, opened, evt.events_ref, &.{}); │ │284 try pch.refreshBranches(.local, repo_kind, opened.self_repo_opts, io, gpa, opened, null, null); │ │285 } │ │281 - if (repo_kind == .xit and undo_allowed) undo_data = try Undo.init(opened.self_repo_opts, arena, opened, repo_identity.identity, undo_index);│ │286 + // tabs switch in-page, so every tab's data is read here │ │287 + if (repo_kind == .xit and undo_allowed) { │ │288 + undo_data = Undo.init(opened.self_repo_opts, arena, opened, repo_identity.identity, undo_index) catch |err| switch (err) { │ │289 + error.OutOfMemory => return err, │ │290 + else => .{ .identity = repo_identity.identity, .failure = @errorName(err) }, │ │291 + }; │ │292 + } │ │293 const files_data = if (patchrev_id.len != 0) │ │294 try Files.initPatchRev(repo_kind, opened.self_repo_opts, arena, opened, io, gpa, location, patchrev_id, files_dir, files_line) │ │295 else │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │308 try Issues.init(repo_kind, opened.self_repo_opts, arena, opened, io, session.haxy_moment, repo_identity.identity, issues_tag, issues_search, issues_selected, issues_comment, issues_comments_start, issues_theirs, issues_view), │ │309 try Patches.init(repo_kind, opened.self_repo_opts, arena, opened, io, session.haxy_moment, session, repo_id_maybe, repo_identity.identity, target_branch, patches_tag, patches_search, patches_selected, patches_comment, patches_comments_start, patches_theirs, patches_view),│ │310 try Discussions.init(repo_kind, opened.self_repo_opts, arena, opened, io, session.haxy_moment, repo_identity.identity, discussions_tag, discussions_search, discussions_selected, discussions_comment, discussions_comments_start, discussions_view), │ │300 - try Events.init(repo_kind, opened.self_repo_opts, arena, opened, io, session.haxy_moment, repo_identity.identity, events_view, events_kind, events_selected, session.local != null, session.data.sync_failure), │ │311 + try Events.init(repo_kind, opened.self_repo_opts, arena, opened, io, session.haxy_moment, repo_identity.identity, events_view, events_kind, events_selected, events_moment, session.local != null, session.data.sync_failure), │ │312 }; │ │313 }, │ │314 } │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │326 try Events.empty(aa, repo_identity.identity, events_view, session.local != null, session.data.sync_failure),│ │327 }; │ │328 }; │ │329 + if (undo_data) |*undo| undo.can_undo = session.local != null or evt.Repo.roleOf(repo, session.userId()) == .owner; │ │330 if (route == .repo_undo and undo_data == null) return error.NotFound; │ │331 issues.repo_source = source; │ │332 patches.repo_source = source; │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯