From 70e3c8bd45d91ecd6b2ab7d4e2d3fb24c1d41e70 Mon Sep 17 00:00:00 2001 From: Steve Ruiz Date: Sat, 25 Jun 2022 12:28:18 +0100 Subject: [PATCH] [fix] bug with images that have the same name (#743) * add unique id to file names to avoid name clashes * Add event callbacks for `onSessionStart` and `onSessionEnd` --- apps/www/hooks/useMultiplayerAssets.ts | 3 ++- apps/www/hooks/useMultiplayerState.ts | 12 ++++++++++++ apps/www/hooks/useUploadAssets.ts | 5 +++-- packages/tldraw/src/Tldraw.tsx | 2 +- packages/tldraw/src/state/TldrawApp.ts | 15 ++++++++++++++- 5 files changed, 32 insertions(+), 5 deletions(-) diff --git a/apps/www/hooks/useMultiplayerAssets.ts b/apps/www/hooks/useMultiplayerAssets.ts index b0da8a958..19cb9a355 100644 --- a/apps/www/hooks/useMultiplayerAssets.ts +++ b/apps/www/hooks/useMultiplayerAssets.ts @@ -1,3 +1,4 @@ +import { Utils } from '@tldraw/core' import { TDAsset, TldrawApp } from '@tldraw/tldraw' import { useCallback } from 'react' @@ -6,7 +7,7 @@ export function useMultiplayerAssets() { // 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 => { - const filename = encodeURIComponent(file.name) + const filename = encodeURIComponent((id ?? Utils.uniqueId()) + file.name) const fileType = encodeURIComponent(file.type) diff --git a/apps/www/hooks/useMultiplayerState.ts b/apps/www/hooks/useMultiplayerState.ts index ebaf2e050..808c3998d 100644 --- a/apps/www/hooks/useMultiplayerState.ts +++ b/apps/www/hooks/useMultiplayerState.ts @@ -216,10 +216,22 @@ export function useMultiplayerState(roomId: string) { } }, [room, app]) + const onSessionStart = React.useCallback(() => { + if (!room) return + room.history.pause() + }, [room]) + + const onSessionEnd = React.useCallback(() => { + if (!room) return + room.history.resume() + }, [room]) + return { onUndo, onRedo, onMount, + onSessionStart, + onSessionEnd, onChangePage, onChangePresence, error, diff --git a/apps/www/hooks/useUploadAssets.ts b/apps/www/hooks/useUploadAssets.ts index cfee6e77c..3b0dc36b9 100644 --- a/apps/www/hooks/useUploadAssets.ts +++ b/apps/www/hooks/useUploadAssets.ts @@ -1,4 +1,5 @@ -import { TDAsset, TldrawApp } from '@tldraw/tldraw' +import { Utils } from '@tldraw/core' +import { TldrawApp } from '@tldraw/tldraw' import { useCallback } from 'react' export function useUploadAssets() { @@ -7,7 +8,7 @@ export function useUploadAssets() { // respond with the URL of the uploaded file. async (app: TldrawApp, file: File, id: string): Promise => { - const filename = encodeURIComponent(file.name) + const filename = encodeURIComponent((id ?? Utils.uniqueId()) + file.name) const fileType = encodeURIComponent(file.type) diff --git a/packages/tldraw/src/Tldraw.tsx b/packages/tldraw/src/Tldraw.tsx index 439407d6f..0cb23014b 100644 --- a/packages/tldraw/src/Tldraw.tsx +++ b/packages/tldraw/src/Tldraw.tsx @@ -436,7 +436,7 @@ const InnerTldraw = React.memo(function InnerTldraw({ en: messages_en, fr: messages_fr, it: messages_it, - 'zh-cn': messages_zh_cn + 'zh-cn': messages_zh_cn, } const defaultLanguage = settings.language ?? navigator.language.split(/[-_]/)[0] diff --git a/packages/tldraw/src/state/TldrawApp.ts b/packages/tldraw/src/state/TldrawApp.ts index 8e4b34be0..bcbf803d7 100644 --- a/packages/tldraw/src/state/TldrawApp.ts +++ b/packages/tldraw/src/state/TldrawApp.ts @@ -171,6 +171,14 @@ export interface TDCallbacks { * (optional) A callback to run when the user exports their page or selection. */ onExport?: (app: TldrawApp, info: TDExport) => Promise + /** + * (optional) A callback to run when a session begins. + */ + onSessionStart?: (app: TldrawApp, id: string) => void + /** + * (optional) A callback to run when a session ends. + */ + onSessionEnd?: (app: TldrawApp, id: string) => void } export class TldrawApp extends StateManager { @@ -2711,6 +2719,7 @@ export class TldrawApp extends StateManager { if (result) { this.patchState(result, `session:start_${this.session.constructor.name}`) + this.callbacks.onSessionStart?.(this, this.session.constructor.name) } return this @@ -2745,6 +2754,7 @@ export class TldrawApp extends StateManager { if (result) { this.patchState(result, `session:cancel:${session.constructor.name}`) + this.callbacks.onSessionEnd?.(this, session.constructor.name) } return this @@ -2764,7 +2774,7 @@ export class TldrawApp extends StateManager { if (result === undefined) { this.isCreating = false - return this.patchState( + this.patchState( { appState: { status: TDStatus.Idle, @@ -2781,6 +2791,9 @@ export class TldrawApp extends StateManager { }, `session:complete:${session.constructor.name}` ) + + this.callbacks.onSessionEnd?.(this, session.constructor.name) + return this } else if ('after' in result) { // Session ended with a command