Merge branch 'main' of https://github.com/tldraw/tldraw
This commit is contained in:
commit
7e85d00c66
7 changed files with 67 additions and 14 deletions
|
@ -1,5 +1,6 @@
|
||||||
import { Tldraw, TldrawApp, TldrawProps, useFileSystem } from '@tldraw/tldraw'
|
import { Tldraw, TldrawApp, TldrawProps, useFileSystem } from '@tldraw/tldraw'
|
||||||
import { useAccountHandlers } from 'hooks/useAccountHandlers'
|
import { useAccountHandlers } from 'hooks/useAccountHandlers'
|
||||||
|
import { useUploadAssets } from 'hooks/useUploadAssets'
|
||||||
import React, { FC } from 'react'
|
import React, { FC } from 'react'
|
||||||
import * as gtag from 'utils/gtag'
|
import * as gtag from 'utils/gtag'
|
||||||
|
|
||||||
|
@ -35,6 +36,8 @@ const Editor: FC<EditorProps & Partial<TldrawProps>> = ({
|
||||||
|
|
||||||
const { onSignIn, onSignOut } = useAccountHandlers()
|
const { onSignIn, onSignOut } = useAccountHandlers()
|
||||||
|
|
||||||
|
const { onAssetUpload } = useUploadAssets()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="tldraw">
|
<div className="tldraw">
|
||||||
<Tldraw
|
<Tldraw
|
||||||
|
@ -45,6 +48,7 @@ const Editor: FC<EditorProps & Partial<TldrawProps>> = ({
|
||||||
showSponsorLink={!isSponsor}
|
showSponsorLink={!isSponsor}
|
||||||
onSignIn={isSponsor ? undefined : onSignIn}
|
onSignIn={isSponsor ? undefined : onSignIn}
|
||||||
onSignOut={isUser ? onSignOut : undefined}
|
onSignOut={isUser ? onSignOut : undefined}
|
||||||
|
onAssetUpload={onAssetUpload}
|
||||||
{...fileSystemEvents}
|
{...fileSystemEvents}
|
||||||
{...rest}
|
{...rest}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -42,7 +42,7 @@ function Editor({ roomId, isUser, isSponsor }: Props) {
|
||||||
const fileSystemEvents = useFileSystem()
|
const fileSystemEvents = useFileSystem()
|
||||||
const { onSignIn, onSignOut } = useAccountHandlers()
|
const { onSignIn, onSignOut } = useAccountHandlers()
|
||||||
const { error, ...events } = useMultiplayerState(roomId)
|
const { error, ...events } = useMultiplayerState(roomId)
|
||||||
const { onAssetCreate, onAssetDelete } = useMultiplayerAssets()
|
const { onAssetCreate, onAssetUpload, onAssetDelete } = useMultiplayerAssets()
|
||||||
|
|
||||||
if (error) return <LoadingScreen>Error: {error.message}</LoadingScreen>
|
if (error) return <LoadingScreen>Error: {error.message}</LoadingScreen>
|
||||||
|
|
||||||
|
@ -57,6 +57,7 @@ function Editor({ roomId, isUser, isSponsor }: Props) {
|
||||||
onSignOut={isUser ? onSignOut : undefined}
|
onSignOut={isUser ? onSignOut : undefined}
|
||||||
onAssetCreate={onAssetCreate}
|
onAssetCreate={onAssetCreate}
|
||||||
onAssetDelete={onAssetDelete}
|
onAssetDelete={onAssetDelete}
|
||||||
|
onAssetUpload={onAssetUpload}
|
||||||
{...fileSystemEvents}
|
{...fileSystemEvents}
|
||||||
{...events}
|
{...events}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { TldrawApp } from '@tldraw/tldraw'
|
import { TDAsset, TldrawApp } from '@tldraw/tldraw'
|
||||||
import { useCallback } from 'react'
|
import { useCallback } from 'react'
|
||||||
|
|
||||||
export function useMultiplayerAssets() {
|
export function useMultiplayerAssets() {
|
||||||
|
@ -62,6 +62,36 @@ export function useMultiplayerAssets() {
|
||||||
[]
|
[]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
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> => {
|
const onAssetDelete = useCallback(async (app: TldrawApp, id: string): Promise<boolean> => {
|
||||||
// noop
|
// noop
|
||||||
return true
|
return true
|
||||||
|
|
|
@ -32,5 +32,6 @@ export function useUploadAssets() {
|
||||||
},
|
},
|
||||||
[]
|
[]
|
||||||
)
|
)
|
||||||
|
|
||||||
return { onAssetUpload }
|
return { onAssetUpload }
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,7 +51,7 @@ export default async function CreateMultiplayerRoom(req: NextApiRequest, res: Ne
|
||||||
// },
|
// },
|
||||||
// }).then((d) => d.json())
|
// }).then((d) => d.json())
|
||||||
|
|
||||||
//POST
|
// POST
|
||||||
const result = await fetch(`https://liveblocks.net/api/v1/room/${roomId}/storage`, {
|
const result = await fetch(`https://liveblocks.net/api/v1/room/${roomId}/storage`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
mode: 'cors',
|
mode: 'cors',
|
||||||
|
@ -64,10 +64,12 @@ export default async function CreateMultiplayerRoom(req: NextApiRequest, res: Ne
|
||||||
})
|
})
|
||||||
|
|
||||||
if (result.status === 200) {
|
if (result.status === 200) {
|
||||||
res.send({ status: 'success', roomId })
|
res.send({ status: 'success', message: result.statusText, roomId })
|
||||||
|
} else {
|
||||||
|
res.send({ status: 'error', message: result.statusText })
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
res.send({ status: 'error' })
|
res.send({ status: 'error', message: e.message })
|
||||||
// noop
|
// noop
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -128,6 +128,7 @@ export function Tldraw({
|
||||||
onChangePage,
|
onChangePage,
|
||||||
onAssetCreate,
|
onAssetCreate,
|
||||||
onAssetDelete,
|
onAssetDelete,
|
||||||
|
onAssetUpload,
|
||||||
onExport,
|
onExport,
|
||||||
}: TldrawProps) {
|
}: TldrawProps) {
|
||||||
const [sId, setSId] = React.useState(id)
|
const [sId, setSId] = React.useState(id)
|
||||||
|
@ -153,6 +154,7 @@ export function Tldraw({
|
||||||
onChangePage,
|
onChangePage,
|
||||||
onAssetDelete,
|
onAssetDelete,
|
||||||
onAssetCreate,
|
onAssetCreate,
|
||||||
|
onAssetUpload,
|
||||||
})
|
})
|
||||||
return app
|
return app
|
||||||
})
|
})
|
||||||
|
@ -179,6 +181,7 @@ export function Tldraw({
|
||||||
onChangePage,
|
onChangePage,
|
||||||
onAssetDelete,
|
onAssetDelete,
|
||||||
onAssetCreate,
|
onAssetCreate,
|
||||||
|
onAssetUpload,
|
||||||
onExport,
|
onExport,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -243,6 +246,7 @@ export function Tldraw({
|
||||||
onChangePage,
|
onChangePage,
|
||||||
onAssetDelete,
|
onAssetDelete,
|
||||||
onAssetCreate,
|
onAssetCreate,
|
||||||
|
onAssetUpload,
|
||||||
onExport,
|
onExport,
|
||||||
}
|
}
|
||||||
}, [
|
}, [
|
||||||
|
@ -264,6 +268,7 @@ export function Tldraw({
|
||||||
onChangePage,
|
onChangePage,
|
||||||
onAssetDelete,
|
onAssetDelete,
|
||||||
onAssetCreate,
|
onAssetCreate,
|
||||||
|
onAssetUpload,
|
||||||
onExport,
|
onExport,
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
|
@ -66,7 +66,7 @@ export const MultiplayerMenu = React.memo(function MultiplayerMenu() {
|
||||||
const body = JSON.stringify({
|
const body = JSON.stringify({
|
||||||
roomId: Utils.uniqueId(),
|
roomId: Utils.uniqueId(),
|
||||||
pageId: app.currentPageId,
|
pageId: app.currentPageId,
|
||||||
document: app.document,
|
document: nextDocument,
|
||||||
})
|
})
|
||||||
|
|
||||||
const myHeaders = new Headers({
|
const myHeaders = new Headers({
|
||||||
|
@ -74,16 +74,26 @@ export const MultiplayerMenu = React.memo(function MultiplayerMenu() {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
})
|
})
|
||||||
|
|
||||||
|
app.setIsLoading(true)
|
||||||
|
|
||||||
|
try {
|
||||||
const res = await fetch(`/api/create`, {
|
const res = await fetch(`/api/create`, {
|
||||||
headers: myHeaders,
|
headers: myHeaders,
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
mode: 'no-cors',
|
mode: 'no-cors',
|
||||||
body,
|
body,
|
||||||
}).then((res) => res.json())
|
}).then(res => res.json())
|
||||||
|
|
||||||
if (res?.roomId) {
|
if (res?.roomId) {
|
||||||
window.location.href = `/r/${res.roomId}`
|
window.location.href = `/r/${res.roomId}`
|
||||||
|
} else {
|
||||||
|
TLDR.warn(res.message)
|
||||||
}
|
}
|
||||||
|
} catch (e) {
|
||||||
|
TLDR.warn(e.message)
|
||||||
|
}
|
||||||
|
|
||||||
|
app.setIsLoading(false)
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue