Fix multiplayer room

This commit is contained in:
Steve Ruiz 2021-11-16 19:41:16 +00:00
parent d0a673931f
commit 6d3251f195
3 changed files with 30 additions and 30 deletions

View file

@ -22,21 +22,23 @@ export function Multiplayer() {
return ( return (
<LiveblocksProvider client={client}> <LiveblocksProvider client={client}>
<RoomProvider id={roomId}> <RoomProvider id={roomId}>
<TldrawWrapper /> <Editor roomId={roomId} />
</RoomProvider> </RoomProvider>
</LiveblocksProvider> </LiveblocksProvider>
) )
} }
function TldrawWrapper() { function Editor({ roomId }: { roomId: string }) {
const [docId] = React.useState(() => Utils.uniqueId()) const [docId] = React.useState(() => Utils.uniqueId())
const [error, setError] = React.useState<Error>()
const [app, setApp] = React.useState<TldrawApp>() const [app, setApp] = React.useState<TldrawApp>()
const [error, setError] = React.useState<Error>()
useErrorListener((err) => setError(err)) useErrorListener((err) => setError(err))
// Setup document
const doc = useObject<{ uuid: string; document: TDDocument }>('doc', { const doc = useObject<{ uuid: string; document: TDDocument }>('doc', {
uuid: docId, uuid: docId,
document: { document: {
@ -46,13 +48,10 @@ function TldrawWrapper() {
}) })
// Put the state into the window, for debugging. // Put the state into the window, for debugging.
const handleMount = React.useCallback( const handleMount = React.useCallback((app: TldrawApp) => {
(app: TldrawApp) => {
window.app = app window.app = app
setApp(app) setApp(app)
}, }, [])
[roomId]
)
React.useEffect(() => { React.useEffect(() => {
const room = client.getRoom(roomId) const room = client.getRoom(roomId)
@ -80,8 +79,7 @@ function TldrawWrapper() {
function handleDocumentUpdates() { function handleDocumentUpdates() {
if (!doc) return if (!doc) return
if (!app) return if (!app?.room) return
if (!app.room) return
const docObject = doc.toObject() const docObject = doc.toObject()
@ -101,7 +99,7 @@ function TldrawWrapper() {
} }
function handleExit() { function handleExit() {
if (!(app && app.room)) return if (!app?.room) return
room?.broadcastEvent({ name: 'exit', userId: app.room.userId }) room?.broadcastEvent({ name: 'exit', userId: app.room.userId })
} }

View file

@ -922,7 +922,7 @@ export class TldrawApp extends StateManager<TDSnapshot> {
* Load a fresh room into the state. * Load a fresh room into the state.
* @param roomId * @param roomId
*/ */
loadRoom = (roomId: string) => { loadRoom = (roomId: string): this => {
this.patchState({ this.patchState({
room: { room: {
id: roomId, id: roomId,
@ -938,6 +938,7 @@ export class TldrawApp extends StateManager<TDSnapshot> {
}, },
}, },
}) })
return this
} }
/** /**

View file

@ -29,7 +29,7 @@ export default function MultiplayerEditor({
}) { }) {
return ( return (
<LiveblocksProvider client={client}> <LiveblocksProvider client={client}>
<RoomProvider id={roomId}> <RoomProvider id={roomId} defaultStorageRoot={TldrawApp.defaultDocument}>
<Editor roomId={roomId} isSponsor={isSponsor} isUser={isUser} /> <Editor roomId={roomId} isSponsor={isSponsor} isUser={isUser} />
</RoomProvider> </RoomProvider>
</LiveblocksProvider> </LiveblocksProvider>
@ -57,6 +57,12 @@ function Editor({ roomId, isSponsor }: { roomId: string; isUser; isSponsor: bool
}, },
}) })
// Put the state into the window, for debugging.
const handleMount = React.useCallback((app: TldrawApp) => {
window.app = app
setApp(app)
}, [])
// Setup client // Setup client
React.useEffect(() => { React.useEffect(() => {
@ -64,12 +70,9 @@ function Editor({ roomId, isSponsor }: { roomId: string; isUser; isSponsor: bool
if (!room) return if (!room) return
if (!doc) return if (!doc) return
if (!app?.room) return if (!app) return
// Update the user's presence with the user from state app.loadRoom(roomId)
const { users, userId } = app.room
room.updatePresence({ id: userId, user: users[userId] })
// Subscribe to presence changes; when others change, update the state // Subscribe to presence changes; when others change, update the state
room.subscribe<TDUserPresence>('others', (others) => { room.subscribe<TDUserPresence>('others', (others) => {
@ -124,6 +127,13 @@ function Editor({ roomId, isSponsor }: { roomId: string; isUser; isSponsor: bool
if (newDocument) { if (newDocument) {
app.loadDocument(newDocument) app.loadDocument(newDocument)
app.loadRoom(roomId)
// Update the user's presence with the user from state
if (app.state.room) {
const { users, userId } = app.state.room
room.updatePresence({ id: userId, user: users[userId] })
}
} }
return () => { return () => {
@ -132,15 +142,6 @@ function Editor({ roomId, isSponsor }: { roomId: string; isUser; isSponsor: bool
} }
}, [doc, docId, app, roomId]) }, [doc, docId, app, roomId])
const handleMount = React.useCallback(
(app: TldrawApp) => {
window.app = app
app.loadRoom(roomId)
setApp(app)
},
[roomId]
)
const handlePersist = React.useCallback( const handlePersist = React.useCallback(
(app: TldrawApp) => { (app: TldrawApp) => {
doc?.update({ uuid: docId, document: app.document }) doc?.update({ uuid: docId, document: app.document })