Compare commits

..

206 Commits

Author SHA1 Message Date
Alex Yang
4109490789 v0.7.0-canary.42 2023-07-12 23:01:11 +08:00
Peng Xiao
e813436af7 fix: iconUrl for windows build (#3194) 2023-07-12 14:35:45 +00:00
Alex Yang
5b87d90ffe fix: first page id conflict (#3192) 2023-07-12 10:43:52 +00:00
Alex Yang
ccbae6f496 fix: unexpected jump 404 page (#3190) 2023-07-12 10:18:02 +00:00
JimmFly
1ac1c33bb1 style: update delete button style (#3180) 2023-07-12 09:23:39 +00:00
Peng Xiao
bd42380f8a fix: add default fonts (#3185) 2023-07-12 08:43:25 +00:00
xiaodong zuo
30dee18835 fix: enhancing the security of image proxy (#3176) 2023-07-12 08:35:46 +00:00
Alex Yang
b509302711 v0.7.0-canary.41 2023-07-12 14:49:08 +08:00
Alex Yang
e51c98c1dd chore: bump version (#3179) 2023-07-12 06:21:11 +00:00
Alex Yang
bbb1387469 feat: display app version in setting panel (#3170) 2023-07-12 02:39:00 +00:00
xiaodong zuo
4f88774999 fix: the image lost after exporting (#3150)
Co-authored-by: Alex Yang <himself65@outlook.com>
2023-07-12 02:21:23 +00:00
Alex Yang
3968deb6d4 feat: add suspense to workspace settings (#3167)
Co-authored-by: Qi <474021214@qq.com>
2023-07-11 15:50:30 +00:00
Alex Yang
37c8465af8 fix: jump to index page after deletion (#3169) 2023-07-11 15:44:00 +00:00
Peng Xiao
d88a21d24a fix: settings style update (#3161) 2023-07-11 12:55:28 +00:00
3720
6ad2d106bc fix: some typo and i18n (#3155) 2023-07-11 11:04:45 +00:00
Alex Yang
8c1fcee135 refactor: remove unused code (#3149) 2023-07-11 08:53:01 +00:00
Peng Xiao
0514da9759 fix: updater not working (#3144) 2023-07-11 07:06:04 +00:00
JimmFly
b2fed03f30 style: modify the style of community item (#3143) 2023-07-11 06:44:06 +00:00
Alex Yang
f5e45573af v0.7.0-canary.40 2023-07-11 12:59:12 +08:00
Alex Yang
ddb2931f38 fix: remove workspace not working (#3140) 2023-07-11 04:37:47 +00:00
Alex Yang
acf17ebace chore: bump version (#3138) 2023-07-11 04:28:01 +00:00
Alex Yang
7af3c05b8b v0.7.0-canary.39 2023-07-10 21:00:06 +08:00
Alex Yang
01de2ae714 revert: restrict node version 2023-07-10 20:51:49 +08:00
Qi
cfa18d1bc3 fix: font style setting only control editor's font (#3117)
Co-authored-by: Alex Yang <himself65@outlook.com>
2023-07-10 11:58:53 +00:00
Alex Yang
127c63601e chore: bump version (#3131) 2023-07-10 11:34:43 +00:00
LongYinan
f079b0b49a fix: add semver into server dependencies 2023-07-10 19:32:39 +08:00
Alex Yang
6caf934d47 refactor: follow correct react rules (#3119) 2023-07-10 10:32:15 +00:00
Qi
2f910fbad0 feat: modify setting modal entry in quick search modal (#3089) 2023-07-10 09:28:14 +00:00
Peng Xiao
dac4e390aa fix: add DB migration to add workspace (#3115) 2023-07-10 08:03:18 +00:00
JimmFly
812e0e9c9a style: change switch tip color (#3123) 2023-07-10 07:00:23 +00:00
Alex Yang
05291a8a36 chore: restrict node version (#3120) 2023-07-10 06:19:59 +00:00
JimmFly
8bcc4d6a57 test: fix incorrect day suffix (#3121) 2023-07-10 05:56:12 +00:00
danielchim
e06d5e1c8d fix: page mode shortcut (#3097) 2023-07-09 18:37:49 +00:00
Alex Yang
1c8895f23f feat: improve error log message (#3112) 2023-07-09 05:54:53 +00:00
Alex Yang
8b5d997322 refactor(hooks): reduce null types (#3111) 2023-07-09 05:01:09 +00:00
Peng Xiao
33644a68b2 fix: disable move db by default (#3105)
Co-authored-by: Alex Yang <himself65@outlook.com>
2023-07-09 03:37:39 +00:00
mon-jai
bc85ad5b65 fix: sidebar noise background on Windows (#3107) 2023-07-08 16:41:07 +00:00
Alex Yang
fe895905bd v0.7.0-canary.38 2023-07-08 15:57:31 +08:00
Alex Yang
3c5ccd7231 fix: init workspace before loaded (#3104) 2023-07-08 07:42:30 +00:00
Alex Yang
da140b0b85 chore: remove unused code (#3102) 2023-07-08 06:49:11 +00:00
Alex Yang
c4d53d59b5 test: fix flaky (#3100) 2023-07-08 06:30:17 +00:00
boomlion8
a48726d088 fix: color of UI in dark mode (#3081)
Co-authored-by: boomlion8 <201116201@manit.ac.in>
Co-authored-by: Alex Yang <himself65@outlook.com>
2023-07-08 06:00:03 +00:00
Alex Yang
b49306607b feat: improve workspace hook (#3099) 2023-07-08 05:43:39 +00:00
Alex Yang
3d15c60cb1 v0.7.0-canary.37 2023-07-08 02:55:18 +08:00
Alex Yang
283f0cd263 refactor: lazy load workspaces (#3091) 2023-07-07 14:15:27 +00:00
JimmFly
66152401be chore: add new item for share component (#3084) 2023-07-07 13:16:49 +00:00
Qi
b12412a3c1 feat: add font style setting (#3092) 2023-07-07 11:59:38 +00:00
Peng Xiao
ce1e8d868c fix: a possible issue on electron flaky test (#3094) 2023-07-07 11:02:58 +00:00
Alex Yang
3294043180 perf: reduce unused provider connection (#3090) 2023-07-07 08:13:32 +00:00
Alex Yang
152fbaabda ci: fix nx.yml (#3086) 2023-07-07 05:37:40 +00:00
JimmFly
5756bdf8d7 style: adjust settings style (#3083) 2023-07-07 05:36:27 +00:00
Alex Yang
80ee33fd3e chore: bump version (#3078) 2023-07-07 01:55:11 +00:00
Alex Yang
955d80e2c1 test: image preview e2e (#3080)
Co-authored-by: danielchim <kahungchim@gmail.com>
2023-07-06 23:24:03 +00:00
Alex Yang
67fe7f04da build: fix nx inputs (#3079) 2023-07-07 01:15:04 +08:00
Alex Yang
6395521f09 test: upgrade playwright (#3077) 2023-07-06 16:15:18 +00:00
Alex Yang
822078e640 fix: cleanup workspace when switch setting panel (#3072) 2023-07-06 15:27:09 +00:00
Alex Yang
fafd93f7dc refactor: block-hub in tool wrapper (#3073) 2023-07-06 15:18:58 +00:00
Peng Xiao
00ce086e79 fix: workspace storage settings issues (#3055) 2023-07-06 12:48:20 +00:00
Alex Yang
28653d6892 fix(web): setting panel refresh (#3070) 2023-07-06 11:24:26 +00:00
Alex Yang
e30c67482f fix(web): fetch hello-world from local (#3062) 2023-07-06 09:46:17 +00:00
Pratik Kumar
bda28e0404 fix(component): new page button in all page (#3053) 2023-07-06 09:40:37 +00:00
Alex Yang
ce63364299 fix(component): image preview fallback (#3058) 2023-07-06 09:22:23 +00:00
JimmFly
f468dff6aa chore: update communities link and icon (#3052) 2023-07-06 07:24:36 +00:00
Peng Xiao
fab03006e8 fix: menu item click area (#3051) 2023-07-06 06:53:50 +00:00
JimmFly
8a565b8633 fix: date-picker hidden in update collection (#3045) 2023-07-06 06:17:19 +00:00
Alex Yang
e79a6a5d47 v0.7.0-canary.36 2023-07-06 14:07:27 +08:00
Pratik Kumar
95c2e20cb5 fix(component): all page list UI padding (#3046)
Co-authored-by: Alex Yang <himself65@outlook.com>
2023-07-06 05:56:08 +00:00
JimmFly
2e0f410978 chore: temporary fix sync script error (#3044) 2023-07-06 12:30:01 +08:00
Alex Yang
fa1cd87348 chore: bump version (#3041) 2023-07-06 03:49:17 +00:00
Alex Yang
e95d28e136 fix: workspace name should change in the setting panel (#3039) 2023-07-06 02:19:06 +00:00
Qi
87ba71e77e fix: a series of setting issues (#3032) 2023-07-05 14:11:42 +00:00
Peng Xiao
dec0c0d3d1 fix: delete workspace in settings (#3030) 2023-07-05 10:31:11 +00:00
Peng Xiao
776172bc88 fix: updater issues (#3027) 2023-07-05 09:29:11 +00:00
Alex Yang
d582548ed8 v0.7.0-canary.35 2023-07-05 16:02:31 +08:00
Alex Yang
70ac31b907 build: remove legacy cloud config (#3024) 2023-07-05 06:57:56 +00:00
Alex Yang
cff9fd1ead chore: bump version (#3023) 2023-07-05 06:54:09 +00:00
Alex Yang
319febb00d docs: update README.md 2023-07-05 14:31:47 +08:00
3720
72fa2da2d3 fix: tags does not exist (#3020) 2023-07-05 04:06:44 +00:00
Alex Yang
3084c427f1 feat: update server login feature (#3004)
Co-authored-by: LongYinan <lynweklm@gmail.com>
2023-07-05 03:13:20 +00:00
3720
9cd1f013f8 fix: flaky tests (#3019) 2023-07-05 02:50:43 +00:00
Alex Yang
a3f58d4302 v0.7.0-canary.34 2023-07-05 02:23:53 +08:00
Alex Yang
d4cb89eafc chore: bump version (#3016) 2023-07-04 17:52:40 +00:00
Peng Xiao
33ba034336 fix: sqlite provider import sub doc db file (#2991)
Co-authored-by: Alex Yang <himself65@outlook.com>
2023-07-04 17:47:42 +00:00
Alex Yang
e158c09160 chore: update pre-commit (#3017) 2023-07-04 17:42:14 +00:00
JimmFly
c6ccd6d5de chore: update setting text (#3000) 2023-07-04 17:40:58 +00:00
Alex Yang
ec87864c34 refactor: simplify code (#3015) 2023-07-04 17:34:22 +00:00
Alex Yang
a06ba403d0 ci: check macOS arm64 bundle output (#3012) 2023-07-04 16:59:00 +00:00
Alex Yang
dfbec46ded feat(electron): move preload to infra (#3011) 2023-07-04 16:43:30 +00:00
Alex Yang
24be73ef63 chore: bump nx (#3014) 2023-07-04 16:26:43 +00:00
Alex Yang
3976c37d41 v0.7.0-canary.33 2023-07-04 21:52:04 +08:00
Fangdun Tsai
2bc15665b9 chore(electron): renaming clipboard api (#3005) 2023-07-04 12:51:59 +00:00
Alex Yang
e4539dfeb1 fix: bookmark block output missing (#3010) 2023-07-04 12:48:47 +00:00
Qi
1070e17310 feat: modify setting modal (#3008) 2023-07-04 12:37:46 +00:00
Alex Yang
b4f7eb36ef v0.7.0-canary.32 2023-07-04 16:12:09 +08:00
3720
000f802baa feat: add tags support (#2988)
Co-authored-by: Alex Yang <himself65@outlook.com>
2023-07-04 07:32:11 +00:00
Alex Yang
e871ffcba0 refactor: input component (#2999) 2023-07-04 06:52:46 +00:00
Alex Yang
8d2ffe3936 chore: bump version (#2998) 2023-07-04 06:47:35 +00:00
ShortCipher5
9e253420d2 docs: update README.md (#2997) 2023-07-04 14:13:25 +08:00
Alex Yang
edb7847e95 test: use static server (#2996) 2023-07-04 05:37:06 +00:00
Alex Yang
3d70148e0f chore: add circular check (#2995) 2023-07-04 04:54:08 +00:00
Alex Yang
7f89b197da build: enable next server (#2992) 2023-07-04 01:59:06 +00:00
danielchim
32692bd54a feat: page mode shortcut (#2985) 2023-07-03 16:23:53 +00:00
Alex Yang
7b2acec7c3 v0.7.0-canary.31 2023-07-03 23:14:38 +08:00
Alex Yang
f1adf23631 chore: bump version (#2989) 2023-07-03 14:51:49 +00:00
Alex Yang
a5d2fafad6 refactor: remove legacy cloud (#2987) 2023-07-03 14:29:37 +00:00
xiaodong zuo
3d0a907b49 fix: dark mode export PDF leaves margin and notification (#2978) 2023-07-03 12:11:07 +00:00
LongYinan
bacd00655d ci: reduce yarn cache (#2983) 2023-07-03 11:09:17 +00:00
Peng Xiao
08e003b0f6 fix: potential updater issue (#2973) 2023-07-03 11:04:45 +00:00
Alex Yang
0f1c5163a1 feat: remove old setting page by default (#2980) 2023-07-03 10:59:23 +00:00
JimmFly
18874d0d1e chore: add import to sidebar (#2981) 2023-07-03 10:51:28 +00:00
Peng Xiao
7f0a74c694 fix: some potential tests issue (#2982) 2023-07-03 10:46:47 +00:00
Peng Xiao
901fc87716 fix: potential race condition on app load when migration (#2977)
Co-authored-by: Alex Yang <himself65@outlook.com>
2023-07-03 09:40:02 +00:00
Alex Yang
ee2ab4086f fix(web): hydration issue (#2974) 2023-07-03 09:06:12 +00:00
JimmFly
af94674c18 style: adjust icon button hover color (#2976) 2023-07-03 08:46:16 +00:00
Alex Yang
262289a398 chore: add affine-cloud build config (#2971) 2023-07-03 07:25:14 +00:00
Alex Yang
467eab4ddf build: update build config (#2967) 2023-07-03 06:17:13 +00:00
Alex Yang
63517e4912 chore: update 'lint-staged' rules (#2969) 2023-07-03 06:00:50 +00:00
JimmFly
6f9487deb7 style: adjust copilot chat style (#2915) 2023-07-03 05:57:30 +00:00
JimmFly
8d0edd5255 i18n: update translation resources (#2968) 2023-07-03 05:15:46 +00:00
Qi
bdea153c82 feat: modify preloading data (#2947) 2023-07-03 02:49:55 +00:00
Alex Yang
d447883b7d v0.7.0-canary.30 2023-07-02 14:18:33 +08:00
Alex Yang
03ec51a96c chore: bump version 2023-07-02 14:17:22 +08:00
Alex Yang
0adf18f5e6 v0.7.0-canary.29 2023-07-02 14:06:14 +08:00
Alex Yang
5e7dc9ff21 chore: bump version (#2960) 2023-07-02 05:26:47 +00:00
Alex Yang
33097382c6 chore: replace 'eslint-plugin-import' (#2957) 2023-07-01 16:35:16 +00:00
Alex Yang
b9df2cdabb ci: update labeler.yml 2023-07-01 23:13:35 +08:00
Alex Yang
158338508a ci: use yarn run test 2023-07-01 23:08:14 +08:00
Alex Yang
640967d9ae v0.7.0-canary.28 2023-07-01 21:35:05 +08:00
Alex Yang
ec973395da fix: remove export script 2023-07-01 21:34:24 +08:00
Alex Yang
b35d99d935 v0.7.0-canary.27 2023-07-01 21:29:11 +08:00
Alex Yang
c0f6e751d2 build: update nx.json 2023-07-01 18:58:14 +08:00
Alex Yang
6af454ceed chore: improve ci build speed (#2953) 2023-07-01 10:47:26 +00:00
Alex Yang
ed829dd43b build: update nx.json 2023-07-01 16:54:21 +08:00
Alex Yang
a9adb4dda2 build: fix nx.json (#2951) 2023-07-01 16:34:30 +08:00
Alex Yang
54a7eeda37 chore: bump version (#2950) 2023-07-01 16:26:43 +08:00
Alex Yang
711e683c6f build: skip type check in next.js build (#2952) 2023-07-01 16:22:21 +08:00
Alex Yang
81c5e6d3d2 build: enhance nx build (#2948) 2023-07-01 01:17:31 +08:00
3720
7a5a5d503a chore: adjust icon and style (#2949) 2023-06-30 23:38:47 +08:00
Alex Yang
b597dbd80f docs: update react badge 2023-06-30 18:03:20 +08:00
Alex Yang
ebdf724012 v0.7.0-canary.26 2023-06-30 17:39:42 +08:00
Alex Yang
14f63e91a9 ci: fix build desktop 2023-06-30 17:39:11 +08:00
Alex Yang
ad218ec65d ci: update paths-ignore 2023-06-30 17:39:11 +08:00
Alex Yang
9fda82564b ci: chmod 777 on output directory 2023-06-30 17:39:11 +08:00
Alex Yang
a52fc54d80 v0.7.0-canary.25 2023-06-30 16:27:59 +08:00
Alex Yang
524c342b5e chore: bump blocksuite to '0.0.0-20230630081054-55a25248-nightly' (#2944) 2023-06-30 16:27:38 +08:00
regischen
f4fc084a0a fix(web): migrate connector (#2941)
Co-authored-by: Alex Yang <himself65@outlook.com>
2023-06-30 16:11:04 +08:00
Alex Yang
38a2aa9d17 build(electron): use nx (#2942) 2023-06-30 16:10:35 +08:00
Peng Xiao
9e90242ddb fix: disable sqlite blob storage (#2943) 2023-06-30 16:09:43 +08:00
Alex Yang
fd0c1da608 fix(cli): run dev-web crash 2023-06-30 15:58:13 +08:00
Alex Yang
68c4fccf98 ci: cancel previous build (#2794) 2023-06-30 07:39:27 +00:00
Alex Yang
3c93f4162d build: remove unused package (#2937) 2023-06-30 07:09:12 +00:00
Alex Yang
b6c314e180 refactor(cli): use typescript (#2938) 2023-06-30 06:58:57 +00:00
Alex Yang
62b465a889 ci: build infra code before build layers 2023-06-30 15:20:36 +08:00
3720
9d0db78f64 feat: support for view management (#2892) 2023-06-30 05:40:00 +00:00
Fangdun Tsai
d3393cb0fc feat: expose clipboard apis (#2932) 2023-06-30 04:47:30 +00:00
Alex Yang
79cded302f chore: bump blocksuite to 0.0.0-20230629103121-76e6587d-nightly (#2931) 2023-06-30 04:36:56 +00:00
Alex Yang
53d90a11de chore: tag deprecated files (#2936) 2023-06-30 04:01:14 +00:00
Alex Yang
271ad57160 feat: special ip address 'localhost' (#2935) 2023-06-30 03:54:24 +00:00
Alex Yang
4adbe64a54 fix(web): disable notification center (#2934) 2023-06-30 03:29:05 +00:00
DarkSky
50a8a147fd ci: make helm release only on bump version (#2928) 2023-06-30 02:02:46 +00:00
Ikko Eltociear Ashimine
eaea8e9368 refactor: fix typo in notification-center/index.tsx (#2929) 2023-06-30 09:55:09 +08:00
Hyden Liu
9873baae9f fix: z-index on app sidebar (#2761)
Co-authored-by: Himself65 <himself65@outlook.com>
2023-06-30 01:14:44 +00:00
xiaodong zuo
bc3ce7395e feat: export page as file (#2923) 2023-06-29 21:58:02 +00:00
Alex Yang
8a7908c692 fix(electron): window only ui (#2926) 2023-06-29 16:15:44 +00:00
LongYinan
8021efd81a build: affine Node.js server charts (#2895) 2023-06-29 14:02:46 +00:00
Qi
d7fcad2d0d feat: add and modify test case for new settings modal (#2925) 2023-06-29 12:54:45 +00:00
Alex Yang
b1d2d77263 docs: set nodejs version to 18.16.1 2023-06-29 20:00:57 +08:00
Alex Yang
2c772bd81b v0.7.0-canary.24 2023-06-29 18:50:48 +08:00
JimmFly
7f00011542 chore: update changelog link and remove obsolete changelog components (#2918) 2023-06-29 10:19:26 +00:00
Alex Yang
f76d8b8818 chore: bump blocksuite to 0.0.0-20230629084521-542de4e8-nightly (#2921) 2023-06-29 09:42:47 +00:00
Alex Yang
1d6b39dec9 ci: allow codecov upload failure (#2922) 2023-06-29 09:39:16 +00:00
Qi
5cfdf6c7e2 fix: a serise of ui issues of new setting (#2920)
Co-authored-by: Alex Yang <himself65@outlook.com>
2023-06-29 09:25:42 +00:00
Alex Yang
8410d83744 refactor: rootWorkspacesMetadataAtom loading logic (#2882) 2023-06-29 08:48:12 +00:00
DarkSky
8a2dac9718 fix: incorrect formatting (#2917) 2023-06-29 08:25:43 +00:00
JimmFly
5ad2908760 chore: update translation (#2916)
Co-authored-by: zuozijian3720 <zuozijian1994@gmail.com>
2023-06-29 08:20:25 +00:00
Alex Yang
5b8771485e docs: add apps/README.md 2023-06-29 16:07:30 +08:00
Alex Yang
ed8480caf0 ci: split migration test 2023-06-29 15:11:16 +08:00
Alex Yang
42ef3c0fc2 test: migration test in real world (#2885) 2023-06-29 06:50:26 +00:00
Alex Yang
e08ee9b7ff ci: add prettier format check (#2908) 2023-06-29 04:13:35 +00:00
liuyi
2c95bfcc3d feat(storage): binding jwst storage to node (#2808) 2023-06-29 01:45:45 +00:00
Alex Yang
86616e152d build: disable sqlite provider in canary 2023-06-29 10:00:41 +08:00
Peng Xiao
b1f478ee5e fix: updater color updates (#2913) 2023-06-28 17:21:07 +00:00
DarkSky
6b0f9fbdad feat: add deployment guide & fix pod label (#2912) 2023-06-28 17:12:23 +00:00
Alex Yang
da3f2b784a ci: fix output variable 2023-06-29 01:20:35 +08:00
Alex Yang
acb140ab78 v0.7.0-canary.23 2023-06-29 00:40:50 +08:00
Alex Yang
0b74bd9bfe ci: use production environment 2023-06-29 00:40:50 +08:00
Alex Yang
acfc030d16 ci: fix package version output 2023-06-29 00:40:50 +08:00
Alex Yang
d0d04ce376 v0.7.0-canary.22 2023-06-29 00:27:17 +08:00
Alex Yang
2250f42d2a ci: fix tag version 2023-06-29 00:26:48 +08:00
Alex Yang
887434fea4 v0.7.0-canary.21 2023-06-29 00:23:06 +08:00
Alex Yang
9b817c4b79 ci: automatically build canary release (#2911) 2023-06-28 15:53:32 +00:00
Alex Yang
ea03bbfb2d ci: add codeql check to merge group (#2909) 2023-06-28 15:07:27 +00:00
Qi
db40cd35c6 feat: migrate workspace setting with new design to setting modal (#2900)
Co-authored-by: Alex Yang <himself65@outlook.com>
2023-06-28 14:45:33 +00:00
Alex Yang
aabac9e921 chore: bump typescript version (#2906) 2023-06-28 12:57:33 +00:00
Alex Yang
0a91c41e0a chore: codesandbox setup (#2907) 2023-06-28 12:32:56 +00:00
DarkSky
d6addc0d0b docs: improve helm ci & document (#2902) 2023-06-28 12:30:02 +00:00
Alex Yang
91d3b76be5 refactor(storybook): move to apps folder (#2901) 2023-06-28 12:29:52 +00:00
Alex Yang
3eed009270 feat: add rule 'sonarjs/no-identical-functions' (#2905) 2023-06-28 12:29:12 +00:00
Alex Yang
bc14d54cfa chore: update pre-commit hook (#2904) 2023-06-28 11:24:37 +00:00
Alex Yang
5496969e58 refactor: environment setup (#2898)
Co-authored-by: Simon He <57086651+Simon-He95@users.noreply.github.com>
2023-06-28 11:19:19 +00:00
Alex Yang
80c2a78273 fix(web): bypass adapter list error (#2903) 2023-06-28 11:06:13 +00:00
Alex Yang
92f378aefc test(server): watch mode (#2893) 2023-06-28 10:00:06 +00:00
Alex Yang
877ceee698 ci: enable merge group (#2899) 2023-06-28 09:56:02 +00:00
Alex Yang
7960b6a22e feat: update migration test page (#2871) 2023-06-28 16:46:08 +08:00
Alex Yang
fa45d8a718 build: unify build flags (#2891) 2023-06-28 16:45:05 +08:00
Alex Yang
87574c9993 build: fix i18n output (#2896) 2023-06-28 16:40:41 +08:00
163 changed files with 1382 additions and 1363 deletions

View File

@@ -22,9 +22,7 @@
"templates",
"y-indexeddb",
"debug",
"storage",
"infra",
"plugin-infra"
"storage"
]
]
}

View File

@@ -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

View File

@@ -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
View File

@@ -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

View File

@@ -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",

View File

@@ -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;
});
},
});
},
});

View File

@@ -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",

View File

@@ -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(

View File

@@ -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": {

View File

@@ -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"
}

View File

@@ -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',

View File

@@ -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',

View File

@@ -6,7 +6,8 @@
"baseUrl": "../..",
"composite": true,
"noEmit": false,
"outDir": "lib"
"outDir": "lib",
"types": ["react/experimental"]
},
"references": [
{

View File

@@ -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",

View File

@@ -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.

View File

Before

Width:  |  Height:  |  Size: 8.5 KiB

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

View File

@@ -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,

View File

@@ -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;
});

View File

@@ -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;
});

View File

@@ -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 (

View File

@@ -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'
);
}}

View File

@@ -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';

View File

@@ -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';

View File

@@ -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}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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

View File

@@ -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%',
},
},
},

View File

@@ -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);

View File

@@ -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}
/>
);
})}

View File

@@ -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])}

View File

@@ -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}
/>
);
})}

View File

@@ -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;
};

View File

@@ -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}

View File

@@ -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>

View 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);
};

View 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);
}

View File

@@ -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(

View File

@@ -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,

View File

@@ -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',
};
};
};

View File

@@ -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';

View File

@@ -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,
{

View File

@@ -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);

View File

@@ -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>
);
};

View File

@@ -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;

View File

@@ -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) => {

View File

@@ -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);

View File

@@ -15,7 +15,8 @@
"jsx": "preserve",
"jsxImportSource": "@emotion/react",
"incremental": true,
"experimentalDecorators": true
"experimentalDecorators": true,
"types": ["react/experimental"]
},
"include": [
"next-env.d.ts",

View File

@@ -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
View File

@@ -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": [

View File

@@ -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",

View File

@@ -19,5 +19,5 @@
"peerDependencies": {
"ts-node": "*"
},
"version": "0.7.0-beta.0"
"version": "0.7.0-canary.42"
}

View File

@@ -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"
}

View File

@@ -125,9 +125,6 @@ export const versionLabel = style({
fontSize: '10px',
lineHeight: '18px',
borderRadius: '4px',
maxWidth: '100px',
overflow: 'hidden',
textOverflow: 'ellipsis',
});
export const whatsNewLabel = style({

View File

@@ -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() {

View File

@@ -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>
);
};

View File

@@ -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" />;
};

View File

@@ -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';

View File

@@ -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';

View File

@@ -1,3 +1,4 @@
/// <reference types="react/experimental" />
import '@blocksuite/blocks';
import { Button, Tooltip } from '@affine/component';

View File

@@ -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;

View File

@@ -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}

View File

@@ -45,7 +45,6 @@ export type TrashListData = {
export type PageListProps = {
isPublicWorkspace?: boolean;
workspaceId: string;
list: ListData[];
fallback?: React.ReactNode;
onCreateNewPage: () => void;

View File

@@ -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(

View File

@@ -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: {

View File

@@ -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']()}

View File

@@ -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)',

View File

@@ -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}

View File

@@ -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)',
};

View File

@@ -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({

View File

@@ -8,5 +8,5 @@
"devDependencies": {
"@types/debug": "^4.1.8"
},
"version": "0.7.0-beta.0"
"version": "0.7.0-canary.42"
}

View File

@@ -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"
}

View File

@@ -29,7 +29,6 @@ export type Filter = {
export type Collection = {
id: string;
workspaceId: string;
name: string;
pinned?: boolean;
filterList: Filter[];

View File

@@ -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",

View File

@@ -8,5 +8,5 @@
"@affine/env": "workspace:*",
"@toeverything/y-indexeddb": "workspace:*"
},
"version": "0.7.0-beta.0"
"version": "0.7.0-canary.42"
}

View File

@@ -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();

View 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]);
}

View File

@@ -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"
}

View File

@@ -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",

View File

@@ -317,8 +317,6 @@
"Terms of Use": "使用条款",
"Unpublished hint": "发布到网络后,访问者可以通过提供的链接查看内容。",
"Version": "版本",
"App Version": "应用版本",
"Editor Version": "编辑器版本",
"Window frame style": "视窗样式",
"Workspace Profile": "工作区配置文件",
"Workspace saved locally": "{{name}} 已保存在本地",

View File

@@ -46,5 +46,5 @@
"optional": true
}
},
"version": "0.7.0-beta.0"
"version": "0.7.0-canary.42"
}

View File

@@ -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"
}

View File

@@ -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"
}

View File

@@ -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"
}

View File

@@ -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]);
}

View File

@@ -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>>;
}

View File

@@ -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>,

View File

@@ -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: [

View File

@@ -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"
},

View File

@@ -6,5 +6,5 @@
"./*.md": "./*.md",
"./preloading.json": "./preloading.json"
},
"version": "0.7.0-beta.0"
"version": "0.7.0-canary.42"
}

View File

@@ -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"
}

View File

@@ -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);

View File

@@ -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';

View File

@@ -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"

View File

@@ -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: {

View File

@@ -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"
}

View File

@@ -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"
}

View File

@@ -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