[improvement] Add ability to copy to new multiplayer room (#693)

* Add ability to copy to new multiplayer room

* cleanup
This commit is contained in:
Steve Ruiz 2022-05-18 16:59:30 +01:00 committed by GitHub
parent 1d3b419baf
commit 13f5787c31
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 109 additions and 11 deletions

View file

@ -1,10 +1,10 @@
import { createClient } from '@liveblocks/client'
import { LiveblocksProvider, RoomProvider } from '@liveblocks/react'
import { Tldraw, useFileSystem } from '@tldraw/tldraw'
import { Tldraw, TldrawApp, useFileSystem } from '@tldraw/tldraw'
import { useAccountHandlers } from 'hooks/useAccountHandlers'
import { useMultiplayerAssets } from 'hooks/useMultiplayerAssets'
import { useMultiplayerState } from 'hooks/useMultiplayerState'
import { FC } from 'react'
import React, { FC } from 'react'
import { styled } from 'styles'
const client = createClient({

View file

@ -209,9 +209,16 @@ export function useMultiplayerState(roomId: string) {
// Update the document with initial content
handleChanges()
// Zoom to fit the content
app.zoomToFit()
if (app.zoom > 1) {
app.resetZoom()
}
setLoading(false)
}
}
setupDocument()
return () => {

View file

@ -29,6 +29,8 @@
"@tldraw/tldraw": "^1.12.4",
"@types/next-auth": "^3.15.0",
"aws-sdk": "^2.1053.0",
"lz-string": "^1.4.4",
"nanoid": "^3.3.4",
"next": "^12.0.7",
"next-auth": "^4.0.5",
"next-pwa": "^5.4.4",

View file

@ -0,0 +1,73 @@
import type { NextApiRequest, NextApiResponse } from 'next'
import { TDDocument } from '@tldraw/tldraw'
export default async function CreateMultiplayerRoom(req: NextApiRequest, res: NextApiResponse) {
const { body } = req
try {
const json = JSON.parse(body) as {
roomId: string
pageId: string
document: TDDocument
}
const { roomId, pageId, document } = json
const requestBody = {
liveblocksType: 'LiveObject',
data: {
version: 2.1,
shapes: {
liveblocksType: 'LiveMap',
data: {},
},
bindings: {
liveblocksType: 'LiveMap',
data: {},
},
assets: {
liveblocksType: 'LiveMap',
data: {},
},
},
}
requestBody.data.shapes.data = document.pages[pageId].shapes ?? {}
requestBody.data.bindings.data = document.pages[pageId].bindings ?? {}
requestBody.data.assets.data = document.assets ?? {}
const auth = await fetch('https://liveblocks.io/api/authorize', {
headers: {
Authorization: `Bearer ${process.env.LIVEBLOCKS_SECRET_KEY}`,
'Content-Type': 'application/json',
},
}).then((d) => d.json())
// // GET
// const result = await fetch(`https://liveblocks.net/api/v1/room/1652883688619/storage`, {
// method: 'GET',
// headers: {
// Authorization: `Bearer ${auth.token}`,
// 'Content-Type': 'application/json',
// },
// }).then((d) => d.json())
//POST
const result = await fetch(`https://liveblocks.net/api/v1/room/${roomId}/storage`, {
method: 'POST',
mode: 'cors',
cache: 'no-cache',
body: JSON.stringify(requestBody),
headers: {
Authorization: `Bearer ${auth.token}`,
'Content-Type': 'application/json',
},
})
if (result.status === 200) {
res.send({ status: 'success', roomId })
}
} catch (e) {
res.send({ status: 'error' })
// noop
}
}

View file

@ -19,6 +19,7 @@ export default function Room({ id, isUser, isSponsor }: RoomProps) {
export const getServerSideProps: GetServerSideProps = async (context) => {
const session = await getSession(context)
const id = context.query.id?.toString()
return {
props: {
id,

View file

@ -4,8 +4,8 @@ export function MultiplayerIcon() {
return (
<svg width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
fill-rule="evenodd"
clip-rule="evenodd"
fillRule="evenodd"
clipRule="evenodd"
d="M5.73545 0.0494623C5.93029 -0.0395285 6.15915 -0.00663838 6.32104 0.133622L14.8111 7.48911C14.9804 7.63581 15.0432 7.87091 14.9696 8.08249C14.8959 8.29408 14.7007 8.4394 14.4769 8.44927L11.4564 8.58248L13.2249 12.4682C13.35 12.7431 13.2286 13.0675 12.9537 13.1927L10.9304 14.1145C10.6554 14.2397 10.331 14.1184 10.2057 13.8435L8.43441 9.95846L6.42883 12.0731L7.0482 13.434C7.17335 13.709 7.05195 14.0333 6.77702 14.1586L5.03829 14.9506C4.76335 15.0759 4.43894 14.9546 4.31361 14.6797L2.83886 11.445L1.13458 13.242C0.980476 13.4045 0.742914 13.4566 0.534904 13.3737C0.326893 13.2907 0.19043 13.0894 0.19043 12.8654V3.2218C0.19043 3.0076 0.315424 2.81309 0.510266 2.7241C0.705108 2.63511 0.933961 2.668 1.09586 2.80826L5.41561 6.55076V0.547159C5.41561 0.332956 5.54061 0.138453 5.73545 0.0494623ZM6.74741 10.147L6.50992 10.3974V10.1575V9.0621V8.94669V7.49882V1.74513L13.0561 7.41656L10.5986 7.52495C10.417 7.53296 10.2512 7.63066 10.1562 7.78567C10.1444 7.80505 10.1338 7.825 10.1245 7.84541C10.0596 7.98828 10.0589 8.15342 10.1247 8.2982V8.2982L12.0023 12.4236L10.9745 12.8919L9.09356 8.7663C9.0181 8.60079 8.86531 8.4836 8.68589 8.45361C8.50647 8.42363 8.32389 8.48478 8.19871 8.61676L8.019 8.80624L6.74741 10.147ZM5.41561 9.11037V7.99863L1.28473 4.41977V11.4934L2.60315 10.1033C2.72833 9.97131 2.91091 9.91016 3.09033 9.94014C3.26975 9.97013 3.42254 10.0873 3.498 10.2528L5.08241 13.728L5.82563 13.3895L4.24404 9.91441C4.16873 9.74894 4.18053 9.55687 4.27553 9.40186C4.37052 9.24685 4.53631 9.14915 4.71793 9.14114L5.41561 9.11037Z"
fill="currentColor"
/>

View file

@ -7,6 +7,7 @@ import { SmallIcon } from '~components/Primitives/SmallIcon'
import { MultiplayerIcon } from '~components/Primitives/icons'
import type { TDSnapshot } from '~types'
import { TLDR } from '~state/TLDR'
import { Utils } from '@tldraw/core'
const roomSelector = (state: TDSnapshot) => state.room
@ -42,20 +43,27 @@ export const MultiplayerMenu = React.memo(function MultiplayerMenu() {
}, [])
const handleCopyToMultiplayerRoom = React.useCallback(async () => {
const body = JSON.stringify({
roomId: Utils.uniqueId(),
pageId: app.currentPageId,
document: app.document,
})
const myHeaders = new Headers({
'Access-Control-Allow-Origin': '*',
'Content-Type': 'application/json',
})
const res = await fetch('http://tldraw.com/api/create-multiplayer-room', {
const res = await fetch(`/api/create`, {
headers: myHeaders,
method: 'POST',
mode: 'cors',
cache: 'no-cache',
body: JSON.stringify(app.document),
mode: 'no-cors',
body,
}).then((res) => res.json())
window.location.href = `http://tldraw.com/r/${res.roomId}`
if (res?.roomId) {
window.location.href = `/r/${res.roomId}`
}
}, [])
return (
@ -71,7 +79,9 @@ export const MultiplayerMenu = React.memo(function MultiplayerMenu() {
<DMItem id="TD-Multiplayer-CreateMultiplayerRoom" onClick={handleCreateMultiplayerRoom}>
<a href="https://tldraw.com/r">Create a Multiplayer Project</a>
</DMItem>
{/* <DMItem id="TD-Multiplayer-CopyToMultiplayerRoom" onClick={handleCopyToMultiplayerRoom}>Copy to Multiplayer Room</DMItem> */}
<DMItem id="TD-Multiplayer-CopyToMultiplayerRoom" onClick={handleCopyToMultiplayerRoom}>
Copy to Multiplayer Room
</DMItem>
</DMContent>
</DropdownMenu.Root>
)

View file

@ -8482,6 +8482,11 @@ nanoid@^3.1.30, nanoid@^3.1.31, nanoid@^3.2.0:
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.2.0.tgz#62667522da6673971cca916a6d3eff3f415ff80c"
integrity sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==
nanoid@^3.3.4:
version "3.3.4"
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.4.tgz#730b67e3cd09e2deacf03c027c81c9d9dbc5e8ab"
integrity sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==
napi-build-utils@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/napi-build-utils/-/napi-build-utils-1.0.2.tgz#b1fddc0b2c46e380a0b7a76f984dd47c41a13806"