feat: bump blocksuite (#5953)

This commit is contained in:
regischen authored and GitHub committed 2024-02-29 14:33:50 +08:00
1 parent fa534869e1
commit d1e6b23e1a
121 files changed
+665 -674

No files matched your search

+2 -2
View File
@@ -3,8 +3,8 @@
"private": true, "private": true,
"type": "module", "type": "module",
"devDependencies": { "devDependencies": {
"@blocksuite/global": "0.12.0-canary-202402220729-0868ac6", "@blocksuite/global": "0.12.0-canary-202402271448-6d3a709",
"@blocksuite/store": "0.12.0-canary-202402220729-0868ac6", "@blocksuite/store": "0.12.0-canary-202402271448-6d3a709",
"react": "18.2.0", "react": "18.2.0",
"react-dom": "18.2.0", "react-dom": "18.2.0",
"vitest": "1.3.1" "vitest": "1.3.1"
+5 -5
View File
@@ -17,9 +17,9 @@
"@affine/debug": "workspace:*", "@affine/debug": "workspace:*",
"@affine/env": "workspace:*", "@affine/env": "workspace:*",
"@affine/templates": "workspace:*", "@affine/templates": "workspace:*",
"@blocksuite/blocks": "0.12.0-canary-202402220729-0868ac6", "@blocksuite/blocks": "0.12.0-canary-202402271448-6d3a709",
"@blocksuite/global": "0.12.0-canary-202402220729-0868ac6", "@blocksuite/global": "0.12.0-canary-202402271448-6d3a709",
"@blocksuite/store": "0.12.0-canary-202402220729-0868ac6", "@blocksuite/store": "0.12.0-canary-202402271448-6d3a709",
"foxact": "^0.2.31", "foxact": "^0.2.31",
"jotai": "^2.6.5", "jotai": "^2.6.5",
"jotai-effect": "^0.5.0", "jotai-effect": "^0.5.0",
@@ -33,8 +33,8 @@
"devDependencies": { "devDependencies": {
"@affine-test/fixtures": "workspace:*", "@affine-test/fixtures": "workspace:*",
"@affine/templates": "workspace:*", "@affine/templates": "workspace:*",
"@blocksuite/lit": "0.12.0-canary-202402220729-0868ac6", "@blocksuite/lit": "0.12.0-canary-202402271448-6d3a709",
"@blocksuite/presets": "0.12.0-canary-202402220729-0868ac6", "@blocksuite/presets": "0.12.0-canary-202402271448-6d3a709",
"@testing-library/react": "^14.2.1", "@testing-library/react": "^14.2.1",
"async-call-rpc": "^6.4.0", "async-call-rpc": "^6.4.0",
"react": "^18.2.0", "react": "^18.2.0",
@@ -30,7 +30,7 @@ export async function migratePages(
spaces.forEach((space: YDoc) => { spaces.forEach((space: YDoc) => {
try { try {
// Catch page upgrade error to avoid blocking the whole workspace migration. // Catch page upgrade error to avoid blocking the whole workspace migration.
schema.upgradePage(0, oldVersions, space); schema.upgradeDoc(0, oldVersions, space);
} catch (e) { } catch (e) {
console.error(e); console.error(e);
} }
@@ -28,7 +28,7 @@ export function checkWorkspaceCompatibility(
} }
// exit if no pages // exit if no pages
if (!workspace.meta.pages?.length) { if (!workspace.meta.docs?.length) {
return null; return null;
} }
@@ -55,7 +55,7 @@ export function checkWorkspaceCompatibility(
// TODO: Catch compatibility error from blocksuite to show upgrade page. // TODO: Catch compatibility error from blocksuite to show upgrade page.
// Temporarily follow the check logic of blocksuite. // Temporarily follow the check logic of blocksuite.
if ((workspace.meta.pages?.length ?? 0) <= 1) { if ((workspace.meta.docs?.length ?? 0) <= 1) {
try { try {
workspace.meta.validateVersion(workspace); workspace.meta.validateVersion(workspace);
} catch (e) { } catch (e) {
@@ -1,8 +1,8 @@
import type { WorkspaceFlavour } from '@affine/env/workspace'; import type { WorkspaceFlavour } from '@affine/env/workspace';
import type { import type {
Doc,
DocSnapshot,
JobMiddleware, JobMiddleware,
Page,
PageSnapshot,
WorkspaceInfoSnapshot, WorkspaceInfoSnapshot,
} from '@blocksuite/store'; } from '@blocksuite/store';
import { Job } from '@blocksuite/store'; import { Job } from '@blocksuite/store';
@@ -13,7 +13,7 @@ import { PageRecordList } from '../page';
import type { WorkspaceManager } from '../workspace'; import type { WorkspaceManager } from '../workspace';
import { replaceIdMiddleware } from './middleware'; import { replaceIdMiddleware } from './middleware';
export function initEmptyPage(page: Page, title?: string) { export function initEmptyPage(page: Doc, title?: string) {
page.load(() => { page.load(() => {
const pageBlockId = page.addBlock('affine:page', { const pageBlockId = page.addBlock('affine:page', {
title: new page.Text(title ?? ''), title: new page.Text(title ?? ''),
@@ -44,7 +44,7 @@ export async function buildShowcaseWorkspace(
const migrationMiddleware: JobMiddleware = ({ slots, workspace }) => { const migrationMiddleware: JobMiddleware = ({ slots, workspace }) => {
slots.afterImport.on(payload => { slots.afterImport.on(payload => {
if (payload.type === 'page') { if (payload.type === 'page') {
workspace.schema.upgradePage( workspace.schema.upgradeDoc(
info?.pageVersion ?? 0, info?.pageVersion ?? 0,
{}, {},
payload.page.spaceDoc payload.page.spaceDoc
@@ -65,15 +65,15 @@ export async function buildShowcaseWorkspace(
// @ts-expect-error - rethinking API // @ts-expect-error - rethinking API
job._assetsManager.writeToBlob = async () => {}; job._assetsManager.writeToBlob = async () => {};
const pageSnapshots: PageSnapshot[] = Object.entries(onboarding) const docSnapshots: DocSnapshot[] = Object.entries(onboarding)
.filter(([key]) => { .filter(([key]) => {
return key.endsWith('snapshot.json'); return key.endsWith('snapshot.json');
}) })
.map(([_, value]) => value as unknown as PageSnapshot); .map(([_, value]) => value as unknown as DocSnapshot);
await Promise.all( await Promise.all(
pageSnapshots.map(snapshot => { docSnapshots.map(snapshot => {
return job.snapshotToPage(snapshot); return job.snapshotToDoc(snapshot);
}) })
); );
+3 -3
View File
@@ -1,10 +1,10 @@
import type { Page as BlockSuitePage } from '@blocksuite/store'; import type { Doc as BlockSuiteDoc } from '@blocksuite/store';
import { createIdentifier, type ServiceCollection } from '../di'; import { createIdentifier, type ServiceCollection } from '../di';
import type { PageRecord } from './record'; import type { PageRecord } from './record';
import { PageScope } from './service-scope'; import { PageScope } from './service-scope';
export const BlockSuitePageContext = createIdentifier<BlockSuitePage>( export const BlockSuitePageContext = createIdentifier<BlockSuiteDoc>(
'BlockSuitePageContext' 'BlockSuitePageContext'
); );
@@ -13,7 +13,7 @@ export const PageRecordContext =
export function configurePageContext( export function configurePageContext(
services: ServiceCollection, services: ServiceCollection,
blockSuitePage: BlockSuitePage, blockSuitePage: BlockSuiteDoc,
pageRecord: PageRecord pageRecord: PageRecord
) { ) {
services services
+2 -2
View File
@@ -9,7 +9,7 @@ import { CleanupService } from '../lifecycle';
import { Workspace, WorkspaceLocalState, WorkspaceScope } from '../workspace'; import { Workspace, WorkspaceLocalState, WorkspaceScope } from '../workspace';
import { BlockSuitePageContext, PageRecordContext } from './context'; import { BlockSuitePageContext, PageRecordContext } from './context';
import { PageManager } from './manager'; import { PageManager } from './manager';
import { Page } from './page'; import { Doc } from './page';
import { PageRecordList } from './record-list'; import { PageRecordList } from './record-list';
import { PageScope } from './service-scope'; import { PageScope } from './service-scope';
@@ -22,5 +22,5 @@ export function configurePageServices(services: ServiceCollection) {
services services
.scope(PageScope) .scope(PageScope)
.add(CleanupService) .add(CleanupService)
.add(Page, [PageRecordContext, BlockSuitePageContext, ServiceProvider]); .add(Doc, [PageRecordContext, BlockSuitePageContext, ServiceProvider]);
} }
+4 -4
View File
@@ -3,11 +3,11 @@ import { ObjectPool } from '../utils/object-pool';
import type { Workspace } from '../workspace'; import type { Workspace } from '../workspace';
import type { PageRecordList } from '.'; import type { PageRecordList } from '.';
import { configurePageContext } from './context'; import { configurePageContext } from './context';
import { Page } from './page'; import { Doc } from './page';
import { PageScope } from './service-scope'; import { PageScope } from './service-scope';
export class PageManager { export class PageManager {
pool = new ObjectPool<string, Page>({}); pool = new ObjectPool<string, Doc>({});
constructor( constructor(
private readonly workspace: Workspace, private readonly workspace: Workspace,
@@ -20,7 +20,7 @@ export class PageManager {
if (!pageRecord) { if (!pageRecord) {
throw new Error('Page record not found'); throw new Error('Page record not found');
} }
const blockSuitePage = this.workspace.blockSuiteWorkspace.getPage(pageId); const blockSuitePage = this.workspace.blockSuiteWorkspace.getDoc(pageId);
if (!blockSuitePage) { if (!blockSuitePage) {
throw new Error('Page not found'); throw new Error('Page not found');
} }
@@ -41,7 +41,7 @@ export class PageManager {
this.serviceProvider this.serviceProvider
); );
const page = provider.get(Page); const page = provider.get(Doc);
const { obj, release } = this.pool.put(pageId, page); const { obj, release } = this.pool.put(pageId, page);
+3 -3
View File
@@ -1,12 +1,12 @@
import type { Page as BlockSuitePage } from '@blocksuite/store'; import type { Doc as BlockSuiteDoc } from '@blocksuite/store';
import type { ServiceProvider } from '@toeverything/infra/di'; import type { ServiceProvider } from '@toeverything/infra/di';
import type { PageMode, PageRecord } from './record'; import type { PageMode, PageRecord } from './record';
export class Page { export class Doc {
constructor( constructor(
public readonly record: PageRecord, public readonly record: PageRecord,
public readonly blockSuitePage: BlockSuitePage, public readonly blockSuiteDoc: BlockSuiteDoc,
public readonly services: ServiceProvider public readonly services: ServiceProvider
) {} ) {}
@@ -18,7 +18,7 @@ export class PageRecordList {
new Observable(subscriber => { new Observable(subscriber => {
const emit = () => { const emit = () => {
subscriber.next( subscriber.next(
this.workspace.blockSuiteWorkspace.meta.pageMetas.map( this.workspace.blockSuiteWorkspace.meta.docMetas.map(
v => new PageRecord(v.id, this.workspace, this.localState) v => new PageRecord(v.id, this.workspace, this.localState)
) )
); );
@@ -27,9 +27,7 @@ export class PageRecordList {
emit(); emit();
const dispose = const dispose =
this.workspace.blockSuiteWorkspace.meta.pageMetasUpdated.on( this.workspace.blockSuiteWorkspace.meta.docMetaUpdated.on(emit).dispose;
emit
).dispose;
return () => { return () => {
dispose(); dispose();
}; };
+6 -8
View File
@@ -1,4 +1,4 @@
import type { PageMeta } from '@blocksuite/store'; import type { DocMeta } from '@blocksuite/store';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { LiveData } from '../livedata'; import { LiveData } from '../livedata';
@@ -13,10 +13,10 @@ export class PageRecord {
private readonly localState: WorkspaceLocalState private readonly localState: WorkspaceLocalState
) {} ) {}
meta = LiveData.from<PageMeta>( meta = LiveData.from<DocMeta>(
new Observable(subscriber => { new Observable(subscriber => {
const emit = () => { const emit = () => {
const meta = this.workspace.blockSuiteWorkspace.meta.pageMetas.find( const meta = this.workspace.blockSuiteWorkspace.meta.docMetas.find(
page => page.id === this.id page => page.id === this.id
); );
if (meta === undefined) { if (meta === undefined) {
@@ -28,9 +28,7 @@ export class PageRecord {
emit(); emit();
const dispose = const dispose =
this.workspace.blockSuiteWorkspace.meta.pageMetasUpdated.on( this.workspace.blockSuiteWorkspace.meta.docMetaUpdated.on(emit).dispose;
emit
).dispose;
return () => { return () => {
dispose(); dispose();
}; };
@@ -43,8 +41,8 @@ export class PageRecord {
} }
); );
setMeta(meta: Partial<PageMeta>): void { setMeta(meta: Partial<DocMeta>): void {
this.workspace.blockSuiteWorkspace.setPageMeta(this.id, meta); this.workspace.blockSuiteWorkspace.setDocMeta(this.id, meta);
} }
mode: LiveData<PageMode> = LiveData.from( mode: LiveData<PageMode> = LiveData.from(
@@ -22,7 +22,7 @@ describe('Workspace System', () => {
expect(workspaceListService.workspaceList.value.length).toBe(1); expect(workspaceListService.workspaceList.value.length).toBe(1);
const page = workspace.blockSuiteWorkspace.createPage({ const page = workspace.blockSuiteWorkspace.createDoc({
id: 'page0', id: 'page0',
}); });
page.load(); page.load();
@@ -30,7 +30,7 @@ describe('Workspace System', () => {
title: new page.Text('test-page'), title: new page.Text('test-page'),
}); });
expect(workspace.blockSuiteWorkspace.pages.size).toBe(1); expect(workspace.blockSuiteWorkspace.docs.size).toBe(1);
expect( expect(
(page!.getBlockByFlavour('affine:page')[0] as any).title.toString() (page!.getBlockByFlavour('affine:page')[0] as any).title.toString()
).toBe('test-page'); ).toBe('test-page');
@@ -42,7 +42,7 @@ describe('SyncEngine', () => {
); );
syncEngine.start(); syncEngine.start();
const page = workspace.createPage({ const page = workspace.createDoc({
id: 'page0', id: 'page0',
}); });
page.load(); page.load();
@@ -35,7 +35,7 @@ describe('SyncPeer', () => {
); );
await syncPeer.waitForLoaded(); await syncPeer.waitForLoaded();
const page = workspace.createPage({ const page = workspace.createDoc({
id: 'page0', id: 'page0',
}); });
page.load(); page.load();
@@ -85,7 +85,7 @@ describe('SyncPeer', () => {
await syncPeer.waitForSynced(); await syncPeer.waitForSynced();
expect(syncPeer.status.step).toBe(SyncPeerStep.Synced); expect(syncPeer.status.step).toBe(SyncPeerStep.Synced);
const page = workspace.createPage({ const page = workspace.createDoc({
id: 'page0', id: 'page0',
}); });
expect(syncPeer.status.step).toBe(SyncPeerStep.LoadingSubDoc); expect(syncPeer.status.step).toBe(SyncPeerStep.LoadingSubDoc);
+3 -3
View File
@@ -32,14 +32,14 @@
} }
}, },
"dependencies": { "dependencies": {
"@blocksuite/global": "0.12.0-canary-202402220729-0868ac6", "@blocksuite/global": "0.12.0-canary-202402271448-6d3a709",
"idb": "^8.0.0", "idb": "^8.0.0",
"nanoid": "^5.0.6", "nanoid": "^5.0.6",
"y-provider": "workspace:*" "y-provider": "workspace:*"
}, },
"devDependencies": { "devDependencies": {
"@blocksuite/blocks": "0.12.0-canary-202402220729-0868ac6", "@blocksuite/blocks": "0.12.0-canary-202402271448-6d3a709",
"@blocksuite/store": "0.12.0-canary-202402220729-0868ac6", "@blocksuite/store": "0.12.0-canary-202402271448-6d3a709",
"fake-indexeddb": "^5.0.2", "fake-indexeddb": "^5.0.2",
"vite": "^5.1.4", "vite": "^5.1.4",
"vite-plugin-dts": "3.7.3", "vite-plugin-dts": "3.7.3",
@@ -7,12 +7,12 @@ import { setTimeout } from 'node:timers/promises';
import { __unstableSchemas, AffineSchemas } from '@blocksuite/blocks/models'; import { __unstableSchemas, AffineSchemas } from '@blocksuite/blocks/models';
import { assertExists } from '@blocksuite/global/utils'; import { assertExists } from '@blocksuite/global/utils';
import type { Page } from '@blocksuite/store'; import type { Doc } from '@blocksuite/store';
import { Schema, Workspace } from '@blocksuite/store'; import { Schema, Workspace } from '@blocksuite/store';
import { openDB } from 'idb'; import { openDB } from 'idb';
import { nanoid } from 'nanoid'; import { nanoid } from 'nanoid';
import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest'; import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest';
import { applyUpdate, Doc, encodeStateAsUpdate } from 'yjs'; import { applyUpdate, Doc as YDoc, encodeStateAsUpdate } from 'yjs';
import type { WorkspacePersist } from '../index'; import type { WorkspacePersist } from '../index';
import { import {
@@ -27,7 +27,7 @@ import {
setMergeCount, setMergeCount,
} from '../index'; } from '../index';
function initEmptyPage(page: Page) { function initEmptyPage(page: Doc) {
const pageBlockId = page.addBlock('affine:page', { const pageBlockId = page.addBlock('affine:page', {
title: new page.Text(''), title: new page.Text(''),
}); });
@@ -99,9 +99,9 @@ describe('indexeddb provider', () => {
}, },
], ],
}); });
const page = workspace.createPage({ id: 'page0' }); const page = workspace.createDoc({ id: 'page0' });
page.waitForLoaded(); page.load();
const pageBlockId = page.addBlock('affine:page', { title: '' }); const pageBlockId = page.addBlock('affine:page', {});
const frameId = page.addBlock('affine:note', {}, pageBlockId); const frameId = page.addBlock('affine:note', {}, pageBlockId);
page.addBlock('affine:paragraph', {}, frameId); page.addBlock('affine:paragraph', {}, frameId);
} }
@@ -129,7 +129,7 @@ describe('indexeddb provider', () => {
| WorkspacePersist | WorkspacePersist
| undefined; | undefined;
assertExists(data); assertExists(data);
testWorkspace.getPage('page0')?.waitForLoaded(); testWorkspace.getDoc('page0')?.load();
data.updates.forEach(({ update }) => { data.updates.forEach(({ update }) => {
Workspace.Y.applyUpdate(subPage, update); Workspace.Y.applyUpdate(subPage, update);
}); });
@@ -147,9 +147,9 @@ describe('indexeddb provider', () => {
provider.disconnect(); provider.disconnect();
expect(provider.connected).toBe(false); expect(provider.connected).toBe(false);
{ {
const page = workspace.createPage({ id: 'page0' }); const page = workspace.createDoc({ id: 'page0' });
page.waitForLoaded(); page.load();
const pageBlockId = page.addBlock('affine:page', { title: '' }); const pageBlockId = page.addBlock('affine:page');
const frameId = page.addBlock('affine:note', {}, pageBlockId); const frameId = page.addBlock('affine:note', {}, pageBlockId);
page.addBlock('affine:paragraph', {}, frameId); page.addBlock('affine:paragraph', {}, frameId);
} }
@@ -202,9 +202,9 @@ describe('indexeddb provider', () => {
const provider = createIndexedDBProvider(workspace.doc, rootDBName); const provider = createIndexedDBProvider(workspace.doc, rootDBName);
provider.connect(); provider.connect();
{ {
const page = workspace.createPage({ id: 'page0' }); const page = workspace.createDoc({ id: 'page0' });
page.waitForLoaded(); page.load();
const pageBlockId = page.addBlock('affine:page', { title: '' }); const pageBlockId = page.addBlock('affine:page');
const frameId = page.addBlock('affine:note', {}, pageBlockId); const frameId = page.addBlock('affine:note', {}, pageBlockId);
for (let i = 0; i < 99; i++) { for (let i = 0; i < 99; i++) {
page.addBlock('affine:paragraph', {}, frameId); page.addBlock('affine:paragraph', {}, frameId);
@@ -250,7 +250,7 @@ describe('indexeddb provider', () => {
expect(event).toBe('beforeunload'); expect(event).toBe('beforeunload');
return oldRemoveEventListener(event, fn, options); return oldRemoveEventListener(event, fn, options);
}); });
const doc = new Doc({ const doc = new YDoc({
guid: '1', guid: '1',
}); });
const provider = createIndexedDBProvider(doc); const provider = createIndexedDBProvider(doc);
@@ -270,7 +270,7 @@ describe('indexeddb provider', () => {
describe('milestone', () => { describe('milestone', () => {
test('milestone', async () => { test('milestone', async () => {
const doc = new Doc(); const doc = new YDoc();
const map = doc.getMap('map'); const map = doc.getMap('map');
const array = doc.getArray('array'); const array = doc.getArray('array');
map.set('1', 1); map.set('1', 1);
@@ -281,7 +281,7 @@ describe('milestone', () => {
expect(milestones).toBeDefined(); expect(milestones).toBeDefined();
expect(Object.keys(milestones).length).toBe(1); expect(Object.keys(milestones).length).toBe(1);
expect(milestones.test1).toBeInstanceOf(Uint8Array); expect(milestones.test1).toBeInstanceOf(Uint8Array);
const snapshot = new Doc(); const snapshot = new YDoc();
applyUpdate(snapshot, milestones.test1); applyUpdate(snapshot, milestones.test1);
{ {
const map = snapshot.getMap('map'); const map = snapshot.getMap('map');
@@ -316,7 +316,7 @@ describe('milestone', () => {
expect(fn).toBeCalled(); expect(fn).toBeCalled();
const doc2 = new Doc(); const doc2 = new YDoc();
applyUpdate(doc2, encodeStateAsUpdate(doc)); applyUpdate(doc2, encodeStateAsUpdate(doc));
revertUpdate(doc2, milestones.test1, key => revertUpdate(doc2, milestones.test1, key =>
@@ -333,11 +333,11 @@ describe('subDoc', () => {
test('basic', async () => { test('basic', async () => {
let json1: any, json2: any; let json1: any, json2: any;
{ {
const doc = new Doc({ const doc = new YDoc({
guid: 'test', guid: 'test',
}); });
const map = doc.getMap(); const map = doc.getMap();
const subDoc = new Doc(); const subDoc = new YDoc();
subDoc.load(); subDoc.load();
map.set('1', subDoc); map.set('1', subDoc);
map.set('2', 'test'); map.set('2', 'test');
@@ -348,14 +348,14 @@ describe('subDoc', () => {
json1 = doc.toJSON(); json1 = doc.toJSON();
} }
{ {
const doc = new Doc({ const doc = new YDoc({
guid: 'test', guid: 'test',
}); });
const provider = createIndexedDBProvider(doc); const provider = createIndexedDBProvider(doc);
provider.connect(); provider.connect();
await setTimeout(200); await setTimeout(200);
const map = doc.getMap(); const map = doc.getMap();
const subDoc = map.get('1') as Doc; const subDoc = map.get('1') as YDoc;
subDoc.load(); subDoc.load();
provider.disconnect(); provider.disconnect();
json2 = doc.toJSON(); json2 = doc.toJSON();
@@ -366,17 +366,17 @@ describe('subDoc', () => {
}); });
test('blocksuite', async () => { test('blocksuite', async () => {
const page0 = workspace.createPage({ const page0 = workspace.createDoc({
id: 'page0', id: 'page0',
}); });
page0.waitForLoaded(); page0.load();
const { paragraphBlockId: paragraphBlockIdPage1 } = initEmptyPage(page0); const { paragraphBlockId: paragraphBlockIdPage1 } = initEmptyPage(page0);
const provider = createIndexedDBProvider(workspace.doc, rootDBName); const provider = createIndexedDBProvider(workspace.doc, rootDBName);
provider.connect(); provider.connect();
const page1 = workspace.createPage({ const page1 = workspace.createDoc({
id: 'page1', id: 'page1',
}); });
page1.waitForLoaded(); page1.load();
const { paragraphBlockId: paragraphBlockIdPage2 } = initEmptyPage(page1); const { paragraphBlockId: paragraphBlockIdPage2 } = initEmptyPage(page1);
await setTimeout(200); await setTimeout(200);
provider.disconnect(); provider.disconnect();
@@ -389,15 +389,15 @@ describe('subDoc', () => {
const provider = createIndexedDBProvider(newWorkspace.doc, rootDBName); const provider = createIndexedDBProvider(newWorkspace.doc, rootDBName);
provider.connect(); provider.connect();
await setTimeout(200); await setTimeout(200);
const page0 = newWorkspace.getPage('page0') as Page; const page0 = newWorkspace.getDoc('page0') as Doc;
page0.waitForLoaded(); page0.load();
await setTimeout(200); await setTimeout(200);
{ {
const block = page0.getBlockById(paragraphBlockIdPage1); const block = page0.getBlockById(paragraphBlockIdPage1);
assertExists(block); assertExists(block);
} }
const page1 = newWorkspace.getPage('page1') as Page; const page1 = newWorkspace.getDoc('page1') as Doc;
page1.waitForLoaded(); page1.load();
await setTimeout(200); await setTimeout(200);
{ {
const block = page1.getBlockById(paragraphBlockIdPage2); const block = page1.getBlockById(paragraphBlockIdPage2);
@@ -409,8 +409,8 @@ describe('subDoc', () => {
describe('utils', () => { describe('utils', () => {
test('download binary', async () => { test('download binary', async () => {
const page = workspace.createPage({ id: 'page0' }); const page = workspace.createDoc({ id: 'page0' });
page.waitForLoaded(); page.load();
initEmptyPage(page); initEmptyPage(page);
const provider = createIndexedDBProvider(workspace.doc, rootDBName); const provider = createIndexedDBProvider(workspace.doc, rootDBName);
provider.connect(); provider.connect();
@@ -437,7 +437,7 @@ describe('utils', () => {
}); });
test('overwrite binary', async () => { test('overwrite binary', async () => {
const doc = new Doc(); const doc = new YDoc();
const map = doc.getMap(); const map = doc.getMap();
map.set('1', 1); map.set('1', 1);
await overwriteBinary('test', new Uint8Array(encodeStateAsUpdate(doc))); await overwriteBinary('test', new Uint8Array(encodeStateAsUpdate(doc)));
+1 -1
View File
@@ -24,7 +24,7 @@
"build": "vite build" "build": "vite build"
}, },
"devDependencies": { "devDependencies": {
"@blocksuite/store": "0.12.0-canary-202402220729-0868ac6", "@blocksuite/store": "0.12.0-canary-202402271448-6d3a709",
"vite": "^5.1.4", "vite": "^5.1.4",
"vite-plugin-dts": "3.7.3", "vite-plugin-dts": "3.7.3",
"vitest": "1.3.1", "vitest": "1.3.1",
+5 -5
View File
@@ -72,12 +72,12 @@
"uuid": "^9.0.1" "uuid": "^9.0.1"
}, },
"devDependencies": { "devDependencies": {
"@blocksuite/blocks": "0.12.0-canary-202402220729-0868ac6", "@blocksuite/blocks": "0.12.0-canary-202402271448-6d3a709",
"@blocksuite/global": "0.12.0-canary-202402220729-0868ac6", "@blocksuite/global": "0.12.0-canary-202402271448-6d3a709",
"@blocksuite/icons": "2.1.44", "@blocksuite/icons": "2.1.44",
"@blocksuite/lit": "0.12.0-canary-202402220729-0868ac6", "@blocksuite/lit": "0.12.0-canary-202402271448-6d3a709",
"@blocksuite/presets": "0.12.0-canary-202402220729-0868ac6", "@blocksuite/presets": "0.12.0-canary-202402271448-6d3a709",
"@blocksuite/store": "0.12.0-canary-202402220729-0868ac6", "@blocksuite/store": "0.12.0-canary-202402271448-6d3a709",
"@storybook/addon-actions": "^7.6.17", "@storybook/addon-actions": "^7.6.17",
"@storybook/addon-essentials": "^7.6.17", "@storybook/addon-essentials": "^7.6.17",
"@storybook/addon-interactions": "^7.6.17", "@storybook/addon-interactions": "^7.6.17",
+7 -7
View File
@@ -25,14 +25,14 @@
"@affine/i18n": "workspace:*", "@affine/i18n": "workspace:*",
"@affine/templates": "workspace:*", "@affine/templates": "workspace:*",
"@affine/workspace-impl": "workspace:*", "@affine/workspace-impl": "workspace:*",
"@blocksuite/block-std": "0.12.0-canary-202402220729-0868ac6", "@blocksuite/block-std": "0.12.0-canary-202402271448-6d3a709",
"@blocksuite/blocks": "0.12.0-canary-202402220729-0868ac6", "@blocksuite/blocks": "0.12.0-canary-202402271448-6d3a709",
"@blocksuite/global": "0.12.0-canary-202402220729-0868ac6", "@blocksuite/global": "0.12.0-canary-202402271448-6d3a709",
"@blocksuite/icons": "2.1.44", "@blocksuite/icons": "2.1.44",
"@blocksuite/inline": "0.12.0-canary-202402220729-0868ac6", "@blocksuite/inline": "0.12.0-canary-202402271448-6d3a709",
"@blocksuite/lit": "0.12.0-canary-202402220729-0868ac6", "@blocksuite/lit": "0.12.0-canary-202402271448-6d3a709",
"@blocksuite/presets": "0.12.0-canary-202402220729-0868ac6", "@blocksuite/presets": "0.12.0-canary-202402271448-6d3a709",
"@blocksuite/store": "0.12.0-canary-202402220729-0868ac6", "@blocksuite/store": "0.12.0-canary-202402271448-6d3a709",
"@dnd-kit/core": "^6.1.0", "@dnd-kit/core": "^6.1.0",
"@dnd-kit/modifiers": "^7.0.0", "@dnd-kit/modifiers": "^7.0.0",
"@dnd-kit/sortable": "^8.0.0", "@dnd-kit/sortable": "^8.0.0",
@@ -24,8 +24,8 @@ export async function createFirstAppData(workspaceManager: WorkspaceManager) {
WorkspaceFlavour.LOCAL, WorkspaceFlavour.LOCAL,
async workspace => { async workspace => {
workspace.meta.setName(DEFAULT_WORKSPACE_NAME); workspace.meta.setName(DEFAULT_WORKSPACE_NAME);
const page = workspace.createPage(); const page = workspace.createDoc();
workspace.setPageMeta(page.id, { workspace.setDocMeta(page.id, {
jumpOnce: true, jumpOnce: true,
}); });
initEmptyPage(page); initEmptyPage(page);
@@ -238,8 +238,8 @@ export const CreateWorkspaceModal = ({
workspaceFlavour, workspaceFlavour,
async workspace => { async workspace => {
workspace.meta.setName(name); workspace.meta.setName(name);
const page = workspace.createPage(); const page = workspace.createDoc();
workspace.setPageMeta(page.id, { workspace.setDocMeta(page.id, {
jumpOnce: true, jumpOnce: true,
}); });
initEmptyPage(page); initEmptyPage(page);
@@ -1,4 +1,4 @@
import { usePageMetaHelper } from '@affine/core/hooks/use-block-suite-page-meta'; import { useDocMetaHelper } from '@affine/core/hooks/use-block-suite-page-meta';
import { useBlockSuiteWorkspacePage } from '@affine/core/hooks/use-block-suite-workspace-page'; import { useBlockSuiteWorkspacePage } from '@affine/core/hooks/use-block-suite-workspace-page';
import { timestampToLocalDate } from '@affine/core/utils'; import { timestampToLocalDate } from '@affine/core/utils';
import { DebugLogger } from '@affine/debug'; import { DebugLogger } from '@affine/debug';
@@ -27,7 +27,7 @@ const logger = new DebugLogger('page-history');
type DocHistory = ListHistoryQuery['workspace']['histories'][number]; type DocHistory = ListHistoryQuery['workspace']['histories'][number];
export const usePageSnapshotList = (workspaceId: string, pageDocId: string) => { export const useDocSnapshotList = (workspaceId: string, pageDocId: string) => {
const pageSize = 10; const pageSize = 10;
const { data, loadingMore, loadMore } = useQueryInfinite({ const { data, loadingMore, loadMore } = useQueryInfinite({
query: listHistoryQuery, query: listHistoryQuery,
@@ -154,16 +154,16 @@ export const useSnapshotPage = (
} }
const pageId = pageDocId + '-' + ts; const pageId = pageDocId + '-' + ts;
const historyShellWorkspace = getOrCreateShellWorkspace(workspace.id); const historyShellWorkspace = getOrCreateShellWorkspace(workspace.id);
let page = historyShellWorkspace.getPage(pageId); let page = historyShellWorkspace.getDoc(pageId);
if (!page && snapshot) { if (!page && snapshot) {
page = historyShellWorkspace.createPage({ page = historyShellWorkspace.createDoc({
id: pageId, id: pageId,
}); });
page.awarenessStore.setReadonly(page, true); page.awarenessStore.setReadonly(page, true);
const spaceDoc = page.spaceDoc; const spaceDoc = page.spaceDoc;
page.load(() => { page.load(() => {
applyUpdate(spaceDoc, new Uint8Array(snapshot)); applyUpdate(spaceDoc, new Uint8Array(snapshot));
historyShellWorkspace.schema.upgradePage(0, {}, spaceDoc); historyShellWorkspace.schema.upgradeDoc(0, {}, spaceDoc);
}); // must load before applyUpdate }); // must load before applyUpdate
} }
return page ?? undefined; return page ?? undefined;
@@ -197,7 +197,7 @@ export const useRestorePage = (workspace: Workspace, pageId: string) => {
const { trigger: recover, isMutating } = useMutation({ const { trigger: recover, isMutating } = useMutation({
mutation: recoverDocMutation, mutation: recoverDocMutation,
}); });
const { getPageMeta, setPageTitle } = usePageMetaHelper(workspace); const { getDocMeta, setDocTitle } = useDocMetaHelper(workspace);
const onRestore = useMemo(() => { const onRestore = useMemo(() => {
return async (version: string, update: Uint8Array) => { return async (version: string, update: Uint8Array) => {
@@ -211,10 +211,10 @@ export const useRestorePage = (workspace: Workspace, pageId: string) => {
}); });
// should also update the page title, since it may be changed in the history // should also update the page title, since it may be changed in the history
const title = page.meta.title; const title = page.meta?.title ?? '';
if (getPageMeta(pageId)?.title !== title) { if (getDocMeta(pageId)?.title !== title) {
setPageTitle(pageId, title); setDocTitle(pageId, title);
} }
await recover({ await recover({
@@ -232,12 +232,12 @@ export const useRestorePage = (workspace: Workspace, pageId: string) => {
logger.info('Page restored', pageDocId, version); logger.info('Page restored', pageDocId, version);
}; };
}, [ }, [
getPageMeta, getDocMeta,
mutateQueryResource, mutateQueryResource,
page, page,
pageId, pageId,
recover, recover,
setPageTitle, setDocTitle,
workspace.id, workspace.id,
]); ]);
@@ -10,11 +10,11 @@ import { useWorkspaceQuota } from '@affine/core/hooks/use-workspace-quota';
import { Trans } from '@affine/i18n'; import { Trans } from '@affine/i18n';
import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { CloseIcon, ToggleCollapseIcon } from '@blocksuite/icons'; import { CloseIcon, ToggleCollapseIcon } from '@blocksuite/icons';
import type { Page as BlockSuitePage } from '@blocksuite/store'; import type { Doc as BlockSuiteDoc } from '@blocksuite/store';
import { type Workspace as BlockSuiteWorkspace } from '@blocksuite/store'; import { type Workspace as BlockSuiteWorkspace } from '@blocksuite/store';
import * as Collapsible from '@radix-ui/react-collapsible'; import * as Collapsible from '@radix-ui/react-collapsible';
import type { DialogContentProps } from '@radix-ui/react-dialog'; import type { DialogContentProps } from '@radix-ui/react-dialog';
import { Page, type PageMode, Workspace } from '@toeverything/infra'; import { Doc, type PageMode, Workspace } from '@toeverything/infra';
import { useService } from '@toeverything/infra/di'; import { useService } from '@toeverything/infra/di';
import { atom, useAtom, useSetAtom } from 'jotai'; import { atom, useAtom, useSetAtom } from 'jotai';
import { import {
@@ -39,7 +39,7 @@ import {
import { AffineErrorBoundary } from '../affine-error-boundary'; import { AffineErrorBoundary } from '../affine-error-boundary';
import { import {
historyListGroupByDay, historyListGroupByDay,
usePageSnapshotList, useDocSnapshotList,
useRestorePage, useRestorePage,
useSnapshotPage, useSnapshotPage,
} from './data'; } from './data';
@@ -90,7 +90,7 @@ const ModalContainer = ({
interface HistoryEditorPreviewProps { interface HistoryEditorPreviewProps {
ts?: string; ts?: string;
snapshotPage?: BlockSuitePage; snapshotPage?: BlockSuiteDoc;
mode: PageMode; mode: PageMode;
onModeChange: (mode: PageMode) => void; onModeChange: (mode: PageMode) => void;
title: string; title: string;
@@ -251,7 +251,7 @@ const PageHistoryList = ({
activeVersion?: string; activeVersion?: string;
onVersionChange: (version: string) => void; onVersionChange: (version: string) => void;
}) => { }) => {
const [historyList, loadMore, loadingMore] = usePageSnapshotList( const [historyList, loadMore, loadingMore] = useDocSnapshotList(
workspaceId, workspaceId,
pageDocId pageDocId
); );
@@ -425,7 +425,7 @@ const PageHistoryManager = ({
const [activeVersion, setActiveVersion] = useState<string>(); const [activeVersion, setActiveVersion] = useState<string>();
const pageDocId = useMemo(() => { const pageDocId = useMemo(() => {
return workspace.getPage(pageId)?.spaceDoc.guid ?? pageId; return workspace.getDoc(pageId)?.spaceDoc.guid ?? pageId;
}, [pageId, workspace]); }, [pageId, workspace]);
const snapshotPage = useSnapshotPage(workspace, pageDocId, activeVersion); const snapshotPage = useSnapshotPage(workspace, pageDocId, activeVersion);
@@ -447,7 +447,7 @@ const PageHistoryManager = ({
[activeVersion, onClose, onRestore, snapshotPage] [activeVersion, onClose, onRestore, snapshotPage]
); );
const page = useService(Page); const page = useService(Doc);
const [mode, setMode] = useState<PageMode>(page.mode.value); const [mode, setMode] = useState<PageMode>(page.mode.value);
const title = useBlockSuiteWorkspacePageTitle(workspace, pageId); const title = useBlockSuiteWorkspacePageTitle(workspace, pageId);
@@ -124,7 +124,7 @@ export class PagePropertiesMetaManager {
// returns page schema properties -> related page // returns page schema properties -> related page
getPropertyStatistics() { getPropertyStatistics() {
const mapping = new Map<string, Set<string>>(); const mapping = new Map<string, Set<string>>();
for (const page of this.adapter.workspace.blockSuiteWorkspace.pages.values()) { for (const page of this.adapter.workspace.blockSuiteWorkspace.docs.values()) {
const properties = this.adapter.getPageProperties(page.id); const properties = this.adapter.getPageProperties(page.id);
for (const id of Object.keys(properties.custom)) { for (const id of Object.keys(properties.custom)) {
if (!mapping.has(id)) mapping.set(id, new Set()); if (!mapping.has(id)) mapping.set(id, new Set());
@@ -169,7 +169,7 @@ export class PagePropertiesManager {
} }
get page() { get page() {
return this.adapter.workspace.blockSuiteWorkspace.getPage(this.pageId); return this.adapter.workspace.blockSuiteWorkspace.getDoc(this.pageId);
} }
get intrinsicMeta() { get intrinsicMeta() {
@@ -1,5 +1,5 @@
import { Checkbox, DatePicker, Menu } from '@affine/component'; import { Checkbox, DatePicker, Menu } from '@affine/component';
import { useAllBlockSuitePageMeta } from '@affine/core/hooks/use-all-block-suite-page-meta'; import { useAllBlockSuiteDocMeta } from '@affine/core/hooks/use-all-block-suite-page-meta';
import { WorkspaceLegacyProperties } from '@affine/core/modules/workspace'; import { WorkspaceLegacyProperties } from '@affine/core/modules/workspace';
import type { import type {
PageInfoCustomProperty, PageInfoCustomProperty,
@@ -9,7 +9,7 @@ import type {
import { timestampToLocalDate } from '@affine/core/utils'; import { timestampToLocalDate } from '@affine/core/utils';
import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { assertExists } from '@blocksuite/global/utils'; import { assertExists } from '@blocksuite/global/utils';
import { Page, useLiveData, useService, Workspace } from '@toeverything/infra'; import { Doc, useLiveData, useService, Workspace } from '@toeverything/infra';
import { noop } from 'lodash-es'; import { noop } from 'lodash-es';
import { import {
type ChangeEventHandler, type ChangeEventHandler,
@@ -176,9 +176,9 @@ export const NumberValue = ({ property }: PropertyRowValueProps) => {
export const TagsValue = () => { export const TagsValue = () => {
const workspace = useService(Workspace); const workspace = useService(Workspace);
const page = useService(Page); const page = useService(Doc);
const blockSuiteWorkspace = workspace.blockSuiteWorkspace; const blockSuiteWorkspace = workspace.blockSuiteWorkspace;
const pageMetas = useAllBlockSuitePageMeta(blockSuiteWorkspace); const pageMetas = useAllBlockSuiteDocMeta(blockSuiteWorkspace);
const legacyProperties = useService(WorkspaceLegacyProperties); const legacyProperties = useService(WorkspaceLegacyProperties);
const options = useLiveData(legacyProperties.tagOptions$); const options = useLiveData(legacyProperties.tagOptions$);
@@ -199,7 +199,7 @@ export const TagsValue = () => {
placeholder={t['com.affine.page-properties.property-value-placeholder']()} placeholder={t['com.affine.page-properties.property-value-placeholder']()}
value={tagIds} value={tagIds}
options={options} options={options}
readonly={page.blockSuitePage.readonly} readonly={page.blockSuiteDoc.readonly}
onChange={onChange} onChange={onChange}
onOptionsChange={legacyProperties.updateTagOptions} onOptionsChange={legacyProperties.updateTagOptions}
/> />
@@ -27,7 +27,7 @@ import {
ToggleExpandIcon, ToggleExpandIcon,
ViewIcon, ViewIcon,
} from '@blocksuite/icons'; } from '@blocksuite/icons';
import type { Page } from '@blocksuite/store'; import type { Doc } from '@blocksuite/store';
import { import {
DndContext, DndContext,
type DragEndEvent, type DragEndEvent,
@@ -1027,7 +1027,7 @@ const PagePropertiesTableInner = () => {
); );
}; };
const usePagePropertiesManager = (page: Page) => { const usePagePropertiesManager = (page: Doc) => {
// the workspace properties adapter adapter is reactive, // the workspace properties adapter adapter is reactive,
// which means it's reference will change when any of the properties change // which means it's reference will change when any of the properties change
// also it will trigger a re-render of the component // also it will trigger a re-render of the component
@@ -1040,7 +1040,7 @@ const usePagePropertiesManager = (page: Page) => {
// this is the main component that renders the page properties table at the top of the page below // this is the main component that renders the page properties table at the top of the page below
// the page title // the page title
export const PagePropertiesTable = ({ page }: { page: Page }) => { export const PagePropertiesTable = ({ page }: { page: Doc }) => {
const manager = usePagePropertiesManager(page); const manager = usePagePropertiesManager(page);
// if the given page is not in the current workspace, then we don't render anything // if the given page is not in the current workspace, then we don't render anything
@@ -1,4 +1,4 @@
import { usePageMetaHelper } from '@affine/core/hooks/use-block-suite-page-meta'; import { useDocMetaHelper } from '@affine/core/hooks/use-block-suite-page-meta';
import { useJournalHelper } from '@affine/core/hooks/use-journal'; import { useJournalHelper } from '@affine/core/hooks/use-journal';
import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { LinkedPageIcon, TodayIcon } from '@blocksuite/icons'; import { LinkedPageIcon, TodayIcon } from '@blocksuite/icons';
@@ -10,7 +10,7 @@ import * as styles from './styles.css';
export interface PageReferenceRendererOptions { export interface PageReferenceRendererOptions {
pageId: string; pageId: string;
pageMetaHelper: ReturnType<typeof usePageMetaHelper>; pageMetaHelper: ReturnType<typeof useDocMetaHelper>;
journalHelper: ReturnType<typeof useJournalHelper>; journalHelper: ReturnType<typeof useJournalHelper>;
t: ReturnType<typeof useAFFiNEI18N>; t: ReturnType<typeof useAFFiNEI18N>;
} }
@@ -22,7 +22,7 @@ export function pageReferenceRenderer({
t, t,
}: PageReferenceRendererOptions) { }: PageReferenceRendererOptions) {
const { isPageJournal, getLocalizedJournalDateString } = journalHelper; const { isPageJournal, getLocalizedJournalDateString } = journalHelper;
const referencedPage = pageMetaHelper.getPageMeta(pageId); const referencedPage = pageMetaHelper.getDocMeta(pageId);
let title = let title =
referencedPage?.title ?? t['com.affine.editor.reference-not-found'](); referencedPage?.title ?? t['com.affine.editor.reference-not-found']();
let icon = <LinkedPageIcon className={styles.pageReferenceIcon} />; let icon = <LinkedPageIcon className={styles.pageReferenceIcon} />;
@@ -35,7 +35,9 @@ export function pageReferenceRenderer({
return ( return (
<> <>
{icon} {icon}
<span className="affine-reference-title">{title}</span> <span className="affine-reference-title">
{title ? title : 'Untitled'}
</span>
</> </>
); );
} }
@@ -49,7 +51,7 @@ export function AffinePageReference({
pageId: string; pageId: string;
wrapper?: React.ComponentType<PropsWithChildren>; wrapper?: React.ComponentType<PropsWithChildren>;
}) { }) {
const pageMetaHelper = usePageMetaHelper(workspace); const pageMetaHelper = useDocMetaHelper(workspace);
const journalHelper = useJournalHelper(workspace); const journalHelper = useJournalHelper(workspace);
const t = useAFFiNEI18N(); const t = useAFFiNEI18N();
const el = pageReferenceRenderer({ const el = pageReferenceRenderer({
@@ -1,6 +1,6 @@
import { useAsyncCallback } from '@affine/core/hooks/affine-async-hooks'; import { useAsyncCallback } from '@affine/core/hooks/affine-async-hooks';
import { WorkspaceFlavour } from '@affine/env/workspace'; import { WorkspaceFlavour } from '@affine/env/workspace';
import type { Page } from '@blocksuite/store'; import type { Doc } from '@blocksuite/store';
import { type Workspace, WorkspaceManager } from '@toeverything/infra'; import { type Workspace, WorkspaceManager } from '@toeverything/infra';
import { useService } from '@toeverything/infra'; import { useService } from '@toeverything/infra';
import { useState } from 'react'; import { useState } from 'react';
@@ -11,7 +11,7 @@ import { ShareMenu } from './share-menu';
type SharePageModalProps = { type SharePageModalProps = {
workspace: Workspace; workspace: Workspace;
page: Page; page: Doc;
isJournal?: boolean; isJournal?: boolean;
}; };
@@ -4,7 +4,7 @@ import { ExportMenuItems } from '@affine/core/components/page-list';
import { WorkspaceFlavour } from '@affine/env/workspace'; import { WorkspaceFlavour } from '@affine/env/workspace';
import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { LinkIcon } from '@blocksuite/icons'; import { LinkIcon } from '@blocksuite/icons';
import { Page, useLiveData } from '@toeverything/infra'; import { Doc, useLiveData } from '@toeverything/infra';
import { useService } from '@toeverything/infra/di'; import { useService } from '@toeverything/infra/di';
import { useExportPage } from '../../../../hooks/affine/use-export-page'; import { useExportPage } from '../../../../hooks/affine/use-export-page';
@@ -17,7 +17,7 @@ export const ShareExport = ({
currentPage, currentPage,
}: ShareMenuProps) => { }: ShareMenuProps) => {
const t = useAFFiNEI18N(); const t = useAFFiNEI18N();
const page = useService(Page); const page = useService(Doc);
const workspaceId = workspace.id; const workspaceId = workspace.id;
const pageId = currentPage.id; const pageId = currentPage.id;
const { sharingUrl, onClickCopyLink } = useSharingUrl({ const { sharingUrl, onClickCopyLink } = useSharingUrl({
@@ -4,7 +4,7 @@ import { Menu } from '@affine/component/ui/menu';
import { WorkspaceFlavour } from '@affine/env/workspace'; import { WorkspaceFlavour } from '@affine/env/workspace';
import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { WebIcon } from '@blocksuite/icons'; import { WebIcon } from '@blocksuite/icons';
import type { Page } from '@blocksuite/store'; import type { Doc } from '@blocksuite/store';
import type { WorkspaceMetadata } from '@toeverything/infra'; import type { WorkspaceMetadata } from '@toeverything/infra';
import clsx from 'clsx'; import clsx from 'clsx';
@@ -15,7 +15,7 @@ import { SharePage } from './share-page';
export interface ShareMenuProps { export interface ShareMenuProps {
workspaceMetadata: WorkspaceMetadata; workspaceMetadata: WorkspaceMetadata;
currentPage: Page; currentPage: Doc;
isJournal?: boolean; isJournal?: boolean;
onEnableAffineCloud: () => void; onEnableAffineCloud: () => void;
} }
@@ -15,7 +15,7 @@ import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { ArrowRightSmallIcon } from '@blocksuite/icons'; import { ArrowRightSmallIcon } from '@blocksuite/icons';
import { useService } from '@toeverything/infra'; import { useService } from '@toeverything/infra';
import { useLiveData } from '@toeverything/infra'; import { useLiveData } from '@toeverything/infra';
import { Page, type PageMode } from '@toeverything/infra'; import { Doc, type PageMode } from '@toeverything/infra';
import { useMemo, useState } from 'react'; import { useMemo, useState } from 'react';
import { useCallback } from 'react'; import { useCallback } from 'react';
@@ -56,7 +56,7 @@ export const AffineSharePage = (props: ShareMenuProps) => {
currentPage, currentPage,
} = props; } = props;
const pageId = currentPage.id; const pageId = currentPage.id;
const page = useService(Page); const page = useService(Doc);
const [showDisable, setShowDisable] = useState(false); const [showDisable, setShowDisable] = useState(false);
const { const {
isSharedPage, isSharedPage,
@@ -1,10 +1,10 @@
import type { BlockElement } from '@blocksuite/lit'; import type { BlockElement } from '@blocksuite/lit';
import type { import type {
AffineEditorContainer, AffineEditorContainer,
DocEditor,
EdgelessEditor, EdgelessEditor,
PageEditor,
} from '@blocksuite/presets'; } from '@blocksuite/presets';
import { type Page, Slot } from '@blocksuite/store'; import { type Doc, Slot } from '@blocksuite/store';
import type { PageMode } from '@toeverything/infra'; import type { PageMode } from '@toeverything/infra';
import clsx from 'clsx'; import clsx from 'clsx';
import type React from 'react'; import type React from 'react';
@@ -37,7 +37,7 @@ function forwardSlot<T extends Record<string, Slot<any>>>(
} }
interface BlocksuiteEditorContainerProps { interface BlocksuiteEditorContainerProps {
page: Page; page: Doc;
mode: PageMode; mode: PageMode;
className?: string; className?: string;
style?: React.CSSProperties; style?: React.CSSProperties;
@@ -48,7 +48,7 @@ interface BlocksuiteEditorContainerProps {
// mimic the interface of the webcomponent and expose slots & host // mimic the interface of the webcomponent and expose slots & host
type BlocksuiteEditorContainerRef = Pick< type BlocksuiteEditorContainerRef = Pick<
(typeof AffineEditorContainer)['prototype'], (typeof AffineEditorContainer)['prototype'],
'mode' | 'page' | 'slots' | 'host' 'mode' | 'doc' | 'slots' | 'host'
> & > &
HTMLDivElement; HTMLDivElement;
@@ -100,14 +100,14 @@ export const BlocksuiteEditorContainer = forwardRef<
ref ref
) { ) {
const rootRef = useRef<HTMLDivElement>(null); const rootRef = useRef<HTMLDivElement>(null);
const docRef = useRef<DocEditor>(null); const docRef = useRef<PageEditor>(null);
const edgelessRef = useRef<EdgelessEditor>(null); const edgelessRef = useRef<EdgelessEditor>(null);
const slots: BlocksuiteEditorContainerRef['slots'] = useMemo(() => { const slots: BlocksuiteEditorContainerRef['slots'] = useMemo(() => {
return { return {
pageLinkClicked: new Slot(), docLinkClicked: new Slot(),
pageModeSwitched: new Slot(), editorModeSwitched: new Slot(),
pageUpdated: new Slot(), docUpdated: new Slot(),
tagClicked: new Slot(), tagClicked: new Slot(),
}; };
}, []); }, []);
@@ -115,11 +115,10 @@ export const BlocksuiteEditorContainer = forwardRef<
// forward the slot to the webcomponent // forward the slot to the webcomponent
useLayoutEffect(() => { useLayoutEffect(() => {
requestAnimationFrame(() => { requestAnimationFrame(() => {
const docPage = rootRef.current?.querySelector('affine-doc-page'); const docPage = rootRef.current?.querySelector('affine-page-root');
const edgelessPage = rootRef.current?.querySelector( const edgelessPage = rootRef.current?.querySelector(
'affine-edgeless-page' 'affine-edgeless-root'
); );
('affine-edgeless-page');
if (docPage) { if (docPage) {
forwardSlot(docPage.slots, slots); forwardSlot(docPage.slots, slots);
} }
@@ -131,12 +130,12 @@ export const BlocksuiteEditorContainer = forwardRef<
}, [page, slots]); }, [page, slots]);
useLayoutEffect(() => { useLayoutEffect(() => {
slots.pageUpdated.emit({ newPageId: page.id }); slots.docUpdated.emit({ newDocId: page.id });
}, [page, slots.pageUpdated]); }, [page, slots.docUpdated]);
useLayoutEffect(() => { useLayoutEffect(() => {
slots.pageModeSwitched.emit(mode); slots.editorModeSwitched.emit(mode);
}, [mode, slots.pageModeSwitched]); }, [mode, slots.editorModeSwitched]);
/** /**
* mimic an AffineEditorContainer using proxy * mimic an AffineEditorContainer using proxy
@@ -1,10 +1,10 @@
import { EditorLoading } from '@affine/component/page-detail-skeleton'; import { EditorLoading } from '@affine/component/page-detail-skeleton';
import { usePageMetaHelper } from '@affine/core/hooks/use-block-suite-page-meta'; import { useDocMetaHelper } from '@affine/core/hooks/use-block-suite-page-meta';
import { useJournalHelper } from '@affine/core/hooks/use-journal'; import { useJournalHelper } from '@affine/core/hooks/use-journal';
import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { assertExists } from '@blocksuite/global/utils'; import { assertExists } from '@blocksuite/global/utils';
import type { AffineEditorContainer } from '@blocksuite/presets'; import type { AffineEditorContainer } from '@blocksuite/presets';
import type { Page } from '@blocksuite/store'; import type { Doc } from '@blocksuite/store';
import { use } from 'foxact/use'; import { use } from 'foxact/use';
import type { CSSProperties, ReactElement } from 'react'; import type { CSSProperties, ReactElement } from 'react';
import { import {
@@ -30,7 +30,7 @@ export type ErrorBoundaryProps = {
}; };
export type EditorProps = { export type EditorProps = {
page: Page; page: Doc;
mode: 'page' | 'edgeless'; mode: 'page' | 'edgeless';
defaultSelectedBlockId?: string; defaultSelectedBlockId?: string;
// on Editor instance instantiated // on Editor instance instantiated
@@ -39,7 +39,7 @@ export type EditorProps = {
className?: string; className?: string;
}; };
function usePageRoot(page: Page) { function usePageRoot(page: Doc) {
if (!page.ready) { if (!page.ready) {
page.load(); page.load();
} }
@@ -81,7 +81,7 @@ const customRenderersFactory: (
* TODO: Define error to unexpected state together in the future. * TODO: Define error to unexpected state together in the future.
*/ */
export class NoPageRootError extends Error { export class NoPageRootError extends Error {
constructor(public page: Page) { constructor(public page: Doc) {
super('Page root not found when render editor!'); super('Page root not found when render editor!');
// Log info to let sentry collect more message // Log info to let sentry collect more message
@@ -138,7 +138,7 @@ const BlockSuiteEditorImpl = forwardRef<AffineEditorContainer, EditorProps>(
}; };
}, []); }, []);
const pageMetaHelper = usePageMetaHelper(page.workspace); const pageMetaHelper = useDocMetaHelper(page.workspace);
const journalHelper = useJournalHelper(page.workspace); const journalHelper = useJournalHelper(page.workspace);
const t = useAFFiNEI18N(); const t = useAFFiNEI18N();
@@ -1,10 +1,10 @@
import { useJournalInfoHelper } from '@affine/core/hooks/use-journal'; import { useJournalInfoHelper } from '@affine/core/hooks/use-journal';
import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { useAFFiNEI18N } from '@affine/i18n/hooks';
import type { Page } from '@blocksuite/store'; import type { Doc } from '@blocksuite/store';
import * as styles from './styles.css'; import * as styles from './styles.css';
export const BlocksuiteEditorJournalDocTitle = ({ page }: { page: Page }) => { export const BlocksuiteEditorJournalDocTitle = ({ page }: { page: Doc }) => {
const { localizedJournalDate, isTodayJournal, journalDate } = const { localizedJournalDate, isTodayJournal, journalDate } =
useJournalInfoHelper(page.workspace, page.id); useJournalInfoHelper(page.workspace, page.id);
const t = useAFFiNEI18N(); const t = useAFFiNEI18N();
@@ -1,14 +1,13 @@
import { createReactComponentFromLit } from '@affine/component'; import { createReactComponentFromLit } from '@affine/component';
import { useJournalInfoHelper } from '@affine/core/hooks/use-journal'; import { useJournalInfoHelper } from '@affine/core/hooks/use-journal';
import type { DocPageService } from '@blocksuite/blocks';
import { import {
BiDirectionalLinkPanel, BiDirectionalLinkPanel,
DocEditor, DocMetaTags,
DocTitle, DocTitle,
EdgelessEditor, EdgelessEditor,
PageMetaTags, PageEditor,
} from '@blocksuite/presets'; } from '@blocksuite/presets';
import { type Page } from '@blocksuite/store'; import { type Doc } from '@blocksuite/store';
import clsx from 'clsx'; import clsx from 'clsx';
import React, { import React, {
forwardRef, forwardRef,
@@ -32,7 +31,7 @@ import * as styles from './styles.css';
const adapted = { const adapted = {
DocEditor: createReactComponentFromLit({ DocEditor: createReactComponentFromLit({
react: React, react: React,
elementClass: DocEditor, elementClass: PageEditor,
}), }),
DocTitle: createReactComponentFromLit({ DocTitle: createReactComponentFromLit({
react: React, react: React,
@@ -40,7 +39,7 @@ const adapted = {
}), }),
PageMetaTags: createReactComponentFromLit({ PageMetaTags: createReactComponentFromLit({
react: React, react: React,
elementClass: PageMetaTags, elementClass: DocMetaTags,
}), }),
EdgelessEditor: createReactComponentFromLit({ EdgelessEditor: createReactComponentFromLit({
react: React, react: React,
@@ -53,23 +52,23 @@ const adapted = {
}; };
interface BlocksuiteDocEditorProps { interface BlocksuiteDocEditorProps {
page: Page; page: Doc;
customRenderers?: InlineRenderers; customRenderers?: InlineRenderers;
// todo: add option to replace docTitle with custom component (e.g., for journal page) // todo: add option to replace docTitle with custom component (e.g., for journal page)
} }
export const BlocksuiteDocEditor = forwardRef< export const BlocksuiteDocEditor = forwardRef<
DocEditor, PageEditor,
BlocksuiteDocEditorProps BlocksuiteDocEditorProps
>(function BlocksuiteDocEditor({ page, customRenderers }, ref) { >(function BlocksuiteDocEditor({ page, customRenderers }, ref) {
const titleRef = useRef<DocTitle>(null); const titleRef = useRef<DocTitle>(null);
const docRef = useRef<DocEditor | null>(null); const docRef = useRef<PageEditor | null>(null);
const [docPage, setDocPage] = const [docPage, setDocPage] =
useState<HTMLElementTagNameMap['affine-doc-page']>(); useState<HTMLElementTagNameMap['affine-page-root']>();
const { isJournal } = useJournalInfoHelper(page.workspace, page.id); const { isJournal } = useJournalInfoHelper(page.workspace, page.id);
const onDocRef = useCallback( const onDocRef = useCallback(
(el: DocEditor) => { (el: PageEditor) => {
docRef.current = el; docRef.current = el;
if (ref) { if (ref) {
if (typeof ref === 'function') { if (typeof ref === 'function') {
@@ -89,7 +88,7 @@ export const BlocksuiteDocEditor = forwardRef<
useEffect(() => { useEffect(() => {
// auto focus the title // auto focus the title
setTimeout(() => { setTimeout(() => {
const docPage = docRef.current?.querySelector('affine-doc-page'); const docPage = docRef.current?.querySelector('affine-page-root');
if (docPage) { if (docPage) {
setDocPage(docPage); setDocPage(docPage);
} }
@@ -105,11 +104,11 @@ export const BlocksuiteDocEditor = forwardRef<
return ( return (
<div className={styles.docEditorRoot}> <div className={styles.docEditorRoot}>
<div <div
className={clsx('affine-doc-viewport', styles.affineDocViewport)} className={clsx('affine-page-viewport', styles.affineDocViewport)}
data-doc-viewport={true} data-doc-viewport={true}
> >
{!isJournal ? ( {!isJournal ? (
<adapted.DocTitle page={page} ref={titleRef} /> <adapted.DocTitle doc={page} ref={titleRef} />
) : ( ) : (
<BlocksuiteEditorJournalDocTitle page={page} /> <BlocksuiteEditorJournalDocTitle page={page} />
)} )}
@@ -117,7 +116,7 @@ export const BlocksuiteDocEditor = forwardRef<
<adapted.DocEditor <adapted.DocEditor
className={styles.docContainer} className={styles.docContainer}
ref={onDocRef} ref={onDocRef}
page={page} doc={page}
specs={specs} specs={specs}
hasViewport={false} hasViewport={false}
/> />
@@ -125,14 +124,12 @@ export const BlocksuiteDocEditor = forwardRef<
<div <div
className={styles.docEditorGap} className={styles.docEditorGap}
onClick={() => { onClick={() => {
( docPage.std.spec.getService('affine:page').appendParagraph();
docPage.std.spec.getService('affine:page') as DocPageService
).appendParagraph();
}} }}
></div> ></div>
) : null} ) : null}
{docPage ? ( {docPage ? (
<adapted.BiDirectionalLinkPanel page={page} docPageBlock={docPage} /> <adapted.BiDirectionalLinkPanel doc={page} pageRoot={docPage} />
) : null} ) : null}
</div> </div>
</div> </div>
@@ -146,5 +143,5 @@ export const BlocksuiteEdgelessEditor = forwardRef<
const specs = useMemo(() => { const specs = useMemo(() => {
return patchSpecs(edgelessModeSpecs, customRenderers); return patchSpecs(edgelessModeSpecs, customRenderers);
}, [customRenderers]); }, [customRenderers]);
return <adapted.EdgelessEditor ref={ref} page={page} specs={specs} />; return <adapted.EdgelessEditor ref={ref} doc={page} specs={specs} />;
}); });
@@ -1,12 +1,12 @@
import type { BlockSpec } from '@blocksuite/block-std'; import type { BlockSpec } from '@blocksuite/block-std';
import type { PageService, ParagraphService } from '@blocksuite/blocks'; import type { ParagraphService, RootService } from '@blocksuite/blocks';
import { import {
AttachmentService, AttachmentService,
CanvasTextFonts, CanvasTextFonts,
DocEditorBlockSpecs,
DocPageService,
EdgelessEditorBlockSpecs, EdgelessEditorBlockSpecs,
EdgelessPageService, EdgelessRootService,
PageEditorBlockSpecs,
PageRootService,
} from '@blocksuite/blocks'; } from '@blocksuite/blocks';
import bytes from 'bytes'; import bytes from 'bytes';
import { html, unsafeStatic } from 'lit/static-html.js'; import { html, unsafeStatic } from 'lit/static-html.js';
@@ -20,7 +20,7 @@ class CustomAttachmentService extends AttachmentService {
} }
} }
function customLoadFonts(service: PageService): void { function customLoadFonts(service: RootService): void {
const officialDomains = new Set(['app.affine.pro', 'affine.fail']); const officialDomains = new Set(['app.affine.pro', 'affine.fail']);
if (!officialDomains.has(window.location.host)) { if (!officialDomains.has(window.location.host)) {
const fonts = CanvasTextFonts.map(font => ({ const fonts = CanvasTextFonts.map(font => ({
@@ -34,12 +34,12 @@ function customLoadFonts(service: PageService): void {
} }
} }
class CustomDocPageService extends DocPageService { class CustomDocPageService extends PageRootService {
override loadFonts(): void { override loadFonts(): void {
customLoadFonts(this); customLoadFonts(this);
} }
} }
class CustomEdgelessPageService extends EdgelessPageService { class CustomEdgelessPageService extends EdgelessRootService {
override loadFonts(): void { override loadFonts(): void {
customLoadFonts(this); customLoadFonts(this);
} }
@@ -97,7 +97,7 @@ export function patchSpecs(
return newSpecs; return newSpecs;
} }
export const docModeSpecs = DocEditorBlockSpecs.map(spec => { export const docModeSpecs = PageEditorBlockSpecs.map(spec => {
if (spec.schema.model.flavour === 'affine:attachment') { if (spec.schema.model.flavour === 'affine:attachment') {
return { return {
...spec, ...spec,
@@ -5,7 +5,7 @@ export const docEditorRoot = style({
background: cssVar('backgroundPrimaryColor'), background: cssVar('backgroundPrimaryColor'),
}); });
// brings styles of .affine-doc-viewport from blocksuite // brings styles of .affine-page-viewport from blocksuite
export const affineDocViewport = style({ export const affineDocViewport = style({
display: 'flex', display: 'flex',
flexDirection: 'column', flexDirection: 'column',
@@ -1,6 +1,6 @@
import { FavoriteTag } from '@affine/core/components/page-list'; import { FavoriteTag } from '@affine/core/components/page-list';
import { useBlockSuiteMetaHelper } from '@affine/core/hooks/affine/use-block-suite-meta-helper'; import { useBlockSuiteMetaHelper } from '@affine/core/hooks/affine/use-block-suite-meta-helper';
import { useBlockSuitePageMeta } from '@affine/core/hooks/use-block-suite-page-meta'; import { useBlockSuiteDocMeta } from '@affine/core/hooks/use-block-suite-page-meta';
import { toast } from '@affine/core/utils'; import { toast } from '@affine/core/utils';
import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { assertExists } from '@blocksuite/global/utils'; import { assertExists } from '@blocksuite/global/utils';
@@ -16,10 +16,10 @@ export const useFavorite = (pageId: string) => {
const t = useAFFiNEI18N(); const t = useAFFiNEI18N();
const workspace = useService(Workspace); const workspace = useService(Workspace);
const blockSuiteWorkspace = workspace.blockSuiteWorkspace; const blockSuiteWorkspace = workspace.blockSuiteWorkspace;
const currentPage = blockSuiteWorkspace.getPage(pageId); const currentPage = blockSuiteWorkspace.getDoc(pageId);
assertExists(currentPage); assertExists(currentPage);
const pageMeta = useBlockSuitePageMeta(blockSuiteWorkspace).find( const pageMeta = useBlockSuiteDocMeta(blockSuiteWorkspace).find(
meta => meta.id === pageId meta => meta.id === pageId
); );
const favorite = pageMeta?.favorite ?? false; const favorite = pageMeta?.favorite ?? false;
@@ -4,13 +4,13 @@ import {
useJournalRouteHelper, useJournalRouteHelper,
} from '@affine/core/hooks/use-journal'; } from '@affine/core/hooks/use-journal';
import type { BlockSuiteWorkspace } from '@affine/core/shared'; import type { BlockSuiteWorkspace } from '@affine/core/shared';
import type { Page } from '@blocksuite/store'; import type { Doc } from '@blocksuite/store';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import { useEffect, useRef, useState } from 'react'; import { useEffect, useRef, useState } from 'react';
export interface JournalWeekDatePickerProps { export interface JournalWeekDatePickerProps {
workspace: BlockSuiteWorkspace; workspace: BlockSuiteWorkspace;
page: Page; page: Doc;
} }
const weekStyle = { maxWidth: 800, width: '100%' }; const weekStyle = { maxWidth: 800, width: '100%' };
@@ -11,7 +11,7 @@ import { Export, MoveToTrash } from '@affine/core/components/page-list';
import { useBlockSuiteMetaHelper } from '@affine/core/hooks/affine/use-block-suite-meta-helper'; import { useBlockSuiteMetaHelper } from '@affine/core/hooks/affine/use-block-suite-meta-helper';
import { useExportPage } from '@affine/core/hooks/affine/use-export-page'; import { useExportPage } from '@affine/core/hooks/affine/use-export-page';
import { useTrashModalHelper } from '@affine/core/hooks/affine/use-trash-modal-helper'; import { useTrashModalHelper } from '@affine/core/hooks/affine/use-trash-modal-helper';
import { useBlockSuitePageMeta } from '@affine/core/hooks/use-block-suite-page-meta'; import { useBlockSuiteDocMeta } from '@affine/core/hooks/use-block-suite-page-meta';
import { WorkspaceFlavour } from '@affine/env/workspace'; import { WorkspaceFlavour } from '@affine/env/workspace';
import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { assertExists } from '@blocksuite/global/utils'; import { assertExists } from '@blocksuite/global/utils';
@@ -25,7 +25,7 @@ import {
ImportIcon, ImportIcon,
PageIcon, PageIcon,
} from '@blocksuite/icons'; } from '@blocksuite/icons';
import { Page, useLiveData, useService, Workspace } from '@toeverything/infra'; import { Doc, useLiveData, useService, Workspace } from '@toeverything/infra';
import { useSetAtom } from 'jotai'; import { useSetAtom } from 'jotai';
import { useCallback, useState } from 'react'; import { useCallback, useState } from 'react';
@@ -48,13 +48,13 @@ export const PageHeaderMenuButton = ({
const workspace = useService(Workspace); const workspace = useService(Workspace);
const blockSuiteWorkspace = workspace.blockSuiteWorkspace; const blockSuiteWorkspace = workspace.blockSuiteWorkspace;
const currentPage = blockSuiteWorkspace.getPage(pageId); const currentPage = blockSuiteWorkspace.getDoc(pageId);
assertExists(currentPage); assertExists(currentPage);
const pageMeta = useBlockSuitePageMeta(blockSuiteWorkspace).find( const pageMeta = useBlockSuiteDocMeta(blockSuiteWorkspace).find(
meta => meta.id === pageId meta => meta.id === pageId
); );
const page = useService(Page); const page = useService(Doc);
const currentMode = useLiveData(page.mode); const currentMode = useLiveData(page.mode);
const { favorite, toggleFavorite } = useFavorite(pageId); const { favorite, toggleFavorite } = useFavorite(pageId);
@@ -1,7 +1,7 @@
import { InlineEdit, type InlineEditProps } from '@affine/component'; import { InlineEdit, type InlineEditProps } from '@affine/component';
import { import {
useBlockSuitePageMeta, useBlockSuiteDocMeta,
usePageMetaHelper, useDocMetaHelper,
} from '@affine/core/hooks/use-block-suite-page-meta'; } from '@affine/core/hooks/use-block-suite-page-meta';
import type { BlockSuiteWorkspace } from '@affine/core/shared'; import type { BlockSuiteWorkspace } from '@affine/core/shared';
import type { HTMLAttributes } from 'react'; import type { HTMLAttributes } from 'react';
@@ -27,18 +27,18 @@ export const BlocksuiteHeaderTitle = (props: BlockSuiteHeaderTitleProps) => {
isPublic, isPublic,
inputHandleRef, inputHandleRef,
} = props; } = props;
const currentPage = workspace.getPage(pageId); const currentPage = workspace.getDoc(pageId);
const pageMeta = useBlockSuitePageMeta(workspace).find( const pageMeta = useBlockSuiteDocMeta(workspace).find(
meta => meta.id === currentPage?.id meta => meta.id === currentPage?.id
); );
const title = pageMeta?.title; const title = pageMeta?.title;
const { setPageTitle } = usePageMetaHelper(workspace); const { setDocTitle } = useDocMetaHelper(workspace);
const onChange = useCallback( const onChange = useCallback(
(v: string) => { (v: string) => {
setPageTitle(currentPage?.id || '', v); setDocTitle(currentPage?.id || '', v);
}, },
[currentPage?.id, setPageTitle] [currentPage?.id, setDocTitle]
); );
return ( return (
@@ -1,8 +1,8 @@
import { Tooltip } from '@affine/component/ui/tooltip'; import { Tooltip } from '@affine/component/ui/tooltip';
import { useBlockSuitePageMeta } from '@affine/core/hooks/use-block-suite-page-meta'; import { useBlockSuiteDocMeta } from '@affine/core/hooks/use-block-suite-page-meta';
import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { import {
Page, Doc,
type PageMode, type PageMode,
useLiveData, useLiveData,
useService, useService,
@@ -42,11 +42,11 @@ export const EditorModeSwitch = ({
publicMode, publicMode,
}: EditorModeSwitchProps) => { }: EditorModeSwitchProps) => {
const t = useAFFiNEI18N(); const t = useAFFiNEI18N();
const pageMeta = useBlockSuitePageMeta(blockSuiteWorkspace).find( const pageMeta = useBlockSuiteDocMeta(blockSuiteWorkspace).find(
meta => meta.id === pageId meta => meta.id === pageId
); );
const trash = pageMeta?.trash ?? false; const trash = pageMeta?.trash ?? false;
const page = useService(Page); const page = useService(Doc);
const currentMode = useLiveData(page.mode); const currentMode = useLiveData(page.mode);
@@ -1,6 +1,6 @@
import { toast } from '@affine/component'; import { toast } from '@affine/component';
import { useAsyncCallback } from '@affine/core/hooks/affine-async-hooks'; import { useAsyncCallback } from '@affine/core/hooks/affine-async-hooks';
import { usePageMetaHelper } from '@affine/core/hooks/use-block-suite-page-meta'; import { useDocMetaHelper } from '@affine/core/hooks/use-block-suite-page-meta';
import { useBlockSuiteWorkspaceHelper } from '@affine/core/hooks/use-block-suite-workspace-helper'; import { useBlockSuiteWorkspaceHelper } from '@affine/core/hooks/use-block-suite-workspace-helper';
import { WorkspaceSubPath } from '@affine/core/shared'; import { WorkspaceSubPath } from '@affine/core/shared';
import { useService } from '@toeverything/infra'; import { useService } from '@toeverything/infra';
@@ -13,8 +13,8 @@ import type { BlockSuiteWorkspace } from '../../../shared';
export const usePageHelper = (blockSuiteWorkspace: BlockSuiteWorkspace) => { export const usePageHelper = (blockSuiteWorkspace: BlockSuiteWorkspace) => {
const { openPage, jumpToSubPath } = useNavigateHelper(); const { openPage, jumpToSubPath } = useNavigateHelper();
const { createPage } = useBlockSuiteWorkspaceHelper(blockSuiteWorkspace); const { createDoc } = useBlockSuiteWorkspaceHelper(blockSuiteWorkspace);
const { setPageMeta } = usePageMetaHelper(blockSuiteWorkspace); const { setDocMeta } = useDocMetaHelper(blockSuiteWorkspace);
const pageRecordList = useService(PageRecordList); const pageRecordList = useService(PageRecordList);
const isPreferredEdgeless = useCallback( const isPreferredEdgeless = useCallback(
@@ -25,13 +25,13 @@ export const usePageHelper = (blockSuiteWorkspace: BlockSuiteWorkspace) => {
const createPageAndOpen = useCallback( const createPageAndOpen = useCallback(
(mode?: 'page' | 'edgeless') => { (mode?: 'page' | 'edgeless') => {
const page = createPage(); const page = createDoc();
initEmptyPage(page); initEmptyPage(page);
pageRecordList.record(page.id).value?.setMode(mode || 'page'); pageRecordList.record(page.id).value?.setMode(mode || 'page');
openPage(blockSuiteWorkspace.id, page.id); openPage(blockSuiteWorkspace.id, page.id);
return page; return page;
}, },
[blockSuiteWorkspace.id, createPage, openPage, pageRecordList] [blockSuiteWorkspace.id, createDoc, openPage, pageRecordList]
); );
const createEdgelessAndOpen = useCallback(() => { const createEdgelessAndOpen = useCallback(() => {
@@ -64,7 +64,7 @@ export const usePageHelper = (blockSuiteWorkspace: BlockSuiteWorkspace) => {
async (pageId: string) => { async (pageId: string) => {
const page = createPageAndOpen(); const page = createPageAndOpen();
page.load(); page.load();
const parentPage = blockSuiteWorkspace.getPage(pageId); const parentPage = blockSuiteWorkspace.getDoc(pageId);
if (parentPage) { if (parentPage) {
parentPage.load(); parentPage.load();
const text = parentPage.Text.fromDelta([ const text = parentPage.Text.fromDelta([
@@ -80,10 +80,10 @@ export const usePageHelper = (blockSuiteWorkspace: BlockSuiteWorkspace) => {
]); ]);
const [frame] = parentPage.getBlockByFlavour('affine:note'); const [frame] = parentPage.getBlockByFlavour('affine:note');
frame && parentPage.addBlock('affine:paragraph', { text }, frame.id); frame && parentPage.addBlock('affine:paragraph', { text }, frame.id);
setPageMeta(page.id, {}); setDocMeta(page.id, {});
} }
}, },
[blockSuiteWorkspace, createPageAndOpen, setPageMeta] [blockSuiteWorkspace, createPageAndOpen, setDocMeta]
); );
return useMemo(() => { return useMemo(() => {
@@ -1,7 +1,7 @@
import { Button } from '@affine/component/ui/button'; import { Button } from '@affine/component/ui/button';
import { useActiveBlocksuiteEditor } from '@affine/core/hooks/use-block-suite-editor'; import { useActiveBlocksuiteEditor } from '@affine/core/hooks/use-block-suite-editor';
import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { useAFFiNEI18N } from '@affine/i18n/hooks';
import type { EdgelessPageService } from '@blocksuite/blocks'; import type { EdgelessRootService } from '@blocksuite/blocks';
import { PresentationIcon } from '@blocksuite/icons'; import { PresentationIcon } from '@blocksuite/icons';
import { useCallback, useEffect, useState } from 'react'; import { useCallback, useEffect, useState } from 'react';
@@ -18,18 +18,18 @@ export const PresentButton = () => {
// TODO: use surfaceService subAtom // TODO: use surfaceService subAtom
const enterPresentationMode = () => { const enterPresentationMode = () => {
const edgelessPageService = editorHost.spec.getService( const edgelessRootService = editorHost.spec.getService(
'affine:page' 'affine:page'
) as EdgelessPageService; ) as EdgelessRootService;
if ( if (
!edgelessPageService || !edgelessRootService ||
edgelessPageService.tool.edgelessTool.type === 'frameNavigator' edgelessRootService.tool.edgelessTool.type === 'frameNavigator'
) { ) {
return; return;
} }
edgelessPageService.tool.setEdgelessTool({ type: 'frameNavigator' }); edgelessRootService.tool.setEdgelessTool({ type: 'frameNavigator' });
}; };
enterPresentationMode(); enterPresentationMode();
@@ -42,7 +42,7 @@ export const PresentButton = () => {
const editorHost = editor?.host; const editorHost = editor?.host;
if (!editorHost) return; if (!editorHost) return;
const edgelessPage = editorHost?.querySelector('affine-edgeless-page'); const edgelessPage = editorHost?.querySelector('affine-edgeless-root');
if (!edgelessPage) return; if (!edgelessPage) return;
edgelessPage.slots.edgelessToolUpdated.on(() => { edgelessPage.slots.edgelessToolUpdated.on(() => {
@@ -96,7 +96,7 @@ const ImagePreviewModalImpl = (
if (!hasPlayedAnimation) { if (!hasPlayedAnimation) {
setHasPlayedAnimation(true); setHasPlayedAnimation(true);
} }
const page = workspace.getPage(props.pageId); const page = workspace.getDoc(props.pageId);
assertExists(page); assertExists(page);
const block = page.getBlockById(blockId); const block = page.getBlockById(blockId);
assertExists(block); assertExists(block);
@@ -116,7 +116,7 @@ const ImagePreviewModalImpl = (
(blockId: string | null) => { (blockId: string | null) => {
assertExists(blockId); assertExists(blockId);
const workspace = props.workspace; const workspace = props.workspace;
const page = workspace.getPage(props.pageId); const page = workspace.getDoc(props.pageId);
assertExists(page); assertExists(page);
const block = page.getBlockById(blockId); const block = page.getBlockById(blockId);
assertExists(block); assertExists(block);
@@ -137,7 +137,7 @@ const ImagePreviewModalImpl = (
(blockId: string) => { (blockId: string) => {
const { pageId, workspace, onClose } = props; const { pageId, workspace, onClose } = props;
const page = workspace.getPage(pageId); const page = workspace.getDoc(pageId);
assertExists(page); assertExists(page);
const block = page.getBlockById(blockId); const block = page.getBlockById(blockId);
assertExists(block); assertExists(block);
@@ -186,7 +186,7 @@ const ImagePreviewModalImpl = (
const downloadHandler = useCallback( const downloadHandler = useCallback(
async (blockId: string | null) => { async (blockId: string | null) => {
const workspace = props.workspace; const workspace = props.workspace;
const page = workspace.getPage(props.pageId); const page = workspace.getDoc(props.pageId);
assertExists(page); assertExists(page);
if (typeof blockId === 'string') { if (typeof blockId === 'string') {
const block = page.getBlockById(blockId) as ImageBlockModel; const block = page.getBlockById(blockId) as ImageBlockModel;
@@ -240,14 +240,14 @@ const ImagePreviewModalImpl = (
[props.pageId, props.workspace] [props.pageId, props.workspace]
); );
const [caption, setCaption] = useState(() => { const [caption, setCaption] = useState(() => {
const page = props.workspace.getPage(props.pageId); const page = props.workspace.getDoc(props.pageId);
assertExists(page); assertExists(page);
const block = page.getBlockById(props.blockId) as ImageBlockModel; const block = page.getBlockById(props.blockId) as ImageBlockModel;
assertExists(block); assertExists(block);
return block?.caption; return block?.caption;
}); });
useEffect(() => { useEffect(() => {
const page = props.workspace.getPage(props.pageId); const page = props.workspace.getDoc(props.pageId);
assertExists(page); assertExists(page);
const block = page.getBlockById(props.blockId) as ImageBlockModel; const block = page.getBlockById(props.blockId) as ImageBlockModel;
assertExists(block); assertExists(block);
@@ -257,7 +257,7 @@ const ImagePreviewModalImpl = (
['workspace', 'image', props.pageId, props.blockId], ['workspace', 'image', props.pageId, props.blockId],
{ {
fetcher: ([_, __, pageId, blockId]) => { fetcher: ([_, __, pageId, blockId]) => {
const page = props.workspace.getPage(pageId); const page = props.workspace.getDoc(pageId);
assertExists(page); assertExists(page);
const block = page.getBlockById(blockId) as ImageBlockModel; const block = page.getBlockById(blockId) as ImageBlockModel;
assertExists(block); assertExists(block);
@@ -510,7 +510,7 @@ export const ImagePreviewModal = (
const workspace = props.workspace; const workspace = props.workspace;
const page = workspace.getPage(props.pageId); const page = workspace.getDoc(props.pageId);
assertExists(page); assertExists(page);
const block = page.getBlockById(blockId); const block = page.getBlockById(blockId);
assertExists(block); assertExists(block);
@@ -11,7 +11,7 @@ export const editor = style({
}, },
}); });
globalStyle( globalStyle(
`${editor} .affine-doc-viewport:not(.affine-embed-synced-doc-editor)`, `${editor} .affine-page-viewport:not(.affine-embed-synced-doc-editor)`,
{ {
paddingBottom: '150px', paddingBottom: '150px',
} }
@@ -5,9 +5,9 @@ import { useBlockSuiteWorkspacePage } from '@affine/core/hooks/use-block-suite-w
import { assertExists, DisposableGroup } from '@blocksuite/global/utils'; import { assertExists, DisposableGroup } from '@blocksuite/global/utils';
import type { AffineEditorContainer } from '@blocksuite/presets'; import type { AffineEditorContainer } from '@blocksuite/presets';
import type { Workspace } from '@blocksuite/store'; import type { Workspace } from '@blocksuite/store';
import type { Page as BlockSuitePage } from '@blocksuite/store'; import type { Doc as BlockSuiteDoc } from '@blocksuite/store';
import { import {
Page, Doc,
type PageMode, type PageMode,
useLiveData, useLiveData,
useService, useService,
@@ -28,7 +28,7 @@ declare global {
} }
export type OnLoadEditor = ( export type OnLoadEditor = (
page: BlockSuitePage, page: BlockSuiteDoc,
editor: AffineEditorContainer editor: AffineEditorContainer
) => () => void; ) => () => void;
@@ -49,8 +49,8 @@ const PageDetailEditorMain = memo(function PageDetailEditorMain({
onLoad, onLoad,
isPublic, isPublic,
publishMode, publishMode,
}: PageDetailEditorProps & { page: BlockSuitePage }) { }: PageDetailEditorProps & { page: BlockSuiteDoc }) {
const currentMode = useLiveData(useService(Page).mode); const currentMode = useLiveData(useService(Doc).mode);
const mode = useMemo(() => { const mode = useMemo(() => {
const shareMode = publishMode || currentMode; const shareMode = publishMode || currentMode;
@@ -81,7 +81,7 @@ const PageDetailEditorMain = memo(function PageDetailEditorMain({
const disposableGroup = new DisposableGroup(); const disposableGroup = new DisposableGroup();
disposableGroup.add( disposableGroup.add(
page.slots.blockUpdated.once(() => { page.slots.blockUpdated.once(() => {
page.workspace.setPageMeta(page.id, { page.workspace.setDocMeta(page.id, {
updatedDate: Date.now(), updatedDate: Date.now(),
}); });
}) })
@@ -5,7 +5,7 @@ import 'fake-indexeddb/auto';
import { __unstableSchemas, AffineSchemas } from '@blocksuite/blocks/models'; import { __unstableSchemas, AffineSchemas } from '@blocksuite/blocks/models';
import { assertExists } from '@blocksuite/global/utils'; import { assertExists } from '@blocksuite/global/utils';
import type { Page } from '@blocksuite/store'; import type { Doc } from '@blocksuite/store';
import { Schema, Workspace as BlockSuiteWorkspace } from '@blocksuite/store'; import { Schema, Workspace as BlockSuiteWorkspace } from '@blocksuite/store';
import { renderHook } from '@testing-library/react'; import { renderHook } from '@testing-library/react';
import { useAtomValue } from 'jotai'; import { useAtomValue } from 'jotai';
@@ -21,8 +21,8 @@ schema.register(AffineSchemas).register(__unstableSchemas);
beforeEach(async () => { beforeEach(async () => {
vi.useFakeTimers({ toFake: ['requestIdleCallback'] }); vi.useFakeTimers({ toFake: ['requestIdleCallback'] });
blockSuiteWorkspace = new BlockSuiteWorkspace({ id: 'test', schema }); blockSuiteWorkspace = new BlockSuiteWorkspace({ id: 'test', schema });
const initPage = async (page: Page) => { const initPage = async (page: Doc) => {
page.waitForLoaded(); page.load();
expect(page).not.toBeNull(); expect(page).not.toBeNull();
assertExists(page); assertExists(page);
const pageBlockId = page.addBlock('affine:page', { const pageBlockId = page.addBlock('affine:page', {
@@ -31,12 +31,12 @@ beforeEach(async () => {
const frameId = page.addBlock('affine:note', {}, pageBlockId); const frameId = page.addBlock('affine:note', {}, pageBlockId);
page.addBlock('affine:paragraph', {}, frameId); page.addBlock('affine:paragraph', {}, frameId);
}; };
await initPage(blockSuiteWorkspace.createPage({ id: 'page0' })); await initPage(blockSuiteWorkspace.createDoc({ id: 'page0' }));
}); });
describe('useBlockSuitePagePreview', () => { describe('useBlockSuitePagePreview', () => {
test('basic', async () => { test('basic', async () => {
const page = blockSuiteWorkspace.getPage('page0') as Page; const page = blockSuiteWorkspace.getDoc('page0') as Doc;
const id = page.addBlock( const id = page.addBlock(
'affine:paragraph', 'affine:paragraph',
{ {
@@ -1,11 +1,11 @@
import { toast } from '@affine/component'; import { toast } from '@affine/component';
import { useBlockSuiteMetaHelper } from '@affine/core/hooks/affine/use-block-suite-meta-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 { useTrashModalHelper } from '@affine/core/hooks/affine/use-trash-modal-helper';
import { useBlockSuitePageMeta } from '@affine/core/hooks/use-block-suite-page-meta'; import { useBlockSuiteDocMeta } from '@affine/core/hooks/use-block-suite-page-meta';
import type { Collection, Filter } from '@affine/env/filter'; import type { Collection, Filter } from '@affine/env/filter';
import { Trans } from '@affine/i18n'; import { Trans } from '@affine/i18n';
import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { useAFFiNEI18N } from '@affine/i18n/hooks';
import type { PageMeta, Tag } from '@blocksuite/store'; import type { DocMeta, Tag } from '@blocksuite/store';
import { useService } from '@toeverything/infra'; import { useService } from '@toeverything/infra';
import { Workspace } from '@toeverything/infra'; import { Workspace } from '@toeverything/infra';
import { useCallback, useMemo, useRef, useState } from 'react'; import { useCallback, useMemo, useRef, useState } from 'react';
@@ -37,7 +37,7 @@ const usePageOperationsRenderer = () => {
const t = useAFFiNEI18N(); const t = useAFFiNEI18N();
const pageOperationsRenderer = useCallback( const pageOperationsRenderer = useCallback(
(page: PageMeta) => { (page: DocMeta) => {
const onDisablePublicSharing = () => { const onDisablePublicSharing = () => {
toast('Successfully disabled', { toast('Successfully disabled', {
portal: document.body, portal: document.body,
@@ -90,14 +90,14 @@ export const VirtualizedPageList = ({
collection?: Collection; collection?: Collection;
filters?: Filter[]; filters?: Filter[];
config?: AllPageListConfig; config?: AllPageListConfig;
listItem?: PageMeta[]; listItem?: DocMeta[];
setHideHeaderCreateNewPage?: (hide: boolean) => void; setHideHeaderCreateNewPage?: (hide: boolean) => void;
}) => { }) => {
const listRef = useRef<ItemListHandle>(null); const listRef = useRef<ItemListHandle>(null);
const [showFloatingToolbar, setShowFloatingToolbar] = useState(false); const [showFloatingToolbar, setShowFloatingToolbar] = useState(false);
const [selectedPageIds, setSelectedPageIds] = useState<string[]>([]); const [selectedPageIds, setSelectedPageIds] = useState<string[]>([]);
const currentWorkspace = useService(Workspace); const currentWorkspace = useService(Workspace);
const pageMetas = useBlockSuitePageMeta(currentWorkspace.blockSuiteWorkspace); const pageMetas = useBlockSuiteDocMeta(currentWorkspace.blockSuiteWorkspace);
const pageOperations = usePageOperationsRenderer(); const pageOperations = usePageOperationsRenderer();
const { isPreferredEdgeless } = usePageHelper( const { isPreferredEdgeless } = usePageHelper(
currentWorkspace.blockSuiteWorkspace currentWorkspace.blockSuiteWorkspace
@@ -125,7 +125,7 @@ export const VirtualizedPageList = ({
const pageOperationRenderer = useCallback( const pageOperationRenderer = useCallback(
(item: ListItem) => { (item: ListItem) => {
const page = item as PageMeta; const page = item as DocMeta;
return pageOperations(page); return pageOperations(page);
}, },
[pageOperations] [pageOperations]
@@ -10,7 +10,7 @@ import {
ToggleCollapseIcon, ToggleCollapseIcon,
ViewLayersIcon, ViewLayersIcon,
} from '@blocksuite/icons'; } from '@blocksuite/icons';
import type { PageMeta, Workspace } from '@blocksuite/store'; import type { DocMeta, Workspace } from '@blocksuite/store';
import * as Collapsible from '@radix-ui/react-collapsible'; import * as Collapsible from '@radix-ui/react-collapsible';
import clsx from 'clsx'; import clsx from 'clsx';
import { selectAtom } from 'jotai/utils'; import { selectAtom } from 'jotai/utils';
@@ -223,7 +223,7 @@ const listsPropsAtom = selectAtom(
export const PageListItemRenderer = (item: ListItem) => { export const PageListItemRenderer = (item: ListItem) => {
const props = useAtomValue(listsPropsAtom); const props = useAtomValue(listsPropsAtom);
const { selectionActive } = useAtomValue(selectionStateAtom); const { selectionActive } = useAtomValue(selectionStateAtom);
const page = item as PageMeta; const page = item as DocMeta;
return ( return (
<PageListItem <PageListItem
{...pageMetaToListItemProp(page, { {...pageMetaToListItemProp(page, {
@@ -294,8 +294,8 @@ const UnifiedPageIcon = ({
}; };
function pageMetaToListItemProp( function pageMetaToListItemProp(
item: PageMeta, item: DocMeta,
props: RequiredProps<PageMeta> props: RequiredProps<DocMeta>
): PageListItemProps { ): PageListItemProps {
const toggleSelection = props.onSelectedIdsChange const toggleSelection = props.onSelectedIdsChange
? () => { ? () => {
@@ -1,9 +1,9 @@
import type { Collection, Tag } from '@affine/env/filter'; import type { Collection, Tag } from '@affine/env/filter';
import type { PageMeta, Workspace } from '@blocksuite/store'; import type { DocMeta, Workspace } from '@blocksuite/store';
import type { PropsWithChildren, ReactNode } from 'react'; import type { PropsWithChildren, ReactNode } from 'react';
import type { To } from 'react-router-dom'; import type { To } from 'react-router-dom';
export type ListItem = PageMeta | CollectionMeta | TagMeta; export type ListItem = DocMeta | CollectionMeta | TagMeta;
export interface CollectionMeta extends Collection { export interface CollectionMeta extends Collection {
title: string; title: string;
@@ -1,13 +1,13 @@
import type { Page } from '@blocksuite/store'; import type { Doc } from '@blocksuite/store';
import type { Atom } from 'jotai'; import type { Atom } from 'jotai';
import { atom } from 'jotai'; import { atom } from 'jotai';
const MAX_PREVIEW_LENGTH = 150; const MAX_PREVIEW_LENGTH = 150;
const MAX_SEARCH_BLOCK_COUNT = 30; const MAX_SEARCH_BLOCK_COUNT = 30;
const weakMap = new WeakMap<Page, Atom<string>>(); const weakMap = new WeakMap<Doc, Atom<string>>();
export const getPagePreviewText = (page: Page) => { export const getPagePreviewText = (page: Doc) => {
const pageRoot = page.root; const pageRoot = page.root;
if (!pageRoot) { if (!pageRoot) {
return ''; return '';
@@ -56,7 +56,7 @@ export const getPagePreviewText = (page: Page) => {
const emptyAtom = atom<string>(''); const emptyAtom = atom<string>('');
export function useBlockSuitePagePreview(page: Page | null): Atom<string> { export function useBlockSuitePagePreview(page: Doc | null): Atom<string> {
if (page === null) { if (page === null) {
return emptyAtom; return emptyAtom;
} else if (weakMap.has(page)) { } else if (weakMap.has(page)) {
@@ -1,26 +1,26 @@
import { DisposableGroup } from '@blocksuite/global/utils'; import { DisposableGroup } from '@blocksuite/global/utils';
import type { Page, Workspace } from '@blocksuite/store'; import type { Doc, Workspace } from '@blocksuite/store';
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
export function useBlockSuiteWorkspacePage( export function useBlockSuiteWorkspacePage(
blockSuiteWorkspace: Workspace, blockSuiteWorkspace: Workspace,
pageId: string | null pageId: string | null
): Page | null { ): Doc | null {
const [page, setPage] = useState( const [page, setPage] = useState(
pageId ? blockSuiteWorkspace.getPage(pageId) : null pageId ? blockSuiteWorkspace.getDoc(pageId) : null
); );
useEffect(() => { useEffect(() => {
const group = new DisposableGroup(); const group = new DisposableGroup();
group.add( group.add(
blockSuiteWorkspace.slots.pageAdded.on(id => { blockSuiteWorkspace.slots.docAdded.on(id => {
if (pageId === id) { if (pageId === id) {
setPage(blockSuiteWorkspace.getPage(id)); setPage(blockSuiteWorkspace.getDoc(id));
} }
}) })
); );
group.add( group.add(
blockSuiteWorkspace.slots.pageRemoved.on(id => { blockSuiteWorkspace.slots.docRemoved.on(id => {
if (pageId === id) { if (pageId === id) {
setPage(null); setPage(null);
} }
@@ -39,7 +39,7 @@ export function useBlockSuiteWorkspacePage(
useEffect(() => { useEffect(() => {
if (page?.id !== pageId) { if (page?.id !== pageId) {
setPage(pageId ? blockSuiteWorkspace.getPage(pageId) : null); setPage(pageId ? blockSuiteWorkspace.getDoc(pageId) : null);
} }
}, [blockSuiteWorkspace, page?.id, pageId]); }, [blockSuiteWorkspace, page?.id, pageId]);
@@ -1,5 +1,5 @@
import type { Collection, Filter, VariableMap } from '@affine/env/filter'; import type { Collection, Filter, VariableMap } from '@affine/env/filter';
import type { PageMeta } from '@blocksuite/store'; import type { DocMeta } from '@blocksuite/store';
import { evalFilterList } from './filter'; import { evalFilterList } from './filter';
@@ -20,7 +20,7 @@ export const filterByFilterList = (filterList: Filter[], varMap: VariableMap) =>
evalFilterList(filterList, varMap); evalFilterList(filterList, varMap);
export type PageDataForFilter = { export type PageDataForFilter = {
meta: PageMeta; meta: DocMeta;
publicMode: undefined | 'page' | 'edgeless'; publicMode: undefined | 'page' | 'edgeless';
}; };
@@ -1,5 +1,5 @@
import type { Collection, Filter } from '@affine/env/filter'; import type { Collection, Filter } from '@affine/env/filter';
import type { PageMeta } from '@blocksuite/store'; import type { DocMeta } from '@blocksuite/store';
import type { Workspace } from '@toeverything/infra'; import type { Workspace } from '@toeverything/infra';
import { useMemo } from 'react'; import { useMemo } from 'react';
@@ -8,7 +8,7 @@ import { filterPage, filterPageByRules } from './use-collection-manager';
export const useFilteredPageMetas = ( export const useFilteredPageMetas = (
workspace: Workspace, workspace: Workspace,
pageMetas: PageMeta[], pageMetas: DocMeta[],
options: { options: {
trash?: boolean; trash?: boolean;
filters?: Filter[]; filters?: Filter[];
@@ -1,14 +1,11 @@
import type { PageMeta, Tag, Workspace } from '@blocksuite/store'; import type { DocMeta, Tag, Workspace } from '@blocksuite/store';
import { useCallback, useMemo } from 'react'; import { useCallback, useMemo } from 'react';
interface TagUsageCounts { interface TagUsageCounts {
[key: string]: number; [key: string]: number;
} }
export function useTagMetas( export function useTagMetas(currentWorkspace: Workspace, pageMetas: DocMeta[]) {
currentWorkspace: Workspace,
pageMetas: PageMeta[]
) {
const tags = useMemo(() => { const tags = useMemo(() => {
return currentWorkspace.meta.properties.tags?.options || []; return currentWorkspace.meta.properties.tags?.options || [];
}, [currentWorkspace]); }, [currentWorkspace]);
@@ -6,7 +6,7 @@ import {
} from '@affine/component'; } from '@affine/component';
import type { Collection } from '@affine/env/filter'; import type { Collection } from '@affine/env/filter';
import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { useAFFiNEI18N } from '@affine/i18n/hooks';
import type { PageMeta, Workspace } from '@blocksuite/store'; import type { DocMeta, Workspace } from '@blocksuite/store';
import type { DialogContentProps } from '@radix-ui/react-dialog'; import type { DialogContentProps } from '@radix-ui/react-dialog';
import { type ReactNode, useCallback, useMemo, useState } from 'react'; import { type ReactNode, useCallback, useMemo, useState } from 'react';
@@ -198,13 +198,13 @@ export const EditCollection = ({
}; };
export type AllPageListConfig = { export type AllPageListConfig = {
allPages: PageMeta[]; allPages: DocMeta[];
workspace: Workspace; workspace: Workspace;
isEdgeless: (id: string) => boolean; isEdgeless: (id: string) => boolean;
/** /**
* Return `undefined` if the page is not public * Return `undefined` if the page is not public
*/ */
getPublicMode: (id: string) => undefined | 'page' | 'edgeless'; getPublicMode: (id: string) => undefined | 'page' | 'edgeless';
getPage: (id: string) => PageMeta | undefined; getPage: (id: string) => DocMeta | undefined;
favoriteRender: (page: PageMeta) => ReactNode; favoriteRender: (page: DocMeta) => ReactNode;
}; };
@@ -2,7 +2,7 @@ import { Menu } from '@affine/component';
import type { Collection } from '@affine/env/filter'; import type { Collection } from '@affine/env/filter';
import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { FilterIcon } from '@blocksuite/icons'; import { FilterIcon } from '@blocksuite/icons';
import type { PageMeta } from '@blocksuite/store'; import type { DocMeta } from '@blocksuite/store';
import clsx from 'clsx'; import clsx from 'clsx';
import { type ReactNode, useCallback } from 'react'; import { type ReactNode, useCallback } from 'react';
@@ -56,7 +56,7 @@ export const PagesMode = ({
}, [collection, updateCollection]); }, [collection, updateCollection]);
const pageOperationsRenderer = useCallback( const pageOperationsRenderer = useCallback(
(item: ListItem) => { (item: ListItem) => {
const page = item as PageMeta; const page = item as DocMeta;
return allPageListConfig.favoriteRender(page); return allPageListConfig.favoriteRender(page);
}, },
[allPageListConfig] [allPageListConfig]
@@ -8,7 +8,7 @@ import {
PlusIcon, PlusIcon,
ToggleCollapseIcon, ToggleCollapseIcon,
} from '@blocksuite/icons'; } from '@blocksuite/icons';
import type { PageMeta } from '@blocksuite/store'; import type { DocMeta } from '@blocksuite/store';
import clsx from 'clsx'; import clsx from 'clsx';
import { type ReactNode, useCallback, useEffect, useState } from 'react'; import { type ReactNode, useCallback, useEffect, useState } from 'react';
@@ -38,8 +38,8 @@ export const RulesMode = ({
}) => { }) => {
const t = useAFFiNEI18N(); const t = useAFFiNEI18N();
const [showPreview, setShowPreview] = useState(true); const [showPreview, setShowPreview] = useState(true);
const allowListPages: PageMeta[] = []; const allowListPages: DocMeta[] = [];
const rulesPages: PageMeta[] = []; const rulesPages: DocMeta[] = [];
const [showTips, setShowTips] = useState(false); const [showTips, setShowTips] = useState(false);
useEffect(() => { useEffect(() => {
setShowTips(!localStorage.getItem('hide-rules-mode-include-page-tips')); setShowTips(!localStorage.getItem('hide-rules-mode-include-page-tips'));
@@ -85,7 +85,7 @@ export const RulesMode = ({
); );
const operationsRenderer = useCallback( const operationsRenderer = useCallback(
(item: ListItem) => { (item: ListItem) => {
const page = item as PageMeta; const page = item as DocMeta;
return allPageListConfig.favoriteRender(page); return allPageListConfig.favoriteRender(page);
}, },
[allPageListConfig] [allPageListConfig]
@@ -2,7 +2,7 @@ import { Button, Menu } from '@affine/component';
import { Trans } from '@affine/i18n'; import { Trans } from '@affine/i18n';
import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { FilterIcon } from '@blocksuite/icons'; import { FilterIcon } from '@blocksuite/icons';
import type { PageMeta } from '@blocksuite/store'; import type { DocMeta } from '@blocksuite/store';
import clsx from 'clsx'; import clsx from 'clsx';
import { useCallback, useState } from 'react'; import { useCallback, useState } from 'react';
@@ -53,7 +53,7 @@ export const SelectPage = ({
const operationsRenderer = useCallback( const operationsRenderer = useCallback(
(item: ListItem) => { (item: ListItem) => {
const page = item as PageMeta; const page = item as DocMeta;
return allPageListConfig.favoriteRender(page); return allPageListConfig.favoriteRender(page);
}, },
[allPageListConfig] [allPageListConfig]
@@ -1,7 +1,7 @@
import type { PageMeta } from '@blocksuite/store'; import type { DocMeta } from '@blocksuite/store';
import { useState } from 'react'; import { useState } from 'react';
export const useSearch = (list: PageMeta[]) => { export const useSearch = (list: DocMeta[]) => {
const [value, onChange] = useState(''); const [value, onChange] = useState('');
return { return {
searchText: value, searchText: value,
@@ -1,6 +1,6 @@
import { import {
useBlockSuitePageMeta, useBlockSuiteDocMeta,
usePageMetaHelper, useDocMetaHelper,
} from '@affine/core/hooks/use-block-suite-page-meta'; } from '@affine/core/hooks/use-block-suite-page-meta';
import { useGetBlockSuiteWorkspacePageTitle } from '@affine/core/hooks/use-block-suite-workspace-page-title'; import { useGetBlockSuiteWorkspacePageTitle } from '@affine/core/hooks/use-block-suite-workspace-page-title';
import { useJournalHelper } from '@affine/core/hooks/use-journal'; import { useJournalHelper } from '@affine/core/hooks/use-journal';
@@ -14,9 +14,9 @@ import {
TodayIcon, TodayIcon,
ViewLayersIcon, ViewLayersIcon,
} from '@blocksuite/icons'; } from '@blocksuite/icons';
import type { PageMeta } from '@blocksuite/store'; import type { DocMeta } from '@blocksuite/store';
import { import {
Page, Doc,
PageRecordList, PageRecordList,
useLiveData, useLiveData,
Workspace, Workspace,
@@ -79,7 +79,7 @@ function getAllCommand(context: CommandContext) {
const useWorkspacePages = () => { const useWorkspacePages = () => {
const workspace = useService(Workspace); const workspace = useService(Workspace);
const pages = useBlockSuitePageMeta(workspace.blockSuiteWorkspace); const pages = useBlockSuiteDocMeta(workspace.blockSuiteWorkspace);
return pages; return pages;
}; };
@@ -92,13 +92,13 @@ const useRecentPages = () => {
const page = pages.find(page => page.id === pageId); const page = pages.find(page => page.id === pageId);
return page; return page;
}) })
.filter((p): p is PageMeta => !!p); .filter((p): p is DocMeta => !!p);
}, [recentPageIds, pages]); }, [recentPageIds, pages]);
}; };
export const pageToCommand = ( export const pageToCommand = (
category: CommandCategory, category: CommandCategory,
page: PageMeta, page: DocMeta,
navigationHelper: ReturnType<typeof useNavigateHelper>, navigationHelper: ReturnType<typeof useNavigateHelper>,
getPageTitle: ReturnType<typeof useGetBlockSuiteWorkspacePageTitle>, getPageTitle: ReturnType<typeof useGetBlockSuiteWorkspacePageTitle>,
isPageJournal: (pageId: string) => boolean, isPageJournal: (pageId: string) => boolean,
@@ -152,7 +152,7 @@ export const usePageCommands = () => {
const pages = useWorkspacePages(); const pages = useWorkspacePages();
const workspace = useService(Workspace); const workspace = useService(Workspace);
const pageHelper = usePageHelper(workspace.blockSuiteWorkspace); const pageHelper = usePageHelper(workspace.blockSuiteWorkspace);
const pageMetaHelper = usePageMetaHelper(workspace.blockSuiteWorkspace); const pageMetaHelper = useDocMetaHelper(workspace.blockSuiteWorkspace);
const query = useAtomValue(cmdkQueryAtom); const query = useAtomValue(cmdkQueryAtom);
const navigationHelper = useNavigateHelper(); const navigationHelper = useNavigateHelper();
const journalHelper = useJournalHelper(workspace.blockSuiteWorkspace); const journalHelper = useJournalHelper(workspace.blockSuiteWorkspace);
@@ -260,7 +260,7 @@ export const usePageCommands = () => {
run: async () => { run: async () => {
const page = pageHelper.createPage(); const page = pageHelper.createPage();
page.load(); page.load();
pageMetaHelper.setPageTitle(page.id, query); pageMetaHelper.setDocTitle(page.id, query);
}, },
icon: <PageIcon />, icon: <PageIcon />,
}); });
@@ -275,7 +275,7 @@ export const usePageCommands = () => {
run: async () => { run: async () => {
const page = pageHelper.createEdgeless(); const page = pageHelper.createEdgeless();
page.load(); page.load();
pageMetaHelper.setPageTitle(page.id, query); pageMetaHelper.setDocTitle(page.id, query);
}, },
icon: <EdgelessIcon />, icon: <EdgelessIcon />,
}); });
@@ -357,7 +357,7 @@ export const useCMDKCommandGroups = () => {
const pageCommands = usePageCommands(); const pageCommands = usePageCommands();
const collectionCommands = useCollectionsCommands(); const collectionCommands = useCollectionsCommands();
const currentPage = useServiceOptional(Page); const currentPage = useServiceOptional(Doc);
const currentPageMode = useLiveData(currentPage?.mode); const currentPageMode = useLiveData(currentPage?.mode);
const affineCommands = useMemo(() => { const affineCommands = useMemo(() => {
return getAllCommand({ return getAllCommand({
@@ -3,7 +3,7 @@ import { formatDate } from '@affine/core/components/page-list';
import { useSyncEngineStatus } from '@affine/core/hooks/affine/use-sync-engine-status'; import { useSyncEngineStatus } from '@affine/core/hooks/affine/use-sync-engine-status';
import { useAsyncCallback } from '@affine/core/hooks/affine-async-hooks'; import { useAsyncCallback } from '@affine/core/hooks/affine-async-hooks';
import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { useAFFiNEI18N } from '@affine/i18n/hooks';
import type { PageMeta } from '@blocksuite/store'; import type { DocMeta } from '@blocksuite/store';
import { SyncEngineStep } from '@toeverything/infra'; import { SyncEngineStep } from '@toeverything/infra';
import type { CommandCategory } from '@toeverything/infra/command'; import type { CommandCategory } from '@toeverything/infra/command';
import clsx from 'clsx'; import clsx from 'clsx';
@@ -155,7 +155,7 @@ export const CMDKContainer = ({
open: boolean; open: boolean;
className?: string; className?: string;
query: string; query: string;
pageMeta?: PageMeta; pageMeta?: DocMeta;
groups: ReturnType<typeof useCMDKCommandGroups>; groups: ReturnType<typeof useCMDKCommandGroups>;
onQueryChange: (query: string) => void; onQueryChange: (query: string) => void;
}>) => { }>) => {
@@ -235,7 +235,7 @@ const CMDKQuickSearchModalInner = ({
pageMeta, pageMeta,
open, open,
...props ...props
}: CMDKModalProps & { pageMeta?: PageMeta }) => { }: CMDKModalProps & { pageMeta?: DocMeta }) => {
const [query, setQuery] = useAtom(cmdkQueryAtom); const [query, setQuery] = useAtom(cmdkQueryAtom);
useLayoutEffect(() => { useLayoutEffect(() => {
if (open) { if (open) {
@@ -261,7 +261,7 @@ export const CMDKQuickSearchModal = ({
pageMeta, pageMeta,
open, open,
...props ...props
}: CMDKModalProps & { pageMeta?: PageMeta }) => { }: CMDKModalProps & { pageMeta?: DocMeta }) => {
return ( return (
<CMDKModal open={open} {...props}> <CMDKModal open={open} {...props}>
<Suspense fallback={<Command.Loading />}> <Suspense fallback={<Command.Loading />}>
@@ -2,7 +2,7 @@ import { Tooltip } from '@affine/component/ui/tooltip';
import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { CloseIcon, NewIcon } from '@blocksuite/icons'; import { CloseIcon, NewIcon } from '@blocksuite/icons';
import { useLiveData, useServiceOptional } from '@toeverything/infra'; import { useLiveData, useServiceOptional } from '@toeverything/infra';
import { Page } from '@toeverything/infra'; import { Doc } from '@toeverything/infra';
import { useSetAtom } from 'jotai/react'; import { useSetAtom } from 'jotai/react';
import { useCallback, useState } from 'react'; import { useCallback, useState } from 'react';
@@ -28,7 +28,7 @@ type IslandItemNames = 'whatNew' | 'contact' | 'shortcuts';
const showList = environment.isDesktop ? DESKTOP_SHOW_LIST : DEFAULT_SHOW_LIST; const showList = environment.isDesktop ? DESKTOP_SHOW_LIST : DEFAULT_SHOW_LIST;
export const HelpIsland = () => { export const HelpIsland = () => {
const page = useServiceOptional(Page); const page = useServiceOptional(Doc);
const pageId = page?.id; const pageId = page?.id;
const mode = useLiveData(page?.mode); const mode = useLiveData(page?.mode);
const setOpenSettingModalAtom = useSetAtom(openSettingModalAtom); const setOpenSettingModalAtom = useSetAtom(openSettingModalAtom);
@@ -1,7 +1,7 @@
import { Button } from '@affine/component/ui/button'; import { Button } from '@affine/component/ui/button';
import { ConfirmModal } from '@affine/component/ui/modal'; import { ConfirmModal } from '@affine/component/ui/modal';
import { Tooltip } from '@affine/component/ui/tooltip'; import { Tooltip } from '@affine/component/ui/tooltip';
import { useBlockSuitePageMeta } from '@affine/core/hooks/use-block-suite-page-meta'; import { useBlockSuiteDocMeta } from '@affine/core/hooks/use-block-suite-page-meta';
import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { assertExists } from '@blocksuite/global/utils'; import { assertExists } from '@blocksuite/global/utils';
import { DeleteIcon, ResetIcon } from '@blocksuite/icons'; import { DeleteIcon, ResetIcon } from '@blocksuite/icons';
@@ -23,7 +23,7 @@ export const TrashPageFooter = ({ pageId }: { pageId: string }) => {
); );
assertExists(workspace); assertExists(workspace);
const blockSuiteWorkspace = workspace.blockSuiteWorkspace; const blockSuiteWorkspace = workspace.blockSuiteWorkspace;
const pageMeta = useBlockSuitePageMeta(blockSuiteWorkspace).find( const pageMeta = useBlockSuiteDocMeta(blockSuiteWorkspace).find(
meta => meta.id === pageId meta => meta.id === pageId
); );
assertExists(pageMeta); assertExists(pageMeta);
@@ -45,7 +45,7 @@ export const TrashPageFooter = ({ pageId }: { pageId: string }) => {
const onConfirmDelete = useCallback(() => { const onConfirmDelete = useCallback(() => {
jumpToSubPath(workspace.id, WorkspaceSubPath.ALL); jumpToSubPath(workspace.id, WorkspaceSubPath.ALL);
blockSuiteWorkspace.removePage(pageId); blockSuiteWorkspace.removeDoc(pageId);
toast(t['com.affine.toastMessage.permanentlyDeleted']()); toast(t['com.affine.toastMessage.permanentlyDeleted']());
}, [blockSuiteWorkspace, jumpToSubPath, pageId, workspace.id, t]); }, [blockSuiteWorkspace, jumpToSubPath, pageId, workspace.id, t]);
@@ -11,7 +11,7 @@ import { CollectionService } from '@affine/core/modules/collection';
import type { Collection, DeleteCollectionInfo } from '@affine/env/filter'; import type { Collection, DeleteCollectionInfo } from '@affine/env/filter';
import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { MoreHorizontalIcon, ViewLayersIcon } from '@blocksuite/icons'; import { MoreHorizontalIcon, ViewLayersIcon } from '@blocksuite/icons';
import type { PageMeta, Workspace } from '@blocksuite/store'; import type { DocMeta, Workspace } from '@blocksuite/store';
import { useDroppable } from '@dnd-kit/core'; import { useDroppable } from '@dnd-kit/core';
import * as Collapsible from '@radix-ui/react-collapsible'; import * as Collapsible from '@radix-ui/react-collapsible';
import { useService } from '@toeverything/infra'; import { useService } from '@toeverything/infra';
@@ -20,7 +20,7 @@ import { useCallback, useMemo, useState } from 'react';
import { useAllPageListConfig } from '../../../../hooks/affine/use-all-page-list-config'; import { useAllPageListConfig } from '../../../../hooks/affine/use-all-page-list-config';
import { getDropItemId } from '../../../../hooks/affine/use-sidebar-drag'; import { getDropItemId } from '../../../../hooks/affine/use-sidebar-drag';
import { useBlockSuitePageMeta } from '../../../../hooks/use-block-suite-page-meta'; import { useBlockSuiteDocMeta } from '../../../../hooks/use-block-suite-page-meta';
import { Workbench } from '../../../../modules/workbench'; import { Workbench } from '../../../../modules/workbench';
import { WorkbenchLink } from '../../../../modules/workbench/workbench-link'; import { WorkbenchLink } from '../../../../modules/workbench/workbench-link';
import type { CollectionsListProps } from '../index'; import type { CollectionsListProps } from '../index';
@@ -34,7 +34,7 @@ const CollectionRenderer = ({
info, info,
}: { }: {
collection: Collection; collection: Collection;
pages: PageMeta[]; pages: DocMeta[];
workspace: Workspace; workspace: Workspace;
info: DeleteCollectionInfo; info: DeleteCollectionInfo;
}) => { }) => {
@@ -173,7 +173,7 @@ export const CollectionsList = ({
info, info,
onCreate, onCreate,
}: CollectionsListProps) => { }: CollectionsListProps) => {
const metas = useBlockSuitePageMeta(workspace); const metas = useBlockSuiteDocMeta(workspace);
const collections = useLiveData(useService(CollectionService).collections); const collections = useLiveData(useService(CollectionService).collections);
const t = useAFFiNEI18N(); const t = useAFFiNEI18N();
if (collections.length === 0) { if (collections.length === 0) {
@@ -2,7 +2,7 @@ import { MenuItem as CollectionItem } from '@affine/component/app-sidebar';
import { useBlockSuitePageReferences } from '@affine/core/hooks/use-block-suite-page-references'; import { useBlockSuitePageReferences } from '@affine/core/hooks/use-block-suite-page-references';
import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { EdgelessIcon, PageIcon } from '@blocksuite/icons'; import { EdgelessIcon, PageIcon } from '@blocksuite/icons';
import type { PageMeta, Workspace } from '@blocksuite/store'; import type { DocMeta, Workspace } from '@blocksuite/store';
import { useDraggable } from '@dnd-kit/core'; import { useDraggable } from '@dnd-kit/core';
import * as Collapsible from '@radix-ui/react-collapsible'; import * as Collapsible from '@radix-ui/react-collapsible';
import { PageRecordList, useLiveData, useService } from '@toeverything/infra'; import { PageRecordList, useLiveData, useService } from '@toeverything/infra';
@@ -23,11 +23,11 @@ export const Page = ({
inAllowList, inAllowList,
removeFromAllowList, removeFromAllowList,
}: { }: {
page: PageMeta; page: DocMeta;
inAllowList: boolean; inAllowList: boolean;
removeFromAllowList: (id: string) => void; removeFromAllowList: (id: string) => void;
workspace: Workspace; workspace: Workspace;
allPageMeta: Record<string, PageMeta>; allPageMeta: Record<string, DocMeta>;
}) => { }) => {
const [collapsed, setCollapsed] = React.useState(true); const [collapsed, setCollapsed] = React.useState(true);
const params = useParams(); const params = useParams();
@@ -1,6 +1,6 @@
import { toast } from '@affine/component'; import { toast } from '@affine/component';
import { RenameModal } from '@affine/component/rename-modal'; import { RenameModal } from '@affine/component/rename-modal';
import { usePageMetaHelper } from '@affine/core/hooks/use-block-suite-page-meta'; import { useDocMetaHelper } from '@affine/core/hooks/use-block-suite-page-meta';
import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { useAFFiNEI18N } from '@affine/i18n/hooks';
import type { Workspace } from '@blocksuite/store'; import type { Workspace } from '@blocksuite/store';
import { useCallback, useState } from 'react'; import { useCallback, useState } from 'react';
@@ -23,15 +23,15 @@ export const PostfixItem = ({ ...props }: PostfixItemProps) => {
const { workspace, pageId, pageTitle } = props; const { workspace, pageId, pageTitle } = props;
const t = useAFFiNEI18N(); const t = useAFFiNEI18N();
const [open, setOpen] = useState(false); const [open, setOpen] = useState(false);
const { setPageTitle } = usePageMetaHelper(workspace); const { setDocTitle } = useDocMetaHelper(workspace);
const handleRename = useCallback( const handleRename = useCallback(
(newName: string) => { (newName: string) => {
setPageTitle(pageId, newName); setDocTitle(pageId, newName);
setOpen(false); setOpen(false);
toast(t['com.affine.toastMessage.rename']()); toast(t['com.affine.toastMessage.rename']());
}, },
[pageId, setPageTitle, t] [pageId, setDocTitle, t]
); );
return ( return (
@@ -2,7 +2,7 @@ import { MenuLinkItem } from '@affine/component/app-sidebar';
import { useBlockSuitePageReferences } from '@affine/core/hooks/use-block-suite-page-references'; import { useBlockSuitePageReferences } from '@affine/core/hooks/use-block-suite-page-references';
import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { EdgelessIcon, PageIcon } from '@blocksuite/icons'; import { EdgelessIcon, PageIcon } from '@blocksuite/icons';
import { type PageMeta, type Workspace } from '@blocksuite/store'; import { type DocMeta, type Workspace } from '@blocksuite/store';
import * as Collapsible from '@radix-ui/react-collapsible'; import * as Collapsible from '@radix-ui/react-collapsible';
import { PageRecordList, useLiveData, useService } from '@toeverything/infra'; import { PageRecordList, useLiveData, useService } from '@toeverything/infra';
import { useMemo, useState } from 'react'; import { useMemo, useState } from 'react';
@@ -13,7 +13,7 @@ import { PostfixItem } from './postfix-item';
export interface ReferencePageProps { export interface ReferencePageProps {
workspace: Workspace; workspace: Workspace;
pageId: string; pageId: string;
metaMapping: Record<string, PageMeta>; metaMapping: Record<string, DocMeta>;
parentIds: Set<string>; parentIds: Set<string>;
} }
@@ -1,6 +1,6 @@
import { IconButton } from '@affine/component/ui/button'; import { IconButton } from '@affine/component/ui/button';
import { useAsyncCallback } from '@affine/core/hooks/affine-async-hooks'; import { useAsyncCallback } from '@affine/core/hooks/affine-async-hooks';
import { usePageMetaHelper } from '@affine/core/hooks/use-block-suite-page-meta'; import { useDocMetaHelper } from '@affine/core/hooks/use-block-suite-page-meta';
import { PlusIcon } from '@blocksuite/icons'; import { PlusIcon } from '@blocksuite/icons';
import type { Workspace } from '@blocksuite/store'; import type { Workspace } from '@blocksuite/store';
@@ -16,7 +16,7 @@ export const AddFavouriteButton = ({
pageId, pageId,
}: AddFavouriteButtonProps) => { }: AddFavouriteButtonProps) => {
const { createPage, createLinkedPage } = usePageHelper(workspace); const { createPage, createLinkedPage } = usePageHelper(workspace);
const { setPageMeta } = usePageMetaHelper(workspace); const { setDocMeta } = useDocMetaHelper(workspace);
const handleAddFavorite = useAsyncCallback( const handleAddFavorite = useAsyncCallback(
async e => { async e => {
if (pageId) { if (pageId) {
@@ -26,10 +26,10 @@ export const AddFavouriteButton = ({
} else { } else {
const page = createPage(); const page = createPage();
page.load(); page.load();
setPageMeta(page.id, { favorite: true }); setDocMeta(page.id, { favorite: true });
} }
}, },
[pageId, createLinkedPage, createPage, setPageMeta] [pageId, createLinkedPage, createPage, setDocMeta]
); );
return ( return (
@@ -1,5 +1,5 @@
import { useBlockSuitePageMeta } from '@affine/core/hooks/use-block-suite-page-meta'; import { useBlockSuiteDocMeta } from '@affine/core/hooks/use-block-suite-page-meta';
import type { PageMeta } from '@blocksuite/store'; import type { DocMeta } from '@blocksuite/store';
import { useDroppable } from '@dnd-kit/core'; import { useDroppable } from '@dnd-kit/core';
import { useMemo } from 'react'; import { useMemo } from 'react';
@@ -12,7 +12,7 @@ import * as styles from './styles.css';
const emptyPageIdSet = new Set<string>(); const emptyPageIdSet = new Set<string>();
export const FavoriteList = ({ workspace }: FavoriteListProps) => { export const FavoriteList = ({ workspace }: FavoriteListProps) => {
const metas = useBlockSuitePageMeta(workspace); const metas = useBlockSuiteDocMeta(workspace);
const dropItemId = getDropItemId('favorites'); const dropItemId = getDropItemId('favorites');
const favoriteList = useMemo( const favoriteList = useMemo(
@@ -27,7 +27,7 @@ export const FavoriteList = ({ workspace }: FavoriteListProps) => {
acc[meta.id] = meta; acc[meta.id] = meta;
return acc; return acc;
}, },
{} as Record<string, PageMeta> {} as Record<string, DocMeta>
), ),
[metas] [metas]
); );
@@ -17,7 +17,7 @@ import { CollectionService } from '@affine/core/modules/collection';
import { apis, events } from '@affine/electron-api'; import { apis, events } from '@affine/electron-api';
import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { FolderIcon, SettingsIcon } from '@blocksuite/icons'; import { FolderIcon, SettingsIcon } from '@blocksuite/icons';
import { type Page } from '@blocksuite/store'; import { type Doc } from '@blocksuite/store';
import { useDroppable } from '@dnd-kit/core'; import { useDroppable } from '@dnd-kit/core';
import { useLiveData, useService, type Workspace } from '@toeverything/infra'; import { useLiveData, useService, type Workspace } from '@toeverything/infra';
import { useAtom, useAtomValue } from 'jotai'; import { useAtom, useAtomValue } from 'jotai';
@@ -57,7 +57,7 @@ export type RootAppSidebarProps = {
onOpenSettingModal: () => void; onOpenSettingModal: () => void;
currentWorkspace: Workspace; currentWorkspace: Workspace;
openPage: (pageId: string) => void; openPage: (pageId: string) => void;
createPage: () => Page; createPage: () => Doc;
paths: { paths: {
all: (workspaceId: string) => string; all: (workspaceId: string) => string;
trash: (workspaceId: string) => string; trash: (workspaceId: string) => string;
@@ -114,7 +114,7 @@ export const RootAppSidebar = ({
const onClickNewPage = useAsyncCallback(async () => { const onClickNewPage = useAsyncCallback(async () => {
const page = createPage(); const page = createPage();
page.waitForLoaded(); page.load();
openPage(page.id); openPage(page.id);
}, [createPage, openPage]); }, [createPage, openPage]);
@@ -6,7 +6,7 @@ import {
import type { BlockSuiteWorkspace } from '@affine/core/shared'; import type { BlockSuiteWorkspace } from '@affine/core/shared';
import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { TodayIcon, TomorrowIcon, YesterdayIcon } from '@blocksuite/icons'; import { TodayIcon, TomorrowIcon, YesterdayIcon } from '@blocksuite/icons';
import { Page, useServiceOptional } from '@toeverything/infra'; import { Doc, useServiceOptional } from '@toeverything/infra';
import { useParams } from 'react-router-dom'; import { useParams } from 'react-router-dom';
interface AppSidebarJournalButtonProps { interface AppSidebarJournalButtonProps {
@@ -17,7 +17,7 @@ export const AppSidebarJournalButton = ({
workspace, workspace,
}: AppSidebarJournalButtonProps) => { }: AppSidebarJournalButtonProps) => {
const t = useAFFiNEI18N(); const t = useAFFiNEI18N();
const currentPage = useServiceOptional(Page); const currentPage = useServiceOptional(Doc);
const { openToday } = useJournalRouteHelper(workspace); const { openToday } = useJournalRouteHelper(workspace);
const { journalDate, isJournal } = useJournalInfoHelper( const { journalDate, isJournal } = useJournalInfoHelper(
workspace, workspace,
@@ -10,16 +10,15 @@ import { initEmptyPage, ServiceProviderContext } from '@toeverything/infra';
import type { PropsWithChildren } from 'react'; import type { PropsWithChildren } from 'react';
import { beforeEach, describe, expect, test, vi } from 'vitest'; import { beforeEach, describe, expect, test, vi } from 'vitest';
import { useBlockSuitePageMeta } from '../use-block-suite-page-meta'; import { useBlockSuiteDocMeta } from '../use-block-suite-page-meta';
import { useBlockSuiteWorkspaceHelper } from '../use-block-suite-workspace-helper'; import { useBlockSuiteWorkspaceHelper } from '../use-block-suite-workspace-helper';
const configureTestingWorkspace = async () => { const configureTestingWorkspace = async () => {
const { workspace } = await configureTestingEnvironment(); const { workspace } = await configureTestingEnvironment();
const blockSuiteWorkspace = workspace.blockSuiteWorkspace; const blockSuiteWorkspace = workspace.blockSuiteWorkspace;
// await initEmptyPage(blockSuiteWorkspace.createPage({ id: 'page-0' })); initEmptyPage(blockSuiteWorkspace.createDoc({ id: 'page1' }));
initEmptyPage(blockSuiteWorkspace.createPage({ id: 'page1' })); initEmptyPage(blockSuiteWorkspace.createDoc({ id: 'page2' }));
initEmptyPage(blockSuiteWorkspace.createPage({ id: 'page2' }));
return workspace; return workspace;
}; };
@@ -43,7 +42,7 @@ describe('useBlockSuiteWorkspaceHelper', () => {
const blockSuiteWorkspace = workspace.blockSuiteWorkspace; const blockSuiteWorkspace = workspace.blockSuiteWorkspace;
const Wrapper = getWrapper(workspace); const Wrapper = getWrapper(workspace);
expect(blockSuiteWorkspace.meta.pageMetas.length).toBe(3); expect(blockSuiteWorkspace.meta.docMetas.length).toBe(3);
const helperHook = renderHook( const helperHook = renderHook(
() => useBlockSuiteWorkspaceHelper(blockSuiteWorkspace), () => useBlockSuiteWorkspaceHelper(blockSuiteWorkspace),
{ {
@@ -51,17 +50,17 @@ describe('useBlockSuiteWorkspaceHelper', () => {
} }
); );
const pageMetaHook = renderHook( const pageMetaHook = renderHook(
() => useBlockSuitePageMeta(blockSuiteWorkspace), () => useBlockSuiteDocMeta(blockSuiteWorkspace),
{ {
wrapper: Wrapper, wrapper: Wrapper,
} }
); );
await new Promise(resolve => setTimeout(resolve)); await new Promise(resolve => setTimeout(resolve));
expect(pageMetaHook.result.current.length).toBe(3); expect(pageMetaHook.result.current.length).toBe(3);
expect(blockSuiteWorkspace.meta.pageMetas.length).toBe(3); expect(blockSuiteWorkspace.meta.docMetas.length).toBe(3);
const page = helperHook.result.current.createPage('page4'); const page = helperHook.result.current.createDoc('page4');
expect(page.id).toBe('page4'); expect(page.id).toBe('page4');
expect(blockSuiteWorkspace.meta.pageMetas.length).toBe(4); expect(blockSuiteWorkspace.meta.docMetas.length).toBe(4);
pageMetaHook.rerender(); pageMetaHook.rerender();
expect(pageMetaHook.result.current.length).toBe(4); expect(pageMetaHook.result.current.length).toBe(4);
}); });
@@ -43,7 +43,7 @@ describe('useBlockSuiteWorkspacePageTitle', () => {
</ServiceProviderContext.Provider> </ServiceProviderContext.Provider>
); );
expect(await findByText('title: Untitled')).toBeDefined(); expect(await findByText('title: Untitled')).toBeDefined();
workspace.blockSuiteWorkspace.setPageMeta(page.id, { title: '1' }); workspace.blockSuiteWorkspace.setDocMeta(page.id, { title: '1' });
rerender( rerender(
<ServiceProviderContext.Provider value={page.services}> <ServiceProviderContext.Provider value={page.services}>
<Provider store={store}> <Provider store={store}>
@@ -3,9 +3,9 @@ import {
type AllPageListConfig, type AllPageListConfig,
FavoriteTag, FavoriteTag,
} from '@affine/core/components/page-list'; } from '@affine/core/components/page-list';
import { useBlockSuitePageMeta } from '@affine/core/hooks/use-block-suite-page-meta'; import { useBlockSuiteDocMeta } from '@affine/core/hooks/use-block-suite-page-meta';
import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { useAFFiNEI18N } from '@affine/i18n/hooks';
import type { PageMeta } from '@blocksuite/store'; import type { DocMeta } from '@blocksuite/store';
import { Workspace } from '@toeverything/infra'; import { Workspace } from '@toeverything/infra';
import { useService } from '@toeverything/infra/di'; import { useService } from '@toeverything/infra/di';
import { useCallback, useMemo } from 'react'; import { useCallback, useMemo } from 'react';
@@ -18,7 +18,7 @@ export const useAllPageListConfig = () => {
const currentWorkspace = useService(Workspace); const currentWorkspace = useService(Workspace);
const { getPublicMode } = usePublicPages(currentWorkspace); const { getPublicMode } = usePublicPages(currentWorkspace);
const workspace = currentWorkspace.blockSuiteWorkspace; const workspace = currentWorkspace.blockSuiteWorkspace;
const pageMetas = useBlockSuitePageMeta(workspace); const pageMetas = useBlockSuiteDocMeta(workspace);
const { isPreferredEdgeless } = usePageHelper(workspace); const { isPreferredEdgeless } = usePageHelper(workspace);
const pageMap = useMemo( const pageMap = useMemo(
() => Object.fromEntries(pageMetas.map(page => [page.id, page])), () => Object.fromEntries(pageMetas.map(page => [page.id, page])),
@@ -29,7 +29,7 @@ export const useAllPageListConfig = () => {
); );
const t = useAFFiNEI18N(); const t = useAFFiNEI18N();
const onToggleFavoritePage = useCallback( const onToggleFavoritePage = useCallback(
(page: PageMeta) => { (page: DocMeta) => {
const status = page.favorite; const status = page.favorite;
toggleFavorite(page.id); toggleFavorite(page.id);
toast( toast(
@@ -1,5 +1,5 @@
import { useAsyncCallback } from '@affine/core/hooks/affine-async-hooks'; import { useAsyncCallback } from '@affine/core/hooks/affine-async-hooks';
import { usePageMetaHelper } from '@affine/core/hooks/use-block-suite-page-meta'; import { useDocMetaHelper } from '@affine/core/hooks/use-block-suite-page-meta';
import { useBlockSuiteWorkspaceHelper } from '@affine/core/hooks/use-block-suite-workspace-helper'; import { useBlockSuiteWorkspaceHelper } from '@affine/core/hooks/use-block-suite-workspace-helper';
import { CollectionService } from '@affine/core/modules/collection'; import { CollectionService } from '@affine/core/modules/collection';
import { PageRecordList, useService } from '@toeverything/infra'; import { PageRecordList, useService } from '@toeverything/infra';
@@ -13,76 +13,76 @@ import { useReferenceLinkHelper } from './use-reference-link-helper';
export function useBlockSuiteMetaHelper( export function useBlockSuiteMetaHelper(
blockSuiteWorkspace: BlockSuiteWorkspace blockSuiteWorkspace: BlockSuiteWorkspace
) { ) {
const { setPageMeta, getPageMeta, setPageReadonly, setPageTitle } = const { setDocMeta, getDocMeta, setDocReadonly, setDocTitle } =
usePageMetaHelper(blockSuiteWorkspace); useDocMetaHelper(blockSuiteWorkspace);
const { addReferenceLink } = useReferenceLinkHelper(blockSuiteWorkspace); const { addReferenceLink } = useReferenceLinkHelper(blockSuiteWorkspace);
const { createPage } = useBlockSuiteWorkspaceHelper(blockSuiteWorkspace); const { createDoc } = useBlockSuiteWorkspaceHelper(blockSuiteWorkspace);
const { openPage } = useNavigateHelper(); const { openPage } = useNavigateHelper();
const collectionService = useService(CollectionService); const collectionService = useService(CollectionService);
const pageRecordList = useService(PageRecordList); const pageRecordList = useService(PageRecordList);
const addToFavorite = useCallback( const addToFavorite = useCallback(
(pageId: string) => { (pageId: string) => {
setPageMeta(pageId, { setDocMeta(pageId, {
favorite: true, favorite: true,
}); });
}, },
[setPageMeta] [setDocMeta]
); );
const removeFromFavorite = useCallback( const removeFromFavorite = useCallback(
(pageId: string) => { (pageId: string) => {
setPageMeta(pageId, { setDocMeta(pageId, {
favorite: false, favorite: false,
}); });
}, },
[setPageMeta] [setDocMeta]
); );
const toggleFavorite = useCallback( const toggleFavorite = useCallback(
(pageId: string) => { (pageId: string) => {
const { favorite } = getPageMeta(pageId) ?? {}; const { favorite } = getDocMeta(pageId) ?? {};
setPageMeta(pageId, { setDocMeta(pageId, {
favorite: !favorite, favorite: !favorite,
}); });
}, },
[getPageMeta, setPageMeta] [getDocMeta, setDocMeta]
); );
// TODO-Doma // TODO-Doma
// "Remove" may cause ambiguity here. Consider renaming as "moveToTrash". // "Remove" may cause ambiguity here. Consider renaming as "moveToTrash".
const removeToTrash = useCallback( const removeToTrash = useCallback(
(pageId: string) => { (pageId: string) => {
setPageMeta(pageId, { setDocMeta(pageId, {
trash: true, trash: true,
trashDate: Date.now(), trashDate: Date.now(),
trashRelate: undefined, trashRelate: undefined,
}); });
setPageReadonly(pageId, true); setDocReadonly(pageId, true);
collectionService.deletePagesFromCollections([pageId]); collectionService.deletePagesFromCollections([pageId]);
}, },
[collectionService, setPageMeta, setPageReadonly] [collectionService, setDocMeta, setDocReadonly]
); );
const restoreFromTrash = useCallback( const restoreFromTrash = useCallback(
(pageId: string) => { (pageId: string) => {
const { trashRelate } = getPageMeta(pageId) ?? {}; const { trashRelate } = getDocMeta(pageId) ?? {};
if (trashRelate) { if (trashRelate) {
addReferenceLink(trashRelate, pageId); addReferenceLink(trashRelate, pageId);
} }
setPageMeta(pageId, { setDocMeta(pageId, {
trash: false, trash: false,
trashDate: undefined, trashDate: undefined,
trashRelate: undefined, trashRelate: undefined,
}); });
setPageReadonly(pageId, false); setDocReadonly(pageId, false);
}, },
[addReferenceLink, getPageMeta, setPageMeta, setPageReadonly] [addReferenceLink, getDocMeta, setDocMeta, setDocReadonly]
); );
const permanentlyDeletePage = useCallback( const permanentlyDeletePage = useCallback(
(pageId: string) => { (pageId: string) => {
blockSuiteWorkspace.removePage(pageId); blockSuiteWorkspace.removeDoc(pageId);
}, },
[blockSuiteWorkspace] [blockSuiteWorkspace]
); );
@@ -92,11 +92,11 @@ export function useBlockSuiteMetaHelper(
*/ */
const publicPage = useCallback( const publicPage = useCallback(
(pageId: string) => { (pageId: string) => {
setPageMeta(pageId, { setDocMeta(pageId, {
isPublic: true, isPublic: true,
}); });
}, },
[setPageMeta] [setDocMeta]
); );
/** /**
@@ -104,21 +104,21 @@ export function useBlockSuiteMetaHelper(
*/ */
const cancelPublicPage = useCallback( const cancelPublicPage = useCallback(
(pageId: string) => { (pageId: string) => {
setPageMeta(pageId, { setDocMeta(pageId, {
isPublic: false, isPublic: false,
}); });
}, },
[setPageMeta] [setDocMeta]
); );
const duplicate = useAsyncCallback( const duplicate = useAsyncCallback(
async (pageId: string, openPageAfterDuplication: boolean = true) => { async (pageId: string, openPageAfterDuplication: boolean = true) => {
const currentPageMode = pageRecordList.record(pageId).value?.mode.value; const currentPageMode = pageRecordList.record(pageId).value?.mode.value;
const currentPageMeta = getPageMeta(pageId); const currentPageMeta = getDocMeta(pageId);
const newPage = createPage(); const newPage = createDoc();
const currentPage = blockSuiteWorkspace.getPage(pageId); const currentPage = blockSuiteWorkspace.getDoc(pageId);
newPage.waitForLoaded(); newPage.load();
if (!currentPageMeta || !currentPage) { if (!currentPageMeta || !currentPage) {
return; return;
} }
@@ -126,7 +126,7 @@ export function useBlockSuiteMetaHelper(
const update = encodeStateAsUpdate(currentPage.spaceDoc); const update = encodeStateAsUpdate(currentPage.spaceDoc);
applyUpdate(newPage.spaceDoc, update); applyUpdate(newPage.spaceDoc, update);
setPageMeta(newPage.id, { setDocMeta(newPage.id, {
tags: currentPageMeta.tags, tags: currentPageMeta.tags,
favorite: currentPageMeta.favorite, favorite: currentPageMeta.favorite,
}); });
@@ -141,17 +141,17 @@ export function useBlockSuiteMetaHelper(
pageRecordList pageRecordList
.record(newPage.id) .record(newPage.id)
.value?.setMode(currentPageMode || 'page'); .value?.setMode(currentPageMode || 'page');
setPageTitle(newPage.id, newPageTitle); setDocTitle(newPage.id, newPageTitle);
openPageAfterDuplication && openPage(blockSuiteWorkspace.id, newPage.id); openPageAfterDuplication && openPage(blockSuiteWorkspace.id, newPage.id);
}, },
[ [
blockSuiteWorkspace, blockSuiteWorkspace,
createPage, createDoc,
getPageMeta, getDocMeta,
openPage, openPage,
pageRecordList, pageRecordList,
setPageMeta, setDocMeta,
setPageTitle, setDocTitle,
] ]
); );
@@ -5,13 +5,13 @@ import {
import { pushNotificationAtom } from '@affine/component/notification-center'; import { pushNotificationAtom } from '@affine/component/notification-center';
import { apis } from '@affine/electron-api'; import { apis } from '@affine/electron-api';
import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { useAFFiNEI18N } from '@affine/i18n/hooks';
import type { PageService } from '@blocksuite/blocks'; import type { PageRootService } from '@blocksuite/blocks';
import { import {
HtmlTransformer, HtmlTransformer,
MarkdownTransformer, MarkdownTransformer,
type PageBlockModel, type RootBlockModel,
} from '@blocksuite/blocks'; } from '@blocksuite/blocks';
import type { Page } from '@blocksuite/store'; import type { Doc } from '@blocksuite/store';
import { useSetAtom } from 'jotai'; import { useSetAtom } from 'jotai';
import { nanoid } from 'nanoid'; import { nanoid } from 'nanoid';
import { useCallback } from 'react'; import { useCallback } from 'react';
@@ -19,27 +19,27 @@ import { useCallback } from 'react';
type ExportType = 'pdf' | 'html' | 'png' | 'markdown'; type ExportType = 'pdf' | 'html' | 'png' | 'markdown';
interface ExportHandlerOptions { interface ExportHandlerOptions {
page: Page; page: Doc;
type: ExportType; type: ExportType;
} }
async function exportHandler({ page, type }: ExportHandlerOptions) { async function exportHandler({ page, type }: ExportHandlerOptions) {
const editorRoot = document.querySelector('editor-host'); const editorRoot = document.querySelector('editor-host');
let pageService: PageService | null = null; let pageService: PageRootService | null = null;
if (editorRoot) { if (editorRoot) {
pageService = editorRoot.spec.getService('affine:page') as PageService; pageService = editorRoot.spec.getService<PageRootService>('affine:page');
} }
switch (type) { switch (type) {
case 'html': case 'html':
await HtmlTransformer.exportPage(page); await HtmlTransformer.exportDoc(page);
break; break;
case 'markdown': case 'markdown':
await MarkdownTransformer.exportPage(page); await MarkdownTransformer.exportDoc(page);
break; break;
case 'pdf': case 'pdf':
if (environment.isDesktop && page.meta.mode === 'page') { if (environment.isDesktop && page.meta?.mode === 'page') {
await apis?.export.savePDFFileAs( await apis?.export.savePDFFileAs(
(page.root as PageBlockModel).title.toString() (page.root as RootBlockModel).title.toString()
); );
} else { } else {
if (!pageService) return; if (!pageService) return;
@@ -54,7 +54,7 @@ async function exportHandler({ page, type }: ExportHandlerOptions) {
} }
} }
export const useExportPage = (page: Page) => { export const useExportPage = (page: Doc) => {
const pushNotification = useSetAtom(pushNotificationAtom); const pushNotification = useSetAtom(pushNotificationAtom);
const pushGlobalLoadingEvent = useSetAtom(pushGlobalLoadingEventAtom); const pushGlobalLoadingEvent = useSetAtom(pushGlobalLoadingEventAtom);
const resolveGlobalLoadingEvent = useSetAtom(resolveGlobalLoadingEventAtom); const resolveGlobalLoadingEvent = useSetAtom(resolveGlobalLoadingEventAtom);
@@ -7,7 +7,7 @@ export function useReferenceLinkHelper(
) { ) {
const addReferenceLink = useCallback( const addReferenceLink = useCallback(
(pageId: string, referenceId: string) => { (pageId: string, referenceId: string) => {
const page = blockSuiteWorkspace?.getPage(pageId); const page = blockSuiteWorkspace?.getDoc(pageId);
if (!page) { if (!page) {
return; return;
} }
@@ -1,10 +1,10 @@
import { toast } from '@affine/component'; import { toast } from '@affine/component';
import { usePageMetaHelper } from '@affine/core/hooks/use-block-suite-page-meta'; import { useDocMetaHelper } from '@affine/core/hooks/use-block-suite-page-meta';
import { WorkspaceFlavour } from '@affine/env/workspace'; import { WorkspaceFlavour } from '@affine/env/workspace';
import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { assertExists } from '@blocksuite/global/utils'; import { assertExists } from '@blocksuite/global/utils';
import { EdgelessIcon, HistoryIcon, PageIcon } from '@blocksuite/icons'; import { EdgelessIcon, HistoryIcon, PageIcon } from '@blocksuite/icons';
import { Page, useLiveData, Workspace } from '@toeverything/infra'; import { Doc, useLiveData, Workspace } from '@toeverything/infra';
import { import {
PreconditionStrategy, PreconditionStrategy,
registerAffineCommand, registerAffineCommand,
@@ -19,16 +19,16 @@ import { useExportPage } from './use-export-page';
import { useTrashModalHelper } from './use-trash-modal-helper'; import { useTrashModalHelper } from './use-trash-modal-helper';
export function useRegisterBlocksuiteEditorCommands() { export function useRegisterBlocksuiteEditorCommands() {
const page = useService(Page); const page = useService(Doc);
const pageId = page.id; const pageId = page.id;
const mode = useLiveData(page.mode); const mode = useLiveData(page.mode);
const t = useAFFiNEI18N(); const t = useAFFiNEI18N();
const workspace = useService(Workspace); const workspace = useService(Workspace);
const blockSuiteWorkspace = workspace.blockSuiteWorkspace; const blockSuiteWorkspace = workspace.blockSuiteWorkspace;
const { getPageMeta } = usePageMetaHelper(blockSuiteWorkspace); const { getDocMeta } = useDocMetaHelper(blockSuiteWorkspace);
const currentPage = blockSuiteWorkspace.getPage(pageId); const currentPage = blockSuiteWorkspace.getDoc(pageId);
assertExists(currentPage); assertExists(currentPage);
const pageMeta = getPageMeta(pageId); const pageMeta = getDocMeta(pageId);
assertExists(pageMeta); assertExists(pageMeta);
const favorite = pageMeta.favorite ?? false; const favorite = pageMeta.favorite ?? false;
const trash = pageMeta.trash ?? false; const trash = pageMeta.trash ?? false;
@@ -1,6 +1,6 @@
import { toast } from '@affine/component'; import { toast } from '@affine/component';
import type { DraggableTitleCellData } from '@affine/core/components/page-list'; import type { DraggableTitleCellData } from '@affine/core/components/page-list';
import { usePageMetaHelper } from '@affine/core/hooks/use-block-suite-page-meta'; import { useDocMetaHelper } from '@affine/core/hooks/use-block-suite-page-meta';
import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { useAFFiNEI18N } from '@affine/i18n/hooks';
import type { DragEndEvent, UniqueIdentifier } from '@dnd-kit/core'; import type { DragEndEvent, UniqueIdentifier } from '@dnd-kit/core';
import { Workspace } from '@toeverything/infra'; import { Workspace } from '@toeverything/infra';
@@ -74,7 +74,7 @@ export const useSidebarDrag = () => {
const { setTrashModal } = useTrashModalHelper(workspace); const { setTrashModal } = useTrashModalHelper(workspace);
const { addToFavorite, removeFromFavorite } = const { addToFavorite, removeFromFavorite } =
useBlockSuiteMetaHelper(workspace); useBlockSuiteMetaHelper(workspace);
const { getPageMeta } = usePageMetaHelper(workspace); const { getDocMeta } = useDocMetaHelper(workspace);
const isDropArea = useCallback( const isDropArea = useCallback(
(id: UniqueIdentifier | undefined, prefix: string) => { (id: UniqueIdentifier | undefined, prefix: string) => {
@@ -109,7 +109,7 @@ export const useSidebarDrag = () => {
const processMoveToTrashDrag = useCallback( const processMoveToTrashDrag = useCallback(
(e: DragEndEvent) => { (e: DragEndEvent) => {
const { pageId } = e.active.data.current as DraggableTitleCellData; const { pageId } = e.active.data.current as DraggableTitleCellData;
const pageTitle = getPageMeta(pageId)?.title ?? t['Untitled'](); const pageTitle = getDocMeta(pageId)?.title ?? t['Untitled']();
processDrag(e, DropPrefix.SidebarTrash, pageId => { processDrag(e, DropPrefix.SidebarTrash, pageId => {
setTrashModal({ setTrashModal({
open: true, open: true,
@@ -118,13 +118,13 @@ export const useSidebarDrag = () => {
}); });
}); });
}, },
[getPageMeta, processDrag, setTrashModal, t] [getDocMeta, processDrag, setTrashModal, t]
); );
const processFavouritesDrag = useCallback( const processFavouritesDrag = useCallback(
(e: DragEndEvent) => { (e: DragEndEvent) => {
const { pageId } = e.active.data.current as DraggableTitleCellData; const { pageId } = e.active.data.current as DraggableTitleCellData;
const isFavourited = getPageMeta(pageId)?.favorite; const isFavourited = getDocMeta(pageId)?.favorite;
const isFavouriteDrag = String(e.over?.id).startsWith( const isFavouriteDrag = String(e.over?.id).startsWith(
DropPrefix.SidebarFavorites DropPrefix.SidebarFavorites
); );
@@ -136,7 +136,7 @@ export const useSidebarDrag = () => {
toast(t['com.affine.cmdk.affine.editor.add-to-favourites']()); toast(t['com.affine.cmdk.affine.editor.add-to-favourites']());
}); });
}, },
[getPageMeta, processDrag, addToFavorite, t] [getDocMeta, processDrag, addToFavorite, t]
); );
const processRemoveDrag = useCallback( const processRemoveDrag = useCallback(
@@ -20,7 +20,7 @@ const useReactiveAdapter = (adapter: WorkspacePropertiesAdapter) => {
} }
const disposables: (() => void)[] = []; const disposables: (() => void)[] = [];
disposables.push( disposables.push(
adapter.workspace.blockSuiteWorkspace.meta.pageMetasUpdated.on(observe) adapter.workspace.blockSuiteWorkspace.meta.docMetaUpdated.on(observe)
.dispose .dispose
); );
adapter.properties.observeDeep(observe); adapter.properties.observeDeep(observe);
@@ -1,25 +1,25 @@
import type { PageMeta, Workspace } from '@blocksuite/store'; import type { DocMeta, Workspace } from '@blocksuite/store';
import type { Atom } from 'jotai'; import type { Atom } from 'jotai';
import { atom, useAtomValue } from 'jotai'; import { atom, useAtomValue } from 'jotai';
const weakMap = new WeakMap<Workspace, Atom<PageMeta[]>>(); const weakMap = new WeakMap<Workspace, Atom<DocMeta[]>>();
// this hook is extracted from './use-block-suite-page-meta.ts' to avoid circular dependency // this hook is extracted from './use-block-suite-page-meta.ts' to avoid circular dependency
export function useAllBlockSuitePageMeta( export function useAllBlockSuiteDocMeta(
blockSuiteWorkspace: Workspace blockSuiteWorkspace: Workspace
): PageMeta[] { ): DocMeta[] {
if (!weakMap.has(blockSuiteWorkspace)) { if (!weakMap.has(blockSuiteWorkspace)) {
const baseAtom = atom<PageMeta[]>(blockSuiteWorkspace.meta.pageMetas); const baseAtom = atom<DocMeta[]>(blockSuiteWorkspace.meta.docMetas);
weakMap.set(blockSuiteWorkspace, baseAtom); weakMap.set(blockSuiteWorkspace, baseAtom);
baseAtom.onMount = set => { baseAtom.onMount = set => {
set(blockSuiteWorkspace.meta.pageMetas); set(blockSuiteWorkspace.meta.docMetas);
const dispose = blockSuiteWorkspace.meta.pageMetasUpdated.on(() => { const dispose = blockSuiteWorkspace.meta.docMetaUpdated.on(() => {
set(blockSuiteWorkspace.meta.pageMetas); set(blockSuiteWorkspace.meta.docMetas);
}); });
return () => { return () => {
dispose.dispose(); dispose.dispose();
}; };
}; };
} }
return useAtomValue(weakMap.get(blockSuiteWorkspace) as Atom<PageMeta[]>); return useAtomValue(weakMap.get(blockSuiteWorkspace) as Atom<DocMeta[]>);
} }
@@ -1,17 +1,17 @@
import type { Page, Workspace } from '@blocksuite/store'; import type { Doc, Workspace } from '@blocksuite/store';
import { type Atom, atom, useAtomValue } from 'jotai'; import { type Atom, atom, useAtomValue } from 'jotai';
import { useBlockSuiteWorkspacePage } from './use-block-suite-workspace-page'; import { useBlockSuiteWorkspacePage } from './use-block-suite-workspace-page';
const weakMap = new WeakMap<Page, Atom<string[]>>(); const weakMap = new WeakMap<Doc, Atom<string[]>>();
function getPageBacklinks(page: Page): string[] { function getPageBacklinks(page: Doc): string[] {
return page.workspace.indexer.backlink return page.workspace.indexer.backlink
.getBacklink(page.id) .getBacklink(page.id)
.map(linkNode => linkNode.pageId) .map(linkNode => linkNode.pageId)
.filter(id => id !== page.id); .filter(id => id !== page.id);
} }
const getPageBacklinksAtom = (page: Page | null) => { const getPageBacklinksAtom = (page: Doc | null) => {
if (!page) { if (!page) {
return atom([]); return atom([]);
} }
@@ -1,9 +1,9 @@
import type { PageBlockModel } from '@blocksuite/blocks'; import type { RootBlockModel } from '@blocksuite/blocks';
import { assertExists } from '@blocksuite/global/utils'; import { assertExists } from '@blocksuite/global/utils';
import type { PageMeta, Workspace } from '@blocksuite/store'; import type { DocMeta, Workspace } from '@blocksuite/store';
import { useMemo } from 'react'; import { useMemo } from 'react';
import { useAllBlockSuitePageMeta } from './use-all-block-suite-page-meta'; import { useAllBlockSuiteDocMeta } from './use-all-block-suite-page-meta';
import { useJournalHelper } from './use-journal'; import { useJournalHelper } from './use-journal';
/** /**
@@ -11,8 +11,8 @@ import { useJournalHelper } from './use-journal';
* If you want to get all pageMetas, use `useAllBlockSuitePageMeta` instead * If you want to get all pageMetas, use `useAllBlockSuitePageMeta` instead
* @returns * @returns
*/ */
export function useBlockSuitePageMeta(blocksuiteWorkspace: Workspace) { export function useBlockSuiteDocMeta(blocksuiteWorkspace: Workspace) {
const pageMetas = useAllBlockSuitePageMeta(blocksuiteWorkspace); const pageMetas = useAllBlockSuiteDocMeta(blocksuiteWorkspace);
const { isPageJournal } = useJournalHelper(blocksuiteWorkspace); const { isPageJournal } = useJournalHelper(blocksuiteWorkspace);
return useMemo( return useMemo(
() => () =>
@@ -23,32 +23,32 @@ export function useBlockSuitePageMeta(blocksuiteWorkspace: Workspace) {
); );
} }
export function usePageMetaHelper(blockSuiteWorkspace: Workspace) { export function useDocMetaHelper(blockSuiteWorkspace: Workspace) {
return useMemo( return useMemo(
() => ({ () => ({
setPageTitle: (pageId: string, newTitle: string) => { setDocTitle: (docId: string, newTitle: string) => {
const page = blockSuiteWorkspace.getPage(pageId); const page = blockSuiteWorkspace.getDoc(docId);
assertExists(page); assertExists(page);
const pageBlock = page const pageBlock = page
.getBlockByFlavour('affine:page') .getBlockByFlavour('affine:page')
.at(0) as PageBlockModel; .at(0) as RootBlockModel;
assertExists(pageBlock); assertExists(pageBlock);
page.transact(() => { page.transact(() => {
pageBlock.title.delete(0, pageBlock.title.length); pageBlock.title.delete(0, pageBlock.title.length);
pageBlock.title.insert(newTitle, 0); pageBlock.title.insert(newTitle, 0);
}); });
blockSuiteWorkspace.meta.setPageMeta(pageId, { title: newTitle }); blockSuiteWorkspace.meta.setDocMeta(docId, { title: newTitle });
}, },
setPageReadonly: (pageId: string, readonly: boolean) => { setDocReadonly: (docId: string, readonly: boolean) => {
const page = blockSuiteWorkspace.getPage(pageId); const page = blockSuiteWorkspace.getDoc(docId);
assertExists(page); assertExists(page);
page.awarenessStore.setReadonly(page, readonly); page.awarenessStore.setReadonly(page, readonly);
}, },
setPageMeta: (pageId: string, pageMeta: Partial<PageMeta>) => { setDocMeta: (docId: string, docMeta: Partial<DocMeta>) => {
blockSuiteWorkspace.meta.setPageMeta(pageId, pageMeta); blockSuiteWorkspace.meta.setDocMeta(docId, docMeta);
}, },
getPageMeta: (pageId: string) => { getDocMeta: (docId: string) => {
return blockSuiteWorkspace.meta.getPageMeta(pageId); return blockSuiteWorkspace.meta.getDocMeta(docId);
}, },
}), }),
[blockSuiteWorkspace] [blockSuiteWorkspace]
@@ -1,16 +1,16 @@
import type { Page, Workspace } from '@blocksuite/store'; import type { Doc, Workspace } from '@blocksuite/store';
import { type Atom, atom, useAtomValue } from 'jotai'; import { type Atom, atom, useAtomValue } from 'jotai';
import { useBlockSuiteWorkspacePage } from './use-block-suite-workspace-page'; import { useBlockSuiteWorkspacePage } from './use-block-suite-workspace-page';
const weakMap = new WeakMap<Page, Atom<string[]>>(); const weakMap = new WeakMap<Doc, Atom<string[]>>();
function getPageReferences(page: Page): string[] { function getPageReferences(page: Doc): string[] {
return Object.values( return Object.values(
page.workspace.indexer.backlink.linkIndexMap[page.id] ?? {} page.workspace.indexer.backlink.linkIndexMap[page.id] ?? {}
).flatMap(linkNodes => linkNodes.map(linkNode => linkNode.pageId)); ).flatMap(linkNodes => linkNodes.map(linkNode => linkNode.pageId));
} }
const getPageReferencesAtom = (page: Page | null) => { const getPageReferencesAtom = (page: Doc | null) => {
if (!page) { if (!page) {
return atom([]); return atom([]);
} }
@@ -1,11 +1,11 @@
import type { Page, Workspace } from '@blocksuite/store'; import type { Doc, Workspace } from '@blocksuite/store';
import { useMemo } from 'react'; import { useMemo } from 'react';
export function useBlockSuiteWorkspaceHelper(blockSuiteWorkspace: Workspace) { export function useBlockSuiteWorkspaceHelper(blockSuiteWorkspace: Workspace) {
return useMemo( return useMemo(
() => ({ () => ({
createPage: (pageId?: string): Page => { createDoc: (pageId?: string): Doc => {
return blockSuiteWorkspace.createPage({ id: pageId }); return blockSuiteWorkspace.createDoc({ id: pageId });
}, },
}), }),
[blockSuiteWorkspace] [blockSuiteWorkspace]
@@ -15,11 +15,11 @@ function getAtom(w: Workspace, pageId: string): Atom<string> {
const map = weakMap.get(w); const map = weakMap.get(w);
assertExists(map); assertExists(map);
if (!map.has(pageId)) { if (!map.has(pageId)) {
const baseAtom = atom<string>(w.getPage(pageId)?.meta.title || 'Untitled'); const baseAtom = atom<string>(w.getDoc(pageId)?.meta?.title || 'Untitled');
baseAtom.onMount = set => { baseAtom.onMount = set => {
const disposable = w.meta.pageMetasUpdated.on(() => { const disposable = w.meta.docMetaUpdated.on(() => {
const page = w.getPage(pageId); const page = w.getDoc(pageId);
set(page?.meta.title || 'Untitled'); set(page?.meta?.title || 'Untitled');
}); });
return () => { return () => {
disposable.dispose(); disposable.dispose();
@@ -56,7 +56,7 @@ export function useGetBlockSuiteWorkspacePageTitle(
(pageId: string) => { (pageId: string) => {
return ( return (
getLocalizedJournalDateString(pageId) || getLocalizedJournalDateString(pageId) ||
blockSuiteWorkspace.getPage(pageId)?.meta.title blockSuiteWorkspace.getDoc(pageId)?.meta?.title
); );
}, },
[blockSuiteWorkspace, getLocalizedJournalDateString] [blockSuiteWorkspace, getLocalizedJournalDateString]
@@ -1,26 +1,26 @@
import { DisposableGroup } from '@blocksuite/global/utils'; import { DisposableGroup } from '@blocksuite/global/utils';
import type { Page, Workspace } from '@blocksuite/store'; import type { Doc, Workspace } from '@blocksuite/store';
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
export function useBlockSuiteWorkspacePage( export function useBlockSuiteWorkspacePage(
blockSuiteWorkspace: Workspace, blockSuiteWorkspace: Workspace,
pageId: string | null pageId: string | null
): Page | null { ): Doc | null {
const [page, setPage] = useState( const [page, setPage] = useState(
pageId ? blockSuiteWorkspace.getPage(pageId) : null pageId ? blockSuiteWorkspace.getDoc(pageId) : null
); );
useEffect(() => { useEffect(() => {
const group = new DisposableGroup(); const group = new DisposableGroup();
group.add( group.add(
blockSuiteWorkspace.slots.pageAdded.on(id => { blockSuiteWorkspace.slots.docAdded.on(id => {
if (pageId === id) { if (pageId === id) {
setPage(blockSuiteWorkspace.getPage(id)); setPage(blockSuiteWorkspace.getDoc(id));
} }
}) })
); );
group.add( group.add(
blockSuiteWorkspace.slots.pageRemoved.on(id => { blockSuiteWorkspace.slots.docRemoved.on(id => {
if (pageId === id) { if (pageId === id) {
setPage(null); setPage(null);
} }
@@ -32,9 +32,9 @@ export const useJournalHelper = (workspace: BlockSuiteWorkspace) => {
const _createJournal = useCallback( const _createJournal = useCallback(
(maybeDate: MaybeDate) => { (maybeDate: MaybeDate) => {
const title = dayjs(maybeDate).format(JOURNAL_DATE_FORMAT); const title = dayjs(maybeDate).format(JOURNAL_DATE_FORMAT);
const page = bsWorkspaceHelper.createPage(); const page = bsWorkspaceHelper.createDoc();
// set created date to match the journal date // set created date to match the journal date
page.workspace.setPageMeta(page.id, { page.workspace.setDocMeta(page.id, {
createDate: dayjs(maybeDate).toDate().getTime(), createDate: dayjs(maybeDate).toDate().getTime(),
}); });
initEmptyPage(page, title); initEmptyPage(page, title);
@@ -57,16 +57,16 @@ export const useJournalHelper = (workspace: BlockSuiteWorkspace) => {
const getJournalsByDate = useCallback( const getJournalsByDate = useCallback(
(maybeDate: MaybeDate) => { (maybeDate: MaybeDate) => {
const day = dayjs(maybeDate); const day = dayjs(maybeDate);
return Array.from(workspace.pages.values()).filter(page => { return Array.from(workspace.docs.values()).filter(page => {
const pageId = page.id; const pageId = page.id;
if (!isPageJournal(pageId)) return false; if (!isPageJournal(pageId)) return false;
if (page.meta.trash) return false; if (page.meta?.trash) return false;
const journalDate = adapter.getJournalPageDateString(page.id); const journalDate = adapter.getJournalPageDateString(page.id);
if (!journalDate) return false; if (!journalDate) return false;
return day.isSame(journalDate, 'day'); return day.isSame(journalDate, 'day');
}); });
}, },
[adapter, isPageJournal, workspace.pages] [adapter, isPageJournal, workspace.docs]
); );
/** /**
@@ -3,7 +3,7 @@ import {
appSidebarResizingAtom, appSidebarResizingAtom,
} from '@affine/component/app-sidebar'; } from '@affine/component/app-sidebar';
import { MainContainer, WorkspaceFallback } from '@affine/component/workspace'; import { MainContainer, WorkspaceFallback } from '@affine/component/workspace';
import { useBlockSuitePageMeta } from '@affine/core/hooks/use-block-suite-page-meta'; import { useBlockSuiteDocMeta } from '@affine/core/hooks/use-block-suite-page-meta';
import { useWorkspaceStatus } from '@affine/core/hooks/use-workspace-status'; import { useWorkspaceStatus } from '@affine/core/hooks/use-workspace-status';
import { assertExists } from '@blocksuite/global/utils'; import { assertExists } from '@blocksuite/global/utils';
import { import {
@@ -58,7 +58,7 @@ export const QuickSearch = () => {
const currentWorkspace = useService(Workspace); const currentWorkspace = useService(Workspace);
const { pageId } = useParams(); const { pageId } = useParams();
const blockSuiteWorkspace = currentWorkspace.blockSuiteWorkspace; const blockSuiteWorkspace = currentWorkspace.blockSuiteWorkspace;
const pageMeta = useBlockSuitePageMeta( const pageMeta = useBlockSuiteDocMeta(
currentWorkspace.blockSuiteWorkspace currentWorkspace.blockSuiteWorkspace
).find(meta => meta.id === pageId); ).find(meta => meta.id === pageId);
@@ -1,4 +1,4 @@
import type { PagesPropertiesMeta, Tag } from '@blocksuite/store'; import type { DocsPropertiesMeta, Tag } from '@blocksuite/store';
import { LiveData } from '@toeverything/infra/livedata'; import { LiveData } from '@toeverything/infra/livedata';
import type { Workspace } from '@toeverything/infra/workspace'; import type { Workspace } from '@toeverything/infra/workspace';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
@@ -20,18 +20,18 @@ export class WorkspaceLegacyProperties {
return this.properties.tags?.options ?? []; return this.properties.tags?.options ?? [];
} }
updateProperties = (properties: PagesPropertiesMeta) => { updateProperties = (properties: DocsPropertiesMeta) => {
this.workspace.blockSuiteWorkspace.meta.setProperties(properties); this.workspace.blockSuiteWorkspace.meta.setProperties(properties);
}; };
subscribe(cb: () => void) { subscribe(cb: () => void) {
const disposable = const disposable =
this.workspace.blockSuiteWorkspace.meta.pageMetasUpdated.on(cb); this.workspace.blockSuiteWorkspace.meta.docMetaUpdated.on(cb);
return disposable.dispose; return disposable.dispose;
} }
properties$ = LiveData.from( properties$ = LiveData.from(
new Observable<PagesPropertiesMeta>(sub => { new Observable<DocsPropertiesMeta>(sub => {
return this.subscribe(() => sub.next(this.properties)); return this.subscribe(() => sub.next(this.properties));
}), }),
this.properties this.properties
@@ -61,11 +61,11 @@ export class WorkspaceLegacyProperties {
this.workspace.blockSuiteWorkspace.doc.transact(() => { this.workspace.blockSuiteWorkspace.doc.transact(() => {
this.updateTagOptions(this.tagOptions.filter(o => o.id !== id)); this.updateTagOptions(this.tagOptions.filter(o => o.id !== id));
// need to remove tag from all pages // need to remove tag from all pages
this.workspace.blockSuiteWorkspace.pages.forEach(page => { this.workspace.blockSuiteWorkspace.docs.forEach(doc => {
const tags = page.meta.tags ?? []; const tags = doc.meta?.tags ?? [];
if (tags.includes(id)) { if (tags.includes(id)) {
this.updatePageTags( this.updatePageTags(
page.id, doc.id,
tags.filter(t => t !== id) tags.filter(t => t !== id)
); );
} }
@@ -74,7 +74,7 @@ export class WorkspaceLegacyProperties {
}; };
updatePageTags = (pageId: string, tags: string[]) => { updatePageTags = (pageId: string, tags: string[]) => {
this.workspace.blockSuiteWorkspace.setPageMeta(pageId, { this.workspace.blockSuiteWorkspace.setDocMeta(pageId, {
tags, tags,
}); });
}; };
@@ -10,7 +10,7 @@ import {
StaticBlobStorage, StaticBlobStorage,
} from '@affine/workspace-impl'; } from '@affine/workspace-impl';
import { Logo1Icon } from '@blocksuite/icons'; import { Logo1Icon } from '@blocksuite/icons';
import type { Page } from '@toeverything/infra'; import type { Doc } from '@toeverything/infra';
import { import {
EmptyBlobStorage, EmptyBlobStorage,
LocalBlobStorage, LocalBlobStorage,
@@ -130,7 +130,7 @@ export const Component = () => {
const currentWorkspace = useService(CurrentWorkspaceService); const currentWorkspace = useService(CurrentWorkspaceService);
const t = useAFFiNEI18N(); const t = useAFFiNEI18N();
const [page, setPage] = useState<Page | null>(null); const [page, setPage] = useState<Doc | null>(null);
useEffect(() => { useEffect(() => {
// create a workspace for share page // create a workspace for share page
@@ -163,7 +163,7 @@ export const Component = () => {
const { page } = workspace.services.get(PageManager).open(pageId); const { page } = workspace.services.get(PageManager).open(pageId);
workspace.blockSuiteWorkspace.awarenessStore.setReadonly( workspace.blockSuiteWorkspace.awarenessStore.setReadonly(
page.blockSuitePage, page.blockSuiteDoc,
true true
); );
@@ -200,14 +200,14 @@ export const Component = () => {
<ShareHeader <ShareHeader
pageId={page.id} pageId={page.id}
publishMode={publishMode} publishMode={publishMode}
blockSuiteWorkspace={page.blockSuitePage.workspace} blockSuiteWorkspace={page.blockSuiteDoc.workspace}
/> />
<Scrollable.Root> <Scrollable.Root>
<Scrollable.Viewport className={styles.editorContainer}> <Scrollable.Viewport className={styles.editorContainer}>
<PageDetailEditor <PageDetailEditor
isPublic isPublic
publishMode={publishMode} publishMode={publishMode}
workspace={page.blockSuitePage.workspace} workspace={page.blockSuiteDoc.workspace}
pageId={page.id} pageId={page.id}
onLoad={() => noop} onLoad={() => noop}
/> />
@@ -4,7 +4,7 @@ import {
useFilteredPageMetas, useFilteredPageMetas,
VirtualizedPageList, VirtualizedPageList,
} from '@affine/core/components/page-list'; } from '@affine/core/components/page-list';
import { useBlockSuitePageMeta } from '@affine/core/hooks/use-block-suite-page-meta'; import { useBlockSuiteDocMeta } from '@affine/core/hooks/use-block-suite-page-meta';
import { useNavigateHelper } from '@affine/core/hooks/use-navigate-helper'; import { useNavigateHelper } from '@affine/core/hooks/use-navigate-helper';
import { performanceRenderLogger } from '@affine/core/shared'; import { performanceRenderLogger } from '@affine/core/shared';
import type { Filter } from '@affine/env/filter'; import type { Filter } from '@affine/env/filter';
@@ -18,7 +18,7 @@ import { AllPageHeader } from './all-page-header';
export const AllPage = () => { export const AllPage = () => {
const currentWorkspace = useService(Workspace); const currentWorkspace = useService(Workspace);
const pageMetas = useBlockSuitePageMeta(currentWorkspace.blockSuiteWorkspace); const pageMetas = useBlockSuiteDocMeta(currentWorkspace.blockSuiteWorkspace);
const [hideHeaderCreateNew, setHideHeaderCreateNew] = useState(true); const [hideHeaderCreateNew, setHideHeaderCreateNew] = useState(true);
const [filters, setFilters] = useState<Filter[]>([]); const [filters, setFilters] = useState<Filter[]>([]);
@@ -58,10 +58,10 @@ export const Component = () => {
useEffect(() => { useEffect(() => {
function checkJumpOnce() { function checkJumpOnce() {
for (const [pageId] of currentWorkspace.blockSuiteWorkspace.pages) { for (const [pageId] of currentWorkspace.blockSuiteWorkspace.docs) {
const page = currentWorkspace.blockSuiteWorkspace.getPage(pageId); const page = currentWorkspace.blockSuiteWorkspace.getDoc(pageId);
if (page && page.meta.jumpOnce) { if (page && page.meta?.jumpOnce) {
currentWorkspace.blockSuiteWorkspace.meta.setPageMeta(page.id, { currentWorkspace.blockSuiteWorkspace.meta.setDocMeta(page.id, {
jumpOnce: false, jumpOnce: false,
}); });
navigateHelper.jumpToPage(currentWorkspace.id, pageId); navigateHelper.jumpToPage(currentWorkspace.id, pageId);
@@ -69,7 +69,7 @@ export const Component = () => {
} }
} }
checkJumpOnce(); checkJumpOnce();
return currentWorkspace.blockSuiteWorkspace.slots.pagesUpdated.on( return currentWorkspace.blockSuiteWorkspace.slots.docUpdated.on(
checkJumpOnce checkJumpOnce
).dispose; ).dispose;
}, [ }, [
@@ -4,7 +4,7 @@ import {
TagListHeader, TagListHeader,
VirtualizedTagList, VirtualizedTagList,
} from '@affine/core/components/page-list/tags'; } from '@affine/core/components/page-list/tags';
import { useBlockSuitePageMeta } from '@affine/core/hooks/use-block-suite-page-meta'; import { useBlockSuiteDocMeta } from '@affine/core/hooks/use-block-suite-page-meta';
import { useService } from '@toeverything/infra'; import { useService } from '@toeverything/infra';
import { Workspace } from '@toeverything/infra'; import { Workspace } from '@toeverything/infra';
@@ -14,7 +14,7 @@ import { AllTagHeader } from './header';
export const AllTag = () => { export const AllTag = () => {
const currentWorkspace = useService(Workspace); const currentWorkspace = useService(Workspace);
const pageMetas = useBlockSuitePageMeta(currentWorkspace.blockSuiteWorkspace); const pageMetas = useBlockSuiteDocMeta(currentWorkspace.blockSuiteWorkspace);
const { tags, tagMetas, deleteTags } = useTagMetas( const { tags, tagMetas, deleteTags } = useTagMetas(
currentWorkspace.blockSuiteWorkspace, currentWorkspace.blockSuiteWorkspace,
@@ -12,7 +12,7 @@ import { PageHeaderMenuButton } from '@affine/core/components/blocksuite/block-s
import { EditorModeSwitch } from '@affine/core/components/blocksuite/block-suite-mode-switch'; import { EditorModeSwitch } from '@affine/core/components/blocksuite/block-suite-mode-switch';
import { useJournalInfoHelper } from '@affine/core/hooks/use-journal'; import { useJournalInfoHelper } from '@affine/core/hooks/use-journal';
import { RightSidebarIcon } from '@blocksuite/icons'; import { RightSidebarIcon } from '@blocksuite/icons';
import type { Page } from '@blocksuite/store'; import type { Doc } from '@blocksuite/store';
import type { Workspace } from '@toeverything/infra'; import type { Workspace } from '@toeverything/infra';
import { useAtomValue, useSetAtom } from 'jotai'; import { useAtomValue, useSetAtom } from 'jotai';
import { useCallback, useRef } from 'react'; import { useCallback, useRef } from 'react';
@@ -104,7 +104,7 @@ function Header({
} }
interface PageHeaderProps { interface PageHeaderProps {
page: Page; page: Doc;
workspace: Workspace; workspace: Workspace;
showSidebarSwitch?: boolean; showSidebarSwitch?: boolean;
} }
@@ -178,7 +178,7 @@ export function NormalPageHeader({
export function DetailPageHeader(props: PageHeaderProps) { export function DetailPageHeader(props: PageHeaderProps) {
const { page } = props; const { page } = props;
const { isJournal } = useJournalInfoHelper(page.workspace, page.id); const { isJournal } = useJournalInfoHelper(page.workspace, page.id);
const isInTrash = page.meta.trash; const isInTrash = page.meta?.trash;
return isJournal && !isInTrash ? ( return isJournal && !isInTrash ? (
<JournalPageHeader {...props} /> <JournalPageHeader {...props} />
@@ -189,7 +189,7 @@ export function DetailPageHeader(props: PageHeaderProps) {
interface SidebarHeaderProps { interface SidebarHeaderProps {
workspace: Workspace; workspace: Workspace;
page: Page; page: Doc;
} }
function WindowsSidebarHeader(props: SidebarHeaderProps) { function WindowsSidebarHeader(props: SidebarHeaderProps) {
return ( return (
@@ -1,8 +1,7 @@
import { Scrollable } from '@affine/component'; import { Scrollable } from '@affine/component';
import { PageDetailSkeleton } from '@affine/component/page-detail-skeleton'; import { PageDetailSkeleton } from '@affine/component/page-detail-skeleton';
import { ResizePanel } from '@affine/component/resize-panel'; import { ResizePanel } from '@affine/component/resize-panel';
import { useBlockSuitePageMeta } from '@affine/core/hooks/use-block-suite-page-meta'; import { useBlockSuiteDocMeta } from '@affine/core/hooks/use-block-suite-page-meta';
import type { PageService } from '@blocksuite/blocks';
import { import {
BookmarkService, BookmarkService,
customImageProxyMiddleware, customImageProxyMiddleware,
@@ -12,10 +11,10 @@ import {
ImageService, ImageService,
} from '@blocksuite/blocks'; } from '@blocksuite/blocks';
import type { AffineEditorContainer } from '@blocksuite/presets'; import type { AffineEditorContainer } from '@blocksuite/presets';
import type { Page as BlockSuitePage } from '@blocksuite/store'; import type { Doc as BlockSuiteDoc } from '@blocksuite/store';
import { import {
Doc,
globalBlockSuiteSchema, globalBlockSuiteSchema,
Page,
PageManager, PageManager,
PageRecordList, PageRecordList,
ServiceProviderContext, ServiceProviderContext,
@@ -109,14 +108,14 @@ const DetailPageLayout = ({
}; };
const DetailPageImpl = memo(function DetailPageImpl() { const DetailPageImpl = memo(function DetailPageImpl() {
const page = useService(Page); const page = useService(Doc);
const pageRecordList = useService(PageRecordList); const pageRecordList = useService(PageRecordList);
const currentPageId = page.id; const currentPageId = page.id;
const { openPage, jumpToTag } = useNavigateHelper(); const { openPage, jumpToTag } = useNavigateHelper();
const currentWorkspace = useService(Workspace); const currentWorkspace = useService(Workspace);
const blockSuiteWorkspace = currentWorkspace.blockSuiteWorkspace; const blockSuiteWorkspace = currentWorkspace.blockSuiteWorkspace;
const pageMeta = useBlockSuitePageMeta(blockSuiteWorkspace).find( const pageMeta = useBlockSuiteDocMeta(blockSuiteWorkspace).find(
meta => meta.id === page.id meta => meta.id === page.id
); );
@@ -128,7 +127,7 @@ const DetailPageImpl = memo(function DetailPageImpl() {
usePageDocumentTitle(title); usePageDocumentTitle(title);
const onLoad = useCallback( const onLoad = useCallback(
(bsPage: BlockSuitePage, editor: AffineEditorContainer) => { (bsPage: BlockSuiteDoc, editor: AffineEditorContainer) => {
try { try {
// todo(joooye34): improve the following migration code // todo(joooye34): improve the following migration code
const surfaceBlock = bsPage.getBlockByFlavour('affine:surface')[0]; const surfaceBlock = bsPage.getBlockByFlavour('affine:surface')[0];
@@ -139,7 +138,7 @@ const DetailPageImpl = memo(function DetailPageImpl() {
'type' 'type'
) !== '$blocksuite:internal:native$' ) !== '$blocksuite:internal:native$'
) { ) {
globalBlockSuiteSchema.upgradePage( globalBlockSuiteSchema.upgradeDoc(
0, 0,
{ {
'affine:surface': 3, 'affine:surface': 3,
@@ -165,12 +164,10 @@ const DetailPageImpl = memo(function DetailPageImpl() {
EmbedLoomService.setLinkPreviewEndpoint(runtimeConfig.linkPreviewUrl); EmbedLoomService.setLinkPreviewEndpoint(runtimeConfig.linkPreviewUrl);
// provide page mode and updated date to blocksuite // provide page mode and updated date to blocksuite
const pageService = editorHost.std.spec.getService( const pageService = editorHost.std.spec.getService('affine:page');
'affine:page' pageService.getEditorMode = (pageId: string) =>
) as PageService;
pageService.getPageMode = (pageId: string) =>
pageRecordList.record(pageId).value?.mode.value ?? 'page'; pageRecordList.record(pageId).value?.mode.value ?? 'page';
pageService.getPageUpdatedAt = (pageId: string) => { pageService.getDocUpdatedAt = (pageId: string) => {
const linkedPage = pageRecordList.record(pageId).value; const linkedPage = pageRecordList.record(pageId).value;
if (!linkedPage) return new Date(); if (!linkedPage) return new Date();
@@ -181,8 +178,8 @@ const DetailPageImpl = memo(function DetailPageImpl() {
page.setMode(mode); page.setMode(mode);
// fixme: it seems pageLinkClicked is not triggered sometimes? // fixme: it seems pageLinkClicked is not triggered sometimes?
const dispose = editor.slots.pageLinkClicked.on(({ pageId }) => { const dispose = editor.slots.docLinkClicked.on(({ docId }) => {
return openPage(blockSuiteWorkspace.id, pageId); return openPage(blockSuiteWorkspace.id, docId);
}); });
const disposeTagClick = editor.slots.tagClicked.on(({ tagId }) => { const disposeTagClick = editor.slots.tagClicked.on(({ tagId }) => {
jumpToTag(currentWorkspace.id, tagId); jumpToTag(currentWorkspace.id, tagId);
@@ -209,7 +206,7 @@ const DetailPageImpl = memo(function DetailPageImpl() {
header={ header={
<> <>
<DetailPageHeader <DetailPageHeader
page={page.blockSuitePage} page={page.blockSuiteDoc}
workspace={currentWorkspace} workspace={currentWorkspace}
showSidebarSwitch={!isInTrash} showSidebarSwitch={!isInTrash}
/> />
@@ -238,11 +235,11 @@ const DetailPageImpl = memo(function DetailPageImpl() {
<div className={styles.sidebarContainerInner}> <div className={styles.sidebarContainerInner}>
<RightSidebarHeader <RightSidebarHeader
workspace={currentWorkspace} workspace={currentWorkspace}
page={page.blockSuitePage} page={page.blockSuiteDoc}
/> />
<EditorSidebar <EditorSidebar
workspace={blockSuiteWorkspace} workspace={blockSuiteWorkspace}
page={page.blockSuitePage} page={page.blockSuiteDoc}
/> />
</div> </div>
) : null ) : null
@@ -271,7 +268,7 @@ export const DetailPage = ({ pageId }: { pageId: string }): ReactElement => {
const pageManager = useService(PageManager); const pageManager = useService(PageManager);
const [page, setPage] = useState<Page | null>(null); const [page, setPage] = useState<Doc | null>(null);
useEffect(() => { useEffect(() => {
if (!pageRecord) { if (!pageRecord) {
@@ -2,7 +2,7 @@ import { IconButton } from '@affine/component';
import { useJournalInfoHelper } from '@affine/core/hooks/use-journal'; import { useJournalInfoHelper } from '@affine/core/hooks/use-journal';
import { useWorkspaceEnabledFeatures } from '@affine/core/hooks/use-workspace-features'; import { useWorkspaceEnabledFeatures } from '@affine/core/hooks/use-workspace-features';
import { FeatureType } from '@affine/graphql'; import { FeatureType } from '@affine/graphql';
import type { Page } from '@blocksuite/store'; import type { Doc } from '@blocksuite/store';
import type { Workspace } from '@toeverything/infra'; import type { Workspace } from '@toeverything/infra';
import { assignInlineVars } from '@vanilla-extract/dynamic'; import { assignInlineVars } from '@vanilla-extract/dynamic';
import { useAtom, useAtomValue } from 'jotai'; import { useAtom, useAtomValue } from 'jotai';
@@ -16,7 +16,7 @@ import * as styles from './extensions.css';
export interface ExtensionTabsProps { export interface ExtensionTabsProps {
workspace: Workspace; workspace: Workspace;
page: Page; page: Doc;
} }
// provide a switcher for active extensions // provide a switcher for active extensions
@@ -7,7 +7,7 @@ import {
} from '@affine/component'; } from '@affine/component';
import { MoveToTrash } from '@affine/core/components/page-list'; import { MoveToTrash } from '@affine/core/components/page-list';
import { useTrashModalHelper } from '@affine/core/hooks/affine/use-trash-modal-helper'; import { useTrashModalHelper } from '@affine/core/hooks/affine/use-trash-modal-helper';
import { useBlockSuitePageMeta } from '@affine/core/hooks/use-block-suite-page-meta'; import { useBlockSuiteDocMeta } from '@affine/core/hooks/use-block-suite-page-meta';
import { useBlockSuiteWorkspacePageTitle } from '@affine/core/hooks/use-block-suite-workspace-page-title'; import { useBlockSuiteWorkspacePageTitle } from '@affine/core/hooks/use-block-suite-workspace-page-title';
import { import {
useJournalHelper, useJournalHelper,
@@ -23,7 +23,7 @@ import {
PageIcon, PageIcon,
TodayIcon, TodayIcon,
} from '@blocksuite/icons'; } from '@blocksuite/icons';
import type { Page, PageMeta } from '@blocksuite/store'; import type { Doc, DocMeta } from '@blocksuite/store';
import { assignInlineVars } from '@vanilla-extract/dynamic'; import { assignInlineVars } from '@vanilla-extract/dynamic';
import clsx from 'clsx'; import clsx from 'clsx';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
@@ -44,7 +44,7 @@ const CountDisplay = ({
return <span {...attrs}>{count > max ? `${max}+` : count}</span>; return <span {...attrs}>{count > max ? `${max}+` : count}</span>;
}; };
interface PageItemProps extends HTMLAttributes<HTMLDivElement> { interface PageItemProps extends HTMLAttributes<HTMLDivElement> {
pageMeta: PageMeta; pageMeta: DocMeta;
workspace: BlockSuiteWorkspace; workspace: BlockSuiteWorkspace;
right?: ReactNode; right?: ReactNode;
} }
@@ -156,7 +156,7 @@ const EditorJournalPanel = (props: EditorExtensionProps) => {
}; };
const sortPagesByDate = ( const sortPagesByDate = (
pages: PageMeta[], pages: DocMeta[],
field: 'updatedDate' | 'createDate', field: 'updatedDate' | 'createDate',
order: 'asc' | 'desc' = 'desc' order: 'asc' | 'desc' = 'desc'
) => { ) => {
@@ -180,7 +180,7 @@ const JournalDailyCountBlock = ({ workspace, date }: JournalBlockProps) => {
const nodeRef = useRef<HTMLDivElement>(null); const nodeRef = useRef<HTMLDivElement>(null);
const t = useAFFiNEI18N(); const t = useAFFiNEI18N();
const [activeItem, setActiveItem] = useState<NavItemName>('createdToday'); const [activeItem, setActiveItem] = useState<NavItemName>('createdToday');
const pageMetas = useBlockSuitePageMeta(workspace); const pageMetas = useBlockSuiteDocMeta(workspace);
const navigateHelper = useNavigateHelper(); const navigateHelper = useNavigateHelper();
@@ -289,7 +289,7 @@ interface ConflictListProps
extends JournalBlockProps, extends JournalBlockProps,
PropsWithChildren, PropsWithChildren,
HTMLAttributes<HTMLDivElement> { HTMLAttributes<HTMLDivElement> {
pages: Page[]; pages: Doc[];
} }
const ConflictList = ({ const ConflictList = ({
page: currentPage, page: currentPage,
@@ -303,7 +303,7 @@ const ConflictList = ({
const { setTrashModal } = useTrashModalHelper(workspace); const { setTrashModal } = useTrashModalHelper(workspace);
const handleOpenTrashModal = useCallback( const handleOpenTrashModal = useCallback(
(page: Page) => { (page: Doc) => {
if (!page.meta) return; if (!page.meta) return;
setTrashModal({ setTrashModal({
open: true, open: true,
@@ -320,9 +320,9 @@ const ConflictList = ({
const isCurrent = page.id === currentPage.id; const isCurrent = page.id === currentPage.id;
return ( return (
<PageItem <PageItem
aria-label={page.meta.title} aria-label={page.meta?.title}
aria-selected={isCurrent} aria-selected={isCurrent}
pageMeta={page.meta} pageMeta={page.meta as DocMeta}
workspace={workspace} workspace={workspace}
key={page.id} key={page.id}
right={ right={
@@ -1,11 +1,11 @@
import type { BlockSuiteWorkspace } from '@affine/core/shared'; import type { BlockSuiteWorkspace } from '@affine/core/shared';
import type { Page } from '@blocksuite/store'; import type { Doc } from '@blocksuite/store';
export type EditorExtensionName = 'outline' | 'frame' | 'copilot' | 'journal'; export type EditorExtensionName = 'outline' | 'frame' | 'copilot' | 'journal';
export interface EditorExtensionProps { export interface EditorExtensionProps {
workspace: BlockSuiteWorkspace; workspace: BlockSuiteWorkspace;
page: Page; page: Doc;
} }
export interface EditorExtension { export interface EditorExtension {
Loaded 100 of 121 files, more files were not shown because too many files have changed in this diff. Show more