feat(core): new favorite (#7590)

This commit is contained in:
EYHN
2024-07-26 08:15:32 +00:00
parent 5207e7abfc
commit 3eb09cde5e
47 changed files with 1248 additions and 167 deletions
@@ -1,5 +1,6 @@
import { cssVar } from '@toeverything/theme';
import { style } from '@vanilla-extract/css';
export const root = style({
fontSize: cssVar('fontXs'),
minHeight: '16px',
@@ -10,6 +11,7 @@ export const root = style({
justifyContent: 'space-between',
marginBottom: '4px',
padding: '0 8px',
gap: '8px',
selectors: {
'&:not(:first-of-type)': {
marginTop: '16px',
@@ -18,4 +20,5 @@ export const root = style({
});
export const label = style({
color: cssVar('black30'),
flex: '1',
});
@@ -1,5 +1,5 @@
import { FavoriteTag } from '@affine/core/components/page-list';
import { FavoriteItemsAdapter } from '@affine/core/modules/properties';
import { CompatibleFavoriteItemsAdapter } from '@affine/core/modules/properties';
import { toast } from '@affine/core/utils';
import { useI18n } from '@affine/i18n';
import { useLiveData, useService } from '@toeverything/infra';
@@ -11,7 +11,7 @@ export interface FavoriteButtonProps {
export const useFavorite = (pageId: string) => {
const t = useI18n();
const favAdapter = useService(FavoriteItemsAdapter);
const favAdapter = useService(CompatibleFavoriteItemsAdapter);
const favorite = useLiveData(favAdapter.isFavorite$(pageId, 'doc'));
@@ -1,4 +1,4 @@
import { FavoriteItemsAdapter } from '@affine/core/modules/properties';
import { CompatibleFavoriteItemsAdapter } from '@affine/core/modules/properties';
import type { Tag } from '@affine/core/modules/tag';
import { TagService } from '@affine/core/modules/tag';
import { useI18n } from '@affine/i18n';
@@ -131,9 +131,9 @@ export const useTagGroupDefinitions = (): ItemGroupDefinition<ListItem>[] => {
const sortedTagsLiveData$ = useMemo(
() =>
LiveData.computed(get =>
get(tagList.tags$).sort((a, b) =>
get(a.value$).localeCompare(get(b.value$))
)
get(tagList.tags$)
.slice()
.sort((a, b) => get(a.value$).localeCompare(get(b.value$)))
),
[tagList.tags$]
);
@@ -174,7 +174,7 @@ export const useFavoriteGroupDefinitions = <
T extends ListItem,
>(): ItemGroupDefinition<T>[] => {
const t = useI18n();
const favAdapter = useService(FavoriteItemsAdapter);
const favAdapter = useService(CompatibleFavoriteItemsAdapter);
const favourites = useLiveData(favAdapter.favorites$);
return useMemo(
() => [
@@ -3,6 +3,7 @@ import { createContainer, style } from '@vanilla-extract/css';
import { root as collectionItemRoot } from './collections/collection-list-item.css';
import { root as pageItemRoot } from './docs/page-list-item.css';
import { root as tagItemRoot } from './tags/tag-list-item.css';
export const listRootContainer = createContainer('list-root-container');
export const pageListScrollContainer = style({
width: '100%',
@@ -49,7 +50,7 @@ export const favoriteCell = style({
flexShrink: 0,
opacity: 0,
selectors: {
[`&[data-favorite], ${pageItemRoot}:hover &, ${collectionItemRoot}:hover &`]:
[`&[data-favorite], ${pageItemRoot}:hover &, ${collectionItemRoot}:hover &, ${tagItemRoot}:hover &`]:
{
opacity: 1,
},
@@ -10,7 +10,8 @@ import {
import { useAppSettingHelper } from '@affine/core/hooks/affine/use-app-setting-helper';
import { useBlockSuiteMetaHelper } from '@affine/core/hooks/affine/use-block-suite-meta-helper';
import { useTrashModalHelper } from '@affine/core/hooks/affine/use-trash-modal-helper';
import { FavoriteItemsAdapter } from '@affine/core/modules/properties';
import { FavoriteService } from '@affine/core/modules/favorite';
import { CompatibleFavoriteItemsAdapter } from '@affine/core/modules/properties';
import { WorkbenchService } from '@affine/core/modules/workbench';
import { mixpanel } from '@affine/core/utils';
import type { Collection, DeleteCollectionInfo } from '@affine/env/filter';
@@ -32,7 +33,12 @@ import {
SplitViewIcon,
} from '@blocksuite/icons/rc';
import type { DocMeta } from '@blocksuite/store';
import { useLiveData, useService, WorkspaceService } from '@toeverything/infra';
import {
useLiveData,
useService,
useServices,
WorkspaceService,
} from '@toeverything/infra';
import { useCallback, useState } from 'react';
import { Link } from 'react-router-dom';
@@ -63,7 +69,7 @@ export const PageOperationCell = ({
const { appSettings } = useAppSettingHelper();
const { setTrashModal } = useTrashModalHelper(currentWorkspace.docCollection);
const [openDisableShared, setOpenDisableShared] = useState(false);
const favAdapter = useService(FavoriteItemsAdapter);
const favAdapter = useService(CompatibleFavoriteItemsAdapter);
const favourite = useLiveData(favAdapter.isFavorite$(page.id, 'doc'));
const workbench = useService(WorkbenchService).workbench;
const { duplicate } = useBlockSuiteMetaHelper(currentWorkspace.docCollection);
@@ -215,14 +221,16 @@ export const PageOperationCell = ({
);
return (
<>
<ColWrapper
hideInSmallContainer
data-testid="page-list-item-favorite"
data-favorite={favourite ? true : undefined}
className={styles.favoriteCell}
>
<FavoriteTag onClick={onToggleFavoritePage} active={favourite} />
</ColWrapper>
{runtimeConfig.enableNewFavorite && (
<ColWrapper
hideInSmallContainer
data-testid="page-list-item-favorite"
data-favorite={favourite ? true : undefined}
className={styles.favoriteCell}
>
<FavoriteTag onClick={onToggleFavoritePage} active={favourite} />
</ColWrapper>
)}
<ColWrapper alignment="start">
<Menu
items={OperationMenu}
@@ -319,7 +327,7 @@ export const CollectionOperationCell = ({
}: CollectionOperationCellProps) => {
const t = useI18n();
const favAdapter = useService(FavoriteItemsAdapter);
const favAdapter = useService(CompatibleFavoriteItemsAdapter);
const docCollection = useService(WorkspaceService).workspace.docCollection;
const { createPage } = usePageHelper(docCollection);
const { openConfirmModal } = useConfirmModal();
@@ -482,12 +490,31 @@ export const TagOperationCell = ({
}: TagOperationCellProps) => {
const t = useI18n();
const [open, setOpen] = useState(false);
const { favoriteService } = useServices({
FavoriteService,
});
const favourite = useLiveData(
favoriteService.favoriteList.isFavorite$('tag', tag.id)
);
const handleDelete = useCallback(() => {
onTagDelete([tag.id]);
}, [onTagDelete, tag.id]);
const onToggleFavoriteCollection = useCallback(() => {
favoriteService.favoriteList.toggle('tag', tag.id);
}, [favoriteService, tag.id]);
return (
<>
<ColWrapper
hideInSmallContainer
data-testid="page-list-item-favorite"
data-favorite={favourite ? true : undefined}
className={styles.favoriteCell}
>
<FavoriteTag onClick={onToggleFavoriteCollection} active={favourite} />
</ColWrapper>
<div className={styles.editTagWrapper} data-show={open}>
<div style={{ width: '100%' }}>
<CreateOrEditTag open={open} onOpenChange={setOpen} tagMeta={tag} />
@@ -1,4 +1,4 @@
import { FavoriteItemsAdapter } from '@affine/core/modules/properties';
import { CompatibleFavoriteItemsAdapter } from '@affine/core/modules/properties';
import { ShareDocsService } from '@affine/core/modules/share-doc';
import type { Collection, Filter } from '@affine/env/filter';
import { PublicPageMode } from '@affine/graphql';
@@ -36,7 +36,7 @@ export const useFilteredPageMetas = (
shareDocsService.shareDocs?.revalidate();
}, [shareDocsService]);
const favAdapter = useService(FavoriteItemsAdapter);
const favAdapter = useService(CompatibleFavoriteItemsAdapter);
const favoriteItems = useLiveData(favAdapter.favorites$);
const filteredPageMetas = useMemo(
@@ -2,7 +2,7 @@ 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 { FavoriteItemsAdapter } from '@affine/core/modules/properties';
import { CompatibleFavoriteItemsAdapter } from '@affine/core/modules/properties';
import { WorkbenchService } from '@affine/core/modules/workbench';
import type { Collection } from '@affine/env/filter';
import { useI18n } from '@affine/i18n';
@@ -79,7 +79,7 @@ export const CollectionOperations = ({
workbench.openCollection(collection.id, { at: 'tail' });
}, [collection.id, workbench]);
const favAdapter = useService(FavoriteItemsAdapter);
const favAdapter = useService(CompatibleFavoriteItemsAdapter);
const onToggleFavoritePage = useCallback(() => {
favAdapter.toggle(collection.id, 'collection');
@@ -1,5 +1,5 @@
import { Tooltip } from '@affine/component';
import { FavoriteItemsAdapter } from '@affine/core/modules/properties';
import { CompatibleFavoriteItemsAdapter } from '@affine/core/modules/properties';
import type { Collection } from '@affine/env/filter';
import { Trans, useI18n } from '@affine/i18n';
import {
@@ -42,7 +42,7 @@ export const RulesMode = ({
const [showPreview, setShowPreview] = useState(true);
const allowListPages: DocMeta[] = [];
const rulesPages: DocMeta[] = [];
const favAdapter = useService(FavoriteItemsAdapter);
const favAdapter = useService(CompatibleFavoriteItemsAdapter);
const favorites = useLiveData(favAdapter.favorites$);
allPageListConfig.allPages.forEach(meta => {
if (meta.trash) {
@@ -1,6 +1,6 @@
import { Menu, toast } from '@affine/component';
import { useBlockSuiteDocMeta } from '@affine/core/hooks/use-block-suite-page-meta';
import { FavoriteItemsAdapter } from '@affine/core/modules/properties';
import { CompatibleFavoriteItemsAdapter } from '@affine/core/modules/properties';
import { ShareDocsService } from '@affine/core/modules/share-doc';
import { PublicPageMode } from '@affine/graphql';
import { Trans, useI18n } from '@affine/i18n';
@@ -60,20 +60,20 @@ export const SelectPage = ({
}, [onChange]);
const {
workspaceService,
favoriteItemsAdapter,
compatibleFavoriteItemsAdapter,
shareDocsService,
docsService,
} = useServices({
DocsService,
ShareDocsService,
WorkspaceService,
FavoriteItemsAdapter,
CompatibleFavoriteItemsAdapter,
});
const shareDocs = useLiveData(shareDocsService.shareDocs?.list$);
const workspace = workspaceService.workspace;
const docCollection = workspace.docCollection;
const pageMetas = useBlockSuiteDocMeta(docCollection);
const favourites = useLiveData(favoriteItemsAdapter.favorites$);
const favourites = useLiveData(compatibleFavoriteItemsAdapter.favorites$);
useEffect(() => {
shareDocsService.shareDocs?.revalidate();
@@ -108,14 +108,14 @@ export const SelectPage = ({
const onToggleFavoritePage = useCallback(
(page: DocMeta) => {
const status = isFavorite(page);
favoriteItemsAdapter.toggle(page.id, 'doc');
compatibleFavoriteItemsAdapter.toggle(page.id, 'doc');
toast(
status
? t['com.affine.toastMessage.removedFavorites']()
: t['com.affine.toastMessage.addedFavorites']()
);
},
[favoriteItemsAdapter, isFavorite, t]
[compatibleFavoriteItemsAdapter, isFavorite, t]
);
const pageHeaderColsDef = usePageHeaderColsDef();
@@ -2,6 +2,8 @@ import { useAsyncCallback } from '@affine/core/hooks/affine-async-hooks';
import {
ExplorerCollections,
ExplorerFavorites,
ExplorerMigrationFavorites,
ExplorerOldFavorites,
ExplorerOrganize,
} from '@affine/core/modules/explorer';
import { ExplorerTags } from '@affine/core/modules/explorer/views/sections/tags';
@@ -161,8 +163,10 @@ export const RootAppSidebar = memo(
</MenuItem>
</SidebarContainer>
<SidebarScrollableContainer>
{runtimeConfig.enableNewFavorite && <ExplorerFavorites />}
{runtimeConfig.enableOrganize && <ExplorerOrganize />}
<ExplorerFavorites />
{runtimeConfig.enableNewFavorite && <ExplorerMigrationFavorites />}
{runtimeConfig.enableOldFavorite && <ExplorerOldFavorites />}
<ExplorerCollections />
<ExplorerTags />
<CategoryDivider label={t['com.affine.rootAppSidebar.others']()} />