From 05859ebc743e76f2a703b5731a18c177218400ce Mon Sep 17 00:00:00 2001 From: Balint Gabor <127662+gbalint@users.noreply.github.com> Date: Sat, 18 Nov 2023 13:14:48 +0100 Subject: [PATCH] Store collaborators in the liveblocks room storage (#4509) --- editor/liveblocks.config.ts | 8 ++++++ .../components/canvas/multiplayer-cursors.tsx | 3 +++ .../components/editor/editor-component.tsx | 3 ++- editor/src/core/commenting/comment-hooks.tsx | 25 ++++++++++++++++++- 4 files changed, 37 insertions(+), 2 deletions(-) diff --git a/editor/liveblocks.config.ts b/editor/liveblocks.config.ts index 19a0edc61a4b..479d9d49b2dc 100644 --- a/editor/liveblocks.config.ts +++ b/editor/liveblocks.config.ts @@ -1,3 +1,4 @@ +import { LiveObject } from '@liveblocks/client' import { createClient } from '@liveblocks/client' import { createRoomContext } from '@liveblocks/react' import type { CanvasVector, WindowPoint } from './src/core/shared/math-utils' @@ -39,6 +40,13 @@ export function initialPresence(): Presence { export type Storage = { // author: LiveObject<{ firstName: string, lastName: string }>, // ... + collaborators: LiveObject<{ [userId: string]: boolean }> // this is an object (and not a list) so we can quickly check if a user is a collaborator, but later we can extend the information by storing something more than a boolean (e.g. a permission level) +} + +export function initialStorage(): Storage { + return { + collaborators: new LiveObject(), + } } // Optionally, UserMeta represents static/readonly metadata on each user, as diff --git a/editor/src/components/canvas/multiplayer-cursors.tsx b/editor/src/components/canvas/multiplayer-cursors.tsx index b92a29049c10..6b4fcd7c8eeb 100644 --- a/editor/src/components/canvas/multiplayer-cursors.tsx +++ b/editor/src/components/canvas/multiplayer-cursors.tsx @@ -14,6 +14,7 @@ import { possiblyUniqueColor, } from '../../core/shared/multiplayer' import { useKeepShallowReferenceEquality } from '../../utils/react-performance' +import { useAddMyselfToCollaborators } from '../../core/commenting/comment-hooks' export const MultiplayerCursors = React.memo(() => { const self = useSelf() @@ -44,6 +45,8 @@ export const MultiplayerCursors = React.memo(() => { 'MultiplayerCursors canvasOffset', ) + useAddMyselfToCollaborators() + React.useEffect(() => { if (!isLoggedIn(loginState)) { return diff --git a/editor/src/components/editor/editor-component.tsx b/editor/src/components/editor/editor-component.tsx index e138a7e112fe..f7052167892b 100644 --- a/editor/src/components/editor/editor-component.tsx +++ b/editor/src/components/editor/editor-component.tsx @@ -55,7 +55,7 @@ import { EditorCommon } from './editor-component-common' import { notice } from '../common/notice' import { isFeatureEnabled } from '../../utils/feature-switches' import { ProjectServerStateUpdater } from './store/project-server-state' -import { RoomProvider, initialPresence } from '../../../liveblocks.config' +import { RoomProvider, initialPresence, initialStorage } from '../../../liveblocks.config' import { generateUUID } from '../../utils/utils' import { isLiveblocksEnabled } from './liveblocks-utils' @@ -517,6 +517,7 @@ export function EditorComponent(props: EditorProps) { id={roomId} autoConnect={isLiveblocksEnabled()} initialPresence={initialPresence()} + initialStorage={initialStorage()} > | null { const { threads } = useThreads() @@ -12,3 +13,25 @@ export function useMyMultiplayerColorIndex() { const self = useSelf() return self.presence.colorIndex } + +export function useAddMyselfToCollaborators() { + const addMyselfToCollaborators = useMutation(({ storage, self }) => { + const collaborators = storage.get('collaborators') + + if (collaborators.get(self.id) !== true) { + collaborators.set(self.id, true) + } + }, []) + + const collabs = useStorage((store) => store.collaborators) + + React.useEffect(() => { + if (collabs != null) { + addMyselfToCollaborators() + } + }, [addMyselfToCollaborators, collabs]) +} + +export function useCollaborators() { + return useStorage((store) => store.collaborators) +}