From e65a5a12806e8bd6b65ef1fdba7d89a9eabc7c98 Mon Sep 17 00:00:00 2001 From: Peng Xiao Date: Wed, 28 Sep 2022 19:03:26 +0800 Subject: [PATCH] feat: remember whiteboard camera in session storage --- src/main/frontend/extensions/tldraw.cljs | 13 +++--- .../react/src/components/Canvas/Canvas.tsx | 2 + tldraw/packages/react/src/hooks/index.ts | 1 + .../react/src/hooks/useRestoreCamera.ts | 42 +++++++++++++++++++ 4 files changed, 51 insertions(+), 7 deletions(-) create mode 100644 tldraw/packages/react/src/hooks/useRestoreCamera.ts diff --git a/src/main/frontend/extensions/tldraw.cljs b/src/main/frontend/extensions/tldraw.cljs index 7cbb951d0..e909eabac 100644 --- a/src/main/frontend/extensions/tldraw.cljs +++ b/src/main/frontend/extensions/tldraw.cljs @@ -72,21 +72,20 @@ (keyword type))) :redirectToPage (fn [page-name] (if (model/whiteboard-page? page-name) - (route-handler/redirect-to-whiteboard! page-name) - (route-handler/redirect-to-page! page-name)))}) + (route-handler/redirect-to-whiteboard! page-name) + (route-handler/redirect-to-page! page-name)))}) (rum/defc tldraw-app [name block-id] (let [data (whiteboard-handler/page-name->tldr! name block-id) [tln set-tln] (rum/use-state nil)] - (rum/use-effect! + (rum/use-layout-effect! (fn [] (when (and tln name) (when-let [^js api (gobj/get tln "api")] - (if (empty? block-id) - (. api zoomToFit) - (do (. api selectShapes block-id) - (. api zoomToSelection))))) + (when block-id + (. api selectShapes block-id) + (. api zoomToSelection)))) nil) [name block-id tln]) (when (and (not-empty name) (not-empty (gobj/get data "currentPageId"))) [:div.draw.tldraw.whiteboard.relative.w-full.h-full diff --git a/tldraw/packages/react/src/components/Canvas/Canvas.tsx b/tldraw/packages/react/src/components/Canvas/Canvas.tsx index 2f6c15f20..f6d52b47c 100644 --- a/tldraw/packages/react/src/components/Canvas/Canvas.tsx +++ b/tldraw/packages/react/src/components/Canvas/Canvas.tsx @@ -14,6 +14,7 @@ import { useCursor, useZoom, useCanvasEvents, + useRestoreCamera, } from '../../hooks' import { useKeyboardEvents } from '../../hooks/useKeyboardEvents' import type { TLReactShape } from '../../lib' @@ -96,6 +97,7 @@ export const Canvas = observer(function Renderer({ usePreventNavigation(rContainer) useResizeObserver(rContainer, viewport, onBoundsChange) useGestureEvents(rContainer) + useRestoreCamera() useCursor(rContainer, cursor, cursorRotation) useZoom(rContainer) useKeyboardEvents(rContainer) diff --git a/tldraw/packages/react/src/hooks/index.ts b/tldraw/packages/react/src/hooks/index.ts index 630e1334a..880ae8d6a 100644 --- a/tldraw/packages/react/src/hooks/index.ts +++ b/tldraw/packages/react/src/hooks/index.ts @@ -16,3 +16,4 @@ export * from './useCursor' export * from './useZoom' export * from './useMinimapEvents' export * from './useDebounced' +export * from './useRestoreCamera' \ No newline at end of file diff --git a/tldraw/packages/react/src/hooks/useRestoreCamera.ts b/tldraw/packages/react/src/hooks/useRestoreCamera.ts new file mode 100644 index 000000000..e042e605c --- /dev/null +++ b/tldraw/packages/react/src/hooks/useRestoreCamera.ts @@ -0,0 +1,42 @@ +/* eslint-disable @typescript-eslint/ban-ts-comment */ +import { reaction } from 'mobx' +import * as React from 'react' +import type { TLReactApp } from '../lib' +import { useApp } from './useApp' + +const storingKey = 'logseq.tldraw.camera' + +const cacheCamera = (app: TLReactApp) => { + window.sessionStorage.setItem( + storingKey + ':' + app.currentPageId, + JSON.stringify(app.viewport.camera) + ) +} + +const loadCamera = (app: TLReactApp) => { + const camera = JSON.parse( + window.sessionStorage.getItem(storingKey + ':' + app.currentPageId) ?? 'null' + ) + if (camera) { + app.viewport.update(camera) + } else if (app.selectedIds.size) { + app.api.zoomToSelection() + } else { + app.api.zoomToFit() + } +} + +export function useRestoreCamera(): void { + const app = useApp() + + React.useEffect(() => { + reaction( + () => ({ ...app.viewport.camera }), + () => cacheCamera(app) + ) + }, [app.viewport.camera]) + + React.useEffect(() => { + loadCamera(app) + }, [app]) +}