╭ changed ─╮ │src/ui.zig│ ╰──────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │1946 } │ │1947 }; │ │1948 } │ │1949 + │ │1950 +// who a repo page is built for, which picks the actions it shows │ │1951 +pub const Viewer = struct { │ │1952 + role: evt.Repo.Role, │ │1953 + email: []const u8, │ │1954 + │ │1955 + // the session's viewer of `repo`, or null when logged out. local mode owns everything. │ │1956 + pub fn init(session: *Session, arena: *std.heap.ArenaAllocator, repo: evt.Repo.Record) !?Viewer {│ │1957 + if (session.data.host_kind == .local) return .{ .role = .owner, .email = "" }; │ │1958 + const user_id = session.userId() orelse return null; │ │1959 + const moment = session.haxy_moment orelse unreachable; │ │1960 + const user = (try activeUser(moment, arena, user_id)) orelse return null; │ │1961 + return .{ .role = evt.Repo.roleOf(repo, user_id), .email = user.event.email }; │ │1962 + } │ │1963 +}; │ │1964 + │ │1965 +// a repo a page shows, and what its viewer may do there │ │1966 +pub const RepoHandle = struct { │ │1967 + location: RoutablePage.RepoLocation, │ │1968 + viewer: ?Viewer = null, │ │1969 + │ │1970 + pub fn dupe(self: RepoHandle, allocator: std.mem.Allocator) !RepoHandle { │ │1971 + var copy = self; │ │1972 + copy.location = try self.location.dupe(allocator); │ │1973 + return copy; │ │1974 + } │ │1975 │ │1976 + // pushing, and seeing the events and undo tabs. local mode is always owner. │ │1977 + pub fn canWrite(self: RepoHandle) bool { │ │1978 + const viewer = self.viewer orelse return false; │ │1979 + return viewer.role.atLeast(.write); │ │1980 + } │ │1981 + │ │1982 + pub fn canUndo(self: RepoHandle) bool { │ │1983 + const viewer = self.viewer orelse return false; │ │1984 + return viewer.role == .owner; │ │1985 + } │ │1986 +}; │ │1987 + │ │1988 // where a repo page reads its on-disk repo from │ │1989 pub const RepoSource = struct { │ │1990 path: []const u8, │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────╯