2023-04-25 11:01:25 +00:00
|
|
|
import {
|
|
|
|
App,
|
|
|
|
Canvas,
|
|
|
|
ErrorBoundary,
|
|
|
|
setRuntimeOverrides,
|
|
|
|
TldrawEditor,
|
2023-05-24 10:48:31 +00:00
|
|
|
TldrawEditorConfig,
|
2023-04-25 11:01:25 +00:00
|
|
|
TLUserId,
|
|
|
|
} from '@tldraw/editor'
|
|
|
|
import { linksUiOverrides } from './utils/links'
|
|
|
|
// eslint-disable-next-line import/no-internal-modules
|
|
|
|
import '@tldraw/editor/editor.css'
|
|
|
|
import { TAB_ID, useLocalSyncClient } from '@tldraw/tlsync-client'
|
|
|
|
import { ContextMenu, MenuSchema, TldrawUi } from '@tldraw/ui'
|
|
|
|
// eslint-disable-next-line import/no-internal-modules
|
2023-05-09 16:08:38 +00:00
|
|
|
import { getAssetUrlsByImport } from '@tldraw/assets/imports'
|
|
|
|
// eslint-disable-next-line import/no-internal-modules
|
2023-04-25 11:01:25 +00:00
|
|
|
import '@tldraw/ui/ui.css'
|
|
|
|
import { useEffect, useMemo, useState } from 'react'
|
|
|
|
import { VscodeMessage } from '../../messages'
|
|
|
|
import '../public/index.css'
|
|
|
|
import { ChangeResponder } from './ChangeResponder'
|
|
|
|
import { FileOpen } from './FileOpen'
|
|
|
|
import { FullPageMessage } from './FullPageMessage'
|
|
|
|
import { onCreateBookmarkFromUrl } from './utils/bookmarks'
|
|
|
|
import { vscode } from './utils/vscode'
|
|
|
|
|
2023-05-24 10:48:31 +00:00
|
|
|
const config = new TldrawEditorConfig()
|
|
|
|
|
2023-04-25 11:01:25 +00:00
|
|
|
// @ts-ignore
|
|
|
|
|
|
|
|
setRuntimeOverrides({
|
|
|
|
openWindow: (url, target) => {
|
|
|
|
vscode.postMessage({
|
|
|
|
type: 'vscode:open-window',
|
|
|
|
data: {
|
|
|
|
url,
|
|
|
|
target,
|
|
|
|
},
|
|
|
|
})
|
|
|
|
},
|
|
|
|
refreshPage: () => {
|
|
|
|
vscode.postMessage({
|
|
|
|
type: 'vscode:refresh-page',
|
|
|
|
})
|
|
|
|
},
|
|
|
|
hardReset: async () => {
|
|
|
|
await (window as any).__tldraw__hardReset?.()
|
|
|
|
vscode.postMessage({
|
|
|
|
type: 'vscode:hard-reset',
|
|
|
|
})
|
|
|
|
},
|
|
|
|
})
|
|
|
|
|
|
|
|
const handleError = (error: any) => {
|
|
|
|
console.error(error.message)
|
|
|
|
}
|
|
|
|
|
|
|
|
export function WrappedTldrawEditor() {
|
|
|
|
return (
|
|
|
|
<div className="tldraw--editor">
|
|
|
|
<ErrorBoundary
|
|
|
|
fallback={() => <FullPageMessage>Fallback</FullPageMessage>}
|
|
|
|
onError={handleError}
|
|
|
|
>
|
|
|
|
<TldrawWrapper />
|
|
|
|
</ErrorBoundary>
|
|
|
|
</div>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
const menuOverrides = {
|
|
|
|
menu: (_app: App, schema: MenuSchema, _helpers: any) => {
|
|
|
|
schema.forEach((item) => {
|
|
|
|
if (item.id === 'menu' && item.type === 'group') {
|
|
|
|
item.children = item.children.filter((menuItem) => {
|
|
|
|
if (menuItem.id === 'file' && menuItem.type === 'submenu') {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
return true
|
|
|
|
})
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
return schema
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
export const TldrawWrapper = () => {
|
|
|
|
const [tldrawInnerProps, setTldrawInnerProps] = useState<TLDrawInnerProps | null>(null)
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
function handleMessage({ data: message }: MessageEvent<VscodeMessage>) {
|
|
|
|
switch (message.type) {
|
|
|
|
case 'vscode:opened-file': {
|
|
|
|
setTldrawInnerProps({
|
|
|
|
assetSrc: message.data.assetSrc,
|
|
|
|
fileContents: message.data.fileContents,
|
|
|
|
uri: message.data.uri,
|
|
|
|
userId: message.data.userId as TLUserId,
|
|
|
|
isDarkMode: message.data.isDarkMode,
|
2023-05-24 10:48:31 +00:00
|
|
|
config,
|
2023-04-25 11:01:25 +00:00
|
|
|
})
|
|
|
|
// We only want to listen for this message once
|
|
|
|
window.removeEventListener('message', handleMessage)
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
window.addEventListener('message', handleMessage)
|
|
|
|
|
|
|
|
vscode.postMessage({ type: 'vscode:ready-to-receive-file' })
|
|
|
|
|
|
|
|
return () => {
|
|
|
|
window.removeEventListener('message', handleMessage)
|
|
|
|
}
|
|
|
|
}, [setTldrawInnerProps])
|
|
|
|
|
|
|
|
return tldrawInnerProps === null ? (
|
|
|
|
<FullPageMessage>Loading</FullPageMessage>
|
|
|
|
) : (
|
|
|
|
<TldrawInner {...tldrawInnerProps} />
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
export type TLDrawInnerProps = {
|
|
|
|
assetSrc: string
|
|
|
|
fileContents: string
|
|
|
|
uri: string
|
|
|
|
userId: TLUserId
|
|
|
|
isDarkMode: boolean
|
2023-05-24 10:48:31 +00:00
|
|
|
config: TldrawEditorConfig
|
2023-04-25 11:01:25 +00:00
|
|
|
}
|
|
|
|
|
2023-05-24 10:48:31 +00:00
|
|
|
function TldrawInner({
|
|
|
|
uri,
|
|
|
|
config,
|
|
|
|
assetSrc,
|
|
|
|
userId,
|
|
|
|
isDarkMode,
|
|
|
|
fileContents,
|
|
|
|
}: TLDrawInnerProps) {
|
2023-04-25 11:01:25 +00:00
|
|
|
const instanceId = TAB_ID
|
|
|
|
const syncedStore = useLocalSyncClient({
|
|
|
|
universalPersistenceKey: uri,
|
|
|
|
instanceId,
|
|
|
|
userId,
|
2023-05-24 10:48:31 +00:00
|
|
|
config,
|
2023-04-25 11:01:25 +00:00
|
|
|
})
|
|
|
|
|
2023-05-09 16:08:38 +00:00
|
|
|
const assetUrls = useMemo(() => getAssetUrlsByImport({ baseUrl: assetSrc }), [assetSrc])
|
2023-04-25 11:01:25 +00:00
|
|
|
|
|
|
|
return (
|
|
|
|
<TldrawEditor
|
2023-05-24 10:48:31 +00:00
|
|
|
config={config}
|
2023-04-25 11:01:25 +00:00
|
|
|
assetUrls={assetUrls}
|
|
|
|
instanceId={TAB_ID}
|
|
|
|
userId={userId}
|
|
|
|
store={syncedStore}
|
|
|
|
onCreateBookmarkFromUrl={onCreateBookmarkFromUrl}
|
|
|
|
autoFocus
|
|
|
|
>
|
|
|
|
{/* <DarkModeHandler themeKind={themeKind} /> */}
|
|
|
|
<TldrawUi assetUrls={assetUrls} overrides={[menuOverrides, linksUiOverrides]}>
|
|
|
|
<FileOpen
|
|
|
|
instanceId={instanceId}
|
|
|
|
userId={userId}
|
|
|
|
fileContents={fileContents}
|
|
|
|
forceDarkMode={isDarkMode}
|
|
|
|
/>
|
|
|
|
<ChangeResponder syncedStore={syncedStore} userId={userId} instanceId={instanceId} />
|
|
|
|
<ContextMenu>
|
|
|
|
<Canvas />
|
|
|
|
</ContextMenu>
|
|
|
|
</TldrawUi>
|
|
|
|
</TldrawEditor>
|
|
|
|
)
|
|
|
|
}
|