╭──────────╮ │← previous│ ╰──────────╯ ╭ changed ──────╮ │src/ui/Repo.zig│ ╰───────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────╮ │265 │ │266 const handle = ui.RepoHandle{ │ │267 .location = .{ .repo = try arena.allocator().dupe(u8, repo_identity.identity) },│ │265 - .viewer = try ui.Viewer.init(session, arena, repo), │ │268 + .viewer = try ui.Viewer.init(session, arena, role), │ │269 }; │ │270 │ │271 // open the repo once for every tab. files and changes share a ref or revision. │ ╰─────────────────────────────────────────────────────────────────────────────────────────────╯ ╭ changed ─────────────╮ │src/ui/Repo/Events.zig│ ╰──────────────────────╯ ╭────────────────────────────────────────────────╮ │258 .user => evt.User, │ │259 .repo => evt.Repo, │ │260 .fork => evt.Fork, │ │261 + .grant => evt.Grant, │ │262 .issue => evt.Issue, │ │263 .discuss => evt.Discussion,│ │264 .comment => evt.Comment, │ ╰────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │304 } │ │305 }, │ │306 .fork => _ = (try evt.readRecordSubset(evt.Fork, struct { removed: bool }, DB, hash_kind, haxy_moment, arena, id)) orelse return null, │ │307 + .grant => _ = (try evt.readRecordSubset(evt.Grant, struct { removed: bool }, DB, hash_kind, haxy_moment, arena, id)) orelse return null,│ │308 .issue => { │ │309 const record = (try evt.readRecordSubset(evt.Issue, Authored, DB, hash_kind, haxy_moment, arena, id)) orelse return null; │ │310 item.author = try ui.Author.initFromEmail(admin_moment, arena, record.author_email); │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭ changed ───────────╮ │src/ui/Repo/Undo.zig│ ╰────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │377 const pair = ui.RoutablePage.RepoIdentity.parse(identity) orelse return error.NotFound; │ │378 const io = session.io orelse return error.NotFound; │ │379 const users_dir = session.users_dir orelse return error.NotFound; │ │380 - const found = try evt.readRepoByOwnerAndName(io, session.page_arena.child_allocator, session.page_arena, moment, users_dir, pair.owner, pair.name) orelse return error.NotFound; │ │380 + const found = try evt.readRepoByOwnerAndName(io, session.page_arena.child_allocator, session.page_arena, moment, users_dir, pair.owner, pair.name, null) orelse return error.NotFound;│ │381 return .{ .path = try evt.repoPath(session.page_arena.allocator(), users_dir, found.repo.event.user_id, &found.event_id), .repo_kind = .xit }; │ │382 } │ │383 │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭ changed ──────╮ │src/ui/User.zig│ ╰───────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │93 _ = try pair.value_cursor.readBytes(&event_id); │ │94 const repo_event = (try evt.Repo.readById(DB, hash_kind, moment, arena, &event_id)) orelse continue; │ │95 // unreadable repos leave their window short rather than shifting the others │ │96 - if (evt.Repo.roleOf(repo_event, session.userId()) == .none) continue; │ │96 + if (try evt.Repo.roleOf(DB, hash_kind, moment, arena, repo_event, &event_id, session.userId()) == .none) continue;│ │97 try repos.append(arena.allocator(), repo_event); │ │98 } │ │99 } │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │110 const kv_cursor = (try iter.next()) orelse break; │ │111 const repo_id = try evt.readOrderKeyId(DB, kv_cursor); │ │112 const repo_event = (try evt.Repo.readById(DB, hash_kind, moment, arena, &repo_id)) orelse continue; │ │113 - if (evt.Repo.roleOf(repo_event, session.userId()) == .none) continue; │ │113 + if (try evt.Repo.roleOf(DB, hash_kind, moment, arena, repo_event, &repo_id, session.userId()) == .none) continue;│ │114 try repos.append(arena.allocator(), repo_event); │ │115 } │ │116 repos_next_start = if (end < count) end else null; │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │135 │ │136 // the target lives in its owner's user repo │ │137 const owner_id = record.event.repo_user_id[0..evt.event_id_size]; │ │138 - const target_repo = (try evt.readRepoById(io, gpa, arena, users_dir, owner_id, record.event.repo_id)) orelse continue; │ │139 - if (evt.Repo.roleOf(target_repo, session.userId()) == .none) continue; │ │138 + const target = (try evt.readRepoById(io, gpa, arena, users_dir, owner_id, record.event.repo_id[0..evt.event_id_size], session.userId())) orelse continue;│ │139 + if (target.role == .none) continue; │ │140 + const target_repo = target.repo; │ │141 │ │142 var title: []const u8 = "(unavailable)"; │ │143 const path = try fork.forkPath(arena.allocator(), users_dir, &user_id, &fork_id); │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭ changed ──╮ │src/web.zig│ ╰───────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │533 break :blk if (try ui.activeUser(moment, &arena, id) != null) id else null; │ │534 }; │ │535 const owner_repo = evt.parseOwnerRepoPath(repo_base[repo_prefix.len..]) orelse return false; │ │536 - const repo = (try evt.readRepoByOwnerAndName(io, allocator, &arena, moment, server.users_dir, owner_repo.owner, owner_repo.name)) orelse return false; │ │537 - return evt.Repo.roleOf(repo.repo, user_id) != .none; │ │536 + const repo = (try evt.readRepoByOwnerAndName(io, allocator, &arena, moment, server.users_dir, owner_repo.owner, owner_repo.name, user_id)) orelse return false;│ │537 + return repo.role != .none; │ │538 } │ │539 │ │540 // the logged-in user the request's session cookie names │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯