Skip to content

Commit

Permalink
feat: allow collections to be added to favorites
Browse files Browse the repository at this point in the history
  • Loading branch information
pengx17 committed Mar 25, 2024
1 parent 4dc0cec commit bbd6660
Show file tree
Hide file tree
Showing 9 changed files with 110 additions and 70 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,12 @@ export const root = style({
paddingLeft: '4px',
paddingRight: '4px',
},
'&[data-type="collection-list-item"][data-collapsible="false"][data-active="true"],&[data-type="reference-page"][data-collapsible="false"][data-active="true"], &[data-type="reference-page"][data-collapsible="false"]:hover, &[data-type="collection-list-item"][data-collapsible="false"]:hover':
{
width: 'calc(100% + 8px)',
transform: 'translateX(-8px)',
paddingLeft: '20px',
paddingRight: '12px',
},
'&[data-collapsible="false"]:is([data-active="true"], :hover)': {
width: 'calc(100% + 8px)',
transform: 'translateX(-8px)',
paddingLeft: '20px',
paddingRight: '12px',
},
[`${linkItemRoot}:first-of-type &`]: {
marginTop: '0px',
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
import { Button, FlexWrapper, Menu } from '@affine/component';
import type {
Collection,
DeleteCollectionInfo,
Filter,
PropertiesMeta,
} from '@affine/env/filter';
import type { Collection, Filter, PropertiesMeta } from '@affine/env/filter';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { FilterIcon } from '@blocksuite/icons';

Expand All @@ -16,20 +11,14 @@ import type { AllPageListConfig } from './edit-collection/edit-collection';
export const CollectionPageListOperationsMenu = ({
collection,
allPageListConfig,
userInfo,
}: {
collection: Collection;
allPageListConfig: AllPageListConfig;
userInfo: DeleteCollectionInfo;
}) => {
const t = useAFFiNEI18N();
return (
<FlexWrapper alignItems="center">
<CollectionOperations
info={userInfo}
collection={collection}
config={allPageListConfig}
>
<CollectionOperations collection={collection} config={allPageListConfig}>
<Button
className={styles.filterMenuTrigger}
type="default"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
import type { MenuItemProps } from '@affine/component';
import { Menu, MenuIcon, MenuItem } from '@affine/component';
import { useAppSettingHelper } from '@affine/core/hooks/affine/use-app-setting-helper';
import { useDeleteCollectionInfo } from '@affine/core/hooks/affine/use-delete-collection-info';
import { Workbench } from '@affine/core/modules/workbench';
import type { Collection, DeleteCollectionInfo } from '@affine/env/filter';
import { FavoriteItemsAdapter } from '@affine/core/modules/workspace';
import type { Collection } from '@affine/env/filter';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import {
DeleteIcon,
EditIcon,
FavoritedIcon,
FavoriteIcon,
FilterIcon,
SplitViewIcon,
} from '@blocksuite/icons';
import { useService } from '@toeverything/infra';
import { useLiveData, useService } from '@toeverything/infra';
import type { PropsWithChildren, ReactElement } from 'react';
import { useCallback, useMemo } from 'react';

Expand All @@ -25,15 +29,14 @@ import {
export const CollectionOperations = ({
collection,
config,
info,
openRenameModal,
children,
}: PropsWithChildren<{
info: DeleteCollectionInfo;
collection: Collection;
config: AllPageListConfig;
openRenameModal?: () => void;
}>) => {
const deleteInfo = useDeleteCollectionInfo();
const { appSettings } = useAppSettingHelper();
const service = useService(CollectionService);
const workbench = useService(Workbench);
Expand Down Expand Up @@ -76,6 +79,19 @@ export const CollectionOperations = ({
workbench.openCollection(collection.id, { at: 'tail' });
}, [collection.id, workbench]);

const favAdapter = useService(FavoriteItemsAdapter);

const onToggleFavoritePage = useCallback(() => {
favAdapter.toggle(collection.id, 'collection');
}, [favAdapter, collection.id]);

const favorite = useLiveData(
useMemo(
() => favAdapter.isFavorite$(collection.id, 'collection'),
[collection.id, favAdapter]
)
);

const actions = useMemo<
Array<
| {
Expand Down Expand Up @@ -109,6 +125,21 @@ export const CollectionOperations = ({
name: t['com.affine.collection.menu.edit'](),
click: showEdit,
},
{
icon: (
<MenuIcon>
{favorite ? (
<FavoritedIcon style={{ color: 'var(--affine-primary-color)' }} />
) : (
<FavoriteIcon />
)}
</MenuIcon>
),
name: favorite
? t['com.affine.favoritePageOperation.remove']()
: t['com.affine.favoritePageOperation.add'](),
click: onToggleFavoritePage,
},
...(appSettings.enableMultiView
? [
{
Expand All @@ -133,7 +164,7 @@ export const CollectionOperations = ({
),
name: t['Delete'](),
click: () => {
service.deleteCollection(info, collection.id);
service.deleteCollection(deleteInfo, collection.id);
},
type: 'danger',
},
Expand All @@ -142,10 +173,12 @@ export const CollectionOperations = ({
t,
showEditName,
showEdit,
favorite,
onToggleFavoritePage,
appSettings.enableMultiView,
openCollectionSplitView,
service,
info,
deleteInfo,
collection.id,
]
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ import {
} from '@affine/core/components/page-list';
import { CollectionService } from '@affine/core/modules/collection';
import { FavoriteItemsAdapter } from '@affine/core/modules/workspace';
import type { Collection, DeleteCollectionInfo } from '@affine/env/filter';
import type { Collection } from '@affine/env/filter';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { MoreHorizontalIcon, ViewLayersIcon } from '@blocksuite/icons';
import type { DocCollection, DocMeta } from '@blocksuite/store';
import type { DocCollection } from '@blocksuite/store';
import { useDroppable } from '@dnd-kit/core';
import * as Collapsible from '@radix-ui/react-collapsible';
import { useLiveData, useService } from '@toeverything/infra';
Expand All @@ -27,17 +27,16 @@ import type { CollectionsListProps } from '../index';
import { Page } from './page';
import * as styles from './styles.css';

const CollectionRenderer = ({
export const CollectionSidebarNavItem = ({
collection,
pages,
docCollection,
info,
className,
}: {
collection: Collection;
pages: DocMeta[];
docCollection: DocCollection;
info: DeleteCollectionInfo;
className?: string;
}) => {
const pages = useBlockSuiteDocMeta(docCollection);
const [collapsed, setCollapsed] = useState(true);
const [open, setOpen] = useState(false);
const collectionService = useService(CollectionService);
Expand Down Expand Up @@ -112,7 +111,12 @@ const CollectionRenderer = ({
}, []);

return (
<Collapsible.Root open={!collapsed} ref={setNodeRef}>
<Collapsible.Root
open={!collapsed}
ref={setNodeRef}
data-testid="collection-"
className={className}
>
<SidebarMenuLinkItem
data-testid="collection-item"
data-type="collection-list-item"
Expand All @@ -127,7 +131,6 @@ const CollectionRenderer = ({
style={{ display: 'flex', alignItems: 'center' }}
>
<CollectionOperations
info={info}
collection={collection}
config={config}
openRenameModal={handleOpen}
Expand Down Expand Up @@ -174,12 +177,11 @@ const CollectionRenderer = ({
};
export const CollectionsList = ({
docCollection: workspace,
info,
onCreate,
}: CollectionsListProps) => {
const metas = useBlockSuiteDocMeta(workspace);
const collections = useLiveData(useService(CollectionService).collections$);
const t = useAFFiNEI18N();

if (collections.length === 0) {
return (
<div className={styles.emptyCollectionWrapper}>
Expand All @@ -204,11 +206,9 @@ export const CollectionsList = ({
<div data-testid="collections" className={styles.wrapper}>
{collections.map(view => {
return (
<CollectionRenderer
info={info}
<CollectionSidebarNavItem
key={view.id}
collection={view}
pages={metas}
docCollection={workspace}
/>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { useBlockSuiteDocMeta } from '@affine/core/hooks/use-block-suite-page-meta';
import { CollectionService } from '@affine/core/modules/collection';
import { FavoriteItemsAdapter } from '@affine/core/modules/workspace';
import type { DocMeta } from '@blocksuite/store';
import { useDroppable } from '@dnd-kit/core';
import { useLiveData, useService } from '@toeverything/infra';
import { useMemo } from 'react';

import { getDropItemId } from '../../../../hooks/affine/use-sidebar-drag';
import { CollectionSidebarNavItem } from '../collections';
import type { FavoriteListProps } from '../index';
import EmptyItem from './empty-item';
import { FavouritePage } from './favourite-page';
Expand All @@ -18,20 +20,12 @@ export const FavoriteList = ({
}: FavoriteListProps) => {
const metas = useBlockSuiteDocMeta(workspace);
const favAdapter = useService(FavoriteItemsAdapter);
const collections = useLiveData(useService(CollectionService).collections$);
const dropItemId = getDropItemId('favorites');

const favourites = useLiveData(favAdapter.favorites$);
const favourites = useLiveData(favAdapter.orderedFavorites$);

const favoriteList = useMemo(
() =>
favourites.filter(fav => {
const meta = metas.find(m => m.id === fav.id);
return meta && !meta.trash;
}),
[favourites, metas]
);

const metaMapping = useMemo(
const docMetaMapping = useMemo(
() =>
metas.reduce(
(acc, meta) => {
Expand All @@ -54,19 +48,34 @@ export const FavoriteList = ({
ref={setNodeRef}
data-over={isOver}
>
{favoriteList.map((pageMeta, index) => {
return (
<FavouritePage
key={`${pageMeta}-${index}`}
metaMapping={metaMapping}
pageId={pageMeta.id}
// memo?
parentIds={emptyPageIdSet}
docCollection={workspace}
/>
);
{favourites.map(item => {
if (item.type === 'collection') {
const collection = collections.find(c => c.id === item.id);
if (collection) {
return (
<CollectionSidebarNavItem
key={item.id}
className={styles.favItemWrapper}
docCollection={workspace}
collection={collection}
/>
);
}
} else if (item.type === 'doc' && !docMetaMapping[item.id].trash) {
return (
<FavouritePage
key={item.id}
metaMapping={docMetaMapping}
pageId={item.id}
// memo?
parentIds={emptyPageIdSet}
docCollection={workspace}
/>
);
}
return null;
})}
{favoriteList.length === 0 && <EmptyItem />}
{favourites.length === 0 && <EmptyItem />}
</div>
);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import type { DeleteCollectionInfo } from '@affine/env/filter';
import type { DocCollection } from '@blocksuite/store';

export type FavoriteListProps = {
Expand All @@ -7,6 +6,5 @@ export type FavoriteListProps = {

export type CollectionsListProps = {
docCollection: DocCollection;
info: DeleteCollectionInfo;
onCreate?: () => void;
};
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import type { HTMLAttributes, ReactElement } from 'react';
import { forwardRef, useCallback, useEffect } from 'react';

import { useAppSettingHelper } from '../../hooks/affine/use-app-setting-helper';
import { useDeleteCollectionInfo } from '../../hooks/affine/use-delete-collection-info';
import { getDropItemId } from '../../hooks/affine/use-sidebar-drag';
import { useTrashModalHelper } from '../../hooks/affine/use-trash-modal-helper';
import { useNavigateHelper } from '../../hooks/use-navigate-helper';
Expand Down Expand Up @@ -161,7 +160,6 @@ export const RootAppSidebar = ({
console.error(err);
});
}, [docCollection.id, collection, navigateHelper, open]);
const userInfo = useDeleteCollectionInfo();

const allPageActive = currentPath === '/all';

Expand Down Expand Up @@ -224,7 +222,6 @@ export const RootAppSidebar = ({
</CategoryDivider>
<CollectionsList
docCollection={docCollection}
info={userInfo}
onCreate={handleCreateCollection}
/>
<CategoryDivider label={t['com.affine.rootAppSidebar.others']()} />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import type { DeleteCollectionInfo } from '@affine/env/filter';
import { useMemo } from 'react';

import { useSession } from './use-current-user';

export const useDeleteCollectionInfo = () => {
const { user } = useSession();

return useMemo(
return useMemo<DeleteCollectionInfo | null>(
() => (user ? { userName: user.name, userId: user.id } : null),
[user]
);
Expand Down
Loading

0 comments on commit bbd6660

Please sign in to comment.