Feature style (#627)
* initial * style: style and remove Svg export * tiny up Co-authored-by: Steve Ruiz <steveruizok@gmail.com>
This commit is contained in:
parent
8aa54f4d8c
commit
4d5a929366
8 changed files with 79 additions and 81 deletions
|
@ -1,28 +1,26 @@
|
||||||
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
||||||
import * as React from 'react'
|
import { TDDocument, TDFile, Tldraw, TldrawApp } from '@tldraw/tldraw'
|
||||||
import { Tldraw, TldrawApp, TDFile, TDDocument } from '@tldraw/tldraw'
|
import { FC, useCallback, useEffect, useRef } from 'react'
|
||||||
import { vscode } from './utils/vscode'
|
|
||||||
import { defaultDocument } from './utils/defaultDocument'
|
|
||||||
import type { MessageFromExtension, MessageFromWebview } from './types'
|
|
||||||
import { exportToImage } from 'utils/export'
|
import { exportToImage } from 'utils/export'
|
||||||
|
import type { MessageFromExtension, MessageFromWebview } from './types'
|
||||||
|
import { defaultDocument } from './utils/defaultDocument'
|
||||||
|
import { vscode } from './utils/vscode'
|
||||||
|
|
||||||
// Will be placed in global scope by extension
|
// Will be placed in global scope by extension
|
||||||
declare let currentFile: TDFile
|
declare let currentFile: TDFile
|
||||||
|
|
||||||
export default function App(): JSX.Element {
|
const App: FC = () => {
|
||||||
const rLoaded = React.useRef(false)
|
const rLoaded = useRef(false)
|
||||||
const rTldrawApp = React.useRef<TldrawApp>()
|
const rTldrawApp = useRef<TldrawApp>()
|
||||||
const rInitialDocument = React.useRef<TDDocument>(
|
const rInitialDocument = useRef<TDDocument>(currentFile ? currentFile.document : defaultDocument)
|
||||||
currentFile ? currentFile.document : defaultDocument
|
|
||||||
)
|
|
||||||
|
|
||||||
// When the editor mounts, save the state instance in a ref.
|
// When the editor mounts, save the state instance in a ref.
|
||||||
const handleMount = React.useCallback((app: TldrawApp) => {
|
const handleMount = useCallback((app: TldrawApp) => {
|
||||||
rTldrawApp.current = app
|
rTldrawApp.current = app
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
// When the editor's document changes, post the stringified document to the vscode extension.
|
// When the editor's document changes, post the stringified document to the vscode extension.
|
||||||
const handlePersist = React.useCallback((app: TldrawApp) => {
|
const handlePersist = useCallback((app: TldrawApp) => {
|
||||||
vscode.postMessage({
|
vscode.postMessage({
|
||||||
type: 'editorUpdated',
|
type: 'editorUpdated',
|
||||||
text: JSON.stringify({
|
text: JSON.stringify({
|
||||||
|
@ -34,7 +32,7 @@ export default function App(): JSX.Element {
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
// When the file changes from VS Code's side, update the editor's document.
|
// When the file changes from VS Code's side, update the editor's document.
|
||||||
React.useEffect(() => {
|
useEffect(() => {
|
||||||
function handleMessage({ data }: MessageEvent<MessageFromExtension>) {
|
function handleMessage({ data }: MessageEvent<MessageFromExtension>) {
|
||||||
if (data.type === 'openedFile') {
|
if (data.type === 'openedFile') {
|
||||||
try {
|
try {
|
||||||
|
@ -73,3 +71,5 @@ export default function App(): JSX.Element {
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default App
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import React from 'react'
|
|
||||||
import * as gtag from 'utils/gtag'
|
|
||||||
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 React, { FC } from 'react'
|
||||||
import { exportToImage } from 'utils/export'
|
import { exportToImage } from 'utils/export'
|
||||||
|
import * as gtag from 'utils/gtag'
|
||||||
|
|
||||||
declare const window: Window & { app: TldrawApp }
|
declare const window: Window & { app: TldrawApp }
|
||||||
|
|
||||||
|
@ -12,12 +12,12 @@ interface EditorProps {
|
||||||
isSponsor?: boolean
|
isSponsor?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Editor({
|
const Editor: FC<EditorProps & Partial<TldrawProps>> = ({
|
||||||
id = 'home',
|
id = 'home',
|
||||||
isUser = false,
|
isUser = false,
|
||||||
isSponsor = false,
|
isSponsor = false,
|
||||||
...rest
|
...rest
|
||||||
}: EditorProps & Partial<TldrawProps>) {
|
}) => {
|
||||||
const handleMount = React.useCallback((app: TldrawApp) => {
|
const handleMount = React.useCallback((app: TldrawApp) => {
|
||||||
window.app = app
|
window.app = app
|
||||||
}, [])
|
}, [])
|
||||||
|
@ -53,3 +53,5 @@ export default function Editor({
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default Editor
|
||||||
|
|
|
@ -1,19 +1,25 @@
|
||||||
import * as React from 'react'
|
|
||||||
import { Tldraw, useFileSystem } from '@tldraw/tldraw'
|
|
||||||
import { createClient } from '@liveblocks/client'
|
import { createClient } from '@liveblocks/client'
|
||||||
import { LiveblocksProvider, RoomProvider } from '@liveblocks/react'
|
import { LiveblocksProvider, RoomProvider } from '@liveblocks/react'
|
||||||
|
import { Tldraw, useFileSystem } from '@tldraw/tldraw'
|
||||||
import { useAccountHandlers } from 'hooks/useAccountHandlers'
|
import { useAccountHandlers } from 'hooks/useAccountHandlers'
|
||||||
import { styled } from 'styles'
|
|
||||||
import { useMultiplayerState } from 'hooks/useMultiplayerState'
|
|
||||||
import { exportToImage } from 'utils/export'
|
|
||||||
import { useMultiplayerAssets } from 'hooks/useMultiplayerAssets'
|
import { useMultiplayerAssets } from 'hooks/useMultiplayerAssets'
|
||||||
|
import { useMultiplayerState } from 'hooks/useMultiplayerState'
|
||||||
|
import { FC } from 'react'
|
||||||
|
import { styled } from 'styles'
|
||||||
|
import { exportToImage } from 'utils/export'
|
||||||
|
|
||||||
const client = createClient({
|
const client = createClient({
|
||||||
publicApiKey: process.env.NEXT_PUBLIC_LIVEBLOCKS_PUBLIC_API_KEY || '',
|
publicApiKey: process.env.NEXT_PUBLIC_LIVEBLOCKS_PUBLIC_API_KEY || '',
|
||||||
throttle: 80,
|
throttle: 80,
|
||||||
})
|
})
|
||||||
|
|
||||||
export default function MultiplayerEditor({
|
interface Props {
|
||||||
|
roomId: string
|
||||||
|
isUser: boolean
|
||||||
|
isSponsor: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
const MultiplayerEditor: FC<Props> = ({
|
||||||
roomId,
|
roomId,
|
||||||
isUser = false,
|
isUser = false,
|
||||||
isSponsor = false,
|
isSponsor = false,
|
||||||
|
@ -21,7 +27,7 @@ export default function MultiplayerEditor({
|
||||||
roomId: string
|
roomId: string
|
||||||
isUser: boolean
|
isUser: boolean
|
||||||
isSponsor: boolean
|
isSponsor: boolean
|
||||||
}) {
|
}) => {
|
||||||
return (
|
return (
|
||||||
<LiveblocksProvider client={client}>
|
<LiveblocksProvider client={client}>
|
||||||
<RoomProvider id={roomId}>
|
<RoomProvider id={roomId}>
|
||||||
|
@ -33,15 +39,7 @@ export default function MultiplayerEditor({
|
||||||
|
|
||||||
// Inner Editor
|
// Inner Editor
|
||||||
|
|
||||||
function Editor({
|
function Editor({ roomId, isUser, isSponsor }: Props) {
|
||||||
roomId,
|
|
||||||
isUser,
|
|
||||||
isSponsor,
|
|
||||||
}: {
|
|
||||||
roomId: string
|
|
||||||
isUser: boolean
|
|
||||||
isSponsor: boolean
|
|
||||||
}) {
|
|
||||||
const fileSystemEvents = useFileSystem()
|
const fileSystemEvents = useFileSystem()
|
||||||
const { onSignIn, onSignOut } = useAccountHandlers()
|
const { onSignIn, onSignOut } = useAccountHandlers()
|
||||||
const { error, ...events } = useMultiplayerState(roomId)
|
const { error, ...events } = useMultiplayerState(roomId)
|
||||||
|
@ -68,6 +66,8 @@ function Editor({
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default MultiplayerEditor
|
||||||
|
|
||||||
const LoadingScreen = styled('div', {
|
const LoadingScreen = styled('div', {
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
top: 0,
|
top: 0,
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
import React from 'react'
|
import { useCallback } from 'react'
|
||||||
|
|
||||||
export function useMultiplayerAssets() {
|
export function useMultiplayerAssets() {
|
||||||
const onAssetCreate = React.useCallback(
|
const onAssetCreate = useCallback(async (file: File, id: string): Promise<string | false> => {
|
||||||
async (file: File, id: string): Promise<string | false> => {
|
|
||||||
const filename = encodeURIComponent(file.name)
|
const filename = encodeURIComponent(file.name)
|
||||||
const fileType = encodeURIComponent(file.type)
|
const fileType = encodeURIComponent(file.type)
|
||||||
const res = await fetch(`/api/upload?file=${filename}&fileType=${fileType}`)
|
const res = await fetch(`/api/upload?file=${filename}&fileType=${fileType}`)
|
||||||
|
@ -20,11 +19,9 @@ export function useMultiplayerAssets() {
|
||||||
} else {
|
} else {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
},
|
}, [])
|
||||||
[]
|
|
||||||
)
|
|
||||||
|
|
||||||
const onAssetDelete = React.useCallback(async (id: string): Promise<boolean> => {
|
const onAssetDelete = useCallback(async (id: string): Promise<boolean> => {
|
||||||
// noop
|
// noop
|
||||||
return true
|
return true
|
||||||
}, [])
|
}, [])
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
||||||
import * as React from 'react'
|
import React, { useState, useRef, useCallback } from 'react'
|
||||||
import type { TldrawApp, TDUser, TDShape, TDBinding, TDDocument, TDAsset } from '@tldraw/tldraw'
|
import type { TldrawApp, TDUser, TDShape, TDBinding, TDDocument, TDAsset } from '@tldraw/tldraw'
|
||||||
import { useRedo, useUndo, useRoom, useUpdateMyPresence } from '@liveblocks/react'
|
import { useRedo, useUndo, useRoom, useUpdateMyPresence } from '@liveblocks/react'
|
||||||
import { LiveMap, LiveObject } from '@liveblocks/client'
|
import { LiveMap, LiveObject } from '@liveblocks/client'
|
||||||
|
@ -8,23 +8,23 @@ import { LiveMap, LiveObject } from '@liveblocks/client'
|
||||||
declare const window: Window & { app: TldrawApp }
|
declare const window: Window & { app: TldrawApp }
|
||||||
|
|
||||||
export function useMultiplayerState(roomId: string) {
|
export function useMultiplayerState(roomId: string) {
|
||||||
const [app, setApp] = React.useState<TldrawApp>()
|
const [app, setApp] = useState<TldrawApp>()
|
||||||
const [error, setError] = React.useState<Error>()
|
const [error, setError] = useState<Error>()
|
||||||
const [loading, setLoading] = React.useState(true)
|
const [loading, setLoading] = useState(true)
|
||||||
|
|
||||||
const room = useRoom()
|
const room = useRoom()
|
||||||
const onUndo = useUndo()
|
const onUndo = useUndo()
|
||||||
const onRedo = useRedo()
|
const onRedo = useRedo()
|
||||||
const updateMyPresence = useUpdateMyPresence()
|
const updateMyPresence = useUpdateMyPresence()
|
||||||
|
|
||||||
const rLiveShapes = React.useRef<LiveMap<string, TDShape>>()
|
const rLiveShapes = useRef<LiveMap<string, TDShape>>()
|
||||||
const rLiveBindings = React.useRef<LiveMap<string, TDBinding>>()
|
const rLiveBindings = useRef<LiveMap<string, TDBinding>>()
|
||||||
const rLiveAssets = React.useRef<LiveMap<string, TDAsset>>()
|
const rLiveAssets = useRef<LiveMap<string, TDAsset>>()
|
||||||
|
|
||||||
// Callbacks --------------
|
// Callbacks --------------
|
||||||
|
|
||||||
// Put the state into the window, for debugging.
|
// Put the state into the window, for debugging.
|
||||||
const onMount = React.useCallback(
|
const onMount = useCallback(
|
||||||
(app: TldrawApp) => {
|
(app: TldrawApp) => {
|
||||||
app.loadRoom(roomId)
|
app.loadRoom(roomId)
|
||||||
app.pause() // Turn off the app's own undo / redo stack
|
app.pause() // Turn off the app's own undo / redo stack
|
||||||
|
@ -35,7 +35,7 @@ export function useMultiplayerState(roomId: string) {
|
||||||
)
|
)
|
||||||
|
|
||||||
// Update the live shapes when the app's shapes change.
|
// Update the live shapes when the app's shapes change.
|
||||||
const onChangePage = React.useCallback(
|
const onChangePage = useCallback(
|
||||||
(
|
(
|
||||||
app: TldrawApp,
|
app: TldrawApp,
|
||||||
shapes: Record<string, TDShape | undefined>,
|
shapes: Record<string, TDShape | undefined>,
|
||||||
|
@ -78,7 +78,7 @@ export function useMultiplayerState(roomId: string) {
|
||||||
)
|
)
|
||||||
|
|
||||||
// Handle presence updates when the user's pointer / selection changes
|
// Handle presence updates when the user's pointer / selection changes
|
||||||
const onChangePresence = React.useCallback(
|
const onChangePresence = useCallback(
|
||||||
(app: TldrawApp, user: TDUser) => {
|
(app: TldrawApp, user: TDUser) => {
|
||||||
updateMyPresence({ id: app.room?.userId, user })
|
updateMyPresence({ id: app.room?.userId, user })
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import dynamic from 'next/dynamic'
|
|
||||||
import type { GetServerSideProps } from 'next'
|
import type { GetServerSideProps } from 'next'
|
||||||
import { getSession } from 'next-auth/react'
|
import { getSession } from 'next-auth/react'
|
||||||
|
import dynamic from 'next/dynamic'
|
||||||
import Head from 'next/head'
|
import Head from 'next/head'
|
||||||
import { useRouter } from 'next/router'
|
import { useRouter } from 'next/router'
|
||||||
import { useMemo } from 'react'
|
import { FC, useMemo } from 'react'
|
||||||
|
|
||||||
const Editor = dynamic(() => import('components/Editor'), { ssr: false })
|
const Editor = dynamic(() => import('components/Editor'), { ssr: false })
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ interface PageProps {
|
||||||
isSponsor: boolean
|
isSponsor: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Home({ isUser, isSponsor }: PageProps): JSX.Element {
|
const Home: FC<PageProps> = ({ isUser, isSponsor }) => {
|
||||||
const { query } = useRouter()
|
const { query } = useRouter()
|
||||||
const isExportMode = useMemo(() => 'exportMode' in query, [query])
|
const isExportMode = useMemo(() => 'exportMode' in query, [query])
|
||||||
|
|
||||||
|
@ -26,6 +26,8 @@ export default function Home({ isUser, isSponsor }: PageProps): JSX.Element {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default Home
|
||||||
|
|
||||||
export const getServerSideProps: GetServerSideProps = async (context) => {
|
export const getServerSideProps: GetServerSideProps = async (context) => {
|
||||||
const session = await getSession(context)
|
const session = await getSession(context)
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import { styled } from 'styles'
|
|
||||||
import { getSession, signIn, signOut, useSession } from 'next-auth/react'
|
|
||||||
import type { GetServerSideProps } from 'next'
|
import type { GetServerSideProps } from 'next'
|
||||||
import Link from 'next/link'
|
import { getSession, signIn, signOut, useSession } from 'next-auth/react'
|
||||||
import React from 'react'
|
|
||||||
import Head from 'next/head'
|
import Head from 'next/head'
|
||||||
|
import Link from 'next/link'
|
||||||
|
import React, { FC } from 'react'
|
||||||
|
import { styled } from 'styles'
|
||||||
|
|
||||||
export default function Sponsorware(): JSX.Element {
|
const Sponsorware: FC = () => {
|
||||||
const { data, status } = useSession()
|
const { data, status } = useSession()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -86,6 +86,8 @@ export default function Sponsorware(): JSX.Element {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default Sponsorware
|
||||||
|
|
||||||
export const getServerSideProps: GetServerSideProps = async (context) => {
|
export const getServerSideProps: GetServerSideProps = async (context) => {
|
||||||
const session = await getSession(context)
|
const session = await getSession(context)
|
||||||
|
|
||||||
|
|
5
packages/core/src/utils/index.d.ts
vendored
5
packages/core/src/utils/index.d.ts
vendored
|
@ -1,5 +0,0 @@
|
||||||
import { Utils } from './utils'
|
|
||||||
export { Utils } from './utils'
|
|
||||||
export { Svg } from './svg'
|
|
||||||
export default Utils
|
|
||||||
//# sourceMappingURL=index.d.ts.map
|
|
Loading…
Reference in a new issue