mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-14 21:27:20 +00:00
feat: add recentlyViewed (#1357)
Co-authored-by: himself65 <himself65@outlook.com>
This commit is contained in:
@@ -13,10 +13,23 @@ import { useRouter } from 'next/router';
|
||||
import routerMock from 'next-router-mock';
|
||||
import { createDynamicRouteParser } from 'next-router-mock/dynamic-routes';
|
||||
import React from 'react';
|
||||
import { beforeAll, beforeEach, describe, expect, test } from 'vitest';
|
||||
import { beforeAll, beforeEach, describe, expect, test, vi } from 'vitest';
|
||||
|
||||
import { workspacesAtom } from '../../atoms';
|
||||
import { BlockSuiteWorkspace, RemWorkspaceFlavour } from '../../shared';
|
||||
import {
|
||||
currentWorkspaceIdAtom,
|
||||
jotaiWorkspacesAtom,
|
||||
workspacesAtom,
|
||||
} from '../../atoms';
|
||||
import { LocalPlugin } from '../../plugins/local';
|
||||
import {
|
||||
BlockSuiteWorkspace,
|
||||
LocalWorkspace,
|
||||
RemWorkspaceFlavour,
|
||||
} from '../../shared';
|
||||
import {
|
||||
useRecentlyViewed,
|
||||
useSyncRecentViewsWithRouter,
|
||||
} from '../affine/use-recent-views';
|
||||
import {
|
||||
currentWorkspaceAtom,
|
||||
useCurrentWorkspace,
|
||||
@@ -248,3 +261,59 @@ describe('useBlockSuiteWorkspaceName', () => {
|
||||
expect(blockSuiteWorkspace.meta.name).toBe('test 3');
|
||||
});
|
||||
});
|
||||
|
||||
describe('useRecentlyViewed', () => {
|
||||
test('basic', async () => {
|
||||
const { ProviderWrapper, store } = await getJotaiContext();
|
||||
const workspaceId = blockSuiteWorkspace.room as string;
|
||||
const pageId = 'page0';
|
||||
store.set(jotaiWorkspacesAtom, [
|
||||
{
|
||||
id: workspaceId,
|
||||
flavour: RemWorkspaceFlavour.LOCAL,
|
||||
},
|
||||
]);
|
||||
LocalPlugin.CRUD.get = vi.fn().mockResolvedValue({
|
||||
id: workspaceId,
|
||||
flavour: RemWorkspaceFlavour.LOCAL,
|
||||
blockSuiteWorkspace,
|
||||
providers: [],
|
||||
} satisfies LocalWorkspace);
|
||||
store.set(currentWorkspaceIdAtom, blockSuiteWorkspace.room as string);
|
||||
const workspace = await store.get(currentWorkspaceAtom);
|
||||
expect(workspace?.id).toBe(blockSuiteWorkspace.room as string);
|
||||
const currentHook = renderHook(() => useCurrentWorkspace(), {
|
||||
wrapper: ProviderWrapper,
|
||||
});
|
||||
expect(currentHook.result.current[0]?.id).toEqual(workspaceId);
|
||||
await store.get(currentWorkspaceAtom);
|
||||
const recentlyViewedHook = renderHook(() => useRecentlyViewed(), {
|
||||
wrapper: ProviderWrapper,
|
||||
});
|
||||
expect(recentlyViewedHook.result.current).toEqual([]);
|
||||
const routerHook = renderHook(() => useRouter());
|
||||
await routerHook.result.current.push({
|
||||
pathname: '/workspace/[workspaceId]/[pageId]',
|
||||
query: {
|
||||
workspaceId,
|
||||
pageId,
|
||||
},
|
||||
});
|
||||
routerHook.rerender();
|
||||
const syncHook = renderHook(
|
||||
router => useSyncRecentViewsWithRouter(router),
|
||||
{
|
||||
wrapper: ProviderWrapper,
|
||||
initialProps: routerHook.result.current,
|
||||
}
|
||||
);
|
||||
syncHook.rerender(routerHook.result.current);
|
||||
expect(recentlyViewedHook.result.current).toEqual([
|
||||
{
|
||||
id: 'page0',
|
||||
mode: 'page',
|
||||
title: 'Untitled',
|
||||
},
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
40
apps/web/src/hooks/affine/use-recent-views.ts
Normal file
40
apps/web/src/hooks/affine/use-recent-views.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
import { useAtomValue, useSetAtom } from 'jotai';
|
||||
import { NextRouter } from 'next/router';
|
||||
import { useEffect } from 'react';
|
||||
|
||||
import {
|
||||
workspaceRecentViewsAtom,
|
||||
workspaceRecentViresWriteAtom,
|
||||
} from '../../atoms';
|
||||
import { useCurrentWorkspace } from '../current/use-current-workspace';
|
||||
import { usePageMeta } from '../use-page-meta';
|
||||
|
||||
export function useRecentlyViewed() {
|
||||
const [workspace] = useCurrentWorkspace();
|
||||
const workspaceId = workspace?.id || null;
|
||||
const recentlyViewed = useAtomValue(workspaceRecentViewsAtom);
|
||||
|
||||
if (!workspaceId) return [];
|
||||
return recentlyViewed[workspaceId] ?? [];
|
||||
}
|
||||
|
||||
export function useSyncRecentViewsWithRouter(router: NextRouter) {
|
||||
const [workspace] = useCurrentWorkspace();
|
||||
const workspaceId = workspace?.id || null;
|
||||
const blockSuiteWorkspace = workspace?.blockSuiteWorkspace || null;
|
||||
const pageId = router.query.pageId as string;
|
||||
const set = useSetAtom(workspaceRecentViresWriteAtom);
|
||||
const meta = usePageMeta(blockSuiteWorkspace).find(
|
||||
meta => meta.id === pageId
|
||||
);
|
||||
useEffect(() => {
|
||||
if (!workspaceId) return;
|
||||
if (pageId && meta) {
|
||||
set(workspaceId, {
|
||||
title: meta.title || 'Untitled',
|
||||
id: pageId as string,
|
||||
mode: meta.mode || 'page',
|
||||
});
|
||||
}
|
||||
}, [pageId, meta, workspaceId, set]);
|
||||
}
|
||||
Reference in New Issue
Block a user