You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

MultiplayerEditor.tsx 1.8KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. /* eslint-disable @typescript-eslint/no-non-null-assertion */
  2. import * as React from 'react'
  3. import { Tldraw, TldrawApp, useFileSystem } from '@tldraw/tldraw'
  4. import { createClient } from '@liveblocks/client'
  5. import { LiveblocksProvider, RoomProvider } from '@liveblocks/react'
  6. import { useAccountHandlers } from '-hooks/useAccountHandlers'
  7. import { styled } from '-styles'
  8. import { useMultiplayerState } from '-hooks/useMultiplayerState'
  9. const client = createClient({
  10. publicApiKey: process.env.NEXT_PUBLIC_LIVEBLOCKS_PUBLIC_API_KEY || '',
  11. throttle: 80,
  12. })
  13. export default function MultiplayerEditor({
  14. roomId,
  15. isUser = false,
  16. isSponsor = false,
  17. }: {
  18. roomId: string
  19. isUser: boolean
  20. isSponsor: boolean
  21. }) {
  22. return (
  23. <LiveblocksProvider client={client}>
  24. <RoomProvider id={roomId} defaultStorageRoot={TldrawApp.defaultDocument}>
  25. <Editor roomId={roomId} isSponsor={isSponsor} isUser={isUser} />
  26. </RoomProvider>
  27. </LiveblocksProvider>
  28. )
  29. }
  30. // Inner Editor
  31. function Editor({
  32. roomId,
  33. isUser,
  34. isSponsor,
  35. }: {
  36. roomId: string
  37. isUser: boolean
  38. isSponsor: boolean
  39. }) {
  40. const fileSystemEvents = useFileSystem()
  41. const { onSignIn, onSignOut } = useAccountHandlers()
  42. const { error, ...events } = useMultiplayerState(roomId)
  43. if (error) return <LoadingScreen>Error: {error.message}</LoadingScreen>
  44. return (
  45. <div className="tldraw">
  46. <Tldraw
  47. autofocus
  48. showPages={false}
  49. showSponsorLink={isSponsor}
  50. onSignIn={isSponsor ? undefined : onSignIn}
  51. onSignOut={isUser ? onSignOut : undefined}
  52. {...fileSystemEvents}
  53. {...events}
  54. />
  55. </div>
  56. )
  57. }
  58. const LoadingScreen = styled('div', {
  59. position: 'absolute',
  60. top: 0,
  61. left: 0,
  62. width: '100%',
  63. height: '100%',
  64. display: 'flex',
  65. alignItems: 'center',
  66. justifyContent: 'center',
  67. })