From f01997f8ee78b6cb32c20067150277ccf92718b5 Mon Sep 17 00:00:00 2001 From: Himself65 Date: Mon, 22 May 2023 17:11:18 +0800 Subject: [PATCH] refactor: remove unused code (#2484) --- apps/web/src/adapters/local/index.tsx | 3 +- .../components/__debug__/client/editor.tsx | 1 + .../src/components/affine/pinboard/index.ts | 2 - .../affine/pinboard/pinboard-menu/index.tsx | 133 -------------- .../pinboard/pinboard-menu/search-content.tsx | 63 ------- .../pinboard/pinboard-render/add-button.tsx | 22 --- .../pinboard/pinboard-render/empty-item.tsx | 14 -- .../affine/pinboard/pinboard-render/index.tsx | 137 -------------- .../pinboard-render/operation-button.tsx | 170 ------------------ .../src/components/affine/pinboard/styles.ts | 148 --------------- .../header-right-items/editor-option-menu.tsx | 14 +- .../web/src/components/page-detail-editor.tsx | 7 +- .../navigation-path/index.tsx | 166 ----------------- .../navigation-path/styles.ts | 63 ------- .../navigation-path/utils.ts | 60 ------- .../pure/workspace-slider-bar/index.tsx | 20 --- .../pure/workspace-slider-bar/pinboard.tsx | 64 ------- .../hooks/affine/use-reference-link-effect.ts | 42 ----- apps/web/src/hooks/use-pinboard-data.ts | 92 ---------- apps/web/src/hooks/use-pinboard-handler.ts | 138 -------------- apps/web/src/layouts/workspace-layout.tsx | 5 - .../[workspaceId]/[pageId].tsx | 17 +- .../workspace/[workspaceId]/[pageId].tsx | 54 ++---- .../components/block-suite-editor/index.tsx | 4 +- packages/component/src/ui/toast/toast.ts | 3 - packages/env/src/blocksuite.ts | 25 +-- .../hooks/src/use-block-suite-page-meta.ts | 1 - packages/workspace/src/type.ts | 3 + tests/libs/load-page.ts | 8 - tests/libs/page-logic.ts | 21 --- tests/parallels/quick-search.spec.ts | 49 +---- 31 files changed, 44 insertions(+), 1505 deletions(-) delete mode 100644 apps/web/src/components/affine/pinboard/index.ts delete mode 100644 apps/web/src/components/affine/pinboard/pinboard-menu/index.tsx delete mode 100644 apps/web/src/components/affine/pinboard/pinboard-menu/search-content.tsx delete mode 100644 apps/web/src/components/affine/pinboard/pinboard-render/add-button.tsx delete mode 100644 apps/web/src/components/affine/pinboard/pinboard-render/empty-item.tsx delete mode 100644 apps/web/src/components/affine/pinboard/pinboard-render/index.tsx delete mode 100644 apps/web/src/components/affine/pinboard/pinboard-render/operation-button.tsx delete mode 100644 apps/web/src/components/affine/pinboard/styles.ts delete mode 100644 apps/web/src/components/pure/quick-search-modal/navigation-path/index.tsx delete mode 100644 apps/web/src/components/pure/quick-search-modal/navigation-path/styles.ts delete mode 100644 apps/web/src/components/pure/quick-search-modal/navigation-path/utils.ts delete mode 100644 apps/web/src/components/pure/workspace-slider-bar/pinboard.tsx delete mode 100644 apps/web/src/hooks/affine/use-reference-link-effect.ts delete mode 100644 apps/web/src/hooks/use-pinboard-data.ts delete mode 100644 apps/web/src/hooks/use-pinboard-handler.ts diff --git a/apps/web/src/adapters/local/index.tsx b/apps/web/src/adapters/local/index.tsx index 306d4f2f23..d3bd4b8e55 100644 --- a/apps/web/src/adapters/local/index.tsx +++ b/apps/web/src/adapters/local/index.tsx @@ -81,7 +81,7 @@ export const LocalPlugin: WorkspaceAdapter = { Provider: ({ children }) => { return <>{children}; }, - PageDetail: ({ currentWorkspace, currentPageId }) => { + PageDetail: ({ currentWorkspace, currentPageId, onLoadEditor }) => { const page = currentWorkspace.blockSuiteWorkspace.getPage(currentPageId); if (!page) { throw new PageNotFoundError( @@ -94,6 +94,7 @@ export const LocalPlugin: WorkspaceAdapter = { diff --git a/apps/web/src/components/__debug__/client/editor.tsx b/apps/web/src/components/__debug__/client/editor.tsx index 37e390d0e9..6e5511c3fa 100644 --- a/apps/web/src/components/__debug__/client/editor.tsx +++ b/apps/web/src/components/__debug__/client/editor.tsx @@ -36,6 +36,7 @@ const Editor: React.FC<{ globalThis.page = page; // @ts-ignore globalThis.editor = editor; + return () => void 0; }, []); if (!page) { diff --git a/apps/web/src/components/affine/pinboard/index.ts b/apps/web/src/components/affine/pinboard/index.ts deleted file mode 100644 index d37c3b63fb..0000000000 --- a/apps/web/src/components/affine/pinboard/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './pinboard-menu'; -export * from './pinboard-render/'; diff --git a/apps/web/src/components/affine/pinboard/pinboard-menu/index.tsx b/apps/web/src/components/affine/pinboard/pinboard-menu/index.tsx deleted file mode 100644 index 82c4840ae5..0000000000 --- a/apps/web/src/components/affine/pinboard/pinboard-menu/index.tsx +++ /dev/null @@ -1,133 +0,0 @@ -import type { PureMenuProps } from '@affine/component'; -import { Input, PureMenu, TreeView } from '@affine/component'; -import { useAFFiNEI18N } from '@affine/i18n/hooks'; -import { RemoveIcon, SearchIcon } from '@blocksuite/icons'; -import type { PageMeta } from '@blocksuite/store'; -import React, { useCallback, useMemo, useState } from 'react'; - -import { useReferenceLinkHelper } from '../../../../hooks/affine/use-reference-link-helper'; -import { usePinboardData } from '../../../../hooks/use-pinboard-data'; -import { usePinboardHandler } from '../../../../hooks/use-pinboard-handler'; -import type { BlockSuiteWorkspace } from '../../../../shared'; -import { toast } from '../../../../utils'; -import { PinboardRender } from '../pinboard-render/'; -import { - StyledMenuContent, - StyledMenuFooter, - StyledMenuSubTitle, - StyledPinboard, - StyledSearchContainer, -} from '../styles'; -import { SearchContent } from './search-content'; - -export interface PinboardMenuProps extends PureMenuProps { - metas: PageMeta[]; - currentMeta: PageMeta; - blockSuiteWorkspace: BlockSuiteWorkspace; - showRemovePinboard?: boolean; - onPinboardClick?: (p: { dragId: string; dropId: string }) => void; -} - -export const PinboardMenu = ({ - metas: propsMetas, - currentMeta, - blockSuiteWorkspace, - showRemovePinboard = false, - onPinboardClick, - ...pureMenuProps -}: PinboardMenuProps) => { - const metas = useMemo( - () => propsMetas.filter(m => m.id !== currentMeta.id), - [currentMeta.id, propsMetas] - ); - const t = useAFFiNEI18N(); - const [query, setQuery] = useState(''); - const isSearching = query.length > 0; - - const searchResult = metas.filter( - meta => !meta.trash && meta.title.includes(query) - ); - const { removeReferenceLink } = useReferenceLinkHelper(blockSuiteWorkspace); - - const { dropPin } = usePinboardHandler({ - blockSuiteWorkspace, - metas, - }); - - const handleClick = useCallback( - (dropId: string) => { - const targetTitle = metas.find(m => m.id === dropId)?.title; - - dropPin(currentMeta.id, dropId, { - bottomLine: false, - topLine: false, - internal: true, - }); - onPinboardClick?.({ dragId: currentMeta.id, dropId }); - toast(`Moved "${currentMeta.title}" to "${targetTitle}"`); - }, - [currentMeta.id, currentMeta.title, dropPin, metas, onPinboardClick] - ); - - const { data } = usePinboardData({ - metas, - pinboardRender: PinboardRender, - blockSuiteWorkspace, - onClick: (e, node) => { - handleClick(node.id); - }, - }); - - return ( - - - - e.stopPropagation()} - data-testid="pinboard-menu-search" - /> - - - - {isSearching && ( - - )} - {!isSearching && ( - <> - Suggested - - - )} - - - {showRemovePinboard && ( - - { - removeReferenceLink(currentMeta.id); - }} - > - - {t['Remove from Pivots']()} - -

{t['RFP']()}

-
- )} -
- ); -}; - -export default PinboardMenu; diff --git a/apps/web/src/components/affine/pinboard/pinboard-menu/search-content.tsx b/apps/web/src/components/affine/pinboard/pinboard-menu/search-content.tsx deleted file mode 100644 index ca7691951d..0000000000 --- a/apps/web/src/components/affine/pinboard/pinboard-menu/search-content.tsx +++ /dev/null @@ -1,63 +0,0 @@ -import { FlexWrapper } from '@affine/component'; -import { useAFFiNEI18N } from '@affine/i18n/hooks'; -import { EdgelessIcon, PageIcon } from '@blocksuite/icons'; -import type { PageMeta } from '@blocksuite/store'; -import { useAtomValue } from 'jotai'; -import Image from 'next/legacy/image'; -import React from 'react'; - -import { workspacePreferredModeAtom } from '../../../../atoms'; -import { StyledMenuSubTitle, StyledPinboard } from '../styles'; - -export const SearchContent = ({ - results, - onClick, -}: { - results: PageMeta[]; - onClick?: (dropId: string) => void; -}) => { - const t = useAFFiNEI18N(); - const record = useAtomValue(workspacePreferredModeAtom); - - if (results.length) { - return ( - <> - - {t['Find results']({ number: `${results.length}` })} - - {results.map(meta => { - return ( - { - onClick?.(meta.id); - }} - data-testid="pinboard-search-result" - > - {record[meta.id] === 'edgeless' ? : } - {meta.title} - - ); - })} - - ); - } - - return ( - <> - {t['Find 0 result']()} - - no result - - - ); -}; diff --git a/apps/web/src/components/affine/pinboard/pinboard-render/add-button.tsx b/apps/web/src/components/affine/pinboard/pinboard-render/add-button.tsx deleted file mode 100644 index b3354a2ca3..0000000000 --- a/apps/web/src/components/affine/pinboard/pinboard-render/add-button.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import { PlusIcon } from '@blocksuite/icons'; - -import { StyledOperationButton } from '../styles'; -import type { OperationButtonProps } from './operation-button'; - -export const AddButton = ({ - onAdd, - visible, -}: Pick) => { - return ( - { - e.stopPropagation(); - onAdd(); - }} - > - - - ); -}; diff --git a/apps/web/src/components/affine/pinboard/pinboard-render/empty-item.tsx b/apps/web/src/components/affine/pinboard/pinboard-render/empty-item.tsx deleted file mode 100644 index af68c6d479..0000000000 --- a/apps/web/src/components/affine/pinboard/pinboard-render/empty-item.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { useAFFiNEI18N } from '@affine/i18n/hooks'; - -import { StyledPinboard } from '../styles'; - -export const EmptyItem = () => { - const t = useAFFiNEI18N(); - return ( - - {t['Organize pages to build knowledge']()} - - ); -}; - -export default EmptyItem; diff --git a/apps/web/src/components/affine/pinboard/pinboard-render/index.tsx b/apps/web/src/components/affine/pinboard/pinboard-render/index.tsx deleted file mode 100644 index 34ae2e2dee..0000000000 --- a/apps/web/src/components/affine/pinboard/pinboard-render/index.tsx +++ /dev/null @@ -1,137 +0,0 @@ -import { Input } from '@affine/component'; -import { - ArrowDownSmallIcon, - EdgelessIcon, - LevelIcon, - PageIcon, - PinboardIcon, -} from '@blocksuite/icons'; -import { usePageMetaHelper } from '@toeverything/hooks/use-block-suite-page-meta'; -import { useAtomValue } from 'jotai'; -import { useRouter } from 'next/router'; -import { useMemo, useState } from 'react'; - -import { workspacePreferredModeAtom } from '../../../../atoms'; -import type { PinboardNode } from '../../../../hooks/use-pinboard-data'; -import { StyledCollapsedButton, StyledPinboard } from '../styles'; -import { AddButton } from './add-button'; -import EmptyItem from './empty-item'; -import { OperationButton } from './operation-button'; - -const getIcon = (type: 'root' | 'edgeless' | 'page') => { - switch (type) { - case 'root': - return ; - case 'edgeless': - return ; - default: - return ; - } -}; - -export const PinboardRender: PinboardNode['render'] = ( - node, - { - isOver, - onAdd, - onDelete, - collapsed, - setCollapsed, - isSelected, - disableCollapse, - }, - renderProps -) => { - const { - onClick, - showOperationButton = false, - currentMeta, - metas = [], - blockSuiteWorkspace, - asPath, - } = renderProps!; - const record = useAtomValue(workspacePreferredModeAtom); - const { setPageTitle } = usePageMetaHelper(blockSuiteWorkspace); - - const router = useRouter(); - - const [isHover, setIsHover] = useState(false); - const [showRename, setShowRename] = useState(false); - - const active = router.query.pageId === node.id; - const isRoot = !!currentMeta.isRootPinboard; - return ( - <> - { - onClick?.(e, node); - }} - onMouseEnter={() => setIsHover(true)} - onMouseLeave={() => setIsHover(false)} - isOver={isOver || isSelected} - active={active} - disableCollapse={!!disableCollapse} - > - {!disableCollapse && ( - { - e.stopPropagation(); - setCollapsed(node.id, !collapsed); - }} - > - - - )} - {asPath && !isRoot ? : null} - {getIcon(isRoot ? 'root' : record[node.id])} - {showRename ? ( - e.stopPropagation()} - height={32} - onBlur={() => { - setShowRename(false); - }} - onChange={value => { - // FIXME: setPageTitle would make input blur, and can't input the Chinese character - setPageTitle(node.id, value); - }} - /> - ) : ( - {isRoot ? 'Pinboard' : currentMeta.title || 'Untitled'} - )} - {showOperationButton && } - - {showOperationButton && ( - setIsHover(false)} - onRename={() => { - setShowRename(true); - setIsHover(false); - }} - /> - )} - - - {useMemo( - () => - isRoot && - !metas.find(m => (currentMeta.subpageIds ?? []).includes(m.id)), - [currentMeta.subpageIds, isRoot, metas] - ) && } - - ); -}; -export default PinboardRender; diff --git a/apps/web/src/components/affine/pinboard/pinboard-render/operation-button.tsx b/apps/web/src/components/affine/pinboard/pinboard-render/operation-button.tsx deleted file mode 100644 index 0fbe534008..0000000000 --- a/apps/web/src/components/affine/pinboard/pinboard-render/operation-button.tsx +++ /dev/null @@ -1,170 +0,0 @@ -import { MenuItem, MuiClickAwayListener, PureMenu } from '@affine/component'; -import { CopyLink, MoveToTrash } from '@affine/component/page-list'; -import { useAFFiNEI18N } from '@affine/i18n/hooks'; -import { - MoreVerticalIcon, - MoveToIcon, - PenIcon, - PlusIcon, -} from '@blocksuite/icons'; -import type { PageMeta } from '@blocksuite/store'; -import { baseTheme } from '@toeverything/theme'; -import { useMemo, useRef, useState } from 'react'; - -import { useBlockSuiteMetaHelper } from '../../../../hooks/affine/use-block-suite-meta-helper'; -import type { BlockSuiteWorkspace } from '../../../../shared'; -import { toast } from '../../../../utils'; -import { PinboardMenu } from '../pinboard-menu/'; -import { StyledOperationButton } from '../styles'; - -export type OperationButtonProps = { - isRoot: boolean; - onAdd: () => void; - onDelete: () => void; - metas: PageMeta[]; - currentMeta: PageMeta; - blockSuiteWorkspace: BlockSuiteWorkspace; - visible: boolean; - onRename?: () => void; - onMenuClose?: () => void; -}; -export const OperationButton = ({ - isRoot, - onAdd, - onDelete, - metas, - currentMeta, - blockSuiteWorkspace, - visible, - onMenuClose, - onRename, -}: OperationButtonProps) => { - const t = useAFFiNEI18N(); - - const timer = useRef>(); - const [anchorEl, setAnchorEl] = useState(null); - const [operationMenuOpen, setOperationMenuOpen] = useState(false); - const [pinboardMenuOpen, setPinboardMenuOpen] = useState(false); - const [confirmModalOpen, setConfirmModalOpen] = useState(false); - const menuIndex = useMemo(() => parseInt(baseTheme.zIndexModal) + 1, []); - const { removeToTrash } = useBlockSuiteMetaHelper(blockSuiteWorkspace); - - return ( - { - setOperationMenuOpen(false); - setPinboardMenuOpen(false); - }} - > -
{ - e.stopPropagation(); - }} - onMouseLeave={() => { - timer.current = setTimeout(() => { - setOperationMenuOpen(false); - setPinboardMenuOpen(false); - }, 150); - }} - onMouseEnter={() => { - clearTimeout(timer.current); - }} - > - setAnchorEl(ref)} - size="small" - onClick={() => { - setOperationMenuOpen(!operationMenuOpen); - }} - visible={visible} - > - - - - - { - onAdd(); - setOperationMenuOpen(false); - onMenuClose?.(); - }} - icon={} - > - {t['Add a subpage inside']()} - - {!isRoot && ( - { - setOperationMenuOpen(false); - setPinboardMenuOpen(true); - }} - icon={} - > - {t['Move to']()} - - )} - {!isRoot && ( - { - onRename?.(); - setOperationMenuOpen(false); - onMenuClose?.(); - }} - icon={} - > - {t['Rename']()} - - )} - {!isRoot && ( - { - setOperationMenuOpen(false); - setConfirmModalOpen(true); - onMenuClose?.(); - }} - /> - )} - - - - - { - toast(t['Moved to Trash']()); - removeToTrash(currentMeta.id); - onDelete(); - }} - onCancel={() => { - setConfirmModalOpen(false); - }} - confirmButtonTestId="move-to-trash-confirm" - cancelButtonTestId="move-to-trash-cancel" - /> -
-
- ); -}; diff --git a/apps/web/src/components/affine/pinboard/styles.ts b/apps/web/src/components/affine/pinboard/styles.ts deleted file mode 100644 index 9448c60360..0000000000 --- a/apps/web/src/components/affine/pinboard/styles.ts +++ /dev/null @@ -1,148 +0,0 @@ -import { - displayFlex, - IconButton, - styled, - textEllipsis, -} from '@affine/component'; - -export const StyledCollapsedButton = styled('button')<{ - collapse: boolean; - show?: boolean; -}>(({ collapse, show = true }) => { - return { - width: '16px', - height: '100%', - ...displayFlex('center', 'center'), - fontSize: '16px', - position: 'absolute', - left: '0', - top: '0', - bottom: '0', - margin: 'auto', - color: 'var(--affine-icon-color)', - opacity: '.6', - transition: 'opacity .15s ease-in-out', - display: show ? 'flex' : 'none', - svg: { - transform: `rotate(${collapse ? '-90' : '0'}deg)`, - }, - ':hover': { - opacity: '1', - }, - }; -}); - -export const StyledPinboard = styled('div')<{ - disable?: boolean; - active?: boolean; - isOver?: boolean; - disableCollapse?: boolean; - textWrap?: boolean; -}>( - ({ - disableCollapse, - disable = false, - active = false, - isOver, - textWrap = false, - }) => { - return { - width: '100%', - lineHeight: '1.5', - minHeight: '32px', - borderRadius: '8px', - ...displayFlex('flex-start', 'center'), - padding: disableCollapse ? '0 5px' : '0 2px 0 16px', - position: 'relative', - color: disable - ? 'var(--affine-text-disable-color)' - : active - ? 'var(--affine-primary-color)' - : 'var(--affine-text-primary-color)', - cursor: disable ? 'not-allowed' : 'pointer', - background: isOver ? 'rgba(118, 95, 254, 0.06)' : '', - fontSize: 'var(--affine-font-base)', - userSelect: 'none', - ...(textWrap - ? { - wordBreak: 'break-word', - whiteSpace: 'pre-wrap', - } - : {}), - - span: { - flexGrow: '1', - textAlign: 'left', - ...textEllipsis(1), - }, - '.path-icon': { - fontSize: '16px', - transform: 'translateY(-4px)', - }, - '.mode-icon': { - fontSize: '20px', - marginRight: '8px', - flexShrink: '0', - color: active - ? 'var(--affine-primary-color)' - : 'var(--affine-icon-color)', - }, - - ':hover': { - backgroundColor: disable ? '' : 'var(--affine-hover-color)', - }, - }; - } -); - -export const StyledOperationButton = styled(IconButton, { - shouldForwardProp: prop => { - return !['visible'].includes(prop as string); - }, -})<{ visible: boolean }>(({ visible }) => { - return { - visibility: visible ? 'visible' : 'hidden', - }; -}); - -export const StyledSearchContainer = styled('div')(() => { - return { - width: 'calc(100% - 24px)', - margin: '0 auto', - ...displayFlex('flex-start', 'center'), - borderBottom: '1px solid var(--affine-border-color)', - label: { - color: 'var(--affine-icon-color)', - fontSize: '20px', - height: '20px', - }, - }; -}); -export const StyledMenuContent = styled('div')(() => { - return { - height: '266px', - overflow: 'auto', - }; -}); -export const StyledMenuSubTitle = styled('div')(() => { - return { - color: 'var(--affine-text-secondary-color)', - lineHeight: '36px', - padding: '0 12px', - }; -}); - -export const StyledMenuFooter = styled('div')(() => { - return { - width: 'calc(100% - 24px)', - margin: '0 auto', - borderTop: '1px solid var(--affine-border-color)', - padding: '6px 0', - - p: { - paddingLeft: '44px', - color: 'var(--affine-text-secondary-color)', - fontSize: '14px', - }, - }; -}); diff --git a/apps/web/src/components/blocksuite/workspace-header/header-right-items/editor-option-menu.tsx b/apps/web/src/components/blocksuite/workspace-header/header-right-items/editor-option-menu.tsx index 8f13b642e9..de34e96a03 100644 --- a/apps/web/src/components/blocksuite/workspace-header/header-right-items/editor-option-menu.tsx +++ b/apps/web/src/components/blocksuite/workspace-header/header-right-items/editor-option-menu.tsx @@ -108,14 +108,12 @@ const PageMenu = () => { {mode === 'page' ? t['Edgeless']() : t['Page']()} - {!pageMeta.isRootPinboard && ( - { - setOpenConfirm(true); - }} - /> - )} + { + setOpenConfirm(true); + }} + />
diff --git a/apps/web/src/components/page-detail-editor.tsx b/apps/web/src/components/page-detail-editor.tsx index 3a75341883..9286e8c816 100644 --- a/apps/web/src/components/page-detail-editor.tsx +++ b/apps/web/src/components/page-detail-editor.tsx @@ -21,7 +21,7 @@ export type PageDetailEditorProps = { workspace: AffineOfficialWorkspace; pageId: string; onInit: (page: Page, editor: Readonly) => void; - onLoad?: (page: Page, editor: EditorContainer) => void; + onLoad?: (page: Page, editor: EditorContainer) => () => void; header?: React.ReactNode; }; @@ -85,7 +85,10 @@ export const PageDetailEditor: React.FC = ({ updatedDate: Date.now(), }); localStorage.setItem('last_page_id', page.id); - onLoad?.(page, editor); + if (onLoad) { + return onLoad(page, editor); + } + return () => {}; }, [onLoad, setEditor] )} diff --git a/apps/web/src/components/pure/quick-search-modal/navigation-path/index.tsx b/apps/web/src/components/pure/quick-search-modal/navigation-path/index.tsx deleted file mode 100644 index 51e6172ea4..0000000000 --- a/apps/web/src/components/pure/quick-search-modal/navigation-path/index.tsx +++ /dev/null @@ -1,166 +0,0 @@ -import { IconButton, Tooltip, TreeView } from '@affine/component'; -import { useAFFiNEI18N } from '@affine/i18n/hooks'; -import { - ArrowRightSmallIcon, - CollapseIcon, - ExpandIcon, - MoreHorizontalIcon, -} from '@blocksuite/icons'; -import type { PageMeta } from '@blocksuite/store'; -import { useBlockSuitePageMeta } from '@toeverything/hooks/use-block-suite-page-meta'; -import { useRouter } from 'next/router'; -import type { MouseEvent } from 'react'; -import { Fragment, useCallback, useMemo, useState } from 'react'; - -import type { PinboardNode } from '../../../../hooks/use-pinboard-data'; -import { usePinboardData } from '../../../../hooks/use-pinboard-data'; -import { useRouterHelper } from '../../../../hooks/use-router-helper'; -import type { BlockSuiteWorkspace } from '../../../../shared'; -import { PinboardRender } from '../../../affine/pinboard'; -import { - StyledNavigationPathContainer, - StyledNavPathExtendContainer, - StyledNavPathLink, -} from './styles'; -import { calcHowManyPathShouldBeShown, findPath } from './utils'; - -export const NavigationPath = ({ - blockSuiteWorkspace, - pageId: propsPageId, - onJumpToPage, -}: { - blockSuiteWorkspace: BlockSuiteWorkspace; - pageId?: string; - onJumpToPage?: (pageId: string) => void; -}) => { - const metas = useBlockSuitePageMeta(blockSuiteWorkspace); - const router = useRouter(); - const t = useAFFiNEI18N(); - - const [openExtend, setOpenExtend] = useState(false); - const pageId = propsPageId ?? router.query.pageId; - const { jumpToPage } = useRouterHelper(router); - const pathData = useMemo(() => { - const meta = metas.find(m => m.id === pageId); - const path = meta ? findPath(metas, meta) : []; - - const actualPath = calcHowManyPathShouldBeShown(path); - return { - hasEllipsis: path.length !== actualPath.length, - path: actualPath, - }; - }, [metas, pageId]); - - if (pathData.path.length < 2) { - // Means there is no parent page - return null; - } - return ( - <> - - {openExtend ? ( - {t['Navigation Path']()} - ) : ( - pathData.path.map((meta, index) => { - const isLast = index === pathData.path.length - 1; - const showEllipsis = pathData.hasEllipsis && index === 1; - return ( - - {showEllipsis && ( - <> - setOpenExtend(true)} - > - - - - - )} - { - if (isLast) return; - jumpToPage(blockSuiteWorkspace.id, meta.id); - onJumpToPage?.(meta.id); - }} - title={meta.title} - > - {meta.title} - - {!isLast && } - - ); - }) - )} - - { - setOpenExtend(!openExtend); - }} - > - {openExtend ? : } - - - - - - ); -}; - -const NavigationPathExtendPanel = ({ - open, - metas, - blockSuiteWorkspace, - onJumpToPage, -}: { - open: boolean; - metas: PageMeta[]; - blockSuiteWorkspace: BlockSuiteWorkspace; - onJumpToPage?: (pageId: string) => void; -}) => { - const router = useRouter(); - const { jumpToPage } = useRouterHelper(router); - - const handlePinboardClick = useCallback( - (e: MouseEvent, node: PinboardNode) => { - jumpToPage(blockSuiteWorkspace.id, node.id); - onJumpToPage?.(node.id); - }, - [blockSuiteWorkspace.id, jumpToPage, onJumpToPage] - ); - - const { data } = usePinboardData({ - metas, - pinboardRender: PinboardRender, - blockSuiteWorkspace: blockSuiteWorkspace, - onClick: handlePinboardClick, - asPath: true, - }); - - return ( - - - - ); -}; diff --git a/apps/web/src/components/pure/quick-search-modal/navigation-path/styles.ts b/apps/web/src/components/pure/quick-search-modal/navigation-path/styles.ts deleted file mode 100644 index c1ec4c728f..0000000000 --- a/apps/web/src/components/pure/quick-search-modal/navigation-path/styles.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { displayFlex, styled, textEllipsis } from '@affine/component'; - -export const StyledNavigationPathContainer = styled('div')(() => { - return { - height: '46px', - ...displayFlex('flex-start', 'center'), - background: 'var(--affine-background-secondary-color)', - padding: '0 40px 0 20px', - position: 'relative', - fontSize: 'var(--affine-font-sm)', - zIndex: 2, - '.collapse-btn': { - position: 'absolute', - right: '12px', - top: 0, - bottom: 0, - margin: 'auto', - }, - '.path-arrow': { - fontSize: '16px', - color: 'var(--affine-icon-color)', - }, - }; -}); - -export const StyledNavPathLink = styled('div')<{ active?: boolean }>( - ({ active }) => { - return { - color: active - ? 'var(--affine-text-primary-color)' - : 'var(--affine-text-secondary-color)', - cursor: active ? 'auto' : 'pointer', - maxWidth: '160px', - ...textEllipsis(1), - padding: '0 4px', - transition: 'background .15s', - ':hover': active - ? {} - : { - background: 'var(--affine-hover-color)', - borderRadius: '4px', - }, - }; - } -); - -export const StyledNavPathExtendContainer = styled('div')<{ show: boolean }>( - ({ show }) => { - return { - position: 'absolute', - left: '0', - top: show ? '0' : '-100%', - zIndex: '1', - height: '100%', - width: '100%', - background: 'var(--affine-background-secondary-color)', - transition: 'top .15s', - fontSize: 'var(--affine-font-sm)', - color: 'var(--affine-text-secondary-color)', - padding: '46px 12px 0 15px', - }; - } -); diff --git a/apps/web/src/components/pure/quick-search-modal/navigation-path/utils.ts b/apps/web/src/components/pure/quick-search-modal/navigation-path/utils.ts deleted file mode 100644 index 80499dd387..0000000000 --- a/apps/web/src/components/pure/quick-search-modal/navigation-path/utils.ts +++ /dev/null @@ -1,60 +0,0 @@ -import type { PageMeta } from '@blocksuite/store'; - -export function findPath(metas: PageMeta[], meta: PageMeta): PageMeta[] { - function helper(group: PageMeta[]): PageMeta[] { - const last = group[group.length - 1]; - const parent = metas.find(m => (m.subpageIds ?? []).includes(last.id)); - if (parent) { - return helper([...group, parent]); - } - return group; - } - - return helper([meta]).reverse(); -} - -function getPathItemWidth(content: string) { - // padding is 8px, arrow is 16px, and each char is 10px - // the max width is 160px - const charWidth = 10; - const w = content.length * charWidth + 8 + 16; - return w > 160 ? 160 : w; -} - -// XXX: this is a static way to calculate the path width, not get the real width -export function calcHowManyPathShouldBeShown(path: PageMeta[]): PageMeta[] { - if (path.length === 0) { - return []; - } - const first = path[0]; - const last = path[path.length - 1]; - // 20 is the ellipsis icon width - const maxWidth = 550 - 20; - if (first.id === last.id) { - return [first]; - } - - function getMiddlePath(restWidth: number, restPath: PageMeta[]): PageMeta[] { - if (restPath.length === 0) { - return []; - } - const last = restPath[restPath.length - 1]; - const w = getPathItemWidth(last.title); - if (restWidth - w > 80) { - return [ - ...getMiddlePath(restWidth - w, restPath.slice(0, restPath.length - 1)), - last, - ]; - } - return []; - } - - return [ - first, - ...getMiddlePath( - maxWidth - getPathItemWidth(first.title), - path.slice(1, -1) - ), - last, - ]; -} diff --git a/apps/web/src/components/pure/workspace-slider-bar/index.tsx b/apps/web/src/components/pure/workspace-slider-bar/index.tsx index c1b3a17b7a..5020cf10db 100644 --- a/apps/web/src/components/pure/workspace-slider-bar/index.tsx +++ b/apps/web/src/components/pure/workspace-slider-bar/index.tsx @@ -1,25 +1,5 @@ -import type { Page } from '@blocksuite/store'; - import type { AllWorkspace } from '../../../shared'; export type FavoriteListProps = { currentWorkspace: AllWorkspace; }; - -export type WorkSpaceSliderBarProps = { - isPublicWorkspace: boolean; - onOpenQuickSearchModal: () => void; - onOpenWorkspaceListModal: () => void; - currentWorkspace: AllWorkspace | null; - currentPageId: string | null; - openPage: (pageId: string) => void; - createPage: () => Page; - currentPath: string; - paths: { - all: (workspaceId: string) => string; - favorite: (workspaceId: string) => string; - trash: (workspaceId: string) => string; - setting: (workspaceId: string) => string; - shared: (workspaceId: string) => string; - }; -}; diff --git a/apps/web/src/components/pure/workspace-slider-bar/pinboard.tsx b/apps/web/src/components/pure/workspace-slider-bar/pinboard.tsx deleted file mode 100644 index 43fc8ae967..0000000000 --- a/apps/web/src/components/pure/workspace-slider-bar/pinboard.tsx +++ /dev/null @@ -1,64 +0,0 @@ -import { TreeView } from '@affine/component'; -import { useBlockSuitePageMeta } from '@toeverything/hooks/use-block-suite-page-meta'; -import type { MouseEvent } from 'react'; -import { useCallback } from 'react'; - -import type { PinboardNode } from '../../../hooks/use-pinboard-data'; -import { usePinboardData } from '../../../hooks/use-pinboard-data'; -import { usePinboardHandler } from '../../../hooks/use-pinboard-handler'; -import type { BlockSuiteWorkspace } from '../../../shared'; -import { PinboardRender } from '../../affine/pinboard'; - -export type PinboardProps = { - blockSuiteWorkspace: BlockSuiteWorkspace; - openPage: (pageId: string) => void; -}; - -/** - * @deprecated - */ -export const Pinboard = ({ blockSuiteWorkspace, openPage }: PinboardProps) => { - const allMetas = useBlockSuitePageMeta(blockSuiteWorkspace); - const handlePinboardClick = useCallback( - (e: MouseEvent, node: PinboardNode) => { - openPage(node.id); - }, - [openPage] - ); - const onAdd = useCallback( - (id: string) => { - openPage(id); - }, - [openPage] - ); - - const { data } = usePinboardData({ - metas: allMetas, - pinboardRender: PinboardRender, - blockSuiteWorkspace: blockSuiteWorkspace, - onClick: handlePinboardClick, - showOperationButton: true, - }); - - const { addPin, deletePin, dropPin } = usePinboardHandler({ - blockSuiteWorkspace: blockSuiteWorkspace, - metas: allMetas, - onAdd, - }); - - if (!data.length) { - return null; - } - return ( -
- -
- ); -}; -export default Pinboard; diff --git a/apps/web/src/hooks/affine/use-reference-link-effect.ts b/apps/web/src/hooks/affine/use-reference-link-effect.ts deleted file mode 100644 index 1180f02d07..0000000000 --- a/apps/web/src/hooks/affine/use-reference-link-effect.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { useAtomValue } from 'jotai'; -import { useEffect } from 'react'; - -import { currentEditorAtom } from '../../atoms'; - -export function useReferenceLinkEffect(props?: { - pageLinkClicked?: (params: { pageId: string }) => void; - subpageLinked?: (params: { pageId: string }) => void; - subpageUnlinked?: (params: { pageId: string }) => void; -}) { - const { pageLinkClicked, subpageLinked, subpageUnlinked } = props ?? {}; - const editor = useAtomValue(currentEditorAtom); - - useEffect(() => { - if (!editor) { - return; - } - - const linkClickedDisposable = editor.slots.pageLinkClicked.on( - ({ pageId }) => { - pageLinkClicked?.({ pageId }); - } - ); - - // const subpageLinkedDisposable = editor.slots.subpageLinked.on( - // ({ pageId }) => { - // subpageLinked?.({ pageId }); - // } - // ); - // const subpageUnlinkedDisposable = editor.slots.subpageUnlinked.on( - // ({ pageId }) => { - // subpageUnlinked?.({ pageId }); - // } - // ); - - return () => { - linkClickedDisposable.dispose(); - // subpageLinkedDisposable.dispose(); - // subpageUnlinkedDisposable.dispose(); - }; - }, [editor, pageLinkClicked, subpageLinked, subpageUnlinked]); -} diff --git a/apps/web/src/hooks/use-pinboard-data.ts b/apps/web/src/hooks/use-pinboard-data.ts deleted file mode 100644 index 6abb9e64f1..0000000000 --- a/apps/web/src/hooks/use-pinboard-data.ts +++ /dev/null @@ -1,92 +0,0 @@ -import type { Node } from '@affine/component'; -import type { PageMeta } from '@blocksuite/store'; -import type { MouseEvent } from 'react'; -import { useMemo } from 'react'; - -import type { BlockSuiteWorkspace } from '../shared'; - -export type RenderProps = { - blockSuiteWorkspace: BlockSuiteWorkspace; - onClick?: (e: MouseEvent, node: PinboardNode) => void; - showOperationButton?: boolean; - // If true, the node will be rendered with path icon at start - asPath?: boolean; -}; - -export type NodeRenderProps = RenderProps & { - metas: PageMeta[]; - currentMeta: PageMeta; -}; - -export type PinboardNode = Node; - -function flattenToTree( - metas: PageMeta[], - pinboardRender: PinboardNode['render'], - renderProps: RenderProps -): PinboardNode[] { - const rootMeta = metas.find(meta => meta.isRootPinboard); - const helper = (internalMetas: PageMeta[]): PinboardNode[] => { - return internalMetas.reduce( - (returnedMetas, internalMeta) => { - const { subpageIds = [] } = internalMeta; - const childrenMetas = subpageIds - .map(id => metas.find(m => m.id === id)!) - .filter(m => m); - // @ts-ignore - const returnedMeta: PinboardNode = { - ...internalMeta, - children: helper(childrenMetas), - render: (node, props) => - pinboardRender(node, props, { - ...renderProps, - currentMeta: internalMeta, - metas, - }), - }; - returnedMetas.push(returnedMeta); - return returnedMetas; - }, - [] - ); - }; - // Unreachable code, we have removed the root pinboard - // @ts-expect-error - return helper(rootMeta ? [{ ...rootMeta, renderTopLine: false }] : []); -} - -export function usePinboardData({ - metas, - pinboardRender, - blockSuiteWorkspace, - onClick, - showOperationButton, - asPath, -}: { - metas: PageMeta[]; - pinboardRender: PinboardNode['render']; -} & RenderProps) { - const data = useMemo( - () => - flattenToTree(metas, pinboardRender, { - blockSuiteWorkspace, - onClick, - showOperationButton, - asPath, - }), - [ - asPath, - blockSuiteWorkspace, - metas, - onClick, - pinboardRender, - showOperationButton, - ] - ); - - return { - data, - }; -} - -export default usePinboardData; diff --git a/apps/web/src/hooks/use-pinboard-handler.ts b/apps/web/src/hooks/use-pinboard-handler.ts deleted file mode 100644 index c0a0482638..0000000000 --- a/apps/web/src/hooks/use-pinboard-handler.ts +++ /dev/null @@ -1,138 +0,0 @@ -import type { TreeViewProps } from '@affine/component'; -import { DebugLogger } from '@affine/debug'; -import type { PageMeta } from '@blocksuite/store'; -import { nanoid } from '@blocksuite/store'; -import { usePageMetaHelper } from '@toeverything/hooks/use-block-suite-page-meta'; -import { useBlockSuiteWorkspaceHelper } from '@toeverything/hooks/use-block-suite-workspace-helper'; -import { useCallback, useMemo } from 'react'; - -import type { BlockSuiteWorkspace } from '../shared'; -import { useBlockSuiteMetaHelper } from './affine/use-block-suite-meta-helper'; -import { useReferenceLinkHelper } from './affine/use-reference-link-helper'; -import type { NodeRenderProps } from './use-pinboard-data'; - -const logger = new DebugLogger('pinboard'); - -function findRootIds(metas: PageMeta[], id: string): string[] { - const parentMeta = metas.find(m => m.subpageIds?.includes(id)); - if (!parentMeta) { - return [id]; - } - return [parentMeta.id, ...findRootIds(metas, parentMeta.id)]; -} -export function usePinboardHandler({ - blockSuiteWorkspace, - metas: propsMetas, - onAdd, - onDelete, - onDrop, -}: { - blockSuiteWorkspace: BlockSuiteWorkspace; - metas?: PageMeta[]; - onAdd?: (addedId: string, parentId: string) => void; - onDelete?: TreeViewProps['onDelete']; - onDrop?: TreeViewProps['onDrop']; -}) { - const metas = useMemo( - () => propsMetas || blockSuiteWorkspace.meta.pageMetas || [], - [blockSuiteWorkspace.meta.pageMetas, propsMetas] - ); - const { createPage } = useBlockSuiteWorkspaceHelper(blockSuiteWorkspace); - const { setPageMeta } = usePageMetaHelper(blockSuiteWorkspace); - const { removeToTrash: removeToTrashHelper } = - useBlockSuiteMetaHelper(blockSuiteWorkspace); - const { addReferenceLink, removeReferenceLink } = - useReferenceLinkHelper(blockSuiteWorkspace); - - const addPin = useCallback( - (parentId: string) => { - const id = nanoid(); - createPage(id); - onAdd?.(id, parentId); - addReferenceLink(parentId, id); - }, - [addReferenceLink, createPage, onAdd] - ); - - const deletePin = useCallback( - (deleteId: string) => { - removeToTrashHelper(deleteId); - onDelete?.(deleteId); - }, - [removeToTrashHelper, onDelete] - ); - - const dropPin = useCallback( - ( - dragId: string, - dropId: string, - position: { - topLine: boolean; - bottomLine: boolean; - internal: boolean; - } - ) => { - if (dragId === dropId) { - return; - } - const dropRootIds = findRootIds(metas, dropId); - if (dropRootIds.includes(dragId)) { - return; - } - logger.info('handleDrop', { - dragId, - dropId, - position, - metas, - }); - - const { topLine, bottomLine } = position; - - const dragParentMeta = metas.find(meta => - meta.subpageIds?.includes(dragId) - ); - if (bottomLine || topLine) { - const insertOffset = bottomLine ? 1 : 0; - - const dropParentMeta = metas.find(m => m.subpageIds?.includes(dropId)); - if (dropParentMeta?.id === dragParentMeta?.id) { - // same parent, resort node - const newSubpageIds = [...(dragParentMeta?.subpageIds ?? [])]; - const deleteIndex = newSubpageIds.findIndex(id => id === dragId); - newSubpageIds.splice(deleteIndex, 1); - const insertIndex = - newSubpageIds.findIndex(id => id === dropId) + insertOffset; - newSubpageIds.splice(insertIndex, 0, dragId); - dragParentMeta && - setPageMeta(dragParentMeta.id, { - subpageIds: newSubpageIds, - }); - return onDrop?.(dragId, dropId, position); - } - // Old parent will delete drag node, new parent will be added - removeReferenceLink(dragId); - dropParentMeta && addReferenceLink(dropParentMeta.id, dragId); - return onDrop?.(dragId, dropId, position); - } - - // drop into the node - if (dragParentMeta && dragParentMeta.id === dropId) { - return; - } - if (dragParentMeta) { - removeReferenceLink(dragId); - } - const dropMeta = metas.find(meta => meta.id === dropId)!; - addReferenceLink(dropMeta.id, dragId); - }, - [addReferenceLink, metas, onDrop, removeReferenceLink, setPageMeta] - ); - - return { - dropPin, - addPin, - deletePin, - }; -} - -export default usePinboardHandler; diff --git a/apps/web/src/layouts/workspace-layout.tsx b/apps/web/src/layouts/workspace-layout.tsx index c9c51d963a..6871eb4f67 100644 --- a/apps/web/src/layouts/workspace-layout.tsx +++ b/apps/web/src/layouts/workspace-layout.tsx @@ -287,11 +287,6 @@ export const WorkspaceLayoutInner: FC = ({ children }) => { void jumpToPage(currentWorkspace.id, pageId); } } - - // fixme: pinboard has been removed, - // the related code should be removed in the future. - // no matter the workspace is empty, ensure the root pinboard exists - // ensureRootPinboard(currentWorkspace.blockSuiteWorkspace); //#endregion useEffect(() => { diff --git a/apps/web/src/pages/public-workspace/[workspaceId]/[pageId].tsx b/apps/web/src/pages/public-workspace/[workspaceId]/[pageId].tsx index 8f825f338f..df077717b4 100644 --- a/apps/web/src/pages/public-workspace/[workspaceId]/[pageId].tsx +++ b/apps/web/src/pages/public-workspace/[workspaceId]/[pageId].tsx @@ -9,7 +9,7 @@ import { useAtom, useAtomValue } from 'jotai'; import Link from 'next/link'; import { useRouter } from 'next/router'; import type { ReactElement } from 'react'; -import { Suspense, useCallback, useEffect } from 'react'; +import { Suspense, useEffect } from 'react'; import { publicPageBlockSuiteAtom, @@ -19,7 +19,6 @@ import { import { PageDetailEditor } from '../../../components/page-detail-editor'; import { WorkspaceAvatar } from '../../../components/pure/footer'; import { PageLoading } from '../../../components/pure/loading'; -import { useReferenceLinkEffect } from '../../../hooks/affine/use-reference-link-effect'; import { useRouterHelper } from '../../../hooks/use-router-helper'; import { PublicQuickSearch, @@ -64,14 +63,6 @@ const PublicWorkspaceDetailPageInner = (): ReactElement => { } const router = useRouter(); const { openPage } = useRouterHelper(router); - useReferenceLinkEffect({ - pageLinkClicked: useCallback( - ({ pageId }: { pageId: string }) => { - return openPage(blockSuiteWorkspace.id, pageId); - }, - [blockSuiteWorkspace.id, openPage] - ), - }); const t = useAFFiNEI18N(); const [name] = useBlockSuiteWorkspaceName(blockSuiteWorkspace); const [avatar] = useBlockSuiteWorkspaceAvatarUrl(blockSuiteWorkspace); @@ -86,6 +77,12 @@ const PublicWorkspaceDetailPageInner = (): ReactElement => { onLoad={(_, editor) => { const { page } = editor; page.awarenessStore.setReadonly(page, true); + const dispose = editor.slots.pageLinkClicked.on(({ pageId }) => { + return openPage(blockSuiteWorkspace.id, pageId); + }); + return () => { + dispose.dispose(); + }; }} onInit={initPage} header={ diff --git a/apps/web/src/pages/workspace/[workspaceId]/[pageId].tsx b/apps/web/src/pages/workspace/[workspaceId]/[pageId].tsx index 39a9d8f4ce..3993f430ef 100644 --- a/apps/web/src/pages/workspace/[workspaceId]/[pageId].tsx +++ b/apps/web/src/pages/workspace/[workspaceId]/[pageId].tsx @@ -4,11 +4,9 @@ import { config } from '@affine/env'; import { Unreachable } from '@affine/env/constant'; import { rootCurrentPageIdAtom } from '@affine/workspace/atom'; import { WorkspaceFlavour } from '@affine/workspace/type'; +import type { EditorContainer } from '@blocksuite/editor'; +import type { Page } from '@blocksuite/store'; import { assertExists } from '@blocksuite/store'; -import { - useBlockSuitePageMeta, - usePageMetaHelper, -} from '@toeverything/hooks/use-block-suite-page-meta'; import { useBlockSuiteWorkspacePage } from '@toeverything/hooks/use-block-suite-workspace-page'; import { useAtomValue } from 'jotai'; import { useRouter } from 'next/router'; @@ -17,9 +15,7 @@ import { useCallback, useEffect } from 'react'; import { WorkspaceAdapters } from '../../../adapters/workspace'; import { rootCurrentWorkspaceAtom } from '../../../atoms/root'; -import { useReferenceLinkEffect } from '../../../hooks/affine/use-reference-link-effect'; import { useCurrentWorkspace } from '../../../hooks/current/use-current-workspace'; -import { usePinboardHandler } from '../../../hooks/use-pinboard-handler'; import { useSyncRecentViewsWithRouter } from '../../../hooks/use-recent-views'; import { useRouterHelper } from '../../../hooks/use-router-helper'; import { WorkspaceLayout } from '../../../layouts/workspace-layout'; @@ -42,41 +38,19 @@ const WorkspaceDetail: React.FC = () => { assertExists(currentWorkspace); assertExists(currentPageId); const blockSuiteWorkspace = currentWorkspace.blockSuiteWorkspace; - const { setPageMeta, getPageMeta } = usePageMetaHelper(blockSuiteWorkspace); - const { deletePin } = usePinboardHandler({ - blockSuiteWorkspace, - metas: useBlockSuitePageMeta(currentWorkspace.blockSuiteWorkspace), - }); - useSyncRecentViewsWithRouter(router, blockSuiteWorkspace); - useReferenceLinkEffect({ - pageLinkClicked: useCallback( - ({ pageId }: { pageId: string }) => { - assertExists(currentWorkspace); - return openPage(currentWorkspace.id, pageId); - }, - [currentWorkspace, openPage] - ), - subpageUnlinked: useCallback( - ({ pageId }: { pageId: string }) => { - deletePin(pageId); - }, - [deletePin] - ), - subpageLinked: useCallback( - ({ pageId }: { pageId: string }) => { - const meta = currentPageId && getPageMeta(currentPageId); - if (!meta || meta.subpageIds?.includes(pageId)) { - return; - } - setPageMeta(currentPageId, { - subpageIds: [...(meta.subpageIds ?? []), pageId], - }); - }, - [currentPageId, getPageMeta, setPageMeta] - ), - }); + const onLoad = useCallback( + (page: Page, editor: EditorContainer) => { + const dispose = editor.slots.pageLinkClicked.on(({ pageId }) => { + return openPage(blockSuiteWorkspace.id, pageId); + }); + return () => { + dispose.dispose(); + }; + }, + [blockSuiteWorkspace.id, openPage] + ); useEffect(() => { if (currentWorkspace) { @@ -90,6 +64,7 @@ const WorkspaceDetail: React.FC = () => { ); } else if (currentWorkspace.flavour === WorkspaceFlavour.LOCAL) { @@ -99,6 +74,7 @@ const WorkspaceDetail: React.FC = () => { ); } diff --git a/packages/component/src/components/block-suite-editor/index.tsx b/packages/component/src/components/block-suite-editor/index.tsx index 0d437d328c..184ea1d758 100644 --- a/packages/component/src/components/block-suite-editor/index.tsx +++ b/packages/component/src/components/block-suite-editor/index.tsx @@ -21,7 +21,7 @@ export type EditorProps = { page: Page; mode: 'page' | 'edgeless'; onInit: (page: Page, editor: Readonly) => void; - onLoad?: (page: Page, editor: EditorContainer) => void; + onLoad?: (page: Page, editor: EditorContainer) => () => void; style?: CSSProperties; }; @@ -67,7 +67,7 @@ const BlockSuiteEditorImpl = (props: EditorProps): ReactElement => { if (page.root === null) { props.onInit(page, editor); } - props.onLoad?.(page, editor); + return props.onLoad?.(page, editor); } }, [props.page, props.onInit, props.onLoad, editor, props, page]); diff --git a/packages/component/src/ui/toast/toast.ts b/packages/component/src/ui/toast/toast.ts index 20d4a629f5..6b0bf157b4 100644 --- a/packages/component/src/ui/toast/toast.ts +++ b/packages/component/src/ui/toast/toast.ts @@ -103,9 +103,6 @@ export const toast = ( easing: 'cubic-bezier(0.21, 1.02, 0.73, 1)', fill: 'forwards' as const, }; // satisfies KeyframeAnimationOptions; - // FIXME: Vitest not support element.animate, - // can try it in `apps/web/src/components/__tests__/PinBoard.spec.tsx` `delete pivot` - typeof element.animate === 'function' && element.animate(fadeIn, options); setTimeout(async () => { if (typeof element.animate !== 'function') return; diff --git a/packages/env/src/blocksuite.ts b/packages/env/src/blocksuite.ts index 39e8b66d8c..dd080e54c7 100644 --- a/packages/env/src/blocksuite.ts +++ b/packages/env/src/blocksuite.ts @@ -1,8 +1,7 @@ import { DebugLogger } from '@affine/debug'; import markdown from '@affine/templates/AFFiNE-beta-0.5.4.md'; import { ContentParser } from '@blocksuite/blocks/content-parser'; -import type { Page, Workspace } from '@blocksuite/store'; -import { nanoid } from '@blocksuite/store'; +import type { Page } from '@blocksuite/store'; declare global { interface Window { @@ -57,25 +56,3 @@ export function _initPageWithDemoMarkdown(page: Page): void { contentParser.importMarkdown(demoText, frameId); page.workspace.setPageMeta(page.id, { title: demoTitle }); } - -export function ensureRootPinboard(blockSuiteWorkspace: Workspace) { - const metas = blockSuiteWorkspace.meta.pageMetas; - const rootMeta = metas.find(m => m.isRootPinboard); - - if (rootMeta) { - return rootMeta.id; - } - - const rootPinboardPage = blockSuiteWorkspace.createPage(nanoid()); - - const title = `${blockSuiteWorkspace.meta.name}'s Pinboard`; - - _initEmptyPage(rootPinboardPage, title); - - blockSuiteWorkspace.meta.setPageMeta(rootPinboardPage.id, { - isRootPinboard: true, - title, - }); - - return rootPinboardPage.id; -} diff --git a/packages/hooks/src/use-block-suite-page-meta.ts b/packages/hooks/src/use-block-suite-page-meta.ts index e613e01c7e..02d4795675 100644 --- a/packages/hooks/src/use-block-suite-page-meta.ts +++ b/packages/hooks/src/use-block-suite-page-meta.ts @@ -20,7 +20,6 @@ declare module '@blocksuite/store' { init?: boolean; // todo: support `number` in the future isPublic?: boolean; - isRootPinboard?: boolean; } } diff --git a/packages/workspace/src/type.ts b/packages/workspace/src/type.ts index 73aee79e1b..77de6ce6d2 100644 --- a/packages/workspace/src/type.ts +++ b/packages/workspace/src/type.ts @@ -1,6 +1,8 @@ // eslint-disable-next-line @typescript-eslint/triple-slash-reference /// import type { Workspace as RemoteWorkspace } from '@affine/workspace/affine/api'; +import type { EditorContainer } from '@blocksuite/editor'; +import type { Page } from '@blocksuite/store'; import type { Workspace as BlockSuiteWorkspace } from '@blocksuite/store'; import type { createStore } from 'jotai'; import type { FC, PropsWithChildren } from 'react'; @@ -183,6 +185,7 @@ type SettingProps = type PageDetailProps = UIBaseProps & { currentPageId: string; + onLoadEditor: (page: Page, editor: EditorContainer) => () => void; }; type PageListProps<_Flavour extends keyof WorkspaceRegistry> = { diff --git a/tests/libs/load-page.ts b/tests/libs/load-page.ts index 1a6d06a79b..87e8c7730c 100644 --- a/tests/libs/load-page.ts +++ b/tests/libs/load-page.ts @@ -1,15 +1,7 @@ import type { Page } from '@playwright/test'; -import { getMetas } from './utils'; - export const webUrl = 'http://localhost:8080'; export async function openHomePage(page: Page) { await page.goto(webUrl); } - -export async function initHomePageWithPinboard(page: Page) { - await openHomePage(page); - await page.waitForSelector('[data-testid="sidebar-pinboard-container"]'); - return (await getMetas(page)).find(m => m.isRootPinboard); -} diff --git a/tests/libs/page-logic.ts b/tests/libs/page-logic.ts index 96d59a6b80..a3021f9055 100644 --- a/tests/libs/page-logic.ts +++ b/tests/libs/page-logic.ts @@ -47,24 +47,3 @@ export async function clickPageMoreActions(page: Page) { .getByTestId('editor-option-menu') .click(); } - -/** - * @deprecated - */ -export async function createPinboardPage( - page: Page, - parentId: string, - title: string -) { - await newPage(page); - await page.focus('.affine-default-page-block-title'); - await page.type('.affine-default-page-block-title', title, { - delay: 100, - }); - await clickPageMoreActions(page); - await page.getByTestId('move-to-menu-item').click(); - await page - .getByTestId('pinboard-menu') - .getByTestId(`pinboard-${parentId}`) - .click(); -} diff --git a/tests/parallels/quick-search.spec.ts b/tests/parallels/quick-search.spec.ts index af6e17ba62..56b30481e2 100644 --- a/tests/parallels/quick-search.spec.ts +++ b/tests/parallels/quick-search.spec.ts @@ -2,12 +2,8 @@ import { test } from '@affine-test/kit/playwright'; import { expect, type Page } from '@playwright/test'; import { withCtrlOrMeta } from '../libs/keyboard'; -import { initHomePageWithPinboard, openHomePage } from '../libs/load-page'; -import { - createPinboardPage, - newPage, - waitMarkdownImported, -} from '../libs/page-logic'; +import { openHomePage } from '../libs/load-page'; +import { newPage, waitMarkdownImported } from '../libs/page-logic'; const openQuickSearchByShortcut = async (page: Page) => await withCtrlOrMeta(page, () => page.keyboard.press('k', { delay: 50 })); @@ -171,12 +167,6 @@ test('Focus title after creating a new page', async ({ page }) => { await titleIsFocused(page); }); -test.skip('Show navigation path if page is a subpage', async ({ page }) => { - const rootPinboardMeta = await initHomePageWithPinboard(page); - await createPinboardPage(page, rootPinboardMeta?.id ?? '', 'test1'); - await openQuickSearchByShortcut(page); - expect(await page.getByTestId('navigation-path').count()).toBe(1); -}); test('Not show navigation path if page is not a subpage or current page is not in editor', async ({ page, }) => { @@ -185,38 +175,3 @@ test('Not show navigation path if page is not a subpage or current page is not i await openQuickSearchByShortcut(page); expect(await page.getByTestId('navigation-path').count()).toBe(0); }); -test.skip('Navigation path item click will jump to page, but not current active item', async ({ - page, -}) => { - const rootPinboardMeta = await initHomePageWithPinboard(page); - await createPinboardPage(page, rootPinboardMeta?.id ?? '', 'test1'); - await openQuickSearchByShortcut(page); - const oldUrl = page.url(); - expect( - await page.locator('[data-testid="navigation-path-link"]').count() - ).toBe(2); - await page.locator('[data-testid="navigation-path-link"]').nth(1).click(); - expect(page.url()).toBe(oldUrl); - await page.locator('[data-testid="navigation-path-link"]').nth(0).click(); - expect(page.url()).not.toBe(oldUrl); -}); -test.skip('Navigation path expand', async ({ page }) => { - // - const rootPinboardMeta = await initHomePageWithPinboard(page); - await createPinboardPage(page, rootPinboardMeta?.id ?? '', 'test1'); - await openQuickSearchByShortcut(page); - const top = await page - .getByTestId('navigation-path-expand-panel') - .evaluate(el => { - return window.getComputedStyle(el).getPropertyValue('top'); - }); - expect(parseInt(top)).toBeLessThan(0); - await page.getByTestId('navigation-path-expand-btn').click(); - await page.waitForTimeout(500); - const expandTop = await page - .getByTestId('navigation-path-expand-panel') - .evaluate(el => { - return window.getComputedStyle(el).getPropertyValue('top'); - }); - expect(expandTop).toBe('0px'); -});