From f15d1911ee41681372c8aa7c0b52aa9551277029 Mon Sep 17 00:00:00 2001 From: JimmFly <447268514@qq.com> Date: Thu, 27 Jun 2024 05:52:04 +0000 Subject: [PATCH] refactor(core): remove the automatic URL change feature (#7339) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit close [AF-954](https://linear.app/affine-design/issue/AF-954/center-peek-中-editor-selection-变化不应修改-location-hash) Since the URL changes constantly with the selection, causing the editor to render frequently and also affecting the use of center peek, we decided to remove the function of automatically changing the URL. --- .../blocksuite-editor-container.tsx | 74 +---------------- .../core/src/hooks/affine/use-share-url.ts | 82 +++++++++++++------ 2 files changed, 60 insertions(+), 96 deletions(-) diff --git a/packages/frontend/core/src/components/blocksuite/block-suite-editor/blocksuite-editor-container.tsx b/packages/frontend/core/src/components/blocksuite/block-suite-editor/blocksuite-editor-container.tsx index f8fab4519..d267d89f7 100644 --- a/packages/frontend/core/src/components/blocksuite/block-suite-editor/blocksuite-editor-container.tsx +++ b/packages/frontend/core/src/components/blocksuite/block-suite-editor/blocksuite-editor-container.tsx @@ -1,10 +1,4 @@ -import { ViewService } from '@affine/core/modules/workbench/services/view'; -import type { - BaseSelection, - BlockElement, - TextSelection, -} from '@blocksuite/block-std'; -import type { Disposable } from '@blocksuite/global/utils'; +import type { BlockElement } from '@blocksuite/block-std'; import type { AffineEditorContainer, EdgelessEditor, @@ -12,7 +6,7 @@ import type { } from '@blocksuite/presets'; import type { Doc } from '@blocksuite/store'; import { Slot } from '@blocksuite/store'; -import { type DocMode, useServiceOptional } from '@toeverything/infra'; +import { type DocMode } from '@toeverything/infra'; import clsx from 'clsx'; import type React from 'react'; import type { RefObject } from 'react'; @@ -111,7 +105,6 @@ export const BlocksuiteEditorContainer = forwardRef< const rootRef = useRef(null); const docRef = useRef(null); const edgelessRef = useRef(null); - const renderStartRef = useRef(Date.now()); const slots: BlocksuiteEditorContainerRef['slots'] = useMemo(() => { return { @@ -214,7 +207,6 @@ export const BlocksuiteEditorContainer = forwardRef< }, [affineEditorContainerProxy, ref]); const blockElement = useBlockElementById(rootRef, defaultSelectedBlockId); - const currentView = useServiceOptional(ViewService)?.view; useEffect(() => { let canceled = false; @@ -253,68 +245,6 @@ export const BlocksuiteEditorContainer = forwardRef< }; }, [blockElement, affineEditorContainerProxy, mode]); - useEffect(() => { - let disposable: Disposable | null = null; - let canceled = false; - // Function to handle block selection change - const handleSelectionChange = (selection: BaseSelection[]) => { - const viewLocation = currentView?.location$.value; - const currentPath = viewLocation?.pathname; - const locationHash = viewLocation?.hash; - if ( - !currentView || - !currentPath || - // do not update the hash during the initial render - renderStartRef.current > Date.now() - 1000 - ) { - return; - } - if (mode === 'edgeless') { - if (locationHash) { - currentView.replace(currentPath); - } - return; - } - - if (selection[0]?.type === 'text') { - const textSelection = selection[0] as TextSelection; - if (textSelection.from.length === 0) { - // Clear the hash if no block is selected - if (locationHash) { - currentView.replace(currentPath); - } - return; - } - } - - const selectedId = selection[0]?.blockId; - if (!selectedId) { - return; - } - const newHash = `#${selectedId}`; - - // Only update the hash if it has changed - if (locationHash !== newHash) { - hashChangedRef.current = true; - currentView.replace(currentPath + newHash); - } - }; - - affineEditorContainerProxy.updateComplete - .then(() => { - const selectManager = affineEditorContainerProxy.host?.selection; - if (!selectManager || canceled) return; - // Set up the new disposable listener - disposable = selectManager.slots.changed.on(handleSelectionChange); - }) - .catch(console.error); - - return () => { - canceled = true; - disposable?.dispose(); - }; - }, [affineEditorContainerProxy, currentView, mode]); - return (
{ +const generateUrl = ({ + workspaceId, + pageId, + urlType, + blockId, +}: UseSharingUrl & { blockId?: string }) => { // to generate a private url like https://app.affine.app/workspace/123/456 // or https://app.affine.app/workspace/123/456#block-123 // to generate a public url like https://app.affine.app/share/123/456 - // or https://app.affine.app/share/123/456?mode=edgeless - - const workbench = useService(WorkbenchService).workbench; - const activeView = useLiveData(workbench.activeView$); - const hash = useLiveData(activeView.location$).hash; - const baseUrl = getAffineCloudBaseUrl(); - const url = useMemo(() => { - // baseUrl is null when running in electron and without network - if (!baseUrl) return null; + if (!baseUrl) return null; - try { - return new URL( - `${baseUrl}/${urlType}/${workspaceId}/${pageId}${urlType === 'workspace' && hash ? `${hash}` : ''}` - ).toString(); - } catch (e) { - return null; - } - }, [baseUrl, hash, pageId, urlType, workspaceId]); - - return url; + try { + return new URL( + `${baseUrl}/${urlType}/${workspaceId}/${pageId}${urlType === 'workspace' && blockId ? `#${blockId}` : ''}` + ).toString(); + } catch (e) { + return null; + } }; export const useSharingUrl = ({ @@ -48,7 +43,18 @@ export const useSharingUrl = ({ urlType, }: UseSharingUrl) => { const t = useI18n(); - const sharingUrl = useGenerateUrl({ workspaceId, pageId, urlType }); + const [blockId, setBlockId] = useState(''); + const [editor] = useActiveBlocksuiteEditor(); + const sharingUrl = useMemo( + () => + generateUrl({ + workspaceId, + pageId, + urlType, + blockId: blockId.length > 0 ? blockId : undefined, + }), + [workspaceId, pageId, urlType, blockId] + ); const onClickCopyLink = useCallback(() => { if (sharingUrl) { @@ -73,6 +79,34 @@ export const useSharingUrl = ({ } }, [sharingUrl, t, urlType]); + useEffect(() => { + let disposable: Disposable | null = null; + const selectManager = editor?.host?.selection; + if (urlType !== 'workspace' || !selectManager) { + return; + } + + // if the block is already selected, set the blockId + const currentBlockSelection = selectManager.find('block'); + if (currentBlockSelection) { + setBlockId(`#${currentBlockSelection.blockId}`); + } + + disposable = selectManager.slots.changed.on(selections => { + setBlockId(prev => { + if (selections[0] && selections[0].type === 'block') { + return `#${selections[0].blockId}`; + } else if (prev.length > 0) { + return ''; + } else { + return prev; + } + }); + }); + return () => { + disposable?.dispose(); + }; + }, [editor?.host?.selection, urlType]); return { sharingUrl, onClickCopyLink,