pull/696/head
Steve Ruiz 2022-05-18 22:04:04 +01:00
rodzic 13f5787c31
commit bb58902d5b
5 zmienionych plików z 111 dodań i 3 usunięć

Wyświetl plik

@ -3,7 +3,37 @@ import { useCallback } from 'react'
export function useMultiplayerAssets() {
const onAssetCreate = useCallback(
// Send the asset to our upload enpoint, which in turn will send it to AWS and
// 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 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)
@ -37,5 +67,5 @@ export function useMultiplayerAssets() {
return true
}, [])
return { onAssetCreate, onAssetDelete }
return { onAssetCreate, onAssetUpload, onAssetDelete }
}

Wyświetl plik

@ -0,0 +1,36 @@
import { TDAsset, TldrawApp } from '@tldraw/tldraw'
import { useCallback } from 'react'
export function useUploadAssets() {
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
},
[]
)
return { onAssetUpload }
}

Wyświetl plik

@ -5,7 +5,7 @@ import { useTldrawApp } from '~hooks'
import { DMItem, DMContent, DMDivider, DMTriggerIcon } from '~components/Primitives/DropdownMenu'
import { SmallIcon } from '~components/Primitives/SmallIcon'
import { MultiplayerIcon } from '~components/Primitives/icons'
import type { TDSnapshot } from '~types'
import { TDAssetType, TDSnapshot } from '~types'
import { TLDR } from '~state/TLDR'
import { Utils } from '@tldraw/core'
@ -43,6 +43,26 @@ export const MultiplayerMenu = React.memo(function MultiplayerMenu() {
}, [])
const handleCopyToMultiplayerRoom = React.useCallback(async () => {
const nextDocument = { ...app.document }
if (app.callbacks.onAssetUpload) {
for (const id in nextDocument.assets) {
const asset = nextDocument.assets[id]
if (asset.src.includes('base64')) {
const file = dataURLtoFile(
asset.src,
asset.fileName ?? asset.type === TDAssetType.Video ? 'image.png' : 'image.mp4'
)
const newSrc = await app.callbacks.onAssetUpload(app, file, id)
if (newSrc) {
asset.src = newSrc
} else {
asset.src = ''
}
}
}
}
const body = JSON.stringify({
roomId: Utils.uniqueId(),
pageId: app.currentPageId,
@ -86,3 +106,17 @@ export const MultiplayerMenu = React.memo(function MultiplayerMenu() {
</DropdownMenu.Root>
)
})
function dataURLtoFile(dataurl: string, filename: string) {
const arr = dataurl.split(',')
const mime = arr[0]?.match(/:(.*?);/)?.[1]
const bstr = window.atob(arr[1])
let n = bstr.length
const u8arr = new Uint8Array(n)
while (n--) {
u8arr[n] = bstr.charCodeAt(n)
}
return new File([u8arr], filename, { type: mime })
}

Wyświetl plik

@ -162,6 +162,10 @@ export interface TDCallbacks {
* (optional) A callback to run when an asset will be created. Should return the value for the image/video's `src` property.
*/
onAssetCreate?: (app: TldrawApp, file: File, id: string) => Promise<string | false>
/**
* (optional) A callback to run when an asset will be uploaded. Should return the value for the image/video's `src` property.
*/
onAssetUpload?: (app: TldrawApp, file: File, id: string) => Promise<string | false>
/**
* (optional) A callback to run when the user exports their page or selection.
*/
@ -3344,6 +3348,7 @@ export class TldrawApp extends StateManager<TDSnapshot> {
const shapeType = isImage ? TDShapeType.Image : TDShapeType.Video
const assetType = isImage ? TDAssetType.Image : TDAssetType.Video
const fileName = file.name
let src: string | ArrayBuffer | null
@ -3393,6 +3398,7 @@ export class TldrawApp extends StateManager<TDSnapshot> {
const asset = {
id: assetId,
type: assetType,
name: fileName,
src,
size,
}

Wyświetl plik

@ -473,12 +473,14 @@ export enum TDAssetType {
export interface TDImageAsset extends TLAsset {
type: TDAssetType.Image
fileName: string
src: string
size: number[]
}
export interface TDVideoAsset extends TLAsset {
type: TDAssetType.Video
fileName: string
src: string
size: number[]
}