embeds work!

This commit is contained in:
Jeff Emmett 2024-10-19 00:42:23 -04:00
parent 375f69b365
commit 895d02a19c
5 changed files with 92 additions and 4 deletions

View File

@ -12,6 +12,8 @@ import { VideoChatTool } from '@/tools/VideoChatTool'
import { VideoChatShape } from '@/shapes/VideoChatShapeUtil'
import { multiplayerAssetStore } from '../client/multiplayerAssetStore'
import { customSchema } from '../../worker/TldrawDurableObject'
import { EmbedShape } from '@/shapes/EmbedShapeUtil'
import { EmbedTool } from '@/tools/EmbedTool'
import React, { useState } from 'react';
import { ChatBox } from '@/shapes/ChatBoxShapeUtil';
@ -19,8 +21,8 @@ import { components, uiOverrides } from '@/ui-overrides'
const WORKER_URL = `https://jeffemmett-canvas.jeffemmett.workers.dev`
const shapeUtils = [ChatBoxShape, VideoChatShape]
const tools = [ChatBoxTool, VideoChatTool]; // Array of tools
const shapeUtils = [ChatBoxShape, VideoChatShape, EmbedShape]
const tools = [ChatBoxTool, VideoChatTool, EmbedTool]; // Array of tools
export function Board() {
const { slug } = useParams<{ slug: string }>(); // Ensure this is inside the Board component

View File

@ -0,0 +1,59 @@
import { BaseBoxShapeUtil, TLBaseShape } from "tldraw";
import { useCallback, useState } from "react";
export type IEmbedShape = TLBaseShape<
'Embed',
{
w: number;
h: number;
url: string | null;
}
>;
export class EmbedShape extends BaseBoxShapeUtil<IEmbedShape> {
static override type = 'Embed';
getDefaultProps(): IEmbedShape['props'] {
return {
url: null,
w: 640,
h: 480,
};
}
indicator(shape: IEmbedShape) {
return <rect x={0} y={0} width={shape.props.w} height={shape.props.h} />;
}
component(shape: IEmbedShape) {
const [inputUrl, setInputUrl] = useState(shape.props.url || '');
const handleSubmit = useCallback((e: React.FormEvent) => {
e.preventDefault();
this.editor.updateShape<IEmbedShape>({ id: shape.id, type: 'Embed', props: { ...shape.props, url: inputUrl } });
}, [inputUrl]);
if (!shape.props.url) {
return (
<div style={{ pointerEvents: 'all' }}>
<form onSubmit={handleSubmit}>
<input
type="text"
value={inputUrl}
onChange={(e) => setInputUrl(e.target.value)}
placeholder="Enter URL"
style={{ width: shape.props.w, height: shape.props.h }}
/>
<button type="submit">Load</button>
</form>
</div>
);
}
return (
<div style={{ pointerEvents: 'all' }}>
<iframe src={shape.props.url} width={shape.props.w} height={shape.props.h} />
</div>
);
}
}

9
src/tools/EmbedTool.ts Normal file
View File

@ -0,0 +1,9 @@
import { BaseBoxShapeTool } from "tldraw";
export class EmbedTool extends BaseBoxShapeTool {
static override id = 'Embed'
shapeType = 'Embed';
override initial = 'idle';
// Additional methods for handling video chat functionality can be added here
}

View File

@ -8,6 +8,7 @@ import {
useTools,
} from 'tldraw'
import { CustomMainMenu } from './components/CustomMainMenu'
import { EmbedShape } from './shapes/EmbedShapeUtil'
export const uiOverrides: TLUiOverrides = {
tools(editor, tools) {
@ -29,6 +30,15 @@ export const uiOverrides: TLUiOverrides = {
editor.setCurrentTool('ChatBox')
},
}
tools.Embed = {
id: 'Embed',
icon: 'embed',
label: 'Embed',
kbd: 'e',
onSelect: () => {
editor.setCurrentTool('Embed')
},
}
return tools
},
}
@ -38,10 +48,12 @@ export const components: TLComponents = {
const tools = useTools()
const isChatBoxSelected = useIsToolSelected(tools['ChatBox'])
const isVideoSelected = useIsToolSelected(tools['VideoChat'])
const isEmbedSelected = useIsToolSelected(tools['Embed'])
return (
<DefaultToolbar {...props}>
<TldrawUiMenuItem {...tools['VideoChat']} isSelected={isVideoSelected} />
<TldrawUiMenuItem {...tools['ChatBox']} isSelected={isChatBoxSelected} />
<TldrawUiMenuItem {...tools['Embed']} isSelected={isEmbedSelected} />
<DefaultToolbarContent />
</DefaultToolbar>
)

View File

@ -13,10 +13,16 @@ import throttle from 'lodash.throttle'
import { Environment } from './types'
import { ChatBoxShape } from '@/shapes/ChatBoxShapeUtil'
import { VideoChatShape } from '@/shapes/VideoChatShapeUtil'
import { EmbedShape } from '@/shapes/EmbedShapeUtil'
// add custom shapes and bindings here if needed:
export const customSchema = createTLSchema({
shapes: { ...defaultShapeSchemas, ChatBox: ChatBoxShape, VideoChat: VideoChatShape },
shapes: {
...defaultShapeSchemas,
ChatBox: ChatBoxShape,
VideoChat: VideoChatShape,
Embed: EmbedShape
},
// bindings: { ...defaultBindingSchemas },
})