mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-12 12:28:42 +00:00
Compare commits
206 Commits
v0.7.0-bet
...
v0.7.0-can
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4109490789 | ||
|
|
e813436af7 | ||
|
|
5b87d90ffe | ||
|
|
ccbae6f496 | ||
|
|
1ac1c33bb1 | ||
|
|
bd42380f8a | ||
|
|
30dee18835 | ||
|
|
b509302711 | ||
|
|
e51c98c1dd | ||
|
|
bbb1387469 | ||
|
|
4f88774999 | ||
|
|
3968deb6d4 | ||
|
|
37c8465af8 | ||
|
|
d88a21d24a | ||
|
|
6ad2d106bc | ||
|
|
8c1fcee135 | ||
|
|
0514da9759 | ||
|
|
b2fed03f30 | ||
|
|
f5e45573af | ||
|
|
ddb2931f38 | ||
|
|
acf17ebace | ||
|
|
7af3c05b8b | ||
|
|
01de2ae714 | ||
|
|
cfa18d1bc3 | ||
|
|
127c63601e | ||
|
|
f079b0b49a | ||
|
|
6caf934d47 | ||
|
|
2f910fbad0 | ||
|
|
dac4e390aa | ||
|
|
812e0e9c9a | ||
|
|
05291a8a36 | ||
|
|
8bcc4d6a57 | ||
|
|
e06d5e1c8d | ||
|
|
1c8895f23f | ||
|
|
8b5d997322 | ||
|
|
33644a68b2 | ||
|
|
bc85ad5b65 | ||
|
|
fe895905bd | ||
|
|
3c5ccd7231 | ||
|
|
da140b0b85 | ||
|
|
c4d53d59b5 | ||
|
|
a48726d088 | ||
|
|
b49306607b | ||
|
|
3d15c60cb1 | ||
|
|
283f0cd263 | ||
|
|
66152401be | ||
|
|
b12412a3c1 | ||
|
|
ce1e8d868c | ||
|
|
3294043180 | ||
|
|
152fbaabda | ||
|
|
5756bdf8d7 | ||
|
|
80ee33fd3e | ||
|
|
955d80e2c1 | ||
|
|
67fe7f04da | ||
|
|
6395521f09 | ||
|
|
822078e640 | ||
|
|
fafd93f7dc | ||
|
|
00ce086e79 | ||
|
|
28653d6892 | ||
|
|
e30c67482f | ||
|
|
bda28e0404 | ||
|
|
ce63364299 | ||
|
|
f468dff6aa | ||
|
|
fab03006e8 | ||
|
|
8a565b8633 | ||
|
|
e79a6a5d47 | ||
|
|
95c2e20cb5 | ||
|
|
2e0f410978 | ||
|
|
fa1cd87348 | ||
|
|
e95d28e136 | ||
|
|
87ba71e77e | ||
|
|
dec0c0d3d1 | ||
|
|
776172bc88 | ||
|
|
d582548ed8 | ||
|
|
70ac31b907 | ||
|
|
cff9fd1ead | ||
|
|
319febb00d | ||
|
|
72fa2da2d3 | ||
|
|
3084c427f1 | ||
|
|
9cd1f013f8 | ||
|
|
a3f58d4302 | ||
|
|
d4cb89eafc | ||
|
|
33ba034336 | ||
|
|
e158c09160 | ||
|
|
c6ccd6d5de | ||
|
|
ec87864c34 | ||
|
|
a06ba403d0 | ||
|
|
dfbec46ded | ||
|
|
24be73ef63 | ||
|
|
3976c37d41 | ||
|
|
2bc15665b9 | ||
|
|
e4539dfeb1 | ||
|
|
1070e17310 | ||
|
|
b4f7eb36ef | ||
|
|
000f802baa | ||
|
|
e871ffcba0 | ||
|
|
8d2ffe3936 | ||
|
|
9e253420d2 | ||
|
|
edb7847e95 | ||
|
|
3d70148e0f | ||
|
|
7f89b197da | ||
|
|
32692bd54a | ||
|
|
7b2acec7c3 | ||
|
|
f1adf23631 | ||
|
|
a5d2fafad6 | ||
|
|
3d0a907b49 | ||
|
|
bacd00655d | ||
|
|
08e003b0f6 | ||
|
|
0f1c5163a1 | ||
|
|
18874d0d1e | ||
|
|
7f0a74c694 | ||
|
|
901fc87716 | ||
|
|
ee2ab4086f | ||
|
|
af94674c18 | ||
|
|
262289a398 | ||
|
|
467eab4ddf | ||
|
|
63517e4912 | ||
|
|
6f9487deb7 | ||
|
|
8d0edd5255 | ||
|
|
bdea153c82 | ||
|
|
d447883b7d | ||
|
|
03ec51a96c | ||
|
|
0adf18f5e6 | ||
|
|
5e7dc9ff21 | ||
|
|
33097382c6 | ||
|
|
b9df2cdabb | ||
|
|
158338508a | ||
|
|
640967d9ae | ||
|
|
ec973395da | ||
|
|
b35d99d935 | ||
|
|
c0f6e751d2 | ||
|
|
6af454ceed | ||
|
|
ed829dd43b | ||
|
|
a9adb4dda2 | ||
|
|
54a7eeda37 | ||
|
|
711e683c6f | ||
|
|
81c5e6d3d2 | ||
|
|
7a5a5d503a | ||
|
|
b597dbd80f | ||
|
|
ebdf724012 | ||
|
|
14f63e91a9 | ||
|
|
ad218ec65d | ||
|
|
9fda82564b | ||
|
|
a52fc54d80 | ||
|
|
524c342b5e | ||
|
|
f4fc084a0a | ||
|
|
38a2aa9d17 | ||
|
|
9e90242ddb | ||
|
|
fd0c1da608 | ||
|
|
68c4fccf98 | ||
|
|
3c93f4162d | ||
|
|
b6c314e180 | ||
|
|
62b465a889 | ||
|
|
9d0db78f64 | ||
|
|
d3393cb0fc | ||
|
|
79cded302f | ||
|
|
53d90a11de | ||
|
|
271ad57160 | ||
|
|
4adbe64a54 | ||
|
|
50a8a147fd | ||
|
|
eaea8e9368 | ||
|
|
9873baae9f | ||
|
|
bc3ce7395e | ||
|
|
8a7908c692 | ||
|
|
8021efd81a | ||
|
|
d7fcad2d0d | ||
|
|
b1d2d77263 | ||
|
|
2c772bd81b | ||
|
|
7f00011542 | ||
|
|
f76d8b8818 | ||
|
|
1d6b39dec9 | ||
|
|
5cfdf6c7e2 | ||
|
|
8410d83744 | ||
|
|
8a2dac9718 | ||
|
|
5ad2908760 | ||
|
|
5b8771485e | ||
|
|
ed8480caf0 | ||
|
|
42ef3c0fc2 | ||
|
|
e08ee9b7ff | ||
|
|
2c95bfcc3d | ||
|
|
86616e152d | ||
|
|
b1f478ee5e | ||
|
|
6b0f9fbdad | ||
|
|
da3f2b784a | ||
|
|
acb140ab78 | ||
|
|
0b74bd9bfe | ||
|
|
acfc030d16 | ||
|
|
d0d04ce376 | ||
|
|
2250f42d2a | ||
|
|
887434fea4 | ||
|
|
9b817c4b79 | ||
|
|
ea03bbfb2d | ||
|
|
db40cd35c6 | ||
|
|
aabac9e921 | ||
|
|
0a91c41e0a | ||
|
|
d6addc0d0b | ||
|
|
91d3b76be5 | ||
|
|
3eed009270 | ||
|
|
bc14d54cfa | ||
|
|
5496969e58 | ||
|
|
80c2a78273 | ||
|
|
92f378aefc | ||
|
|
877ceee698 | ||
|
|
7960b6a22e | ||
|
|
fa45d8a718 | ||
|
|
87574c9993 |
@@ -22,9 +22,7 @@
|
||||
"templates",
|
||||
"y-indexeddb",
|
||||
"debug",
|
||||
"storage",
|
||||
"infra",
|
||||
"plugin-infra"
|
||||
"storage"
|
||||
]
|
||||
]
|
||||
}
|
||||
|
||||
1
.github/workflows/build.yml
vendored
1
.github/workflows/build.yml
vendored
@@ -232,7 +232,6 @@ jobs:
|
||||
|
||||
- name: Run playwright tests
|
||||
run: yarn e2e --forbid-only --shard=${{ matrix.shard }}/${{ strategy.job-total }}
|
||||
working-directory: tests/affine-local
|
||||
env:
|
||||
COVERAGE: true
|
||||
|
||||
|
||||
2
.github/workflows/nightly-build.yml
vendored
2
.github/workflows/nightly-build.yml
vendored
@@ -34,7 +34,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
environment: production
|
||||
outputs:
|
||||
version: 0.0.0-internal.${{ steps.version.outputs.version }}
|
||||
version: 0.0.0-${{ steps.version.outputs.version }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: toeverything/set-build-version@latest
|
||||
|
||||
7
.gitignore
vendored
7
.gitignore
vendored
@@ -60,10 +60,9 @@ out/
|
||||
storybook-static
|
||||
i18n-generated.ts
|
||||
|
||||
test-results
|
||||
playwright-report
|
||||
playwright/.cache
|
||||
download
|
||||
/test-results/
|
||||
/playwright-report/
|
||||
/playwright/.cache/
|
||||
|
||||
# Cache
|
||||
.eslintcache
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@affine/docs",
|
||||
"version": "0.7.0-beta.0",
|
||||
"version": "0.7.0-canary.42",
|
||||
"type": "module",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
@@ -10,12 +10,12 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@affine/component": "workspace:*",
|
||||
"@blocksuite/block-std": "0.0.0-20230717055529-79180930-nightly",
|
||||
"@blocksuite/blocks": "0.0.0-20230717055529-79180930-nightly",
|
||||
"@blocksuite/editor": "0.0.0-20230717055529-79180930-nightly",
|
||||
"@blocksuite/global": "0.0.0-20230717055529-79180930-nightly",
|
||||
"@blocksuite/lit": "0.0.0-20230717055529-79180930-nightly",
|
||||
"@blocksuite/store": "0.0.0-20230717055529-79180930-nightly",
|
||||
"@blocksuite/block-std": "0.0.0-20230711103520-ce18dd84-nightly",
|
||||
"@blocksuite/blocks": "0.0.0-20230711103520-ce18dd84-nightly",
|
||||
"@blocksuite/editor": "0.0.0-20230711103520-ce18dd84-nightly",
|
||||
"@blocksuite/global": "0.0.0-20230711103520-ce18dd84-nightly",
|
||||
"@blocksuite/lit": "0.0.0-20230711103520-ce18dd84-nightly",
|
||||
"@blocksuite/store": "0.0.0-20230711103520-ce18dd84-nightly",
|
||||
"express": "^4.18.2",
|
||||
"jotai": "^2.2.2",
|
||||
"react": "18.3.0-canary-1fdacbefd-20230630",
|
||||
|
||||
@@ -26,6 +26,10 @@ export const test = base.extend<{
|
||||
appData: string;
|
||||
sessionData: string;
|
||||
};
|
||||
workspace: {
|
||||
// get current workspace
|
||||
current: () => Promise<any>; // todo: type
|
||||
};
|
||||
router: {
|
||||
goto: (path: RoutePath) => Promise<void>;
|
||||
};
|
||||
@@ -117,4 +121,14 @@ export const test = base.extend<{
|
||||
});
|
||||
await use(appInfo);
|
||||
},
|
||||
workspace: async ({ page }, use) => {
|
||||
await use({
|
||||
current: async () => {
|
||||
return await page.evaluate(async () => {
|
||||
// @ts-expect-error
|
||||
return globalThis.currentWorkspace;
|
||||
});
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@affine/electron",
|
||||
"private": true,
|
||||
"version": "0.7.0-beta.0",
|
||||
"version": "0.7.0-canary.42",
|
||||
"author": "affine",
|
||||
"repository": {
|
||||
"url": "https://github.com/toeverything/AFFiNE",
|
||||
@@ -26,10 +26,10 @@
|
||||
"@affine-test/kit": "workspace:*",
|
||||
"@affine/env": "workspace:*",
|
||||
"@affine/native": "workspace:*",
|
||||
"@blocksuite/blocks": "0.0.0-20230717055529-79180930-nightly",
|
||||
"@blocksuite/editor": "0.0.0-20230717055529-79180930-nightly",
|
||||
"@blocksuite/lit": "0.0.0-20230717055529-79180930-nightly",
|
||||
"@blocksuite/store": "0.0.0-20230717055529-79180930-nightly",
|
||||
"@blocksuite/blocks": "0.0.0-20230711103520-ce18dd84-nightly",
|
||||
"@blocksuite/editor": "0.0.0-20230711103520-ce18dd84-nightly",
|
||||
"@blocksuite/lit": "0.0.0-20230711103520-ce18dd84-nightly",
|
||||
"@blocksuite/store": "0.0.0-20230711103520-ce18dd84-nightly",
|
||||
"@electron-forge/cli": "^6.2.1",
|
||||
"@electron-forge/core": "^6.2.1",
|
||||
"@electron-forge/core-utils": "^6.2.1",
|
||||
|
||||
@@ -26,8 +26,6 @@ const outputList = [
|
||||
'node_modules/@toeverything/plugin-infra/dist',
|
||||
['manager.js', 'manager.cjs'],
|
||||
],
|
||||
['node_modules/@blocksuite/global/dist', ['utils.js']],
|
||||
['node_modules/jotai', ['vanilla.js']],
|
||||
] as [entry: string, expected: string[]][];
|
||||
|
||||
await Promise.all(
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@affine/server",
|
||||
"private": true,
|
||||
"version": "0.7.0-beta.0",
|
||||
"version": "0.7.0-canary.42",
|
||||
"description": "Affine Node.js server",
|
||||
"type": "module",
|
||||
"bin": {
|
||||
|
||||
@@ -30,15 +30,15 @@
|
||||
"wait-on": "^7.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@blocksuite/block-std": "0.0.0-20230717055529-79180930-nightly",
|
||||
"@blocksuite/blocks": "0.0.0-20230717055529-79180930-nightly",
|
||||
"@blocksuite/editor": "0.0.0-20230717055529-79180930-nightly",
|
||||
"@blocksuite/global": "0.0.0-20230717055529-79180930-nightly",
|
||||
"@blocksuite/icons": "^2.1.25",
|
||||
"@blocksuite/lit": "0.0.0-20230717055529-79180930-nightly",
|
||||
"@blocksuite/store": "0.0.0-20230717055529-79180930-nightly",
|
||||
"react": "18.2.0",
|
||||
"react-dom": "18.2.0"
|
||||
"@blocksuite/block-std": "0.0.0-20230711103520-ce18dd84-nightly",
|
||||
"@blocksuite/blocks": "0.0.0-20230711103520-ce18dd84-nightly",
|
||||
"@blocksuite/editor": "0.0.0-20230711103520-ce18dd84-nightly",
|
||||
"@blocksuite/global": "0.0.0-20230711103520-ce18dd84-nightly",
|
||||
"@blocksuite/icons": "^2.1.24",
|
||||
"@blocksuite/lit": "0.0.0-20230711103520-ce18dd84-nightly",
|
||||
"@blocksuite/store": "0.0.0-20230711103520-ce18dd84-nightly",
|
||||
"react": "18.3.0-canary-1fdacbefd-20230630",
|
||||
"react-dom": "18.3.0-canary-1fdacbefd-20230630"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@blocksuite/blocks": "*",
|
||||
@@ -48,5 +48,5 @@
|
||||
"@blocksuite/lit": "*",
|
||||
"@blocksuite/store": "*"
|
||||
},
|
||||
"version": "0.7.0-beta.0"
|
||||
"version": "0.7.0-canary.42"
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import type { Page } from '@blocksuite/store';
|
||||
import { createMemoryStorage, Workspace } from '@blocksuite/store';
|
||||
import { expect } from '@storybook/jest';
|
||||
import type { Meta, StoryFn } from '@storybook/react';
|
||||
import { use } from 'foxact/use';
|
||||
import { use } from 'react';
|
||||
|
||||
const blockSuiteWorkspace = new Workspace({
|
||||
id: 'test',
|
||||
|
||||
@@ -13,8 +13,7 @@ import { createEmptyBlockSuiteWorkspace } from '@affine/workspace/utils';
|
||||
import type { Page } from '@blocksuite/store';
|
||||
import { expect } from '@storybook/jest';
|
||||
import type { StoryFn } from '@storybook/react';
|
||||
import { use } from 'foxact/use';
|
||||
import { useState } from 'react';
|
||||
import { use, useState } from 'react';
|
||||
|
||||
export default {
|
||||
title: 'AFFiNE/ShareMenu',
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
"baseUrl": "../..",
|
||||
"composite": true,
|
||||
"noEmit": false,
|
||||
"outDir": "lib"
|
||||
"outDir": "lib",
|
||||
"types": ["react/experimental"]
|
||||
},
|
||||
"references": [
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@affine/web",
|
||||
"private": true,
|
||||
"version": "0.7.0-beta.0",
|
||||
"version": "0.7.0-canary.42",
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
"build": "next build && next export",
|
||||
@@ -19,13 +19,13 @@
|
||||
"@affine/jotai": "workspace:*",
|
||||
"@affine/templates": "workspace:*",
|
||||
"@affine/workspace": "workspace:*",
|
||||
"@blocksuite/block-std": "0.0.0-20230717055529-79180930-nightly",
|
||||
"@blocksuite/blocks": "0.0.0-20230717055529-79180930-nightly",
|
||||
"@blocksuite/editor": "0.0.0-20230717055529-79180930-nightly",
|
||||
"@blocksuite/global": "0.0.0-20230717055529-79180930-nightly",
|
||||
"@blocksuite/icons": "^2.1.25",
|
||||
"@blocksuite/lit": "0.0.0-20230717055529-79180930-nightly",
|
||||
"@blocksuite/store": "0.0.0-20230717055529-79180930-nightly",
|
||||
"@blocksuite/block-std": "0.0.0-20230711103520-ce18dd84-nightly",
|
||||
"@blocksuite/blocks": "0.0.0-20230711103520-ce18dd84-nightly",
|
||||
"@blocksuite/editor": "0.0.0-20230711103520-ce18dd84-nightly",
|
||||
"@blocksuite/global": "0.0.0-20230711103520-ce18dd84-nightly",
|
||||
"@blocksuite/icons": "^2.1.24",
|
||||
"@blocksuite/lit": "0.0.0-20230711103520-ce18dd84-nightly",
|
||||
"@blocksuite/store": "0.0.0-20230711103520-ce18dd84-nightly",
|
||||
"@dnd-kit/core": "^6.0.8",
|
||||
"@dnd-kit/sortable": "^7.0.2",
|
||||
"@emotion/cache": "^11.11.0",
|
||||
@@ -47,8 +47,8 @@
|
||||
"lit": "^2.7.5",
|
||||
"lottie-web": "^5.12.2",
|
||||
"next-themes": "^0.2.1",
|
||||
"react": "18.2.0",
|
||||
"react-dom": "18.2.0",
|
||||
"react": "18.3.0-canary-1fdacbefd-20230630",
|
||||
"react-dom": "18.3.0-canary-1fdacbefd-20230630",
|
||||
"react-is": "^18.2.0",
|
||||
"react-resizable-panels": "^0.0.53",
|
||||
"rxjs": "^7.8.1",
|
||||
|
||||
@@ -23,7 +23,7 @@ const buildPreset = {
|
||||
enableTestProperties: false,
|
||||
enableBroadcastChannelProvider: true,
|
||||
enableDebugPage: true,
|
||||
changelogUrl: 'https://affine.pro/blog/what-is-new-affine-0717',
|
||||
changelogUrl: 'https://affine.pro/blog/whats-new-affine-0630',
|
||||
imageProxyUrl: 'https://workers.toeverything.workers.dev/proxy/image',
|
||||
enablePreloading: true,
|
||||
enableNewSettingModal: true,
|
||||
@@ -41,7 +41,7 @@ const buildPreset = {
|
||||
enableTestProperties: true,
|
||||
enableBroadcastChannelProvider: true,
|
||||
enableDebugPage: true,
|
||||
changelogUrl: 'https://affine.pro/blog/what-is-new-affine-0717',
|
||||
changelogUrl: 'https://affine.pro/blog/whats-new-affine-0630',
|
||||
imageProxyUrl: 'https://workers.toeverything.workers.dev/proxy/image',
|
||||
enablePreloading: true,
|
||||
enableNewSettingModal: true,
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 8.5 KiB After Width: | Height: | Size: 8.5 KiB |
Binary file not shown.
@@ -19,7 +19,7 @@ import {
|
||||
import { createIndexedDBDownloadProvider } from '@affine/workspace/providers';
|
||||
import { createEmptyBlockSuiteWorkspace } from '@affine/workspace/utils';
|
||||
import { nanoid } from '@blocksuite/store';
|
||||
import { useStaticBlockSuiteWorkspace } from '@toeverything/plugin-infra/__internal__/react';
|
||||
import { useStaticBlockSuiteWorkspace } from '@toeverything/hooks/use-block-suite-workspace';
|
||||
|
||||
import {
|
||||
BlockSuitePageList,
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
import { currentPageIdAtom } from '@toeverything/plugin-infra/manager';
|
||||
import { atom } from 'jotai/vanilla';
|
||||
|
||||
import { pageSettingFamily } from './index';
|
||||
|
||||
export const currentModeAtom = atom<'page' | 'edgeless'>(get => {
|
||||
const pageId = get(currentPageIdAtom);
|
||||
if (!pageId) {
|
||||
return 'page';
|
||||
}
|
||||
return get(pageSettingFamily(pageId)).mode;
|
||||
});
|
||||
@@ -4,25 +4,16 @@ import type {
|
||||
LocalIndexedDBDownloadProvider,
|
||||
WorkspaceAdapter,
|
||||
} from '@affine/env/workspace';
|
||||
import { WorkspaceFlavour, WorkspaceVersion } from '@affine/env/workspace';
|
||||
import { WorkspaceFlavour } from '@affine/env/workspace';
|
||||
import type { RootWorkspaceMetadata } from '@affine/workspace/atom';
|
||||
import {
|
||||
type RootWorkspaceMetadataV2,
|
||||
rootWorkspacesMetadataAtom,
|
||||
workspaceAdaptersAtom,
|
||||
} from '@affine/workspace/atom';
|
||||
import { workspaceAdaptersAtom } from '@affine/workspace/atom';
|
||||
import {
|
||||
migrateLocalBlobStorage,
|
||||
upgradeV1ToV2,
|
||||
} from '@affine/workspace/migration';
|
||||
import { createIndexedDBDownloadProvider } from '@affine/workspace/providers';
|
||||
import { assertExists } from '@blocksuite/global/utils';
|
||||
import {
|
||||
currentPageIdAtom,
|
||||
currentWorkspaceIdAtom,
|
||||
rootStore,
|
||||
} from '@toeverything/plugin-infra/manager';
|
||||
import Router from 'next/router';
|
||||
import { rootStore } from '@toeverything/plugin-infra/manager';
|
||||
|
||||
import { WorkspaceAdapters } from '../adapters/workspace';
|
||||
|
||||
@@ -40,79 +31,6 @@ if (process.env.NODE_ENV === 'development') {
|
||||
console.log('Runtime Preset', runtimeConfig);
|
||||
}
|
||||
|
||||
if (!environment.isServer) {
|
||||
currentWorkspaceIdAtom.onMount = set => {
|
||||
if (environment.isBrowser) {
|
||||
const callback = (url: string) => {
|
||||
const value = url.split('/')[2];
|
||||
if (value === 'all' || value === 'trash' || value === 'shared') {
|
||||
set(null);
|
||||
} else if (value) {
|
||||
set(value);
|
||||
localStorage.setItem('last_workspace_id', value);
|
||||
} else {
|
||||
set(null);
|
||||
}
|
||||
};
|
||||
callback(window.location.pathname);
|
||||
Router.events.on('routeChangeStart', callback);
|
||||
return () => {
|
||||
Router.events.off('routeChangeStart', callback);
|
||||
};
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
currentPageIdAtom.onMount = set => {
|
||||
if (environment.isBrowser) {
|
||||
const callback = (url: string) => {
|
||||
const value = url.split('/')[3];
|
||||
if (value) {
|
||||
set(value);
|
||||
} else {
|
||||
set(null);
|
||||
}
|
||||
};
|
||||
callback(window.location.pathname);
|
||||
Router.events.on('routeChangeStart', callback);
|
||||
return () => {
|
||||
Router.events.off('routeChangeStart', callback);
|
||||
};
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
const createFirst = (): RootWorkspaceMetadataV2[] => {
|
||||
const Plugins = Object.values(WorkspaceAdapters).sort(
|
||||
(a, b) => a.loadPriority - b.loadPriority
|
||||
);
|
||||
|
||||
return Plugins.flatMap(Plugin => {
|
||||
return Plugin.Events['app:init']?.().map(
|
||||
id =>
|
||||
({
|
||||
id,
|
||||
flavour: Plugin.flavour,
|
||||
// new workspace should all support sub-doc feature
|
||||
version: WorkspaceVersion.SubDoc,
|
||||
}) satisfies RootWorkspaceMetadataV2
|
||||
);
|
||||
}).filter((ids): ids is RootWorkspaceMetadataV2 => !!ids);
|
||||
};
|
||||
|
||||
rootStore
|
||||
.get(rootWorkspacesMetadataAtom)
|
||||
.then(meta => {
|
||||
if (meta.length === 0 && localStorage.getItem('is-first-open') === null) {
|
||||
const result = createFirst();
|
||||
console.info('create first workspace', result);
|
||||
localStorage.setItem('is-first-open', 'false');
|
||||
rootStore.set(rootWorkspacesMetadataAtom, result).catch(console.error);
|
||||
}
|
||||
})
|
||||
.catch(console.error);
|
||||
}
|
||||
|
||||
if (runtimeConfig.enablePlugin && !environment.isServer) {
|
||||
import('@affine/copilot');
|
||||
}
|
||||
@@ -157,7 +75,6 @@ if (environment.isBrowser) {
|
||||
try {
|
||||
const metadata = JSON.parse(value) as RootWorkspaceMetadata[];
|
||||
const promises: Promise<void>[] = [];
|
||||
const newMetadata = [...metadata];
|
||||
metadata.forEach(oldMeta => {
|
||||
if (!('version' in oldMeta)) {
|
||||
const adapter = WorkspaceAdapters[oldMeta.flavour];
|
||||
@@ -195,13 +112,6 @@ if (environment.isBrowser) {
|
||||
);
|
||||
|
||||
await adapter.CRUD.delete(workspace as any);
|
||||
console.log('migrated', oldMeta.id, newId);
|
||||
const index = newMetadata.findIndex(meta => meta.id === oldMeta.id);
|
||||
newMetadata[index] = {
|
||||
...oldMeta,
|
||||
id: newId,
|
||||
version: WorkspaceVersion.SubDoc,
|
||||
};
|
||||
await migrateLocalBlobStorage(workspace.id, newId);
|
||||
};
|
||||
|
||||
@@ -218,7 +128,6 @@ if (environment.isBrowser) {
|
||||
console.error('migration failed');
|
||||
})
|
||||
.finally(() => {
|
||||
localStorage.setItem('jotai-workspaces', JSON.stringify(newMetadata));
|
||||
window.dispatchEvent(new CustomEvent('migration-done'));
|
||||
window.$migrationDone = true;
|
||||
});
|
||||
|
||||
@@ -4,12 +4,12 @@ import type {
|
||||
WorkspaceNotFoundError,
|
||||
} from '@affine/env/constant';
|
||||
import { PageNotFoundError } from '@affine/env/constant';
|
||||
import { rootWorkspacesMetadataAtom } from '@affine/workspace/atom';
|
||||
import {
|
||||
currentPageIdAtom,
|
||||
currentWorkspaceIdAtom,
|
||||
rootStore,
|
||||
} from '@toeverything/plugin-infra/manager';
|
||||
rootCurrentPageIdAtom,
|
||||
rootCurrentWorkspaceIdAtom,
|
||||
rootWorkspacesMetadataAtom,
|
||||
} from '@affine/workspace/atom';
|
||||
import { rootStore } from '@toeverything/plugin-infra/manager';
|
||||
import { useAtomValue } from 'jotai/react';
|
||||
import { Provider } from 'jotai/react';
|
||||
import type { NextRouter } from 'next/router';
|
||||
@@ -35,8 +35,8 @@ interface AffineErrorBoundaryState {
|
||||
export const DumpInfo = (props: Pick<AffineErrorBoundaryProps, 'router'>) => {
|
||||
const router = props.router;
|
||||
const metadata = useAtomValue(rootWorkspacesMetadataAtom);
|
||||
const currentWorkspaceId = useAtomValue(currentWorkspaceIdAtom);
|
||||
const currentPageId = useAtomValue(currentPageIdAtom);
|
||||
const currentWorkspaceId = useAtomValue(rootCurrentWorkspaceIdAtom);
|
||||
const currentPageId = useAtomValue(rootCurrentPageIdAtom);
|
||||
const path = router.asPath;
|
||||
const query = router.query;
|
||||
return (
|
||||
|
||||
@@ -27,11 +27,8 @@ export const AboutAffine = () => {
|
||||
data-testid="about-title"
|
||||
/>
|
||||
<SettingWrapper title={t['Version']()}>
|
||||
<SettingRow name={t['App Version']()} desc={runtimeConfig.appVersion} />
|
||||
<SettingRow
|
||||
name={t['Editor Version']()}
|
||||
desc={runtimeConfig.editorVersion}
|
||||
/>
|
||||
<SettingRow name="App Version" desc={runtimeConfig.appVersion} />
|
||||
<SettingRow name="Editor Version" desc={runtimeConfig.editorVersion} />
|
||||
{runtimeConfig.enableNewSettingUnstableApi && environment.isDesktop ? (
|
||||
<>
|
||||
<SettingRow
|
||||
@@ -62,7 +59,7 @@ export const AboutAffine = () => {
|
||||
style={{ cursor: 'pointer' }}
|
||||
onClick={() => {
|
||||
window.open(
|
||||
'https://affine.pro/blog/what-is-new-affine-0717',
|
||||
'https://affine.pro/blog/whats-new-affine-0630',
|
||||
'_blank'
|
||||
);
|
||||
}}
|
||||
|
||||
@@ -6,8 +6,8 @@ import { WorkspaceAvatar } from '@affine/component/workspace-avatar';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import type { RootWorkspaceMetadata } from '@affine/workspace/atom';
|
||||
import { rootWorkspacesMetadataAtom } from '@affine/workspace/atom';
|
||||
import { useStaticBlockSuiteWorkspace } from '@toeverything/hooks/use-block-suite-workspace';
|
||||
import { useBlockSuiteWorkspaceName } from '@toeverything/hooks/use-block-suite-workspace-name';
|
||||
import { useStaticBlockSuiteWorkspace } from '@toeverything/plugin-infra/__internal__/react';
|
||||
import clsx from 'clsx';
|
||||
import { useAtomValue } from 'jotai';
|
||||
import type { FC } from 'react';
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { WorkspaceDetailSkeleton } from '@affine/component/setting-components';
|
||||
import { usePassiveWorkspaceEffect } from '@toeverything/plugin-infra/__internal__/react';
|
||||
import { usePassiveWorkspaceEffect } from '@toeverything/hooks/use-block-suite-workspace';
|
||||
import { useSetAtom } from 'jotai';
|
||||
import { useRouter } from 'next/router';
|
||||
import { Suspense, useCallback } from 'react';
|
||||
|
||||
@@ -109,7 +109,7 @@ export const BlockSuitePageList: React.FC<BlockSuitePageListProps> = ({
|
||||
const { createPage, createEdgeless, importFile, isPreferredEdgeless } =
|
||||
usePageHelper(blockSuiteWorkspace);
|
||||
const t = useAFFiNEI18N();
|
||||
const getPageInfo = useGetPageInfoById(blockSuiteWorkspace);
|
||||
const getPageInfo = useGetPageInfoById();
|
||||
const tagOptionMap = useMemo(
|
||||
() =>
|
||||
Object.fromEntries(
|
||||
@@ -187,6 +187,7 @@ export const BlockSuitePageList: React.FC<BlockSuitePageListProps> = ({
|
||||
const pageList: ListData[] = list.map(pageMeta => {
|
||||
const page = blockSuiteWorkspace.getPage(pageMeta.id);
|
||||
const preview = page ? getPagePreviewText(page) : undefined;
|
||||
|
||||
return {
|
||||
icon: isPreferredEdgeless(pageMeta.id) ? <EdgelessIcon /> : <PageIcon />,
|
||||
pageId: pageMeta.id,
|
||||
@@ -229,7 +230,6 @@ export const BlockSuitePageList: React.FC<BlockSuitePageListProps> = ({
|
||||
});
|
||||
return (
|
||||
<PageList
|
||||
workspaceId={blockSuiteWorkspace.id}
|
||||
propertiesMeta={blockSuiteWorkspace.meta.properties}
|
||||
getPageInfo={getPageInfo}
|
||||
onCreateNewPage={createPage}
|
||||
|
||||
@@ -14,13 +14,13 @@ import {
|
||||
useBlockSuitePageMeta,
|
||||
usePageMetaHelper,
|
||||
} from '@toeverything/hooks/use-block-suite-page-meta';
|
||||
import { currentPageIdAtom } from '@toeverything/plugin-infra/manager';
|
||||
import { useAtom, useAtomValue } from 'jotai';
|
||||
import { useAtom } from 'jotai';
|
||||
import { useRouter } from 'next/router';
|
||||
import { useState } from 'react';
|
||||
|
||||
import { pageSettingFamily } from '../../../../atoms';
|
||||
import { useBlockSuiteMetaHelper } from '../../../../hooks/affine/use-block-suite-meta-helper';
|
||||
import { useCurrentPageId } from '../../../../hooks/current/use-current-page-id';
|
||||
import { useCurrentWorkspace } from '../../../../hooks/current/use-current-workspace';
|
||||
import { toast } from '../../../../utils';
|
||||
import { MenuThemeModeSwitch } from '../header-right-items/theme-mode-switch';
|
||||
@@ -56,7 +56,7 @@ const PageMenu = () => {
|
||||
const t = useAFFiNEI18N();
|
||||
// fixme(himself65): remove these hooks ASAP
|
||||
const [workspace] = useCurrentWorkspace();
|
||||
const pageId = useAtomValue(currentPageIdAtom);
|
||||
const [pageId] = useCurrentPageId();
|
||||
assertExists(workspace);
|
||||
assertExists(pageId);
|
||||
const blockSuiteWorkspace = workspace.blockSuiteWorkspace;
|
||||
|
||||
@@ -2,18 +2,17 @@ import { Button, Confirm } from '@affine/component';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import { assertExists } from '@blocksuite/global/utils';
|
||||
import { useBlockSuitePageMeta } from '@toeverything/hooks/use-block-suite-page-meta';
|
||||
import { currentPageIdAtom } from '@toeverything/plugin-infra/manager';
|
||||
import { useAtomValue } from 'jotai';
|
||||
import { useRouter } from 'next/router';
|
||||
import { useState } from 'react';
|
||||
|
||||
import { useBlockSuiteMetaHelper } from '../../../../hooks/affine/use-block-suite-meta-helper';
|
||||
import { useCurrentPageId } from '../../../../hooks/current/use-current-page-id';
|
||||
import { useCurrentWorkspace } from '../../../../hooks/current/use-current-workspace';
|
||||
|
||||
export const TrashButtonGroup = () => {
|
||||
// fixme(himself65): remove these hooks ASAP
|
||||
const [workspace] = useCurrentWorkspace();
|
||||
const pageId = useAtomValue(currentPageIdAtom);
|
||||
const [pageId] = useCurrentPageId();
|
||||
assertExists(workspace);
|
||||
assertExists(pageId);
|
||||
const blockSuiteWorkspace = workspace.blockSuiteWorkspace;
|
||||
|
||||
@@ -23,7 +23,7 @@ import {
|
||||
|
||||
import { guideDownloadClientTipAtom } from '../../../atoms/guide';
|
||||
import { contentLayoutAtom } from '../../../atoms/layout';
|
||||
import { currentModeAtom } from '../../../atoms/mode';
|
||||
import { useCurrentMode } from '../../../hooks/current/use-current-mode';
|
||||
import type { AffineOfficialWorkspace } from '../../../shared';
|
||||
import { DownloadClientTip } from './download-tips';
|
||||
import EditPage from './header-right-items/edit-page';
|
||||
@@ -205,7 +205,7 @@ export const Header = forwardRef<
|
||||
const open = useAtomValue(appSidebarOpenAtom);
|
||||
const appSidebarFloating = useAtomValue(appSidebarFloatingAtom);
|
||||
|
||||
const mode = useAtomValue(currentModeAtom);
|
||||
const mode = useCurrentMode();
|
||||
|
||||
return (
|
||||
<div
|
||||
|
||||
@@ -10,8 +10,7 @@ export const editor = style({
|
||||
selectors: {
|
||||
'&.full-screen': {
|
||||
vars: {
|
||||
'--affine-editor-width': '100%',
|
||||
'--affine-editor-side-padding': '15px',
|
||||
'--affine-editor-width': '90%',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
import { MuiFade, Tooltip } from '@affine/component';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import { CloseIcon, NewIcon, UserGuideIcon } from '@blocksuite/icons';
|
||||
import { useSetAtom } from 'jotai/react';
|
||||
import { useAtomValue } from 'jotai/react';
|
||||
import { useSetAtom } from 'jotai';
|
||||
import { useCallback, useState } from 'react';
|
||||
|
||||
import { openOnboardingModalAtom, openSettingModalAtom } from '../../../atoms';
|
||||
import { currentModeAtom } from '../../../atoms/mode';
|
||||
import { useCurrentMode } from '../../../hooks/current/use-current-mode';
|
||||
import { ShortcutsModal } from '../shortcuts-modal';
|
||||
import { ContactIcon, HelpIcon, KeyboardIcon } from './icons';
|
||||
import {
|
||||
@@ -28,7 +27,7 @@ export const HelpIsland = ({
|
||||
}: {
|
||||
showList?: IslandItemNames[];
|
||||
}) => {
|
||||
const mode = useAtomValue(currentModeAtom);
|
||||
const mode = useCurrentMode();
|
||||
const setOpenOnboarding = useSetAtom(openOnboardingModalAtom);
|
||||
const setOpenSettingModalAtom = useSetAtom(openSettingModalAtom);
|
||||
const [spread, setShowSpread] = useState(false);
|
||||
|
||||
@@ -15,7 +15,7 @@ import {
|
||||
UnpinIcon,
|
||||
ViewLayersIcon,
|
||||
} from '@blocksuite/icons';
|
||||
import type { PageMeta, Workspace } from '@blocksuite/store';
|
||||
import type { PageMeta } from '@blocksuite/store';
|
||||
import type { DragEndEvent } from '@dnd-kit/core';
|
||||
import { useDroppable } from '@dnd-kit/core';
|
||||
import * as Collapsible from '@radix-ui/react-collapsible';
|
||||
@@ -25,6 +25,7 @@ import type { ReactElement } from 'react';
|
||||
import React, { useCallback, useMemo, useState } from 'react';
|
||||
|
||||
import { useGetPageInfoById } from '../../../../hooks/use-get-page-info';
|
||||
import type { AllWorkspace } from '../../../../shared';
|
||||
import { filterPage } from '../../../../utils/filter';
|
||||
import type { CollectionsListProps } from '../index';
|
||||
import { Page } from './page';
|
||||
@@ -125,11 +126,11 @@ const CollectionRenderer = ({
|
||||
}: {
|
||||
collection: Collection;
|
||||
pages: PageMeta[];
|
||||
workspace: Workspace;
|
||||
workspace: AllWorkspace;
|
||||
getPageInfo: GetPageInfoById;
|
||||
}) => {
|
||||
const [collapsed, setCollapsed] = React.useState(true);
|
||||
const setting = useCollectionManager(workspace.id);
|
||||
const setting = useCollectionManager();
|
||||
const router = useRouter();
|
||||
const clickCollection = useCallback(() => {
|
||||
router
|
||||
@@ -188,7 +189,7 @@ const CollectionRenderer = ({
|
||||
return (
|
||||
<Collapsible.Root open={!collapsed}>
|
||||
<EditCollectionModel
|
||||
propertiesMeta={workspace.meta.properties}
|
||||
propertiesMeta={workspace.blockSuiteWorkspace.meta.properties}
|
||||
getPageInfo={getPageInfo}
|
||||
init={collection}
|
||||
onConfirm={setting.saveCollection}
|
||||
@@ -252,10 +253,10 @@ const CollectionRenderer = ({
|
||||
</Collapsible.Root>
|
||||
);
|
||||
};
|
||||
export const CollectionsList = ({ workspace }: CollectionsListProps) => {
|
||||
const metas = useBlockSuitePageMeta(workspace);
|
||||
const { savedCollections } = useSavedCollections(workspace.id);
|
||||
const getPageInfo = useGetPageInfoById(workspace);
|
||||
export const CollectionsList = ({ currentWorkspace }: CollectionsListProps) => {
|
||||
const metas = useBlockSuitePageMeta(currentWorkspace.blockSuiteWorkspace);
|
||||
const { savedCollections } = useSavedCollections();
|
||||
const getPageInfo = useGetPageInfoById();
|
||||
return (
|
||||
<div data-testid="collections" className={styles.wrapper}>
|
||||
{savedCollections
|
||||
@@ -267,7 +268,7 @@ export const CollectionsList = ({ workspace }: CollectionsListProps) => {
|
||||
key={view.id}
|
||||
collection={view}
|
||||
pages={metas}
|
||||
workspace={workspace}
|
||||
workspace={currentWorkspace}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
|
||||
@@ -19,6 +19,7 @@ import React, { useCallback, useMemo } from 'react';
|
||||
|
||||
import { pageSettingFamily } from '../../../../atoms';
|
||||
import { useBlockSuiteMetaHelper } from '../../../../hooks/affine/use-block-suite-meta-helper';
|
||||
import type { AllWorkspace } from '../../../../shared';
|
||||
import { ReferencePage } from '../components/reference-page';
|
||||
import * as styles from './styles.css';
|
||||
|
||||
@@ -129,7 +130,7 @@ export const Page = ({
|
||||
removeFromAllowList: (id: string) => void;
|
||||
inExcludeList: boolean;
|
||||
addToExcludeList: (id: string) => void;
|
||||
workspace: Workspace;
|
||||
workspace: AllWorkspace;
|
||||
allPageMeta: Record<string, PageMeta>;
|
||||
}) => {
|
||||
const [collapsed, setCollapsed] = React.useState(true);
|
||||
@@ -139,7 +140,10 @@ export const Page = ({
|
||||
const active = router.query.pageId === pageId;
|
||||
const setting = useAtomValue(pageSettingFamily(pageId));
|
||||
const icon = setting?.mode === 'edgeless' ? <EdgelessIcon /> : <PageIcon />;
|
||||
const references = useBlockSuitePageReferences(workspace, pageId);
|
||||
const references = useBlockSuitePageReferences(
|
||||
workspace.blockSuiteWorkspace,
|
||||
pageId
|
||||
);
|
||||
const clickPage = useCallback(() => {
|
||||
return router.push(`/workspace/${workspace.id}/${page.id}`);
|
||||
}, [page.id, router, workspace.id]);
|
||||
@@ -166,7 +170,7 @@ export const Page = ({
|
||||
inExcludeList={inExcludeList}
|
||||
addToExcludeList={addToExcludeList}
|
||||
page={page}
|
||||
workspace={workspace}
|
||||
workspace={workspace.blockSuiteWorkspace}
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
@@ -185,7 +189,7 @@ export const Page = ({
|
||||
return (
|
||||
<ReferencePage
|
||||
key={id}
|
||||
workspace={workspace}
|
||||
workspace={workspace.blockSuiteWorkspace}
|
||||
pageId={id}
|
||||
metaMapping={allPageMeta}
|
||||
parentIds={new Set([pageId])}
|
||||
|
||||
@@ -6,8 +6,8 @@ import { ReferencePage } from '../components/reference-page';
|
||||
import type { FavoriteListProps } from '../index';
|
||||
import EmptyItem from './empty-item';
|
||||
|
||||
export const FavoriteList = ({ workspace }: FavoriteListProps) => {
|
||||
const metas = useBlockSuitePageMeta(workspace);
|
||||
export const FavoriteList = ({ currentWorkspace }: FavoriteListProps) => {
|
||||
const metas = useBlockSuitePageMeta(currentWorkspace.blockSuiteWorkspace);
|
||||
|
||||
const favoriteList = useMemo(
|
||||
() => metas.filter(p => p.favorite && !p.trash),
|
||||
@@ -36,7 +36,7 @@ export const FavoriteList = ({ workspace }: FavoriteListProps) => {
|
||||
pageId={pageMeta.id}
|
||||
// memo?
|
||||
parentIds={new Set()}
|
||||
workspace={workspace}
|
||||
workspace={currentWorkspace.blockSuiteWorkspace}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import type { Workspace } from '@blocksuite/store';
|
||||
import type { AllWorkspace } from '../../../shared';
|
||||
|
||||
export type FavoriteListProps = {
|
||||
workspace: Workspace;
|
||||
currentWorkspace: AllWorkspace;
|
||||
};
|
||||
|
||||
export type CollectionsListProps = {
|
||||
workspace: Workspace;
|
||||
currentWorkspace: AllWorkspace;
|
||||
};
|
||||
|
||||
@@ -10,7 +10,6 @@ import {
|
||||
SidebarContainer,
|
||||
SidebarScrollableContainer,
|
||||
} from '@affine/component/app-sidebar';
|
||||
import { useCollectionManager } from '@affine/component/page-list';
|
||||
import { isDesktop } from '@affine/env/constant';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import {
|
||||
@@ -94,10 +93,10 @@ export const RootAppSidebar = ({
|
||||
onOpenWorkspaceListModal,
|
||||
onOpenSettingModal,
|
||||
}: RootAppSidebarProps): ReactElement => {
|
||||
const currentWorkspaceId = currentWorkspace.id;
|
||||
const currentWorkspaceId = currentWorkspace?.id || null;
|
||||
const [appSettings] = useAppSetting();
|
||||
const { backToAll } = useCollectionManager(currentWorkspace.id);
|
||||
const blockSuiteWorkspace = currentWorkspace.blockSuiteWorkspace;
|
||||
|
||||
const blockSuiteWorkspace = currentWorkspace?.blockSuiteWorkspace;
|
||||
const t = useAFFiNEI18N();
|
||||
const onClickNewPage = useCallback(async () => {
|
||||
const page = createPage();
|
||||
@@ -170,7 +169,6 @@ export const RootAppSidebar = ({
|
||||
icon={<FolderIcon />}
|
||||
currentPath={currentPath}
|
||||
path={currentWorkspaceId && paths.all(currentWorkspaceId)}
|
||||
onClick={backToAll}
|
||||
>
|
||||
<span data-testid="all-pages">{t['All pages']()}</span>
|
||||
</RouteMenuLinkItem>
|
||||
@@ -189,9 +187,13 @@ export const RootAppSidebar = ({
|
||||
|
||||
<SidebarScrollableContainer>
|
||||
<CategoryDivider label={t['Favorites']()} />
|
||||
<FavoriteList workspace={blockSuiteWorkspace} />
|
||||
{blockSuiteWorkspace && (
|
||||
<FavoriteList currentWorkspace={currentWorkspace} />
|
||||
)}
|
||||
<CategoryDivider label={t['Collections']()} />
|
||||
<CollectionsList workspace={blockSuiteWorkspace} />
|
||||
{blockSuiteWorkspace && (
|
||||
<CollectionsList currentWorkspace={currentWorkspace} />
|
||||
)}
|
||||
<CategoryDivider label={t['others']()} />
|
||||
<RouteMenuLinkItem
|
||||
ref={trashDroppable.setNodeRef}
|
||||
|
||||
@@ -23,7 +23,7 @@ export function WorkspaceHeader({
|
||||
currentWorkspaceId,
|
||||
currentEntry,
|
||||
}: WorkspaceHeaderProps<WorkspaceFlavour>): ReactElement {
|
||||
const setting = useCollectionManager(currentWorkspaceId);
|
||||
const setting = useCollectionManager();
|
||||
const t = useAFFiNEI18N();
|
||||
const saveToCollection = useCallback(
|
||||
async (collection: Collection) => {
|
||||
@@ -35,9 +35,7 @@ export function WorkspaceHeader({
|
||||
|
||||
const currentWorkspace = useWorkspace(currentWorkspaceId);
|
||||
|
||||
const getPageInfoById = useGetPageInfoById(
|
||||
currentWorkspace.blockSuiteWorkspace
|
||||
);
|
||||
const getPageInfoById = useGetPageInfoById();
|
||||
if ('subPath' in currentEntry) {
|
||||
if (currentEntry.subPath === WorkspaceSubPath.ALL) {
|
||||
const leftSlot = (
|
||||
@@ -75,7 +73,6 @@ export function WorkspaceHeader({
|
||||
id: uuidv4(),
|
||||
name: '',
|
||||
filterList: setting.currentCollection.filterList,
|
||||
workspaceId: currentWorkspaceId,
|
||||
}}
|
||||
onConfirm={saveToCollection}
|
||||
></SaveCollectionButton>
|
||||
|
||||
17
apps/web/src/hooks/current/use-current-mode.ts
Normal file
17
apps/web/src/hooks/current/use-current-mode.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { rootCurrentPageIdAtom } from '@affine/workspace/atom';
|
||||
import { atom, useAtomValue } from 'jotai';
|
||||
|
||||
import { pageSettingFamily } from '../../atoms';
|
||||
|
||||
const currentModeAtom = atom<'page' | 'edgeless'>(get => {
|
||||
const pageId = get(rootCurrentPageIdAtom);
|
||||
// fixme(himself65): pageId should not be null
|
||||
if (!pageId) {
|
||||
return 'page';
|
||||
}
|
||||
return get(pageSettingFamily(pageId))?.mode ?? 'page';
|
||||
});
|
||||
|
||||
export const useCurrentMode = () => {
|
||||
return useAtomValue(currentModeAtom);
|
||||
};
|
||||
12
apps/web/src/hooks/current/use-current-page-id.ts
Normal file
12
apps/web/src/hooks/current/use-current-page-id.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { rootCurrentPageIdAtom } from '@affine/workspace/atom';
|
||||
import { useAtom } from 'jotai';
|
||||
|
||||
/**
|
||||
* @deprecated Use `rootCurrentPageIdAtom` directly instead.
|
||||
*/
|
||||
export function useCurrentPageId(): [
|
||||
string | null,
|
||||
(newId: string | null) => void,
|
||||
] {
|
||||
return useAtom(rootCurrentPageIdAtom);
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
import { assertExists } from '@blocksuite/global/utils';
|
||||
import {
|
||||
currentPageIdAtom,
|
||||
currentWorkspaceIdAtom,
|
||||
} from '@toeverything/plugin-infra/manager';
|
||||
rootCurrentPageIdAtom,
|
||||
rootCurrentWorkspaceIdAtom,
|
||||
} from '@affine/workspace/atom';
|
||||
import { assertExists } from '@blocksuite/global/utils';
|
||||
import { useAtom, useSetAtom } from 'jotai';
|
||||
import { useCallback, useEffect } from 'react';
|
||||
|
||||
@@ -24,7 +24,7 @@ export function useCurrentWorkspace(): [
|
||||
AllWorkspace,
|
||||
(id: string | null) => void,
|
||||
] {
|
||||
const [id, setId] = useAtom(currentWorkspaceIdAtom);
|
||||
const [id, setId] = useAtom(rootCurrentWorkspaceIdAtom);
|
||||
assertExists(id);
|
||||
const currentWorkspace = useWorkspace(id);
|
||||
useEffect(() => {
|
||||
@@ -35,7 +35,7 @@ export function useCurrentWorkspace(): [
|
||||
})
|
||||
);
|
||||
}, [currentWorkspace]);
|
||||
const setPageId = useSetAtom(currentPageIdAtom);
|
||||
const setPageId = useSetAtom(rootCurrentPageIdAtom);
|
||||
return [
|
||||
currentWorkspace,
|
||||
useCallback(
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { WorkspaceRegistry } from '@affine/env/workspace';
|
||||
import type { WorkspaceFlavour } from '@affine/env/workspace';
|
||||
import { currentPageIdAtom } from '@toeverything/plugin-infra/manager';
|
||||
import { rootCurrentWorkspaceIdAtom } from '@affine/workspace/atom';
|
||||
import { useSetAtom } from 'jotai';
|
||||
import { useCallback } from 'react';
|
||||
|
||||
@@ -8,7 +8,7 @@ import { useTransformWorkspace } from '../use-transform-workspace';
|
||||
|
||||
export function useOnTransformWorkspace() {
|
||||
const transformWorkspace = useTransformWorkspace();
|
||||
const setWorkspaceId = useSetAtom(currentPageIdAtom);
|
||||
const setWorkspaceId = useSetAtom(rootCurrentWorkspaceIdAtom);
|
||||
return useCallback(
|
||||
async <From extends WorkspaceFlavour, To extends WorkspaceFlavour>(
|
||||
from: From,
|
||||
|
||||
@@ -1,29 +1,27 @@
|
||||
import type { GetPageInfoById } from '@affine/env/page-info';
|
||||
import type { Workspace } from '@blocksuite/store';
|
||||
import { useBlockSuitePageMeta } from '@toeverything/hooks/use-block-suite-page-meta';
|
||||
import { useAtomValue } from 'jotai';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
import { useMemo } from 'react';
|
||||
|
||||
import { pageSettingsAtom } from '../atoms';
|
||||
import { useCurrentWorkspace } from './current/use-current-workspace';
|
||||
|
||||
export const useGetPageInfoById = (workspace: Workspace): GetPageInfoById => {
|
||||
const pageMetas = useBlockSuitePageMeta(workspace);
|
||||
export const useGetPageInfoById = (): GetPageInfoById => {
|
||||
const [currentWorkspace] = useCurrentWorkspace();
|
||||
const pageMetas = useBlockSuitePageMeta(currentWorkspace.blockSuiteWorkspace);
|
||||
const pageMap = useMemo(
|
||||
() => Object.fromEntries(pageMetas.map(page => [page.id, page])),
|
||||
[pageMetas]
|
||||
);
|
||||
const pageSettings = useAtomValue(pageSettingsAtom);
|
||||
return useCallback(
|
||||
(id: string) => {
|
||||
const page = pageMap[id];
|
||||
if (!page) {
|
||||
return;
|
||||
}
|
||||
return {
|
||||
...page,
|
||||
isEdgeless: pageSettings[id]?.mode === 'edgeless',
|
||||
};
|
||||
},
|
||||
[pageMap, pageSettings]
|
||||
);
|
||||
return (id: string) => {
|
||||
const page = pageMap[id];
|
||||
if (!page) {
|
||||
return;
|
||||
}
|
||||
return {
|
||||
...page,
|
||||
isEdgeless: pageSettings[id]?.mode === 'edgeless',
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { rootWorkspacesMetadataAtom } from '@affine/workspace/atom';
|
||||
import { assertExists } from '@blocksuite/global/utils';
|
||||
import type { Workspace } from '@blocksuite/store';
|
||||
import { useStaticBlockSuiteWorkspace } from '@toeverything/plugin-infra/__internal__/react';
|
||||
import { useStaticBlockSuiteWorkspace } from '@toeverything/hooks/use-block-suite-workspace';
|
||||
import type { Atom } from 'jotai';
|
||||
import { atom, useAtomValue } from 'jotai';
|
||||
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
import { DebugLogger } from '@affine/debug';
|
||||
import { initEmptyPage, initPageWithPreloading } from '@affine/env/blocksuite';
|
||||
import { DEFAULT_HELLO_WORLD_PAGE_ID_SUFFIX } from '@affine/env/constant';
|
||||
import { WorkspaceFlavour, WorkspaceVersion } from '@affine/env/workspace';
|
||||
import { rootWorkspacesMetadataAtom } from '@affine/workspace/atom';
|
||||
import { saveWorkspaceToLocalStorage } from '@affine/workspace/local/crud';
|
||||
import { createEmptyBlockSuiteWorkspace } from '@affine/workspace/utils';
|
||||
import { assertEquals } from '@blocksuite/global/utils';
|
||||
import { nanoid } from '@blocksuite/store';
|
||||
import { getWorkspace } from '@toeverything/plugin-infra/__internal__/workspace';
|
||||
import { getWorkspace } from '@toeverything/hooks/use-block-suite-workspace';
|
||||
import { useAtomValue, useSetAtom } from 'jotai';
|
||||
import { useCallback } from 'react';
|
||||
|
||||
@@ -48,30 +45,6 @@ export function useAppHelper() {
|
||||
);
|
||||
blockSuiteWorkspace.meta.setName(name);
|
||||
const id = await LocalAdapter.CRUD.create(blockSuiteWorkspace);
|
||||
{
|
||||
// this is hack, because CRUD doesn't return the workspace
|
||||
const blockSuiteWorkspace = createEmptyBlockSuiteWorkspace(
|
||||
id,
|
||||
WorkspaceFlavour.LOCAL
|
||||
);
|
||||
const pageId = `${blockSuiteWorkspace.id}-${DEFAULT_HELLO_WORLD_PAGE_ID_SUFFIX}`;
|
||||
const page = blockSuiteWorkspace.createPage({
|
||||
id: pageId,
|
||||
});
|
||||
assertEquals(page.id, pageId);
|
||||
if (runtimeConfig.enablePreloading) {
|
||||
await initPageWithPreloading(page).catch(error => {
|
||||
console.error('import error:', error);
|
||||
});
|
||||
} else {
|
||||
await initEmptyPage(page).catch(error => {
|
||||
console.error('init empty page error', error);
|
||||
});
|
||||
}
|
||||
blockSuiteWorkspace.setPageMeta(page.id, {
|
||||
jumpOnce: true,
|
||||
});
|
||||
}
|
||||
await set(workspaces => [
|
||||
...workspaces,
|
||||
{
|
||||
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
ToolContainer,
|
||||
WorkspaceFallback,
|
||||
} from '@affine/component/workspace';
|
||||
import { initEmptyPage, initPageWithPreloading } from '@affine/env/blocksuite';
|
||||
import {
|
||||
DEFAULT_HELLO_WORLD_PAGE_ID_SUFFIX,
|
||||
isDesktop,
|
||||
@@ -17,9 +18,11 @@ import {
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import {
|
||||
rootBlockHubAtom,
|
||||
rootCurrentPageIdAtom,
|
||||
rootCurrentWorkspaceIdAtom,
|
||||
rootWorkspacesMetadataAtom,
|
||||
} from '@affine/workspace/atom';
|
||||
import { assertExists } from '@blocksuite/global/utils';
|
||||
import { assertEquals, assertExists } from '@blocksuite/global/utils';
|
||||
import { nanoid } from '@blocksuite/store';
|
||||
import type { DragEndEvent } from '@dnd-kit/core';
|
||||
import {
|
||||
@@ -31,12 +34,8 @@ import {
|
||||
useSensor,
|
||||
useSensors,
|
||||
} from '@dnd-kit/core';
|
||||
import { usePassiveWorkspaceEffect } from '@toeverything/hooks/use-block-suite-workspace';
|
||||
import { useBlockSuiteWorkspaceHelper } from '@toeverything/hooks/use-block-suite-workspace-helper';
|
||||
import { usePassiveWorkspaceEffect } from '@toeverything/plugin-infra/__internal__/react';
|
||||
import {
|
||||
currentPageIdAtom,
|
||||
currentWorkspaceIdAtom,
|
||||
} from '@toeverything/plugin-infra/manager';
|
||||
import { useAtom, useAtomValue, useSetAtom } from 'jotai';
|
||||
import Head from 'next/head';
|
||||
import { useRouter } from 'next/router';
|
||||
@@ -112,7 +111,7 @@ if (globalThis.HALTING_PROBLEM_TIMEOUT === undefined) {
|
||||
export const CurrentWorkspaceContext = ({
|
||||
children,
|
||||
}: PropsWithChildren): ReactElement => {
|
||||
const workspaceId = useAtomValue(currentWorkspaceIdAtom);
|
||||
const workspaceId = useAtomValue(rootCurrentWorkspaceIdAtom);
|
||||
const metadata = useAtomValue(rootWorkspacesMetadataAtom);
|
||||
const exist = metadata.find(m => m.id === workspaceId);
|
||||
const router = useRouter();
|
||||
@@ -150,7 +149,7 @@ export const CurrentWorkspaceContext = ({
|
||||
export const WorkspaceLayout: FC<PropsWithChildren> =
|
||||
function WorkspacesSuspense({ children }) {
|
||||
useTrackRouterHistoryEffect();
|
||||
const currentWorkspaceId = useAtomValue(currentWorkspaceIdAtom);
|
||||
const currentWorkspaceId = useAtomValue(rootCurrentWorkspaceIdAtom);
|
||||
const jotaiWorkspaces = useAtomValue(rootWorkspacesMetadataAtom);
|
||||
const meta = useMemo(
|
||||
() => jotaiWorkspaces.find(x => x.id === currentWorkspaceId),
|
||||
@@ -182,10 +181,42 @@ export const WorkspaceLayout: FC<PropsWithChildren> =
|
||||
|
||||
export const WorkspaceLayoutInner: FC<PropsWithChildren> = ({ children }) => {
|
||||
const [currentWorkspace] = useCurrentWorkspace();
|
||||
const [currentPageId, setCurrentPageId] = useAtom(currentPageIdAtom);
|
||||
const setCurrentPageId = useSetAtom(rootCurrentPageIdAtom);
|
||||
const currentPageId = useAtomValue(rootCurrentPageIdAtom);
|
||||
const router = useRouter();
|
||||
const { jumpToPage } = useRouterHelper(router);
|
||||
|
||||
//#region init workspace
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-expect-error
|
||||
if (currentWorkspace.blockSuiteWorkspace.meta._proxy.isEmpty !== true) {
|
||||
// this is a new workspace, so we should redirect to the new page
|
||||
const pageId = `${currentWorkspace.blockSuiteWorkspace.id}-${DEFAULT_HELLO_WORLD_PAGE_ID_SUFFIX}`;
|
||||
if (currentWorkspace.blockSuiteWorkspace.getPage(pageId) === null) {
|
||||
const page = currentWorkspace.blockSuiteWorkspace.createPage({
|
||||
id: pageId,
|
||||
});
|
||||
assertEquals(page.id, pageId);
|
||||
if (runtimeConfig.enablePreloading) {
|
||||
initPageWithPreloading(page).catch(error => {
|
||||
console.error('import error:', error);
|
||||
});
|
||||
} else {
|
||||
initEmptyPage(page).catch(error => {
|
||||
console.error('init empty page error', error);
|
||||
});
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-expect-error
|
||||
currentWorkspace.blockSuiteWorkspace.meta._proxy.isEmpty = false;
|
||||
if (!router.query.pageId) {
|
||||
setCurrentPageId(pageId);
|
||||
jumpToPage(currentWorkspace.id, pageId).catch(console.error);
|
||||
}
|
||||
}
|
||||
}
|
||||
//#endregion
|
||||
|
||||
usePassiveWorkspaceEffect(currentWorkspace.blockSuiteWorkspace);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -193,9 +224,12 @@ export const WorkspaceLayoutInner: FC<PropsWithChildren> = ({ children }) => {
|
||||
`${currentWorkspace.blockSuiteWorkspace.id}-${DEFAULT_HELLO_WORLD_PAGE_ID_SUFFIX}`
|
||||
);
|
||||
if (page && page.meta.jumpOnce) {
|
||||
currentWorkspace.blockSuiteWorkspace.meta.setPageMeta(page.id, {
|
||||
jumpOnce: false,
|
||||
});
|
||||
currentWorkspace.blockSuiteWorkspace.meta.setPageMeta(
|
||||
`${currentWorkspace.blockSuiteWorkspace.id}-${DEFAULT_HELLO_WORLD_PAGE_ID_SUFFIX}`,
|
||||
{
|
||||
jumpOnce: false,
|
||||
}
|
||||
);
|
||||
setCurrentPageId(currentPageId);
|
||||
jumpToPage(currentWorkspace.id, page.id).catch(err => {
|
||||
console.error(err);
|
||||
|
||||
@@ -2,8 +2,7 @@ import { WorkspaceFallback } from '@affine/component/workspace';
|
||||
import { DebugLogger } from '@affine/debug';
|
||||
import { WorkspaceSubPath } from '@affine/env/workspace';
|
||||
import { rootWorkspacesMetadataAtom } from '@affine/workspace/atom';
|
||||
import { NoSsr } from '@mui/material';
|
||||
import { getWorkspace } from '@toeverything/plugin-infra/__internal__/workspace';
|
||||
import { getWorkspace } from '@toeverything/hooks/use-block-suite-workspace';
|
||||
import { useAtomValue } from 'jotai';
|
||||
import type { NextPage } from 'next';
|
||||
import { useRouter } from 'next/router';
|
||||
@@ -98,11 +97,9 @@ const IndexPageInner = () => {
|
||||
|
||||
const IndexPage: NextPage = () => {
|
||||
return (
|
||||
<NoSsr>
|
||||
<Suspense fallback={<WorkspaceFallback />}>
|
||||
<IndexPageInner />
|
||||
</Suspense>
|
||||
</NoSsr>
|
||||
<Suspense fallback={<WorkspaceFallback />}>
|
||||
<IndexPageInner />
|
||||
</Suspense>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -4,10 +4,10 @@ import {
|
||||
useCollectionManager,
|
||||
} from '@affine/component/page-list';
|
||||
import { WorkspaceSubPath } from '@affine/env/workspace';
|
||||
import { rootCurrentPageIdAtom } from '@affine/workspace/atom';
|
||||
import type { EditorContainer } from '@blocksuite/editor';
|
||||
import { assertExists } from '@blocksuite/global/utils';
|
||||
import type { Page } from '@blocksuite/store';
|
||||
import { currentPageIdAtom } from '@toeverything/plugin-infra/manager';
|
||||
import { useAtom, useAtomValue } from 'jotai';
|
||||
import { useRouter } from 'next/router';
|
||||
import type React from 'react';
|
||||
@@ -22,12 +22,12 @@ import type { NextPageWithLayout } from '../../../shared';
|
||||
const WorkspaceDetail: React.FC = () => {
|
||||
const router = useRouter();
|
||||
const { openPage, jumpToSubPath } = useRouterHelper(router);
|
||||
const currentPageId = useAtomValue(currentPageIdAtom);
|
||||
const currentPageId = useAtomValue(rootCurrentPageIdAtom);
|
||||
const [currentWorkspace] = useCurrentWorkspace();
|
||||
assertExists(currentWorkspace);
|
||||
assertExists(currentPageId);
|
||||
const blockSuiteWorkspace = currentWorkspace.blockSuiteWorkspace;
|
||||
const collectionManager = useCollectionManager(currentWorkspace.id);
|
||||
const collectionManager = useCollectionManager();
|
||||
const onLoad = useCallback(
|
||||
(page: Page, editor: EditorContainer) => {
|
||||
const dispose = editor.slots.pageLinkClicked.on(({ pageId }) => {
|
||||
@@ -73,7 +73,7 @@ const WorkspaceDetail: React.FC = () => {
|
||||
const WorkspaceDetailPage: NextPageWithLayout = () => {
|
||||
const router = useRouter();
|
||||
const [currentWorkspace] = useCurrentWorkspace();
|
||||
const [currentPageId, setCurrentPageId] = useAtom(currentPageIdAtom);
|
||||
const [currentPageId, setCurrentPageId] = useAtom(rootCurrentPageIdAtom);
|
||||
const page = currentPageId
|
||||
? currentWorkspace.blockSuiteWorkspace.getPage(currentPageId)
|
||||
: null;
|
||||
|
||||
@@ -15,9 +15,9 @@ import type { NextPageWithLayout } from '../../../shared';
|
||||
|
||||
const AllPage: NextPageWithLayout = () => {
|
||||
const router = useRouter();
|
||||
const setting = useCollectionManager();
|
||||
const { jumpToPage } = useRouterHelper(router);
|
||||
const [currentWorkspace] = useCurrentWorkspace();
|
||||
const setting = useCollectionManager(currentWorkspace.id);
|
||||
const t = useAFFiNEI18N();
|
||||
const onClickPage = useCallback(
|
||||
(pageId: string, newTab?: boolean) => {
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { WorkspaceSubPath } from '@affine/env/workspace';
|
||||
import { rootWorkspacesMetadataAtom } from '@affine/workspace/atom';
|
||||
import {
|
||||
rootCurrentPageIdAtom,
|
||||
rootCurrentWorkspaceIdAtom,
|
||||
rootWorkspacesMetadataAtom,
|
||||
} from '@affine/workspace/atom';
|
||||
import { assertExists } from '@blocksuite/global/utils';
|
||||
import { arrayMove } from '@dnd-kit/sortable';
|
||||
import {
|
||||
currentPageIdAtom,
|
||||
currentWorkspaceIdAtom,
|
||||
} from '@toeverything/plugin-infra/manager';
|
||||
import { useAtom, useAtomValue, useSetAtom } from 'jotai';
|
||||
import { useRouter } from 'next/router';
|
||||
import type { FC, ReactElement } from 'react';
|
||||
@@ -123,9 +123,9 @@ export const AllWorkspaceModals = (): ReactElement => {
|
||||
const workspaces = useAtomValue(rootWorkspacesMetadataAtom);
|
||||
const setWorkspaces = useSetAtom(rootWorkspacesMetadataAtom);
|
||||
const [currentWorkspaceId, setCurrentWorkspaceId] = useAtom(
|
||||
currentWorkspaceIdAtom
|
||||
rootCurrentWorkspaceIdAtom
|
||||
);
|
||||
const setCurrentPageId = useSetAtom(currentPageIdAtom);
|
||||
const setCurrentPageId = useSetAtom(rootCurrentPageIdAtom);
|
||||
const [transitioning, transition] = useTransition();
|
||||
const [, setOpenSettingModalAtom] = useAtom(openSettingModalAtom);
|
||||
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
"jsx": "preserve",
|
||||
"jsxImportSource": "@emotion/react",
|
||||
"incremental": true,
|
||||
"experimentalDecorators": true
|
||||
"experimentalDecorators": true,
|
||||
"types": ["react/experimental"]
|
||||
},
|
||||
"include": [
|
||||
"next-env.d.ts",
|
||||
|
||||
@@ -23,9 +23,6 @@ To run AFFiNE Desktop Client Application locally, run the following commands:
|
||||
yarn install
|
||||
yarn dev
|
||||
|
||||
# in packages/native
|
||||
yarn build
|
||||
|
||||
# in apps/electron
|
||||
yarn generate-assets
|
||||
yarn dev
|
||||
|
||||
11
nx.json
11
nx.json
@@ -88,6 +88,17 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"e2e:coverage": {
|
||||
"outputs": ["{workspaceRoot}/.nyc_output", "{projectRoot}/test-results"],
|
||||
"inputs": [
|
||||
{
|
||||
"runtime": "node -v"
|
||||
},
|
||||
{
|
||||
"runtime": "yarn playwright --version"
|
||||
}
|
||||
]
|
||||
},
|
||||
"test": {
|
||||
"outputs": ["{workspaceRoot}/.nyc_output"],
|
||||
"inputs": [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@affine/monorepo",
|
||||
"version": "0.7.0-beta.0",
|
||||
"version": "0.7.0-canary.42",
|
||||
"private": true,
|
||||
"author": "toeverything",
|
||||
"license": "MPL-2.0",
|
||||
@@ -11,8 +11,7 @@
|
||||
"packages/*",
|
||||
"tests/fixtures",
|
||||
"tests/kit",
|
||||
"tests/affine-legacy/*",
|
||||
"tests/affine-local"
|
||||
"tests/affine-legacy/*"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18.16.1 <19.0.0"
|
||||
@@ -36,6 +35,8 @@
|
||||
"lint:prettier:fix": "prettier --ignore-unknown --cache --write .",
|
||||
"lint": "yarn lint:eslint && yarn lint:prettier",
|
||||
"lint:fix": "yarn lint:eslint:fix && yarn lint:prettier:fix",
|
||||
"e2e": "playwright test",
|
||||
"e2e:coverage": "COVERAGE=true yarn e2e --forbid-only",
|
||||
"test": "ENABLE_PRELOADING=false vitest --run",
|
||||
"test:ui": "ENABLE_PRELOADING=false vitest --ui",
|
||||
"test:coverage": "ENABLE_PRELOADING=false vitest run --coverage",
|
||||
|
||||
@@ -19,5 +19,5 @@
|
||||
"peerDependencies": {
|
||||
"ts-node": "*"
|
||||
},
|
||||
"version": "0.7.0-beta.0"
|
||||
"version": "0.7.0-canary.42"
|
||||
}
|
||||
|
||||
@@ -43,20 +43,20 @@
|
||||
"jotai": "^2.2.2",
|
||||
"lit": "^2.7.5",
|
||||
"lottie-web": "^5.12.2",
|
||||
"react": "18.2.0",
|
||||
"react": "18.3.0-canary-1fdacbefd-20230630",
|
||||
"react-datepicker": "^4.15.0",
|
||||
"react-dom": "18.2.0",
|
||||
"react-dom": "18.3.0-canary-1fdacbefd-20230630",
|
||||
"react-error-boundary": "^4.0.10",
|
||||
"react-is": "^18.2.0",
|
||||
"rxjs": "^7.8.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@blocksuite/blocks": "0.0.0-20230717055529-79180930-nightly",
|
||||
"@blocksuite/editor": "0.0.0-20230717055529-79180930-nightly",
|
||||
"@blocksuite/global": "0.0.0-20230717055529-79180930-nightly",
|
||||
"@blocksuite/icons": "^2.1.25",
|
||||
"@blocksuite/lit": "0.0.0-20230717055529-79180930-nightly",
|
||||
"@blocksuite/store": "0.0.0-20230717055529-79180930-nightly",
|
||||
"@blocksuite/blocks": "0.0.0-20230711103520-ce18dd84-nightly",
|
||||
"@blocksuite/editor": "0.0.0-20230711103520-ce18dd84-nightly",
|
||||
"@blocksuite/global": "0.0.0-20230711103520-ce18dd84-nightly",
|
||||
"@blocksuite/icons": "^2.1.24",
|
||||
"@blocksuite/lit": "0.0.0-20230711103520-ce18dd84-nightly",
|
||||
"@blocksuite/store": "0.0.0-20230711103520-ce18dd84-nightly",
|
||||
"@types/react": "^18.2.14",
|
||||
"@types/react-datepicker": "^4.11.2",
|
||||
"@types/react-dnd": "^3.0.2",
|
||||
@@ -66,5 +66,5 @@
|
||||
"vite": "^4.3.9",
|
||||
"yjs": "^13.6.6"
|
||||
},
|
||||
"version": "0.7.0-beta.0"
|
||||
"version": "0.7.0-canary.42"
|
||||
}
|
||||
|
||||
@@ -125,9 +125,6 @@ export const versionLabel = style({
|
||||
fontSize: '10px',
|
||||
lineHeight: '18px',
|
||||
borderRadius: '4px',
|
||||
maxWidth: '100px',
|
||||
overflow: 'hidden',
|
||||
textOverflow: 'ellipsis',
|
||||
});
|
||||
|
||||
export const whatsNewLabel = style({
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import { Tooltip } from '@affine/component';
|
||||
import { isBrowser, Unreachable } from '@affine/env/constant';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import { CloseIcon, NewIcon, ResetIcon } from '@blocksuite/icons';
|
||||
import clsx from 'clsx';
|
||||
import { atom, useAtomValue, useSetAtom } from 'jotai';
|
||||
import { startTransition, useCallback, useState } from 'react';
|
||||
import { startTransition, useCallback } from 'react';
|
||||
|
||||
import * as styles from './index.css';
|
||||
import {
|
||||
@@ -49,7 +48,6 @@ export function AppUpdaterButton({ className, style }: AddPageButtonProps) {
|
||||
const currentVersion = useAtomValue(currentVersionAtom);
|
||||
const downloadProgress = useAtomValue(downloadProgressAtom);
|
||||
const setChangelogCheckAtom = useSetAtom(changelogCheckedAtom);
|
||||
const [appQuitting, setAppQuitting] = useState(false);
|
||||
|
||||
const onDismissCurrentChangelog = useCallback(() => {
|
||||
if (!currentVersion) {
|
||||
@@ -66,7 +64,6 @@ export function AppUpdaterButton({ className, style }: AddPageButtonProps) {
|
||||
}, [currentVersion, setChangelogCheckAtom]);
|
||||
const onClickUpdate = useCallback(() => {
|
||||
if (updateReady) {
|
||||
setAppQuitting(true);
|
||||
window.apis?.updater.quitAndInstall().catch(err => {
|
||||
// TODO: add error toast here
|
||||
console.error(err);
|
||||
@@ -106,37 +103,19 @@ export function AppUpdaterButton({ className, style }: AddPageButtonProps) {
|
||||
const whatsNew =
|
||||
!updateAvailable && currentChangelogUnread ? renderWhatsNew() : null;
|
||||
|
||||
const wrapWithTooltip = (
|
||||
node: React.ReactElement,
|
||||
tooltip?: React.ReactElement | string
|
||||
) => {
|
||||
if (!tooltip) {
|
||||
return node;
|
||||
}
|
||||
|
||||
return (
|
||||
<Tooltip content={tooltip} placement="top-start">
|
||||
{node}
|
||||
</Tooltip>
|
||||
);
|
||||
};
|
||||
|
||||
return wrapWithTooltip(
|
||||
return (
|
||||
<button
|
||||
style={style}
|
||||
className={clsx([styles.root, className])}
|
||||
data-has-update={updateAvailable ? 'true' : 'false'}
|
||||
data-disabled={
|
||||
(updateAvailable?.allowAutoUpdate && !updateReady) || appQuitting
|
||||
}
|
||||
data-disabled={updateAvailable?.allowAutoUpdate && !updateReady}
|
||||
onClick={onClickUpdate}
|
||||
>
|
||||
{updateAvailableNode}
|
||||
{whatsNew}
|
||||
<div className={styles.particles} aria-hidden="true"></div>
|
||||
<span className={styles.halo} aria-hidden="true"></span>
|
||||
</button>,
|
||||
updateAvailable?.version
|
||||
</button>
|
||||
);
|
||||
|
||||
function renderUpdateAvailableAllowAutoUpdate() {
|
||||
|
||||
@@ -9,7 +9,6 @@ import { fallbackHeaderStyle, fallbackStyle } from './fallback.css';
|
||||
import {
|
||||
floatingMaxWidth,
|
||||
navBodyStyle,
|
||||
navHeaderStyle,
|
||||
navStyle,
|
||||
navWidthVar,
|
||||
navWrapperStyle,
|
||||
@@ -29,6 +28,7 @@ import { SidebarHeader } from './sidebar-header';
|
||||
export type AppSidebarProps = PropsWithChildren<
|
||||
SidebarHeaderProps & {
|
||||
hasBackground?: boolean;
|
||||
isFallback?: boolean;
|
||||
}
|
||||
>;
|
||||
|
||||
@@ -53,7 +53,7 @@ export function AppSidebar(props: AppSidebarProps): ReactElement {
|
||||
const [appSidebarFloating, setAppSidebarFloating] = useAtom(
|
||||
appSidebarFloatingAtom
|
||||
);
|
||||
const initialRender = open === undefined;
|
||||
const initialRender = open === undefined && !props.isFallback;
|
||||
|
||||
const isResizing = useAtomValue(appSidebarResizingAtom);
|
||||
const navRef = useRef<HTMLDivElement>(null);
|
||||
@@ -128,29 +128,15 @@ export function AppSidebar(props: AppSidebarProps): ReactElement {
|
||||
}
|
||||
|
||||
export const AppSidebarFallback = (): ReactElement | null => {
|
||||
const appSidebarWidth = useAtomValue(appSidebarWidthAtom);
|
||||
return (
|
||||
<div
|
||||
style={assignInlineVars({
|
||||
[navWidthVar]: `${appSidebarWidth}px`,
|
||||
})}
|
||||
className={clsx(navWrapperStyle, {
|
||||
'has-border': true,
|
||||
})}
|
||||
data-open="true"
|
||||
>
|
||||
<nav className={navStyle}>
|
||||
<div className={navHeaderStyle} data-open="true" />
|
||||
<div className={navBodyStyle}>
|
||||
<div className={fallbackStyle}>
|
||||
<div className={fallbackHeaderStyle}>
|
||||
<Skeleton variant="circular" width={40} height={40} />
|
||||
<Skeleton variant="rectangular" width={150} height={40} />
|
||||
</div>
|
||||
</div>
|
||||
<AppSidebar isFallback>
|
||||
<div className={fallbackStyle}>
|
||||
<div className={fallbackHeaderStyle}>
|
||||
<Skeleton variant="circular" width={40} height={40} />
|
||||
<Skeleton variant="rectangular" width={150} height={40} />
|
||||
</div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</AppSidebar>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import type { BlockHub } from '@blocksuite/blocks';
|
||||
import type { Atom } from 'jotai';
|
||||
import { useAtomValue } from 'jotai';
|
||||
import type { HTMLAttributes, ReactElement } from 'react';
|
||||
import { useEffect, useRef } from 'react';
|
||||
import { useRef } from 'react';
|
||||
|
||||
export interface BlockHubProps extends HTMLAttributes<HTMLDivElement> {
|
||||
blockHubAtom: Atom<Readonly<BlockHub> | null>;
|
||||
@@ -11,16 +11,15 @@ export interface BlockHubProps extends HTMLAttributes<HTMLDivElement> {
|
||||
export const BlockHubWrapper = (props: BlockHubProps): ReactElement => {
|
||||
const blockHub = useAtomValue(props.blockHubAtom);
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
useEffect(() => {
|
||||
if (ref.current) {
|
||||
const div = ref.current;
|
||||
if (blockHub) {
|
||||
if (div.hasChildNodes()) {
|
||||
div.removeChild(div.firstChild as ChildNode);
|
||||
}
|
||||
div.appendChild(blockHub);
|
||||
if (ref.current) {
|
||||
const div = ref.current;
|
||||
if (!blockHub) {
|
||||
if (div.hasChildNodes()) {
|
||||
div.removeChild(div.firstChild as ChildNode);
|
||||
}
|
||||
} else {
|
||||
div.appendChild(blockHub);
|
||||
}
|
||||
}, [blockHub]);
|
||||
}
|
||||
return <div ref={ref} data-testid="block-hub" />;
|
||||
};
|
||||
|
||||
@@ -4,10 +4,17 @@ import type { EditorContainer } from '@blocksuite/editor';
|
||||
import { assertExists } from '@blocksuite/global/utils';
|
||||
import type { Page } from '@blocksuite/store';
|
||||
import { Skeleton } from '@mui/material';
|
||||
import { use } from 'foxact/use';
|
||||
import { useAtomValue } from 'jotai';
|
||||
import type { CSSProperties, ReactElement } from 'react';
|
||||
import { lazy, memo, Suspense, useCallback, useEffect, useRef } from 'react';
|
||||
import {
|
||||
lazy,
|
||||
memo,
|
||||
Suspense,
|
||||
use,
|
||||
useCallback,
|
||||
useEffect,
|
||||
useRef,
|
||||
} from 'react';
|
||||
import { createPortal } from 'react-dom';
|
||||
import type { FallbackProps } from 'react-error-boundary';
|
||||
import { ErrorBoundary } from 'react-error-boundary';
|
||||
|
||||
@@ -8,8 +8,8 @@ import {
|
||||
LocalDataIcon as DefaultLocalDataIcon,
|
||||
LocalWorkspaceIcon as DefaultLocalWorkspaceIcon,
|
||||
} from '@blocksuite/icons';
|
||||
import { useStaticBlockSuiteWorkspace } from '@toeverything/hooks/use-block-suite-workspace';
|
||||
import { useBlockSuiteWorkspaceName } from '@toeverything/hooks/use-block-suite-workspace-name';
|
||||
import { useStaticBlockSuiteWorkspace } from '@toeverything/plugin-infra/__internal__/react';
|
||||
import type { FC } from 'react';
|
||||
import { useCallback } from 'react';
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/// <reference types="react/experimental" />
|
||||
import '@blocksuite/blocks';
|
||||
|
||||
import { Button, Tooltip } from '@affine/component';
|
||||
|
||||
@@ -12,13 +12,12 @@ import { useCollectionManager } from '../use-collection-manager';
|
||||
const defaultMeta = { tags: { options: [] } };
|
||||
|
||||
test('useAllPageSetting', async () => {
|
||||
const settingHook = renderHook(() => useCollectionManager('test'));
|
||||
const settingHook = renderHook(() => useCollectionManager());
|
||||
const prevCollection = settingHook.result.current.currentCollection;
|
||||
expect(settingHook.result.current.savedCollections).toEqual([]);
|
||||
await settingHook.result.current.updateCollection({
|
||||
...settingHook.result.current.currentCollection,
|
||||
filterList: [createDefaultFilter(vars[0], defaultMeta)],
|
||||
workspaceId: 'test',
|
||||
});
|
||||
settingHook.rerender();
|
||||
const nextCollection = settingHook.result.current.currentCollection;
|
||||
|
||||
@@ -36,7 +36,6 @@ const AllPagesHead = ({
|
||||
importFile,
|
||||
getPageInfo,
|
||||
propertiesMeta,
|
||||
workspaceId,
|
||||
}: {
|
||||
isPublicWorkspace: boolean;
|
||||
sorter: ReturnType<typeof useSorter<ListData>>;
|
||||
@@ -45,7 +44,6 @@ const AllPagesHead = ({
|
||||
importFile: () => void;
|
||||
getPageInfo: GetPageInfoById;
|
||||
propertiesMeta: PropertiesMeta;
|
||||
workspaceId: string;
|
||||
}) => {
|
||||
const t = useAFFiNEI18N();
|
||||
const titleList = useMemo(
|
||||
@@ -145,7 +143,6 @@ const AllPagesHead = ({
|
||||
<TableHead>
|
||||
<TableHeadRow>{tableItem}</TableHeadRow>
|
||||
<CollectionBar
|
||||
workspaceId={workspaceId}
|
||||
columnsCount={titleList.length}
|
||||
getPageInfo={getPageInfo}
|
||||
propertiesMeta={propertiesMeta}
|
||||
@@ -156,7 +153,6 @@ const AllPagesHead = ({
|
||||
|
||||
export const PageList = ({
|
||||
isPublicWorkspace = false,
|
||||
workspaceId,
|
||||
list,
|
||||
onCreateNewPage,
|
||||
onCreateNewEdgeless,
|
||||
@@ -201,7 +197,6 @@ export const PageList = ({
|
||||
<StyledTableContainer ref={ref}>
|
||||
<Table showBorder={hasScrollTop} style={{ maxHeight: '100%' }}>
|
||||
<AllPagesHead
|
||||
workspaceId={workspaceId}
|
||||
propertiesMeta={propertiesMeta}
|
||||
isPublicWorkspace={isPublicWorkspace}
|
||||
sorter={sorter}
|
||||
|
||||
@@ -45,7 +45,6 @@ export type TrashListData = {
|
||||
|
||||
export type PageListProps = {
|
||||
isPublicWorkspace?: boolean;
|
||||
workspaceId: string;
|
||||
list: ListData[];
|
||||
fallback?: React.ReactNode;
|
||||
onCreateNewPage: () => void;
|
||||
|
||||
@@ -35,7 +35,6 @@ const defaultCollection = {
|
||||
id: NIL,
|
||||
name: 'All',
|
||||
filterList: [],
|
||||
workspaceId: 'temporary',
|
||||
};
|
||||
const collectionAtom = atomWithReset<{
|
||||
currentId: string;
|
||||
@@ -45,15 +44,14 @@ const collectionAtom = atomWithReset<{
|
||||
defaultCollection: defaultCollection,
|
||||
});
|
||||
|
||||
export const useSavedCollections = (workspaceId: string) => {
|
||||
export const useSavedCollections = () => {
|
||||
const { data: savedCollections, mutate } = useSWRImmutable<Collection[]>(
|
||||
['affine', 'page-collection', workspaceId],
|
||||
['affine', 'page-collection'],
|
||||
{
|
||||
fetcher: async () => {
|
||||
const db = await pageCollectionDBPromise;
|
||||
const t = db.transaction('view').objectStore('view');
|
||||
const all = await t.getAll();
|
||||
return all.filter(v => v.workspaceId === workspaceId);
|
||||
return await t.getAll();
|
||||
},
|
||||
suspense: true,
|
||||
fallbackData: [],
|
||||
@@ -105,9 +103,9 @@ export const useSavedCollections = (workspaceId: string) => {
|
||||
};
|
||||
};
|
||||
|
||||
export const useCollectionManager = (workspaceId: string) => {
|
||||
export const useCollectionManager = () => {
|
||||
const { savedCollections, saveCollection, deleteCollection, addPage } =
|
||||
useSavedCollections(workspaceId);
|
||||
useSavedCollections();
|
||||
const [collectionData, setCollectionData] = useAtom(collectionAtom);
|
||||
|
||||
const updateCollection = useCallback(
|
||||
|
||||
@@ -22,14 +22,12 @@ export const CollectionBar = ({
|
||||
getPageInfo,
|
||||
propertiesMeta,
|
||||
columnsCount,
|
||||
workspaceId,
|
||||
}: {
|
||||
getPageInfo: GetPageInfoById;
|
||||
propertiesMeta: PropertiesMeta;
|
||||
columnsCount: number;
|
||||
workspaceId: string;
|
||||
}) => {
|
||||
const setting = useCollectionManager(workspaceId);
|
||||
const setting = useCollectionManager();
|
||||
const collection = setting.currentCollection;
|
||||
const [open, setOpen] = useState(false);
|
||||
const actions: {
|
||||
|
||||
@@ -61,8 +61,8 @@ export const TourModal: FC<TourModalProps> = ({ open, onClose }) => {
|
||||
{step !== -1 && (
|
||||
<div
|
||||
className={clsx(titleStyle, {
|
||||
[slideToRightStyle]: step === 0,
|
||||
[formSlideToLeftStyle]: step === 1,
|
||||
[slideToLeftStyle]: step === 0,
|
||||
[formSlideToRightStyle]: step === 1,
|
||||
})}
|
||||
>
|
||||
{t['com.affine.onboarding.title2']()}
|
||||
@@ -70,8 +70,8 @@ export const TourModal: FC<TourModalProps> = ({ open, onClose }) => {
|
||||
)}
|
||||
<div
|
||||
className={clsx(titleStyle, {
|
||||
[slideToLeftStyle]: step === 1,
|
||||
[formSlideToRightStyle]: step === 0,
|
||||
[slideToRightStyle]: step === 1,
|
||||
[formSlideToLeftStyle]: step === 0,
|
||||
})}
|
||||
>
|
||||
{t['com.affine.onboarding.title1']()}
|
||||
@@ -94,8 +94,8 @@ export const TourModal: FC<TourModalProps> = ({ open, onClose }) => {
|
||||
muted
|
||||
loop
|
||||
className={clsx(videoStyle, {
|
||||
[slideToRightStyle]: step === 0,
|
||||
[formSlideToLeftStyle]: step === 1,
|
||||
[slideToLeftStyle]: step === 0,
|
||||
[formSlideToRightStyle]: step === 1,
|
||||
})}
|
||||
data-testid="onboarding-modal-editing-video"
|
||||
>
|
||||
@@ -108,8 +108,8 @@ export const TourModal: FC<TourModalProps> = ({ open, onClose }) => {
|
||||
muted
|
||||
loop
|
||||
className={clsx(videoStyle, {
|
||||
[slideToLeftStyle]: step === 1,
|
||||
[formSlideToRightStyle]: step === 0,
|
||||
[slideToRightStyle]: step === 1,
|
||||
[formSlideToLeftStyle]: step === 0,
|
||||
})}
|
||||
data-testid="onboarding-modal-switch-video"
|
||||
>
|
||||
@@ -142,8 +142,8 @@ export const TourModal: FC<TourModalProps> = ({ open, onClose }) => {
|
||||
{step !== -1 && (
|
||||
<div
|
||||
className={clsx(descriptionStyle, {
|
||||
[slideToRightStyle]: step === 0,
|
||||
[formSlideToLeftStyle]: step === 1,
|
||||
[slideToLeftStyle]: step === 0,
|
||||
[formSlideToRightStyle]: step === 1,
|
||||
})}
|
||||
>
|
||||
{t['com.affine.onboarding.videoDescription2']()}
|
||||
@@ -151,8 +151,8 @@ export const TourModal: FC<TourModalProps> = ({ open, onClose }) => {
|
||||
)}
|
||||
<div
|
||||
className={clsx(descriptionStyle, {
|
||||
[slideToLeftStyle]: step === 1,
|
||||
[formSlideToRightStyle]: step === 0,
|
||||
[slideToRightStyle]: step === 1,
|
||||
[formSlideToLeftStyle]: step === 0,
|
||||
})}
|
||||
>
|
||||
{t['com.affine.onboarding.videoDescription1']()}
|
||||
|
||||
@@ -52,8 +52,7 @@ globalStyle(`html[data-theme="dark"] ${appStyle}`, {
|
||||
|
||||
export const mainContainerStyle = style({
|
||||
position: 'relative',
|
||||
width: 0,
|
||||
flex: 1,
|
||||
flexGrow: 1,
|
||||
maxWidth: '100%',
|
||||
zIndex: 2,
|
||||
backgroundColor: 'var(--affine-background-primary-color)',
|
||||
|
||||
@@ -1,10 +1,5 @@
|
||||
import { clsx } from 'clsx';
|
||||
import type {
|
||||
FC,
|
||||
HTMLAttributes,
|
||||
PropsWithChildren,
|
||||
ReactElement,
|
||||
} from 'react';
|
||||
import type { FC, PropsWithChildren, ReactElement } from 'react';
|
||||
|
||||
import { AppSidebarFallback } from '../app-sidebar';
|
||||
import { appStyle, mainContainerStyle, toolStyle } from './index.css';
|
||||
@@ -40,7 +35,7 @@ export type MainContainerProps = PropsWithChildren<{
|
||||
className?: string;
|
||||
padding?: boolean;
|
||||
}> &
|
||||
HTMLAttributes<HTMLDivElement>;
|
||||
React.HTMLAttributes<HTMLDivElement>;
|
||||
|
||||
export const MainContainer = ({
|
||||
className,
|
||||
@@ -52,7 +47,7 @@ export const MainContainer = ({
|
||||
<div
|
||||
{...props}
|
||||
className={clsx(mainContainerStyle, 'main-container', className)}
|
||||
data-is-macos={environment.isDesktop && environment.isMacOs}
|
||||
data-is-macos={environment.isBrowser && environment.isMacOs}
|
||||
data-show-padding={padding}
|
||||
>
|
||||
{children}
|
||||
|
||||
@@ -13,7 +13,7 @@ export const ModalWrapper = styled('div')<{
|
||||
minHeight,
|
||||
backgroundColor: 'var(--affine-background-secondary-color)',
|
||||
boxShadow: 'var(--affine-shadow-3)',
|
||||
borderRadius: '12px',
|
||||
borderRadius: '16px',
|
||||
position: 'relative',
|
||||
maxHeight: 'calc(100vh - 32px)',
|
||||
};
|
||||
|
||||
@@ -61,9 +61,8 @@ export const scrollbar = style({
|
||||
},
|
||||
});
|
||||
export const TableScrollbar = style({
|
||||
marginTop: '60px',
|
||||
height: 'calc(100% - 120px)',
|
||||
borderRadius: '4px',
|
||||
paddingTop: '60px',
|
||||
paddingBottom: '60px',
|
||||
});
|
||||
|
||||
export const scrollbarThumb = style({
|
||||
|
||||
@@ -8,5 +8,5 @@
|
||||
"devDependencies": {
|
||||
"@types/debug": "^4.1.8"
|
||||
},
|
||||
"version": "0.7.0-beta.0"
|
||||
"version": "0.7.0-canary.42"
|
||||
}
|
||||
|
||||
8
packages/env/package.json
vendored
8
packages/env/package.json
vendored
@@ -5,10 +5,10 @@
|
||||
"module": "./src/index.ts",
|
||||
"types": "./src/global.ts",
|
||||
"devDependencies": {
|
||||
"@blocksuite/global": "0.0.0-20230717055529-79180930-nightly",
|
||||
"@blocksuite/global": "0.0.0-20230711103520-ce18dd84-nightly",
|
||||
"next": "=13.4.2",
|
||||
"react": "18.2.0",
|
||||
"react-dom": "18.2.0",
|
||||
"react": "18.3.0-canary-1fdacbefd-20230630",
|
||||
"react-dom": "18.3.0-canary-1fdacbefd-20230630",
|
||||
"zod": "^3.21.4"
|
||||
},
|
||||
"exports": {
|
||||
@@ -27,5 +27,5 @@
|
||||
"dependencies": {
|
||||
"lit": "^2.7.5"
|
||||
},
|
||||
"version": "0.7.0-beta.0"
|
||||
"version": "0.7.0-canary.42"
|
||||
}
|
||||
|
||||
1
packages/env/src/filter.ts
vendored
1
packages/env/src/filter.ts
vendored
@@ -29,7 +29,6 @@ export type Filter = {
|
||||
|
||||
export type Collection = {
|
||||
id: string;
|
||||
workspaceId: string;
|
||||
name: string;
|
||||
pinned?: boolean;
|
||||
filterList: Filter[];
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@affine/graphql",
|
||||
"version": "0.7.0-beta.0",
|
||||
"version": "0.7.0-canary.42",
|
||||
"description": "Autogenerated GraphQL client for affine.pro",
|
||||
"license": "MPL-2.0",
|
||||
"type": "module",
|
||||
|
||||
@@ -8,5 +8,5 @@
|
||||
"@affine/env": "workspace:*",
|
||||
"@toeverything/y-indexeddb": "workspace:*"
|
||||
},
|
||||
"version": "0.7.0-beta.0"
|
||||
"version": "0.7.0-canary.42"
|
||||
}
|
||||
|
||||
@@ -3,17 +3,14 @@
|
||||
*/
|
||||
import { Workspace } from '@blocksuite/store';
|
||||
import { renderHook } from '@testing-library/react';
|
||||
import { getDefaultStore } from 'jotai/vanilla';
|
||||
import { expect, test, vi } from 'vitest';
|
||||
|
||||
import {
|
||||
usePassiveWorkspaceEffect,
|
||||
useStaticBlockSuiteWorkspace,
|
||||
} from '../__internal__/react';
|
||||
import {
|
||||
getActiveBlockSuiteWorkspaceAtom,
|
||||
INTERNAL_BLOCKSUITE_HASH_MAP,
|
||||
} from '../__internal__/workspace';
|
||||
usePassiveWorkspaceEffect,
|
||||
useStaticBlockSuiteWorkspace,
|
||||
} from '@toeverything/hooks/use-block-suite-workspace';
|
||||
import { getDefaultStore } from 'jotai/vanilla';
|
||||
import { expect, test, vi } from 'vitest';
|
||||
|
||||
test('useStaticBlockSuiteWorkspace', async () => {
|
||||
const sync = vi.fn();
|
||||
84
packages/hooks/src/use-block-suite-workspace.ts
Normal file
84
packages/hooks/src/use-block-suite-workspace.ts
Normal file
@@ -0,0 +1,84 @@
|
||||
import type { ActiveDocProvider, Workspace } from '@blocksuite/store';
|
||||
import type { PassiveDocProvider } from '@blocksuite/store';
|
||||
import { useAtomValue } from 'jotai/react';
|
||||
import type { Atom } from 'jotai/vanilla';
|
||||
import { atom } from 'jotai/vanilla';
|
||||
import { useEffect } from 'react';
|
||||
|
||||
/**
|
||||
* DO NOT ACCESS THIS MAP IN PRODUCTION, OR YOU WILL BE FIRED
|
||||
* Map: guid -> Workspace
|
||||
*/
|
||||
export const INTERNAL_BLOCKSUITE_HASH_MAP = new Map<string, Workspace>([]);
|
||||
|
||||
const workspacePassiveAtomWeakMap = new WeakMap<
|
||||
Workspace,
|
||||
Atom<Promise<Workspace>>
|
||||
>();
|
||||
|
||||
// Whether the workspace is active to use
|
||||
const workspaceActiveWeakMap = new WeakMap<Workspace, boolean>();
|
||||
|
||||
// Whether the workspace has been enabled the passive effect (background)
|
||||
const workspacePassiveEffectWeakMap = new WeakMap<Workspace, boolean>();
|
||||
|
||||
export function getWorkspace(id: string) {
|
||||
if (!INTERNAL_BLOCKSUITE_HASH_MAP.has(id)) {
|
||||
throw new Error('Workspace not found');
|
||||
}
|
||||
return INTERNAL_BLOCKSUITE_HASH_MAP.get(id) as Workspace;
|
||||
}
|
||||
|
||||
export function getActiveBlockSuiteWorkspaceAtom(
|
||||
id: string
|
||||
): Atom<Promise<Workspace>> {
|
||||
if (!INTERNAL_BLOCKSUITE_HASH_MAP.has(id)) {
|
||||
throw new Error('Workspace not found');
|
||||
}
|
||||
const workspace = INTERNAL_BLOCKSUITE_HASH_MAP.get(id) as Workspace;
|
||||
if (!workspacePassiveAtomWeakMap.has(workspace)) {
|
||||
const baseAtom = atom(async () => {
|
||||
if (workspaceActiveWeakMap.get(workspace) !== true) {
|
||||
const providers = workspace.providers.filter(
|
||||
(provider): provider is ActiveDocProvider =>
|
||||
'active' in provider && provider.active === true
|
||||
);
|
||||
for (const provider of providers) {
|
||||
provider.sync();
|
||||
// we will wait for the necessary providers to be ready
|
||||
await provider.whenReady;
|
||||
}
|
||||
workspaceActiveWeakMap.set(workspace, true);
|
||||
}
|
||||
return workspace;
|
||||
});
|
||||
workspacePassiveAtomWeakMap.set(workspace, baseAtom);
|
||||
}
|
||||
return workspacePassiveAtomWeakMap.get(workspace) as Atom<Promise<Workspace>>;
|
||||
}
|
||||
|
||||
export function useStaticBlockSuiteWorkspace(id: string): Workspace {
|
||||
return useAtomValue(getActiveBlockSuiteWorkspaceAtom(id));
|
||||
}
|
||||
|
||||
export function usePassiveWorkspaceEffect(workspace: Workspace) {
|
||||
useEffect(() => {
|
||||
if (workspacePassiveEffectWeakMap.get(workspace) === true) {
|
||||
return;
|
||||
}
|
||||
const providers = workspace.providers.filter(
|
||||
(provider): provider is PassiveDocProvider =>
|
||||
'passive' in provider && provider.passive === true
|
||||
);
|
||||
providers.forEach(provider => {
|
||||
provider.connect();
|
||||
});
|
||||
workspacePassiveEffectWeakMap.set(workspace, true);
|
||||
return () => {
|
||||
providers.forEach(provider => {
|
||||
provider.disconnect();
|
||||
});
|
||||
workspacePassiveEffectWeakMap.delete(workspace);
|
||||
};
|
||||
}, [workspace]);
|
||||
}
|
||||
@@ -28,7 +28,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"i18next": "^23.2.6",
|
||||
"react-i18next": "^13.0.2"
|
||||
"react-i18next": "^13.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^18.16.19",
|
||||
@@ -37,5 +37,5 @@
|
||||
"ts-node": "^10.9.1",
|
||||
"typescript": "^5.1.6"
|
||||
},
|
||||
"version": "0.7.0-beta.0"
|
||||
"version": "0.7.0-canary.42"
|
||||
}
|
||||
|
||||
@@ -360,8 +360,6 @@
|
||||
"Move Down": "Move Down",
|
||||
"Ungroup": "Ungroup",
|
||||
"Version": "Version",
|
||||
"App Version": "App Version",
|
||||
"Editor Version": "Editor Version",
|
||||
"frameless": "Frameless",
|
||||
"Check for updates automatically": "Check for updates automatically",
|
||||
"Note": "Note",
|
||||
|
||||
@@ -317,8 +317,6 @@
|
||||
"Terms of Use": "使用条款",
|
||||
"Unpublished hint": "发布到网络后,访问者可以通过提供的链接查看内容。",
|
||||
"Version": "版本",
|
||||
"App Version": "应用版本",
|
||||
"Editor Version": "编辑器版本",
|
||||
"Window frame style": "视窗样式",
|
||||
"Workspace Profile": "工作区配置文件",
|
||||
"Workspace saved locally": "{{name}} 已保存在本地",
|
||||
|
||||
@@ -46,5 +46,5 @@
|
||||
"optional": true
|
||||
}
|
||||
},
|
||||
"version": "0.7.0-beta.0"
|
||||
"version": "0.7.0-canary.42"
|
||||
}
|
||||
|
||||
@@ -6,11 +6,11 @@
|
||||
"jotai": "^2.2.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@blocksuite/blocks": "0.0.0-20230717055529-79180930-nightly",
|
||||
"@blocksuite/editor": "0.0.0-20230717055529-79180930-nightly",
|
||||
"@blocksuite/global": "0.0.0-20230717055529-79180930-nightly",
|
||||
"@blocksuite/lit": "0.0.0-20230717055529-79180930-nightly",
|
||||
"@blocksuite/store": "0.0.0-20230717055529-79180930-nightly",
|
||||
"@blocksuite/blocks": "0.0.0-20230711103520-ce18dd84-nightly",
|
||||
"@blocksuite/editor": "0.0.0-20230711103520-ce18dd84-nightly",
|
||||
"@blocksuite/global": "0.0.0-20230711103520-ce18dd84-nightly",
|
||||
"@blocksuite/lit": "0.0.0-20230711103520-ce18dd84-nightly",
|
||||
"@blocksuite/store": "0.0.0-20230711103520-ce18dd84-nightly",
|
||||
"lottie-web": "^5.12.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
@@ -21,5 +21,5 @@
|
||||
"@blocksuite/store": "*",
|
||||
"lottie-web": "*"
|
||||
},
|
||||
"version": "0.7.0-beta.0"
|
||||
"version": "0.7.0-canary.42"
|
||||
}
|
||||
|
||||
@@ -38,5 +38,5 @@
|
||||
"test": "cross-env TS_NODE_TRANSPILE_ONLY=1 TS_NODE_PROJECT=./tsconfig.json node --test --loader ts-node/esm --experimental-specifier-resolution=node ./__tests__/**/*.mts",
|
||||
"version": "napi version"
|
||||
},
|
||||
"version": "0.7.0-beta.0"
|
||||
"version": "0.7.0-canary.42"
|
||||
}
|
||||
|
||||
@@ -18,36 +18,30 @@
|
||||
"type": "./dist/type.d.ts",
|
||||
"import": "./dist/type.js",
|
||||
"require": "./dist/type.cjs"
|
||||
},
|
||||
"./__internal__/workspace": {
|
||||
"type": "./dist/__internal__/workspace.d.ts",
|
||||
"import": "./dist/__internal__/workspace.js",
|
||||
"require": "./dist/__internal__/workspace.cjs"
|
||||
},
|
||||
"./__internal__/react": {
|
||||
"type": "./dist/__internal__/react.d.ts",
|
||||
"import": "./dist/__internal__/react.js",
|
||||
"require": "./dist/__internal__/react.cjs"
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@blocksuite/global": "0.0.0-20230717055529-79180930-nightly",
|
||||
"@blocksuite/store": "0.0.0-20230717055529-79180930-nightly",
|
||||
"@blocksuite/blocks": "0.0.0-20230711103520-ce18dd84-nightly",
|
||||
"@blocksuite/editor": "0.0.0-20230711103520-ce18dd84-nightly",
|
||||
"@blocksuite/global": "0.0.0-20230711103520-ce18dd84-nightly",
|
||||
"@blocksuite/lit": "0.0.0-20230711103520-ce18dd84-nightly",
|
||||
"@blocksuite/store": "0.0.0-20230711103520-ce18dd84-nightly",
|
||||
"jotai": "^2.2.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@blocksuite/blocks": "0.0.0-20230717055529-79180930-nightly",
|
||||
"@blocksuite/editor": "0.0.0-20230717055529-79180930-nightly",
|
||||
"@blocksuite/lit": "0.0.0-20230717055529-79180930-nightly",
|
||||
"jotai": "^2.2.2",
|
||||
"vite": "^4.3.9",
|
||||
"vite-plugin-dts": "3.0.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@blocksuite/blocks": "*",
|
||||
"@blocksuite/editor": "*",
|
||||
"@blocksuite/global": "*",
|
||||
"@blocksuite/lit": "*",
|
||||
"@blocksuite/store": "*",
|
||||
"jotai": "*",
|
||||
"react": "*",
|
||||
"react-dom": "*"
|
||||
},
|
||||
"version": "0.7.0-beta.0"
|
||||
"version": "0.7.0-canary.42"
|
||||
}
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
import type { Workspace } from '@blocksuite/store';
|
||||
import { type PassiveDocProvider } from '@blocksuite/store';
|
||||
import { useAtomValue } from 'jotai/react';
|
||||
import { useEffect } from 'react';
|
||||
|
||||
import {
|
||||
getActiveBlockSuiteWorkspaceAtom,
|
||||
workspacePassiveEffectWeakMap,
|
||||
} from './workspace';
|
||||
|
||||
export function useStaticBlockSuiteWorkspace(id: string): Workspace {
|
||||
return useAtomValue(getActiveBlockSuiteWorkspaceAtom(id));
|
||||
}
|
||||
|
||||
export function usePassiveWorkspaceEffect(workspace: Workspace) {
|
||||
useEffect(() => {
|
||||
if (workspacePassiveEffectWeakMap.get(workspace) === true) {
|
||||
return;
|
||||
}
|
||||
const providers = workspace.providers.filter(
|
||||
(provider): provider is PassiveDocProvider =>
|
||||
'passive' in provider && provider.passive === true
|
||||
);
|
||||
providers.forEach(provider => {
|
||||
provider.connect();
|
||||
});
|
||||
workspacePassiveEffectWeakMap.set(workspace, true);
|
||||
return () => {
|
||||
providers.forEach(provider => {
|
||||
provider.disconnect();
|
||||
});
|
||||
workspacePassiveEffectWeakMap.delete(workspace);
|
||||
};
|
||||
}, [workspace]);
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
import type { ActiveDocProvider, Workspace } from '@blocksuite/store';
|
||||
import type { Atom } from 'jotai/vanilla';
|
||||
import { atom } from 'jotai/vanilla';
|
||||
|
||||
/**
|
||||
* DO NOT ACCESS THIS MAP IN PRODUCTION, OR YOU WILL BE FIRED
|
||||
* Map: guid -> Workspace
|
||||
*/
|
||||
export const INTERNAL_BLOCKSUITE_HASH_MAP = new Map<string, Workspace>([]);
|
||||
|
||||
const workspacePassiveAtomWeakMap = new WeakMap<
|
||||
Workspace,
|
||||
Atom<Promise<Workspace>>
|
||||
>();
|
||||
|
||||
// Whether the workspace is active to use
|
||||
export const workspaceActiveWeakMap = new WeakMap<Workspace, boolean>();
|
||||
|
||||
// Whether the workspace has been enabled the passive effect (background)
|
||||
export const workspacePassiveEffectWeakMap = new WeakMap<Workspace, boolean>();
|
||||
|
||||
export async function waitForWorkspace(workspace: Workspace) {
|
||||
if (workspaceActiveWeakMap.get(workspace) !== true) {
|
||||
const providers = workspace.providers.filter(
|
||||
(provider): provider is ActiveDocProvider =>
|
||||
'active' in provider && provider.active === true
|
||||
);
|
||||
for (const provider of providers) {
|
||||
provider.sync();
|
||||
// we will wait for the necessary providers to be ready
|
||||
await provider.whenReady;
|
||||
}
|
||||
workspaceActiveWeakMap.set(workspace, true);
|
||||
}
|
||||
}
|
||||
|
||||
export function getWorkspace(id: string) {
|
||||
if (!INTERNAL_BLOCKSUITE_HASH_MAP.has(id)) {
|
||||
throw new Error('Workspace not found');
|
||||
}
|
||||
return INTERNAL_BLOCKSUITE_HASH_MAP.get(id) as Workspace;
|
||||
}
|
||||
|
||||
export function getActiveBlockSuiteWorkspaceAtom(
|
||||
id: string
|
||||
): Atom<Promise<Workspace>> {
|
||||
if (!INTERNAL_BLOCKSUITE_HASH_MAP.has(id)) {
|
||||
throw new Error('Workspace not found');
|
||||
}
|
||||
const workspace = INTERNAL_BLOCKSUITE_HASH_MAP.get(id) as Workspace;
|
||||
if (!workspacePassiveAtomWeakMap.has(workspace)) {
|
||||
const baseAtom = atom(async () => {
|
||||
await waitForWorkspace(workspace);
|
||||
return workspace;
|
||||
});
|
||||
workspacePassiveAtomWeakMap.set(workspace, baseAtom);
|
||||
}
|
||||
return workspacePassiveAtomWeakMap.get(workspace) as Atom<Promise<Workspace>>;
|
||||
}
|
||||
@@ -1,8 +1,5 @@
|
||||
import { assertExists } from '@blocksuite/global/utils';
|
||||
import type { Page, Workspace } from '@blocksuite/store';
|
||||
import { atom, createStore } from 'jotai/vanilla';
|
||||
|
||||
import { getWorkspace, waitForWorkspace } from './__internal__/workspace';
|
||||
import type { AffinePlugin, Definition, ServerAdapter } from './type';
|
||||
import type { Loader, PluginUIAdapter } from './type';
|
||||
import type { PluginBlockSuiteAdapter } from './type';
|
||||
@@ -15,29 +12,6 @@ export const rootStore = createStore();
|
||||
|
||||
// todo: for now every plugin is enabled by default
|
||||
export const affinePluginsAtom = atom<Record<string, AffinePlugin<string>>>({});
|
||||
export const currentWorkspaceIdAtom = atom<string | null>(null);
|
||||
export const currentPageIdAtom = atom<string | null>(null);
|
||||
export const currentWorkspaceAtom = atom<Promise<Workspace>>(async get => {
|
||||
const currentWorkspaceId = get(currentWorkspaceIdAtom);
|
||||
assertExists(currentWorkspaceId, 'current workspace id');
|
||||
const workspace = getWorkspace(currentWorkspaceId);
|
||||
await waitForWorkspace(workspace);
|
||||
return workspace;
|
||||
});
|
||||
export const currentPageAtom = atom<Promise<Page>>(async get => {
|
||||
const currentWorkspaceId = get(currentWorkspaceIdAtom);
|
||||
assertExists(currentWorkspaceId, 'current workspace id');
|
||||
const currentPageId = get(currentPageIdAtom);
|
||||
assertExists(currentPageId, 'current page id');
|
||||
const workspace = getWorkspace(currentWorkspaceId);
|
||||
await waitForWorkspace(workspace);
|
||||
const page = workspace.getPage(currentPageId);
|
||||
assertExists(page);
|
||||
if (!page.loaded) {
|
||||
await page.waitForLoaded();
|
||||
}
|
||||
return page;
|
||||
});
|
||||
|
||||
export function definePlugin<ID extends string>(
|
||||
definition: Definition<ID>,
|
||||
|
||||
@@ -13,15 +13,18 @@ export default defineConfig({
|
||||
entry: {
|
||||
type: resolve(root, 'src/type.ts'),
|
||||
manager: resolve(root, 'src/manager.ts'),
|
||||
'__internal__/workspace': resolve(
|
||||
root,
|
||||
'src/__internal__/workspace.ts'
|
||||
),
|
||||
'__internal__/react': resolve(root, 'src/__internal__/react.ts'),
|
||||
},
|
||||
},
|
||||
rollupOptions: {
|
||||
external: ['react', /^jotai/, /^@blocksuite/],
|
||||
external: [
|
||||
'jotai',
|
||||
'jotai/vanilla',
|
||||
'@blocksuite/blocks',
|
||||
'@blocksuite/store',
|
||||
'@blocksuite/global',
|
||||
'@blocksuite/editor',
|
||||
'@blocksuite/lit',
|
||||
],
|
||||
},
|
||||
},
|
||||
plugins: [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@affine/storage",
|
||||
"version": "0.7.0-beta.0",
|
||||
"version": "0.7.0-canary.42",
|
||||
"engines": {
|
||||
"node": ">= 10.16.0 < 11 || >= 11.8.0"
|
||||
},
|
||||
|
||||
@@ -6,5 +6,5 @@
|
||||
"./*.md": "./*.md",
|
||||
"./preloading.json": "./preloading.json"
|
||||
},
|
||||
"version": "0.7.0-beta.0"
|
||||
"version": "0.7.0-canary.42"
|
||||
}
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
"js-base64": "^3.7.5",
|
||||
"ky": "^0.33.3",
|
||||
"lib0": "^0.2.78",
|
||||
"react": "18.2.0",
|
||||
"react-dom": "18.2.0",
|
||||
"react": "18.3.0-canary-1fdacbefd-20230630",
|
||||
"react-dom": "18.3.0-canary-1fdacbefd-20230630",
|
||||
"y-protocols": "^1.0.5",
|
||||
"yjs": "^13.6.6",
|
||||
"zod": "^3.21.4"
|
||||
@@ -36,5 +36,5 @@
|
||||
"next": "=13.4.2",
|
||||
"ws": "^8.13.0"
|
||||
},
|
||||
"version": "0.7.0-beta.0"
|
||||
"version": "0.7.0-canary.42"
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import { createEmptyBlockSuiteWorkspace } from '@affine/workspace/utils';
|
||||
import type { BlockHub } from '@blocksuite/blocks';
|
||||
import { assertExists } from '@blocksuite/global/utils';
|
||||
import { atom } from 'jotai';
|
||||
import Router from 'next/router';
|
||||
import { z } from 'zod';
|
||||
|
||||
const rootWorkspaceMetadataV1Schema = z.object({
|
||||
@@ -71,6 +72,27 @@ const rootWorkspacesMetadataPromiseAtom = atom<
|
||||
if (maybeMetadata !== null) {
|
||||
return maybeMetadata;
|
||||
}
|
||||
const createFirst = (): RootWorkspaceMetadataV2[] => {
|
||||
if (signal.aborted) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const Plugins = Object.values(WorkspaceAdapters).sort(
|
||||
(a, b) => a.loadPriority - b.loadPriority
|
||||
);
|
||||
|
||||
return Plugins.flatMap(Plugin => {
|
||||
return Plugin.Events['app:init']?.().map(
|
||||
id =>
|
||||
({
|
||||
id,
|
||||
flavour: Plugin.flavour,
|
||||
// new workspace should all support sub-doc feature
|
||||
version: WorkspaceVersion.SubDoc,
|
||||
}) satisfies RootWorkspaceMetadataV2
|
||||
);
|
||||
}).filter((ids): ids is RootWorkspaceMetadataV2 => !!ids);
|
||||
};
|
||||
|
||||
if (environment.isServer) {
|
||||
// return a promise in SSR to avoid the hydration mismatch
|
||||
@@ -81,19 +103,6 @@ const rootWorkspacesMetadataPromiseAtom = atom<
|
||||
// fixme(himself65): we might not need step 1
|
||||
// step 1: try load metadata from localStorage
|
||||
{
|
||||
// migration step, only data in `METADATA_STORAGE_KEY` will be migrated
|
||||
if (
|
||||
metadata.some(meta => !('version' in meta)) &&
|
||||
!globalThis.$migrationDone
|
||||
) {
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
signal.addEventListener('abort', () => reject(), { once: true });
|
||||
window.addEventListener('migration-done', () => resolve(), {
|
||||
once: true,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// don't change this key,
|
||||
// otherwise it will cause the data loss in the production
|
||||
const primitiveMetadata = localStorage.getItem(METADATA_STORAGE_KEY);
|
||||
@@ -108,6 +117,19 @@ const rootWorkspacesMetadataPromiseAtom = atom<
|
||||
console.error('cannot parse worksapce', e);
|
||||
}
|
||||
}
|
||||
|
||||
// migration step, only data in `METADATA_STORAGE_KEY` will be migrated
|
||||
if (
|
||||
metadata.some(meta => !('version' in meta)) &&
|
||||
!globalThis.$migrationDone
|
||||
) {
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
signal.addEventListener('abort', () => reject(), { once: true });
|
||||
window.addEventListener('migration-done', () => resolve(), {
|
||||
once: true,
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
// step 2: fetch from adapters
|
||||
{
|
||||
@@ -138,6 +160,17 @@ const rootWorkspacesMetadataPromiseAtom = atom<
|
||||
}
|
||||
}
|
||||
}
|
||||
// step 3: create initial workspaces
|
||||
{
|
||||
if (
|
||||
metadata.length === 0 &&
|
||||
localStorage.getItem('is-first-open') === null
|
||||
) {
|
||||
metadata.push(...createFirst());
|
||||
console.info('create first workspace', metadata);
|
||||
localStorage.setItem('is-first-open', 'false');
|
||||
}
|
||||
}
|
||||
const metadataMap = new Map(metadata.map(x => [x.id, x]));
|
||||
// init workspace data
|
||||
metadataMap.forEach((meta, id) => {
|
||||
@@ -162,6 +195,9 @@ export const rootWorkspacesMetadataAtom = atom<
|
||||
Promise<RootWorkspaceMetadata[]>
|
||||
>(
|
||||
async get => {
|
||||
if (environment.isServer) {
|
||||
return Promise.resolve([]);
|
||||
}
|
||||
const maybeMetadata = get(rootWorkspacesMetadataPrimitiveAtom);
|
||||
if (maybeMetadata !== null) {
|
||||
return maybeMetadata;
|
||||
@@ -187,6 +223,7 @@ export const rootWorkspacesMetadataAtom = atom<
|
||||
|
||||
const metadataMap = new Map(metadata.map(x => [x.id, x]));
|
||||
metadata = Array.from(metadataMap.values());
|
||||
|
||||
// write back to localStorage
|
||||
rootWorkspaceMetadataArraySchema.parse(metadata);
|
||||
localStorage.setItem(METADATA_STORAGE_KEY, JSON.stringify(metadata));
|
||||
@@ -195,6 +232,50 @@ export const rootWorkspacesMetadataAtom = atom<
|
||||
}
|
||||
);
|
||||
|
||||
// two more atoms to store the current workspace and page
|
||||
export const rootCurrentWorkspaceIdAtom = atom<string | null>(null);
|
||||
|
||||
rootCurrentWorkspaceIdAtom.onMount = set => {
|
||||
if (environment.isBrowser) {
|
||||
const callback = (url: string) => {
|
||||
const value = url.split('/')[2];
|
||||
if (value) {
|
||||
set(value);
|
||||
localStorage.setItem('last_workspace_id', value);
|
||||
} else {
|
||||
set(null);
|
||||
}
|
||||
};
|
||||
callback(window.location.pathname);
|
||||
Router.events.on('routeChangeStart', callback);
|
||||
return () => {
|
||||
Router.events.off('routeChangeStart', callback);
|
||||
};
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
export const rootCurrentPageIdAtom = atom<string | null>(null);
|
||||
|
||||
rootCurrentPageIdAtom.onMount = set => {
|
||||
if (environment.isBrowser) {
|
||||
const callback = (url: string) => {
|
||||
const value = url.split('/')[3];
|
||||
if (value) {
|
||||
set(value);
|
||||
} else {
|
||||
set(null);
|
||||
}
|
||||
};
|
||||
callback(window.location.pathname);
|
||||
Router.events.on('routeChangeStart', callback);
|
||||
return () => {
|
||||
Router.events.off('routeChangeStart', callback);
|
||||
};
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
// blocksuite atoms,
|
||||
// each app should have only one block-hub in the same time
|
||||
export const rootBlockHubAtom = atom<Readonly<BlockHub> | null>(null);
|
||||
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
Generator,
|
||||
Workspace,
|
||||
} from '@blocksuite/store';
|
||||
import { INTERNAL_BLOCKSUITE_HASH_MAP } from '@toeverything/plugin-infra/__internal__/workspace';
|
||||
import { INTERNAL_BLOCKSUITE_HASH_MAP } from '@toeverything/hooks/use-block-suite-workspace';
|
||||
|
||||
import { createStaticStorage } from './blob/local-static-storage';
|
||||
import { createSQLiteStorage } from './blob/sqlite-blob-storage';
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@toeverything/y-indexeddb",
|
||||
"type": "module",
|
||||
"version": "0.7.0-beta.0",
|
||||
"version": "0.7.0-canary.42",
|
||||
"description": "IndexedDB database adapter for Yjs",
|
||||
"repository": "toeverything/AFFiNE",
|
||||
"author": "toeverything",
|
||||
@@ -36,8 +36,8 @@
|
||||
"idb": "^7.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@blocksuite/blocks": "0.0.0-20230717055529-79180930-nightly",
|
||||
"@blocksuite/store": "0.0.0-20230717055529-79180930-nightly",
|
||||
"@blocksuite/blocks": "0.0.0-20230711103520-ce18dd84-nightly",
|
||||
"@blocksuite/store": "0.0.0-20230711103520-ce18dd84-nightly",
|
||||
"vite": "^4.3.9",
|
||||
"vite-plugin-dts": "3.0.2",
|
||||
"y-indexeddb": "^9.0.11"
|
||||
|
||||
@@ -14,7 +14,7 @@ import type {
|
||||
* See https://playwright.dev/docs/test-configuration.
|
||||
*/
|
||||
const config: PlaywrightTestConfig = {
|
||||
testDir: './e2e',
|
||||
testDir: './tests/parallels',
|
||||
fullyParallel: true,
|
||||
timeout: process.env.CI ? 50_000 : 30_000,
|
||||
use: {
|
||||
@@ -18,12 +18,12 @@
|
||||
"link-preview-js": "^3.0.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"react": "18.2.0",
|
||||
"react-dom": "18.2.0"
|
||||
"react": "18.3.0-canary-1fdacbefd-20230630",
|
||||
"react-dom": "18.3.0-canary-1fdacbefd-20230630"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "*",
|
||||
"react-dom": "*"
|
||||
},
|
||||
"version": "0.7.0-beta.0"
|
||||
"version": "0.7.0-canary.42"
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
"dependencies": {
|
||||
"@affine/component": "workspace:*",
|
||||
"@toeverything/plugin-infra": "workspace:*",
|
||||
"langchain": "^0.0.107",
|
||||
"langchain": "^0.0.102",
|
||||
"marked": "^5.1.0",
|
||||
"marked-gfm-heading-id": "^3.0.4",
|
||||
"marked-mangle": "^1.1.0"
|
||||
@@ -20,13 +20,13 @@
|
||||
"@types/react-dom": "^18.2.6",
|
||||
"idb": "^7.1.1",
|
||||
"jotai": "^2.2.2",
|
||||
"react": "18.2.0",
|
||||
"react-dom": "18.2.0",
|
||||
"react": "18.3.0-canary-1fdacbefd-20230630",
|
||||
"react-dom": "18.3.0-canary-1fdacbefd-20230630",
|
||||
"zod": "^3.21.4"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "*",
|
||||
"react-dom": "*"
|
||||
},
|
||||
"version": "0.7.0-beta.0"
|
||||
"version": "0.7.0-canary.42"
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import type { BaseMessage } from 'langchain/schema';
|
||||
import type { BaseChatMessage } from 'langchain/schema';
|
||||
|
||||
import { Conversation } from '../conversation';
|
||||
import { conversationListStyle } from './index.css';
|
||||
|
||||
export type ConversationListProps = {
|
||||
conversations: BaseMessage[];
|
||||
conversations: BaseChatMessage[];
|
||||
};
|
||||
|
||||
export const ConversationList = (props: ConversationListProps) => {
|
||||
@@ -13,7 +13,7 @@ export const ConversationList = (props: ConversationListProps) => {
|
||||
{props.conversations.map((conversation, idx) => (
|
||||
<Conversation
|
||||
type={conversation._getType()}
|
||||
text={conversation.content}
|
||||
text={conversation.text}
|
||||
key={idx}
|
||||
/>
|
||||
))}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user