diff --git a/packages/frontend/component/src/index.ts b/packages/frontend/component/src/index.ts index 2ad4ce1a4d..65fe616406 100644 --- a/packages/frontend/component/src/index.ts +++ b/packages/frontend/component/src/index.ts @@ -28,6 +28,7 @@ export * from './ui/slider'; export * from './ui/switch'; export * from './ui/table'; export * from './ui/tabs'; +export * from './ui/themed-img'; export * from './ui/toast'; export * from './ui/tooltip'; export * from './utils'; diff --git a/packages/frontend/component/src/ui/empty/empty.tsx b/packages/frontend/component/src/ui/empty/empty.tsx index 75ff8aceee..9b95fc51e9 100644 --- a/packages/frontend/component/src/ui/empty/empty.tsx +++ b/packages/frontend/component/src/ui/empty/empty.tsx @@ -16,6 +16,9 @@ export type EmptyContentProps = { descriptionStyle?: CSSProperties; }; +/** + * @deprecated use different empty components for different use cases, like `EmptyDocs` for documentation empty state + */ export const Empty = ({ containerStyle, title, diff --git a/packages/frontend/component/src/ui/themed-img/index.tsx b/packages/frontend/component/src/ui/themed-img/index.tsx new file mode 100644 index 0000000000..a27d016728 --- /dev/null +++ b/packages/frontend/component/src/ui/themed-img/index.tsx @@ -0,0 +1,17 @@ +import { useTheme } from 'next-themes'; +import { forwardRef, type HTMLAttributes } from 'react'; + +export interface ThemedImgProps + extends Omit, 'src'> { + lightSrc: string; + darkSrc?: string; +} + +export const ThemedImg = forwardRef( + function ThemedImg({ lightSrc, darkSrc, ...attrs }, ref) { + const { resolvedTheme } = useTheme(); + const src = resolvedTheme === 'dark' && darkSrc ? darkSrc : lightSrc; + + return ; + } +); diff --git a/packages/frontend/component/src/utils/index.ts b/packages/frontend/component/src/utils/index.ts index 5a46d59e6b..6029e65643 100644 --- a/packages/frontend/component/src/utils/index.ts +++ b/packages/frontend/component/src/utils/index.ts @@ -1,2 +1,3 @@ export * from './observe-resize'; export { startScopedViewTransition } from './view-transition'; +export * from './with-unit'; diff --git a/packages/frontend/core/src/components/affine/empty/action-button.tsx b/packages/frontend/core/src/components/affine/empty/action-button.tsx new file mode 100644 index 0000000000..bc28cd5bbd --- /dev/null +++ b/packages/frontend/core/src/components/affine/empty/action-button.tsx @@ -0,0 +1,30 @@ +import { Button, type ButtonProps } from '@affine/component'; +import clsx from 'clsx'; + +import { + actionButton, + actionContent, + mobileActionButton, + mobileActionContent, +} from './style.css'; + +export const ActionButton = ({ + className, + contentClassName, + ...props +}: ButtonProps) => { + return ( + +
+
+ {t['com.affine.collections.header']()}
- {node} - + +
); }; diff --git a/packages/frontend/core/src/components/page-list/collections/virtualized-collection-list.tsx b/packages/frontend/core/src/components/page-list/collections/virtualized-collection-list.tsx index d559199851..c77971e4bd 100644 --- a/packages/frontend/core/src/components/page-list/collections/virtualized-collection-list.tsx +++ b/packages/frontend/core/src/components/page-list/collections/virtualized-collection-list.tsx @@ -2,7 +2,6 @@ import { useDeleteCollectionInfo } from '@affine/core/hooks/affine/use-delete-co import type { Collection, DeleteCollectionInfo } from '@affine/env/filter'; import { Trans } from '@affine/i18n'; import { useService, WorkspaceService } from '@toeverything/infra'; -import type { ReactElement } from 'react'; import { useCallback, useMemo, useRef, useState } from 'react'; import { CollectionService } from '../../../modules/collection'; @@ -42,12 +41,10 @@ export const VirtualizedCollectionList = ({ collections, collectionMetas, setHideHeaderCreateNewCollection, - node, handleCreateCollection, }: { collections: Collection[]; collectionMetas: CollectionMeta[]; - node: ReactElement | null; handleCreateCollection: () => void; setHideHeaderCreateNewCollection: (hide: boolean) => void; }) => { @@ -107,9 +104,7 @@ export const VirtualizedCollectionList = ({ atTopThreshold={80} atTopStateChange={setHideHeaderCreateNewCollection} onSelectionActiveChange={setShowFloatingToolbar} - heading={ - - } + heading={} selectedIds={filteredSelectedCollectionIds} onSelectedIdsChange={setSelectedCollectionIds} items={collectionMetas} diff --git a/packages/frontend/core/src/components/page-list/docs/page-list-header.tsx b/packages/frontend/core/src/components/page-list/docs/page-list-header.tsx index 3223c8e7d5..baa63d11b2 100644 --- a/packages/frontend/core/src/components/page-list/docs/page-list-header.tsx +++ b/packages/frontend/core/src/components/page-list/docs/page-list-header.tsx @@ -110,7 +110,7 @@ export const CollectionPageListHeader = ({ jumpToCollections(workspaceId); }, [jumpToCollections, workspaceId]); - const { node, open } = useEditCollection(); + const { open } = useEditCollection(); const handleEdit = useAsyncCallback(async () => { const ret = await open({ ...collection }, 'page'); @@ -162,32 +162,29 @@ export const CollectionPageListHeader = ({ }, [createPage, onConfirmAddDocument]); return ( - <> - {node} -
-
-
- {t['com.affine.collections.header']()} / -
-
- -
-
{collection.name}
+
+
+
+ {t['com.affine.collections.header']()} /
-
- - -
{t['New Page']()}
-
+
+
+
{collection.name}
- +
+ + +
{t['New Page']()}
+
+
+
); }; @@ -205,7 +202,7 @@ export const TagPageListHeader = ({ const { jumpToTags, jumpToCollection } = useNavigateHelper(); const collectionService = useService(CollectionService); const [openMenu, setOpenMenu] = useState(false); - const { open, node } = useEditCollectionName({ + const { open } = useEditCollectionName({ title: t['com.affine.editCollection.saveCollection'](), showTips: true, }); @@ -235,47 +232,44 @@ export const TagPageListHeader = ({ }, [open, saveToCollection]); return ( - <> - {node} -
-
-
- {t['Tags']()} / -
- } - > -
-
-
{tagTitle}
- -
-
+
+
+
+ {t['Tags']()} /
- + } + > +
+
+
{tagTitle}
+ +
+
- + +
); }; diff --git a/packages/frontend/core/src/components/page-list/operation-cell.tsx b/packages/frontend/core/src/components/page-list/operation-cell.tsx index a2a170bc21..49687992ab 100644 --- a/packages/frontend/core/src/components/page-list/operation-cell.tsx +++ b/packages/frontend/core/src/components/page-list/operation-cell.tsx @@ -317,13 +317,11 @@ export const CollectionOperationCell = ({ favAdapter.isFavorite$(collection.id, 'collection') ); - const { open: openEditCollectionModal, node: editModal } = - useEditCollection(); + const { open: openEditCollectionModal } = useEditCollection(); - const { open: openEditCollectionNameModal, node: editNameModal } = - useEditCollectionName({ - title: t['com.affine.editCollection.renameCollection'](), - }); + const { open: openEditCollectionNameModal } = useEditCollectionName({ + title: t['com.affine.editCollection.renameCollection'](), + }); const handlePropagation = useCallback((event: MouseEvent) => { event.preventDefault(); @@ -402,8 +400,6 @@ export const CollectionOperationCell = ({ return ( <> - {editModal} - {editNameModal} - {editModal} - {editNameModal} - - {actions.map(action => { - if (action.element) { - return action.element; - } - return ( - - {action.name} - - ); - })} -
- } - > - {children} - - + + {actions.map(action => { + if (action.element) { + return action.element; + } + return ( + + {action.name} + + ); + })} +
+ } + > + {children} + ); }; diff --git a/packages/frontend/core/src/components/page-list/view/save-as-collection-button.tsx b/packages/frontend/core/src/components/page-list/view/save-as-collection-button.tsx index 1c5fb163e9..c1ef31d5f1 100644 --- a/packages/frontend/core/src/components/page-list/view/save-as-collection-button.tsx +++ b/packages/frontend/core/src/components/page-list/view/save-as-collection-button.tsx @@ -17,7 +17,7 @@ export const SaveAsCollectionButton = ({ onConfirm, }: SaveAsCollectionButtonProps) => { const t = useI18n(); - const { open, node } = useEditCollectionName({ + const { open } = useEditCollectionName({ title: t['com.affine.editCollection.saveCollection'](), showTips: true, }); @@ -31,16 +31,13 @@ export const SaveAsCollectionButton = ({ }); }, [open, onConfirm]); return ( - <> - - {node} - + ); }; diff --git a/packages/frontend/core/src/components/page-list/view/use-edit-collection.tsx b/packages/frontend/core/src/components/page-list/view/use-edit-collection.tsx index 5afb09d16c..8288ba63e2 100644 --- a/packages/frontend/core/src/components/page-list/view/use-edit-collection.tsx +++ b/packages/frontend/core/src/components/page-list/view/use-edit-collection.tsx @@ -1,5 +1,6 @@ import type { Collection } from '@affine/env/filter'; -import { useCallback, useState } from 'react'; +import { useMount } from '@toeverything/infra'; +import { useCallback, useEffect, useState } from 'react'; import { CreateCollectionModal } from './create-collection'; import type { EditCollectionMode } from './edit-collection/edit-collection'; @@ -16,9 +17,11 @@ export const useEditCollection = () => { setData(undefined); } }, []); + const { mount } = useMount('useEditCollection'); - return { - node: ( + useEffect(() => { + if (!data) return; + return mount( { onOpenChange={close} onConfirm={data?.onConfirm ?? (() => {})} /> - ), + ); + }, [close, data, mount]); + + return { open: ( collection: Collection, mode?: EditCollectionMode @@ -59,9 +65,11 @@ export const useEditCollectionName = ({ setData(undefined); } }, []); + const { mount } = useMount('useEditCollectionName'); - return { - node: ( + useEffect(() => { + if (!data) return; + return mount( {})} /> - ), + ); + }, [close, data, mount, showTips, title]); + + return { open: (name: string): Promise => new Promise(res => { setData({ diff --git a/packages/frontend/core/src/modules/explorer/views/nodes/collection/index.tsx b/packages/frontend/core/src/modules/explorer/views/nodes/collection/index.tsx index 7ee474cf94..f6ea3d5365 100644 --- a/packages/frontend/core/src/modules/explorer/views/nodes/collection/index.tsx +++ b/packages/frontend/core/src/modules/explorer/views/nodes/collection/index.tsx @@ -62,8 +62,7 @@ export const ExplorerCollectionNode = ({ const { globalContextService } = useServices({ GlobalContextService, }); - const { open: openEditCollectionModal, node: editModal } = - useEditCollection(); + const { open: openEditCollectionModal } = useEditCollection(); const active = useLiveData(globalContextService.globalContext.collectionId.$) === collectionId; @@ -211,29 +210,26 @@ export const ExplorerCollectionNode = ({ } return ( - <> - } - operations={finalOperations} - dropEffect={handleDropEffectOnCollection} - data-testid={`explorer-collection-${collectionId}`} - > - - - {editModal} - + } + operations={finalOperations} + dropEffect={handleDropEffectOnCollection} + data-testid={`explorer-collection-${collectionId}`} + > + + ); }; diff --git a/packages/frontend/core/src/modules/explorer/views/sections/collections/index.tsx b/packages/frontend/core/src/modules/explorer/views/sections/collections/index.tsx index 290486d7d4..5594c3de6c 100644 --- a/packages/frontend/core/src/modules/explorer/views/sections/collections/index.tsx +++ b/packages/frontend/core/src/modules/explorer/views/sections/collections/index.tsx @@ -25,7 +25,7 @@ export const ExplorerCollections = () => { }); const explorerSection = explorerService.sections.collections; const collections = useLiveData(collectionService.collections$); - const { node, open: openCreateCollectionModel } = useEditCollectionName({ + const { open: openCreateCollectionModel } = useEditCollectionName({ title: t['com.affine.editCollection.createCollection'](), showTips: true, }); @@ -52,40 +52,37 @@ export const ExplorerCollections = () => { ]); return ( - <> - - - - } - > - } + - {collections.map(collection => ( - - ))} - - - {node} - + + + } + > + } + > + {collections.map(collection => ( + + ))} + + ); }; diff --git a/packages/frontend/core/src/pages/workspace/all-collection/index.tsx b/packages/frontend/core/src/pages/workspace/all-collection/index.tsx index 0d55a794c1..726a8143cd 100644 --- a/packages/frontend/core/src/pages/workspace/all-collection/index.tsx +++ b/packages/frontend/core/src/pages/workspace/all-collection/index.tsx @@ -40,7 +40,7 @@ export const AllCollection = () => { }, [collections]); const navigateHelper = useNavigateHelper(); - const { open, node } = useEditCollectionName({ + const { open } = useEditCollectionName({ title: t['com.affine.editCollection.createCollection'](), showTips: true, }); @@ -74,16 +74,12 @@ export const AllCollection = () => { collections={collections} collectionMetas={collectionMetas} setHideHeaderCreateNewCollection={setHideHeaderCreateNew} - node={node} handleCreateCollection={handleCreateCollection} /> ) : ( + } /> )} diff --git a/packages/frontend/core/src/pages/workspace/all-page/all-page.tsx b/packages/frontend/core/src/pages/workspace/all-page/all-page.tsx index 1706b14fcc..ec928e3949 100644 --- a/packages/frontend/core/src/pages/workspace/all-page/all-page.tsx +++ b/packages/frontend/core/src/pages/workspace/all-page/all-page.tsx @@ -72,11 +72,7 @@ export const AllPage = () => { filters={filters} /> ) : ( - } - docCollection={currentWorkspace.docCollection} - /> + } /> )}
diff --git a/packages/frontend/core/src/pages/workspace/collection/index.tsx b/packages/frontend/core/src/pages/workspace/collection/index.tsx index 7f5c73dd0e..fa1f5e7454 100644 --- a/packages/frontend/core/src/pages/workspace/collection/index.tsx +++ b/packages/frontend/core/src/pages/workspace/collection/index.tsx @@ -1,19 +1,14 @@ import { notify } from '@affine/component'; +import { EmptyCollectionDetail } from '@affine/core/components/affine/empty/collection-detail'; import { - AffineShapeIcon, useEditCollection, VirtualizedPageList, } from '@affine/core/components/page-list'; import { useAsyncCallback } from '@affine/core/hooks/affine-async-hooks'; import { CollectionService } from '@affine/core/modules/collection'; import type { Collection } from '@affine/env/filter'; -import { Trans, useI18n } from '@affine/i18n'; -import { - CloseIcon, - FilterIcon, - PageIcon, - ViewLayersIcon, -} from '@blocksuite/icons/rc'; +import { useI18n } from '@affine/i18n'; +import { ViewLayersIcon } from '@blocksuite/icons/rc'; import { GlobalContextService, useLiveData, @@ -33,7 +28,6 @@ import { ViewTitle, } from '../../../modules/workbench'; import { WorkspaceSubPath } from '../../../shared'; -import * as styles from './collection.css'; import { CollectionDetailHeader } from './header'; export const CollectionDetail = ({ @@ -41,7 +35,7 @@ export const CollectionDetail = ({ }: { collection: Collection; }) => { - const { node, open } = useEditCollection(); + const { open } = useEditCollection(); const collectionService = useService(CollectionService); const [hideHeaderCreateNew, setHideHeaderCreateNew] = useState(true); @@ -64,7 +58,6 @@ export const CollectionDetail = ({ setHideHeaderCreateNewPage={setHideHeaderCreateNew} /> - {node} ); }; @@ -138,25 +131,7 @@ export const Component = function CollectionPage() { const Placeholder = ({ collection }: { collection: Collection }) => { const workspace = useService(WorkspaceService).workspace; - const collectionService = useService(CollectionService); - const { node, open } = useEditCollection(); const { jumpToCollections } = useNavigateHelper(); - const openPageEdit = useAsyncCallback(async () => { - const ret = await open({ ...collection }, 'page'); - collectionService.updateCollection(ret.id, () => ret); - }, [open, collection, collectionService]); - const openRuleEdit = useAsyncCallback(async () => { - const ret = await open({ ...collection }, 'rule'); - collectionService.updateCollection(ret.id, () => ret); - }, [collection, open, collectionService]); - const [showTips, setShowTips] = useState(false); - useEffect(() => { - setShowTips(!localStorage.getItem('hide-empty-collection-help-info')); - }, []); - const hideTips = useCallback(() => { - setShowTips(false); - localStorage.setItem('hide-empty-collection-help-info', 'true'); - }, []); const t = useI18n(); const handleJumpToCollections = useCallback(() => { @@ -206,142 +181,11 @@ const Placeholder = ({ collection }: { collection: Collection }) => {
-
-
- -
- {t['com.affine.collection.emptyCollection']()} -
-
- {t['com.affine.collection.emptyCollectionDescription']()} -
-
-
- - - {t['com.affine.collection.addPages']()} - -
-
- - - {t['com.affine.collection.addRules']()} - -
-
-
- {showTips ? ( -
-
-
{t['com.affine.collection.helpInfo']()}
- -
-
-
- - Add pages: You can - freely select pages and add them to the collection. - -
-
- - Add rules: Rules - are based on filtering. After adding rules, pages that meet - the requirements will be automatically added to the current - collection. - -
-
-
- ) : null} -
+
- {node} ); }; diff --git a/packages/frontend/core/src/pages/workspace/page-list-empty.css.ts b/packages/frontend/core/src/pages/workspace/page-list-empty.css.ts index 7c1a9119ef..9cde50a236 100644 --- a/packages/frontend/core/src/pages/workspace/page-list-empty.css.ts +++ b/packages/frontend/core/src/pages/workspace/page-list-empty.css.ts @@ -2,7 +2,13 @@ import { cssVar } from '@toeverything/theme'; import { cssVarV2 } from '@toeverything/theme/v2'; import { style } from '@vanilla-extract/css'; export const pageListEmptyStyle = style({ - height: 'calc(100% - 52px)', + height: '100%', + display: 'flex', + flexDirection: 'column', +}); +export const pageListEmptyBody = style({ + height: 0, + flex: 1, }); export const emptyDescButton = style({ cursor: 'pointer', diff --git a/packages/frontend/core/src/pages/workspace/page-list-empty.tsx b/packages/frontend/core/src/pages/workspace/page-list-empty.tsx index 73d0bb1d00..6eb5e800eb 100644 --- a/packages/frontend/core/src/pages/workspace/page-list-empty.tsx +++ b/packages/frontend/core/src/pages/workspace/page-list-empty.tsx @@ -1,7 +1,5 @@ -import { Empty, IconButton } from '@affine/component'; -import { Trans, useI18n } from '@affine/i18n'; -import { PlusIcon } from '@blocksuite/icons/rc'; -import type { DocCollection } from '@blocksuite/store'; +import { EmptyDocs, EmptyTags } from '@affine/core/components/affine/empty'; +import { EmptyCollections } from '@affine/core/components/affine/empty/collections'; import type { ReactNode } from 'react'; import * as styles from './page-list-empty.css'; @@ -9,79 +7,38 @@ import * as styles from './page-list-empty.css'; export const EmptyPageList = ({ type, heading, + tagId, }: { - type: 'all' | 'trash' | 'shared' | 'public'; - docCollection: DocCollection; + type: 'all' | 'trash'; heading?: ReactNode; + tagId?: string; }) => { - const t = useI18n(); - - const getEmptyDescription = () => { - if (type === 'all') { - const createNewPageButton = ( - } - /> - ); - if (environment.isElectron) { - const shortcut = environment.isMacOs ? '⌘ + N' : 'Ctrl + N'; - return ( - - Click on the {createNewPageButton} button Or press - {{ shortcut } as any} to - create your first page. - - ); - } - return ( - - Click on the - {createNewPageButton} - button to create your first page. - - ); - } - if (type === 'trash') { - return t['com.affine.workspaceSubPath.trash.empty-description'](); - } - if (type === 'shared') { - return t['emptySharedPages'](); - } - return; - }; - return (
{heading &&
{heading}
} - {getEmptyDescription()} - } +
); }; export const EmptyCollectionList = ({ heading }: { heading: ReactNode }) => { - const t = useI18n(); return (
{heading &&
{heading}
} - +
); }; export const EmptyTagList = ({ heading }: { heading: ReactNode }) => { - const t = useI18n(); return (
{heading &&
{heading}
} - +
); }; diff --git a/packages/frontend/core/src/pages/workspace/tag/index.tsx b/packages/frontend/core/src/pages/workspace/tag/index.tsx index 5aa89b27b6..6f1efda891 100644 --- a/packages/frontend/core/src/pages/workspace/tag/index.tsx +++ b/packages/frontend/core/src/pages/workspace/tag/index.tsx @@ -79,13 +79,13 @@ export const TagDetail = ({ tagId }: { tagId?: string }) => { ) : ( } - docCollection={currentWorkspace.docCollection} /> )}
diff --git a/packages/frontend/core/src/pages/workspace/trash-page.tsx b/packages/frontend/core/src/pages/workspace/trash-page.tsx index 4bb123b43a..6de6f28715 100644 --- a/packages/frontend/core/src/pages/workspace/trash-page.tsx +++ b/packages/frontend/core/src/pages/workspace/trash-page.tsx @@ -75,10 +75,7 @@ export const TrashPage = () => { {filteredPageMetas.length > 0 ? ( ) : ( - + )} diff --git a/packages/frontend/i18n/src/resources/en.json b/packages/frontend/i18n/src/resources/en.json index 47971b83fc..c4d77a05db 100644 --- a/packages/frontend/i18n/src/resources/en.json +++ b/packages/frontend/i18n/src/resources/en.json @@ -686,6 +686,19 @@ "com.affine.emptyDesc": "There's no doc here yet", "com.affine.emptyDesc.collection": "There's no collection here yet", "com.affine.emptyDesc.tag": "There's no tag here yet", + "com.affine.empty.docs.title": "Docs management", + "com.affine.empty.docs.all-description": "Create your first doc here.", + "com.affine.empty.docs.trash-description": "Deleted docs will appear here.", + "com.affine.empty.docs.action.new-doc": "New doc", + "com.affine.empty.collections.title": "Collection management", + "com.affine.empty.collections.description": "Create your first collection here.", + "com.affine.empty.collections.action.new-collection": "Add collection", + "com.affine.empty.tags.title": "Tag management", + "com.affine.empty.tags.description": "Create a new tag for your documents.", + "com.affine.empty.collection-detail.title": "Empty collection", + "com.affine.empty.collection-detail.description": "Collection is a smart folder where you can manually add docs or automatically add docs through rules.", + "com.affine.empty.collection-detail.action.add-doc": "Add docs", + "com.affine.empty.collection-detail.action.add-rule": "Add rules", "com.affine.enableAffineCloudModal.button.cancel": "Cancel", "com.affine.error.contact.description": "If you are still experiencing this issue, please <1>contact us through the community.", "com.affine.error.no-page-root.title": "Doc content is missing", diff --git a/packages/frontend/mobile/src/pages/workspace/collection/detail.tsx b/packages/frontend/mobile/src/pages/workspace/collection/detail.tsx index 34eccd2ecd..896aa5b21d 100644 --- a/packages/frontend/mobile/src/pages/workspace/collection/detail.tsx +++ b/packages/frontend/mobile/src/pages/workspace/collection/detail.tsx @@ -1,7 +1,6 @@ import { notify, useThemeColorV2 } from '@affine/component'; import { useNavigateHelper } from '@affine/core/hooks/use-navigate-helper'; import { CollectionService } from '@affine/core/modules/collection'; -import { isEmptyCollection } from '@affine/core/pages/workspace/collection'; import { WorkspaceSubPath } from '@affine/core/shared'; import { GlobalContextService, @@ -13,7 +12,7 @@ import { useCallback, useEffect } from 'react'; import { useParams } from 'react-router-dom'; import { AppTabs } from '../../../components'; -import { CollectionDetail, EmptyCollection } from '../../../views'; +import { CollectionDetail } from '../../../views'; export const Component = () => { useThemeColorV2('layer/background/secondary'); @@ -70,10 +69,6 @@ export const Component = () => { return null; } - if (isEmptyCollection(collection)) { - return ; - } - return ( <> diff --git a/packages/frontend/mobile/src/views/all-docs/collection/detail.tsx b/packages/frontend/mobile/src/views/all-docs/collection/detail.tsx index 0466a58a61..f8498d39fe 100644 --- a/packages/frontend/mobile/src/views/all-docs/collection/detail.tsx +++ b/packages/frontend/mobile/src/views/all-docs/collection/detail.tsx @@ -1,4 +1,6 @@ import { IconButton, MobileMenu } from '@affine/component'; +import { EmptyCollectionDetail } from '@affine/core/components/affine/empty'; +import { isEmptyCollection } from '@affine/core/pages/workspace/collection'; import type { Collection } from '@affine/env/filter'; import { MoreHorizontalIcon, ViewLayersIcon } from '@blocksuite/icons/rc'; @@ -34,6 +36,15 @@ export const CollectionDetail = ({ }: { collection: Collection; }) => { + if (isEmptyCollection(collection)) { + return ( + <> + + + + ); + } + return ( <> diff --git a/packages/frontend/mobile/src/views/all-docs/collection/list.tsx b/packages/frontend/mobile/src/views/all-docs/collection/list.tsx index 60aa8851e9..49ccd03b93 100644 --- a/packages/frontend/mobile/src/views/all-docs/collection/list.tsx +++ b/packages/frontend/mobile/src/views/all-docs/collection/list.tsx @@ -1,3 +1,4 @@ +import { EmptyCollections } from '@affine/core/components/affine/empty'; import type { CollectionMeta } from '@affine/core/components/page-list'; import { CollectionService } from '@affine/core/modules/collection'; import { useLiveData, useService } from '@toeverything/infra'; @@ -19,6 +20,10 @@ export const CollectionList = () => { [collections] ); + if (!collectionMetas.length) { + return ; + } + return (
    {collectionMetas.map(meta => ( diff --git a/packages/frontend/mobile/src/views/all-docs/doc/list.tsx b/packages/frontend/mobile/src/views/all-docs/doc/list.tsx index 7e9aa63b7b..422ef4bd01 100644 --- a/packages/frontend/mobile/src/views/all-docs/doc/list.tsx +++ b/packages/frontend/mobile/src/views/all-docs/doc/list.tsx @@ -1,3 +1,4 @@ +import { EmptyDocs } from '@affine/core/components/affine/empty'; import { type ItemGroupDefinition, type ItemGroupProps, @@ -78,6 +79,10 @@ export const AllDocList = ({ return itemsToItemGroups(finalPageMetas ?? [], groupDefs); }, [finalPageMetas, groupDefs]); + if (!groups.length) { + return ; + } + return (
    {groups.map(group => ( diff --git a/packages/frontend/mobile/src/views/all-docs/tag/detail.tsx b/packages/frontend/mobile/src/views/all-docs/tag/detail.tsx index b6f0f6d1b3..1e040a536f 100644 --- a/packages/frontend/mobile/src/views/all-docs/tag/detail.tsx +++ b/packages/frontend/mobile/src/views/all-docs/tag/detail.tsx @@ -1,17 +1,10 @@ import type { Tag } from '@affine/core/modules/tag'; -import { useLiveData } from '@toeverything/infra'; import { AppTabs } from '../../../components'; import { AllDocList } from '../doc'; import { TagDetailHeader } from './detail-header'; -import { TagEmpty } from './empty'; export const TagDetail = ({ tag }: { tag: Tag }) => { - const pageIds = useLiveData(tag?.pageIds$); - - if (!pageIds.length) { - return ; - } return ( <> diff --git a/packages/frontend/mobile/src/views/all-docs/tag/list.tsx b/packages/frontend/mobile/src/views/all-docs/tag/list.tsx index a0761ad17d..48a2592608 100644 --- a/packages/frontend/mobile/src/views/all-docs/tag/list.tsx +++ b/packages/frontend/mobile/src/views/all-docs/tag/list.tsx @@ -1,3 +1,4 @@ +import { EmptyTags } from '@affine/core/components/affine/empty'; import { TagService } from '@affine/core/modules/tag'; import { useLiveData, useService } from '@toeverything/infra'; @@ -8,6 +9,10 @@ export const TagList = () => { const tagList = useService(TagService).tagList; const tags = useLiveData(tagList.tags$); + if (!tags.length) { + return ; + } + return (
      {tags.map(tag => ( diff --git a/packages/frontend/mobile/src/views/recent-docs/index.tsx b/packages/frontend/mobile/src/views/recent-docs/index.tsx index bf2eb4359f..7e6dab7e4d 100644 --- a/packages/frontend/mobile/src/views/recent-docs/index.tsx +++ b/packages/frontend/mobile/src/views/recent-docs/index.tsx @@ -12,10 +12,15 @@ export const RecentDocs = ({ max = 5 }: { max?: number }) => { const cardMetas = useMemo(() => { return [...allPageMetas] + .filter(meta => !meta.trash) .sort((a, b) => (b.updatedDate ?? 0) - (a.updatedDate ?? 0)) .slice(0, max); }, [allPageMetas, max]); + if (!cardMetas.length) { + return null; + } + return (