cleanup
This commit is contained in:
parent
0a23ad61b6
commit
be8c85eb5f
4 changed files with 50 additions and 115 deletions
|
@ -4,6 +4,7 @@ import { Tldraw, TldrawApp, useFileSystem } from '@tldraw/tldraw'
|
|||
import { useAccountHandlers } from 'hooks/useAccountHandlers'
|
||||
import { useMultiplayerAssets } from 'hooks/useMultiplayerAssets'
|
||||
import { useMultiplayerState } from 'hooks/useMultiplayerState'
|
||||
import { useUploadAssets } from 'hooks/useUploadAssets'
|
||||
import React, { FC } from 'react'
|
||||
import { styled } from 'styles'
|
||||
|
||||
|
@ -42,7 +43,8 @@ function Editor({ roomId, isUser, isSponsor }: Props) {
|
|||
const fileSystemEvents = useFileSystem()
|
||||
const { onSignIn, onSignOut } = useAccountHandlers()
|
||||
const { error, ...events } = useMultiplayerState(roomId)
|
||||
const { onAssetCreate, onAssetUpload, onAssetDelete } = useMultiplayerAssets()
|
||||
const { onAssetCreate, onAssetDelete } = useMultiplayerAssets()
|
||||
const { onAssetUpload } = useUploadAssets()
|
||||
|
||||
if (error) return <LoadingScreen>Error: {error.message}</LoadingScreen>
|
||||
|
||||
|
|
|
@ -32,70 +32,10 @@ export function useMultiplayerAssets() {
|
|||
[]
|
||||
)
|
||||
|
||||
const onAssetUpload = useCallback(
|
||||
// Send the asset to our upload endpoint, which in turn will send it to AWS and
|
||||
// respond with the URL of the uploaded file.
|
||||
async (app: TldrawApp, file: File, id: string): Promise<string | false> => {
|
||||
const filename = encodeURIComponent(file.name)
|
||||
|
||||
const fileType = encodeURIComponent(file.type)
|
||||
|
||||
const res = await fetch(`/api/upload?file=${filename}&fileType=${fileType}`)
|
||||
|
||||
const { url, fields } = await res.json()
|
||||
|
||||
const formData = new FormData()
|
||||
|
||||
Object.entries({ ...fields, file }).forEach(([key, value]) => {
|
||||
formData.append(key, value as any)
|
||||
})
|
||||
|
||||
const upload = await fetch(url, {
|
||||
method: 'POST',
|
||||
body: formData,
|
||||
})
|
||||
|
||||
if (!upload.ok) return false
|
||||
|
||||
return url + '/' + filename
|
||||
},
|
||||
[]
|
||||
)
|
||||
|
||||
const onAssetUpload = useCallback(
|
||||
// Send the asset to our upload enpoint, which in turn will send it to AWS and
|
||||
// respond with the URL of the uploaded file.
|
||||
async (app: TldrawApp, id: string, asset: TDAsset): Promise<string | false> => {
|
||||
const filename = encodeURIComponent(asset.id)
|
||||
|
||||
const fileType = encodeURIComponent(asset.type)
|
||||
|
||||
const res = await fetch(`/api/upload?file=${filename}&fileType=${fileType}`)
|
||||
|
||||
const { url, fields } = await res.json()
|
||||
|
||||
const formData = new FormData()
|
||||
|
||||
Object.entries({ ...fields, asset }).forEach(([key, value]) => {
|
||||
formData.append(key, value as any)
|
||||
})
|
||||
|
||||
const upload = await fetch(url, {
|
||||
method: 'POST',
|
||||
body: formData,
|
||||
})
|
||||
|
||||
if (!upload.ok) return false
|
||||
|
||||
return url + '/' + filename
|
||||
},
|
||||
[]
|
||||
)
|
||||
|
||||
const onAssetDelete = useCallback(async (app: TldrawApp, id: string): Promise<boolean> => {
|
||||
// noop
|
||||
return true
|
||||
}, [])
|
||||
|
||||
return { onAssetCreate, onAssetUpload, onAssetDelete }
|
||||
return { onAssetCreate, onAssetDelete }
|
||||
}
|
||||
|
|
|
@ -1,18 +1,28 @@
|
|||
import type { NextApiRequest, NextApiResponse } from 'next'
|
||||
import { NextApiRequest, NextApiResponse } from 'next'
|
||||
import { TDDocument } from '@tldraw/tldraw'
|
||||
import { Utils } from '@tldraw/core'
|
||||
|
||||
type RequestBody = {
|
||||
pageId: string
|
||||
document: TDDocument
|
||||
}
|
||||
|
||||
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
|
||||
// 1. Get an authentication token from Liveblocks
|
||||
|
||||
const requestBody = {
|
||||
const { token } = await fetch('https://liveblocks.io/api/authorize', {
|
||||
headers: {
|
||||
Authorization: `Bearer ${process.env.LIVEBLOCKS_SECRET_KEY}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
}).then(d => d.json())
|
||||
|
||||
// 2. Create the Liveblocks storage JSON
|
||||
|
||||
const { pageId, document } = JSON.parse(req.body) as RequestBody
|
||||
|
||||
const storageJson = {
|
||||
liveblocksType: 'LiveObject',
|
||||
data: {
|
||||
version: 2.1,
|
||||
|
@ -31,45 +41,32 @@ export default async function CreateMultiplayerRoom(req: NextApiRequest, res: Ne
|
|||
},
|
||||
}
|
||||
|
||||
requestBody.data.shapes.data = document.pages[pageId].shapes ?? {}
|
||||
requestBody.data.bindings.data = document.pages[pageId].bindings ?? {}
|
||||
requestBody.data.assets.data = document.assets ?? {}
|
||||
const page = document.pages[pageId]
|
||||
|
||||
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())
|
||||
storageJson.data.shapes.data = page.shapes ?? {}
|
||||
storageJson.data.bindings.data = page.bindings ?? {}
|
||||
storageJson.data.assets.data = document.assets ?? {}
|
||||
|
||||
// // 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())
|
||||
// 3. Post the JSON and token to Liveblocks
|
||||
|
||||
const roomId = Utils.uniqueId()
|
||||
|
||||
// POST
|
||||
const result = await fetch(`https://liveblocks.net/api/v1/room/${roomId}/storage`, {
|
||||
method: 'POST',
|
||||
mode: 'cors',
|
||||
cache: 'no-cache',
|
||||
body: JSON.stringify(requestBody),
|
||||
body: JSON.stringify(storageJson),
|
||||
headers: {
|
||||
Authorization: `Bearer ${auth.token}`,
|
||||
Authorization: `Bearer ${token}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
})
|
||||
|
||||
if (result.status === 200) {
|
||||
res.send({ status: 'success', message: result.statusText, roomId })
|
||||
// If success, send back the url for the new room
|
||||
res.send({ status: 'success', message: result.statusText, url: '/r/' + roomId })
|
||||
} else {
|
||||
res.send({ status: 'error', message: result.statusText })
|
||||
throw Error(result.statusText)
|
||||
}
|
||||
} catch (e) {
|
||||
res.send({ status: 'error', message: e.message })
|
||||
// noop
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,28 +66,24 @@ export const MultiplayerMenu = React.memo(function MultiplayerMenu() {
|
|||
}
|
||||
}
|
||||
|
||||
const body = JSON.stringify({
|
||||
roomId: Utils.uniqueId(),
|
||||
pageId: app.currentPageId,
|
||||
document: nextDocument,
|
||||
})
|
||||
|
||||
const myHeaders = new Headers({
|
||||
'Access-Control-Allow-Origin': '*',
|
||||
'Content-Type': 'application/json',
|
||||
})
|
||||
|
||||
const res = await fetch(`/api/create`, {
|
||||
headers: myHeaders,
|
||||
const result = await fetch(`/api/create`, {
|
||||
method: 'POST',
|
||||
mode: 'no-cors',
|
||||
body,
|
||||
}).then(res => res.json())
|
||||
headers: {
|
||||
'Access-Control-Allow-Origin': '*',
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
roomId: Utils.uniqueId(),
|
||||
pageId: app.currentPageId,
|
||||
document: nextDocument,
|
||||
}),
|
||||
}).then(d => d.json())
|
||||
|
||||
if (res?.roomId) {
|
||||
window.location.href = `/r/${res.roomId}`
|
||||
if (result?.url) {
|
||||
window.location.href = result.url
|
||||
} else {
|
||||
TLDR.warn(res.message)
|
||||
TLDR.warn(result?.message)
|
||||
}
|
||||
} catch (e) {
|
||||
TLDR.warn((e as any).message)
|
||||
|
|
Loading…
Reference in a new issue