From a06113d48c7d11194283763ddfd97ddc47120fe1 Mon Sep 17 00:00:00 2001 From: Himself65 Date: Tue, 11 Apr 2023 21:39:39 -0500 Subject: [PATCH] refactor: workspace header (#1880) --- apps/web/src/atoms/public-workspace/index.ts | 19 +- .../animation-data/edgeless-hover.json | 1 - .../animation-data/page-hover.json | 1 - .../components/blocksuite/header/header.tsx | 119 ---- .../components/blocksuite/header/index.tsx | 158 ----- .../editor-mode-switch/CustomLottie.tsx | 0 .../animation-data/edgeless-hover.json | 669 ++++++++++++++++++ .../animation-data/page-hover.json | 521 ++++++++++++++ .../editor-mode-switch/index.tsx | 0 .../editor-mode-switch/style.ts | 0 .../editor-mode-switch/switch-items.tsx | 0 .../header-right-items/EditorOptionMenu.tsx | 0 .../header-right-items/SyncUser.tsx | 0 .../header-right-items/TrashButtonGroup.tsx | 0 .../theme-mode-switch/Icons.tsx | 0 .../theme-mode-switch/index.tsx | 0 .../theme-mode-switch/style.ts | 0 .../blocksuite/workspace-header/header.tsx | 177 +++++ .../blocksuite/workspace-header/index.tsx | 128 ++++ .../{header => workspace-header}/styles.ts | 0 .../{header => workspace-header}/utils.tsx | 0 .../web/src/components/page-detail-editor.tsx | 21 +- .../pure/workspace-list-modal/index.tsx | 8 +- .../components/pure/workspace-title/index.tsx | 16 +- .../hooks/affine/use-is-workspace-owner.ts | 4 +- ...-router-with-current-workspace-and-page.ts | 3 + apps/web/src/layouts/index.tsx | 6 +- .../src/layouts/public-workspace-layout.tsx | 6 +- apps/web/src/pages/preview/[previewId].tsx | 145 ---- .../pages/public-workspace/[workspaceId].tsx | 6 +- .../[workspaceId]/[pageId].tsx | 5 +- .../src/pages/workspace/[workspaceId]/all.tsx | 20 +- .../workspace/[workspaceId]/favorite.tsx | 10 +- .../pages/workspace/[workspaceId]/setting.tsx | 16 +- .../pages/workspace/[workspaceId]/trash.tsx | 8 +- apps/web/src/plugins/affine/index.tsx | 2 +- apps/web/src/plugins/index.tsx | 27 +- apps/web/src/plugins/local/index.tsx | 2 +- apps/web/src/shared/index.ts | 6 +- .../src/components/workspace-avatar/index.tsx | 8 +- packages/workspace/src/type.ts | 9 + .../local-first-favorite-page.spec.ts | 2 +- 42 files changed, 1653 insertions(+), 470 deletions(-) delete mode 100644 apps/web/src/components/blocksuite/header/editor-mode-switch/animation-data/edgeless-hover.json delete mode 100644 apps/web/src/components/blocksuite/header/editor-mode-switch/animation-data/page-hover.json delete mode 100644 apps/web/src/components/blocksuite/header/header.tsx delete mode 100644 apps/web/src/components/blocksuite/header/index.tsx rename apps/web/src/components/blocksuite/{header => workspace-header}/editor-mode-switch/CustomLottie.tsx (100%) create mode 100644 apps/web/src/components/blocksuite/workspace-header/editor-mode-switch/animation-data/edgeless-hover.json create mode 100644 apps/web/src/components/blocksuite/workspace-header/editor-mode-switch/animation-data/page-hover.json rename apps/web/src/components/blocksuite/{header => workspace-header}/editor-mode-switch/index.tsx (100%) rename apps/web/src/components/blocksuite/{header => workspace-header}/editor-mode-switch/style.ts (100%) rename apps/web/src/components/blocksuite/{header => workspace-header}/editor-mode-switch/switch-items.tsx (100%) rename apps/web/src/components/blocksuite/{header => workspace-header}/header-right-items/EditorOptionMenu.tsx (100%) rename apps/web/src/components/blocksuite/{header => workspace-header}/header-right-items/SyncUser.tsx (100%) rename apps/web/src/components/blocksuite/{header => workspace-header}/header-right-items/TrashButtonGroup.tsx (100%) rename apps/web/src/components/blocksuite/{header => workspace-header}/header-right-items/theme-mode-switch/Icons.tsx (100%) rename apps/web/src/components/blocksuite/{header => workspace-header}/header-right-items/theme-mode-switch/index.tsx (100%) rename apps/web/src/components/blocksuite/{header => workspace-header}/header-right-items/theme-mode-switch/style.ts (100%) create mode 100644 apps/web/src/components/blocksuite/workspace-header/header.tsx create mode 100644 apps/web/src/components/blocksuite/workspace-header/index.tsx rename apps/web/src/components/blocksuite/{header => workspace-header}/styles.ts (100%) rename apps/web/src/components/blocksuite/{header => workspace-header}/utils.tsx (100%) delete mode 100644 apps/web/src/pages/preview/[previewId].tsx diff --git a/apps/web/src/atoms/public-workspace/index.ts b/apps/web/src/atoms/public-workspace/index.ts index f2f45c6cd..6f3e71f97 100644 --- a/apps/web/src/atoms/public-workspace/index.ts +++ b/apps/web/src/atoms/public-workspace/index.ts @@ -1,11 +1,16 @@ import { getLoginStorage } from '@affine/workspace/affine/login'; +import type { AffinePublicWorkspace } from '@affine/workspace/type'; +import { WorkspaceFlavour } from '@affine/workspace/type'; import { createEmptyBlockSuiteWorkspace } from '@affine/workspace/utils'; import { atom } from 'jotai'; import { BlockSuiteWorkspace } from '../../shared'; import { affineApis } from '../../shared/apis'; -function createPublicWorkspace(workspaceId: string, binary: ArrayBuffer) { +function createPublicWorkspace( + workspaceId: string, + binary: ArrayBuffer +): AffinePublicWorkspace { const blockSuiteWorkspace = createEmptyBlockSuiteWorkspace( workspaceId, (k: string) => @@ -22,12 +27,18 @@ function createPublicWorkspace(workspaceId: string, binary: ArrayBuffer) { blockSuiteWorkspace.awarenessStore.setFlag('enable_edgeless_toolbar', false); blockSuiteWorkspace.awarenessStore.setFlag('enable_slash_menu', false); blockSuiteWorkspace.awarenessStore.setFlag('enable_drag_handle', false); - return blockSuiteWorkspace; + return { + flavour: WorkspaceFlavour.PUBLIC, + id: workspaceId, + blockSuiteWorkspace, + // maybe we can add some sync providers here + providers: [], + }; } export const publicWorkspaceIdAtom = atom(null); export const publicWorkspacePageIdAtom = atom(null); -export const publicPageBlockSuiteAtom = atom>( +export const publicPageBlockSuiteAtom = atom>( async get => { const workspaceId = get(publicWorkspaceIdAtom); const pageId = get(publicWorkspacePageIdAtom); @@ -41,7 +52,7 @@ export const publicPageBlockSuiteAtom = atom>( return createPublicWorkspace(workspaceId, binary); } ); -export const publicBlockSuiteAtom = atom>( +export const publicWorkspaceAtom = atom>( async get => { const workspaceId = get(publicWorkspaceIdAtom); if (!workspaceId) { diff --git a/apps/web/src/components/blocksuite/header/editor-mode-switch/animation-data/edgeless-hover.json b/apps/web/src/components/blocksuite/header/editor-mode-switch/animation-data/edgeless-hover.json deleted file mode 100644 index dcfd8643d..000000000 --- a/apps/web/src/components/blocksuite/header/editor-mode-switch/animation-data/edgeless-hover.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.9.0","fr":29.9700012207031,"ip":0,"op":60.0000024438501,"w":500,"h":500,"nm":"edgeless-hover","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Layer 3/paper-edgeless-icons Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[250,250,0],"ix":2,"l":2},"a":{"a":0,"k":[183.5,183.5,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,-5.604],[0,0],[-5.614,0],[0,0],[0,5.605],[0,0],[5.615,0]],"o":[[-5.614,0],[0,0],[0,5.605],[0,0],[5.615,0],[0,0],[0,-5.604],[0,0]],"v":[[-30.525,-40.7],[-40.699,-30.525],[-40.699,30.524],[-30.525,40.699],[30.525,40.699],[40.699,30.524],[40.699,-30.525],[30.525,-40.7]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[22.447,0],[0,0],[0,22.437],[0,0],[-22.446,0],[0,0],[0,-22.437],[0,0]],"o":[[0,0],[-22.446,0],[0,0],[0,-22.437],[0,0],[22.447,0],[0,0],[0,22.437]],"v":[[30.525,71.224],[-30.525,71.224],[-71.225,30.524],[-71.225,-30.525],[-30.525,-71.225],[30.525,-71.225],[71.224,-30.525],[71.224,30.524]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.466666696586,0.458823559331,0.490196108351,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[295.322,295.323],"to":[0,0],"ti":[0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":30,"s":[315.322,315.323],"to":[0,0],"ti":[0,0]},{"t":58.0000023623884,"s":[295.322,295.323]}],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":4,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[8.426,0],[0,8.426],[0,0],[-8.426,0],[0,-8.426],[0,0]],"o":[[-8.426,0],[0,0],[0,-8.426],[8.426,0],[0,0],[0,8.426]],"v":[[0,30.525],[-15.262,15.263],[-15.262,-15.262],[0,-30.525],[15.262,-15.262],[15.262,15.263]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.466666696586,0.458823559331,0.490196108351,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[76.561,183.399],"to":[0,0],"ti":[0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":30,"s":[56.561,183.399],"to":[0,0],"ti":[0,0]},{"t":58.0000023623884,"s":[76.561,183.399]}],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":2,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[8.426,0],[0,8.426],[5.395,13.057],[9.956,9.956],[13.037,5.406],[14.1,0],[0,8.426],[-8.426,0],[-16.753,-6.955],[-12.808,-12.818],[-6.955,-16.773],[0,-18.105]],"o":[[-8.426,0],[0,-14.09],[-5.416,-13.016],[-9.957,-9.956],[-13.026,-5.385],[-8.426,0],[0,-8.426],[18.134,0],[16.763,6.936],[12.788,12.778],[6.936,16.773],[0,8.426]],"v":[[61.049,76.312],[45.788,61.05],[37.66,20.151],[14.497,-14.487],[-20.161,-37.659],[-61.049,-45.787],[-76.311,-61.049],[-61.049,-76.312],[-8.475,-65.839],[36.09,-36.069],[65.858,8.486],[76.311,61.05]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.466666696586,0.458823559331,0.490196108351,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[254.447,112.349],"to":[0,0],"ti":[0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":30,"s":[274.447,92.349],"to":[0,0],"ti":[0,0]},{"t":58.0000023623884,"s":[254.447,112.349]}],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 3","np":2,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[22.446,0],[0,-22.437],[-22.446,0],[0,22.436]],"o":[[-22.446,0],[0,22.436],[22.446,0],[0,-22.437]],"v":[[0,-40.7],[-40.7,0],[0,40.699],[40.7,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[39.269,0],[0,39.268],[-39.269,0],[0,-39.269]],"o":[[-39.269,0],[0,-39.269],[39.269,0],[0,39.268]],"v":[[0,71.224],[-71.224,0],[0,-71.225],[71.224,0]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.466666696586,0.458823559331,0.490196108351,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[71.474,295.323],"to":[0,0],"ti":[0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":30,"s":[51.474,315.323],"to":[0,0],"ti":[0,0]},{"t":58.0000023623884,"s":[71.474,295.323]}],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 4","np":4,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[22.446,0],[0,-22.437],[-22.446,0],[0,22.436]],"o":[[-22.446,0],[0,22.436],[22.446,0],[0,-22.437]],"v":[[0,-40.7],[-40.7,0.001],[0,40.7],[40.7,0.001]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[39.269,0],[0,39.268],[-39.269,0],[0,-39.269]],"o":[[-39.269,0],[0,-39.269],[39.269,0],[0,39.268]],"v":[[0,71.225],[-71.224,0.001],[0,-71.225],[71.224,0.001]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.466666696586,0.458823559331,0.490196108351,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[71.474,71.475],"to":[0,0],"ti":[0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":30,"s":[51.474,51.475],"to":[0,0],"ti":[0,0]},{"t":58.0000023623884,"s":[71.474,71.475]}],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 5","np":4,"cix":2,"bm":0,"ix":5,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":60.0000024438501,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/apps/web/src/components/blocksuite/header/editor-mode-switch/animation-data/page-hover.json b/apps/web/src/components/blocksuite/header/editor-mode-switch/animation-data/page-hover.json deleted file mode 100644 index 0b870fa0c..000000000 --- a/apps/web/src/components/blocksuite/header/editor-mode-switch/animation-data/page-hover.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.9.0","fr":29.9700012207031,"ip":0,"op":60.0000024438501,"w":500,"h":500,"nm":"page-hover","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Layer 1/paper-edgeless-icons Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[250,250,0],"ix":2,"l":2},"a":{"a":0,"k":[183,183,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[22.557,0],[0,0],[0,8.639],[-8.64,0],[0,0],[-2.201,1.651],[0,9.536],[0,0],[-8.64,0],[0,-8.64],[0,0],[16.892,-16.892]],"o":[[0,0],[-8.64,0],[0,-8.64],[0,0],[17.442,0],[10.412,-10.453],[0,0],[0,-8.64],[8.639,0],[0,0],[0,18.155],[-9.027,8.987]],"v":[[46.947,182.579],[-109.545,182.579],[-125.194,166.93],[-109.545,151.281],[46.947,151.281],[78.001,145.086],[93.895,114.766],[93.895,-166.93],[109.545,-182.579],[125.194,-166.93],[125.194,114.766],[99.743,167.561]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.466666696586,0.458823559331,0.490196108351,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[240.204,182.829],"to":[0,0],"ti":[0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":30,"s":[260.204,202.829],"to":[0,0],"ti":[0,0]},{"t":58.0000023623884,"s":[240.204,182.829]}],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[8.64,0],[0,8.639],[0,0],[-16.892,16.882],[-22.598,0],[0,0],[0,-8.64],[8.639,0],[0,0],[2.171,-1.65],[0,-9.546],[0,0]],"o":[[-8.64,0],[0,0],[0,-18.145],[8.976,-8.986],[0,0],[8.639,0],[0,8.64],[0,0],[-17.453,0],[-10.443,10.484],[0,0],[0,8.639]],"v":[[-109.545,182.579],[-125.194,166.93],[-125.194,-114.766],[-99.743,-167.562],[-46.948,-182.579],[109.545,-182.579],[125.194,-166.93],[109.545,-151.281],[-46.948,-151.281],[-77.972,-145.107],[-93.896,-114.766],[-93.896,166.93]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.466666696586,0.458823559331,0.490196108351,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[125.443,182.829],"to":[0,0],"ti":[0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":30,"s":[105.443,162.829],"to":[0,0],"ti":[0,0]},{"t":58.0000023623884,"s":[125.443,182.829]}],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":2,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[8.64,0],[0,0],[0,8.639],[-8.64,0],[0,0],[0,-8.64]],"o":[[0,0],[-8.64,0],[0,-8.64],[0,0],[8.64,0],[0,8.639]],"v":[[67.813,15.649],[-67.813,15.649],[-83.463,0],[-67.813,-15.649],[67.813,-15.649],[83.462,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.466666696586,0.458823559331,0.490196108351,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[182.824,271.513],"to":[0,0],"ti":[0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":30,"s":[212.824,281.513],"to":[0,0],"ti":[0,0]},{"t":58.0000023623884,"s":[182.824,271.513]}],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 3","np":2,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,-5.757],[0,0],[-5.756,0],[0,0],[0,5.756],[0,0],[5.747,0]],"o":[[-5.756,0],[0,0],[0,5.756],[0,0],[5.747,0],[0,0],[0,-5.757],[0,0]],"v":[[-41.732,-31.294],[-52.165,-20.86],[-52.165,20.87],[-41.732,31.303],[41.73,31.303],[52.163,20.87],[52.163,-20.86],[41.73,-31.294]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[23.006,0],[0,0],[0,23.015],[0,0],[-23.015,0],[0,0],[0,-23.016],[0,0]],"o":[[0,0],[-23.015,0],[0,0],[0,-23.016],[0,0],[23.006,0],[0,0],[0,23.015]],"v":[[41.73,62.592],[-41.732,62.592],[-83.463,20.87],[-83.463,-20.86],[-41.732,-62.592],[41.73,-62.592],[83.463,-20.86],[83.463,20.87]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.466666696586,0.458823559331,0.490196108351,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[182.824,141.088],"to":[0,0],"ti":[0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":30,"s":[152.824,131.088],"to":[0,0],"ti":[0,0]},{"t":58.0000023623884,"s":[182.824,141.088]}],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 4","np":4,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":60.0000024438501,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/apps/web/src/components/blocksuite/header/header.tsx b/apps/web/src/components/blocksuite/header/header.tsx deleted file mode 100644 index e0c69fcb8..000000000 --- a/apps/web/src/components/blocksuite/header/header.tsx +++ /dev/null @@ -1,119 +0,0 @@ -import { useTranslation } from '@affine/i18n'; -import { CloseIcon } from '@blocksuite/icons'; -import type { HTMLAttributes, PropsWithChildren } from 'react'; -import type React from 'react'; -import { forwardRef, useEffect, useMemo, useState } from 'react'; - -import { - useSidebarFloating, - useSidebarStatus, -} from '../../../hooks/use-sidebar-status'; -import { SidebarSwitch } from '../../affine/sidebar-switch'; -import { EditorOptionMenu } from './header-right-items/EditorOptionMenu'; -import SyncUser from './header-right-items/SyncUser'; -import ThemeModeSwitch from './header-right-items/theme-mode-switch'; -import TrashButtonGroup from './header-right-items/TrashButtonGroup'; -import { - StyledBrowserWarning, - StyledCloseButton, - StyledHeader, - StyledHeaderContainer, - StyledHeaderRightSide, -} from './styles'; -import { OSWarningMessage, shouldShowWarning } from './utils'; - -const BrowserWarning = ({ - show, - onClose, -}: { - show: boolean; - onClose: () => void; -}) => { - return ( - - - - - - - ); -}; - -type HeaderRightItemNames = - | 'editorOptionMenu' - | 'trashButtonGroup' - | 'themeModeSwitch' - | 'syncUser'; - -const HeaderRightItems: Record = { - editorOptionMenu: EditorOptionMenu, - trashButtonGroup: TrashButtonGroup, - themeModeSwitch: ThemeModeSwitch, - syncUser: SyncUser, -}; - -export type HeaderProps = PropsWithChildren<{ - rightItems?: HeaderRightItemNames[]; -}>; - -export const Header = forwardRef< - HTMLDivElement, - HeaderProps & HTMLAttributes ->( - ( - { rightItems = ['syncUser', 'themeModeSwitch'], children, ...props }, - ref - ) => { - const [showWarning, setShowWarning] = useState(false); - useEffect(() => { - setShowWarning(shouldShowWarning()); - }, []); - const [open] = useSidebarStatus(); - const sidebarFloating = useSidebarFloating(); - const { t } = useTranslation(); - - return ( - - { - setShowWarning(false); - }} - /> - - - - {children} - - {useMemo( - () => - rightItems.map(itemName => { - const Item = HeaderRightItems[itemName]; - return ; - }), - [rightItems] - )} - {/**/} - - - - ); - } -); - -Header.displayName = 'Header'; - -export default Header; diff --git a/apps/web/src/components/blocksuite/header/index.tsx b/apps/web/src/components/blocksuite/header/index.tsx deleted file mode 100644 index 1fe783ae0..000000000 --- a/apps/web/src/components/blocksuite/header/index.tsx +++ /dev/null @@ -1,158 +0,0 @@ -import type { PopperProps } from '@affine/component'; -import { QuickSearchTips } from '@affine/component'; -import { getEnvironment } from '@affine/env'; -import { ArrowDownSmallIcon } from '@blocksuite/icons'; -import { assertExists } from '@blocksuite/store'; -import { useAtomValue, useSetAtom } from 'jotai'; -import type { HTMLAttributes } from 'react'; -import { forwardRef, useCallback, useRef } from 'react'; - -import { currentEditorAtom, openQuickSearchModalAtom } from '../../../atoms'; -import { useGuideHidden } from '../../../hooks/use-is-first-load'; -import { usePageMeta } from '../../../hooks/use-page-meta'; -import { useElementResizeEffect } from '../../../hooks/use-workspaces'; -import type { BlockSuiteWorkspace } from '../../../shared'; -import { PageNotFoundError } from '../../affine/affine-error-eoundary'; -import { QuickSearchButton } from '../../pure/quick-search-button'; -import { EditorModeSwitch } from './editor-mode-switch'; -import Header from './header'; -import { - StyledQuickSearchTipButton, - StyledQuickSearchTipContent, - StyledSearchArrowWrapper, - StyledSwitchWrapper, - StyledTitle, - StyledTitleContainer, - StyledTitleWrapper, -} from './styles'; - -export type BlockSuiteEditorHeaderProps = React.PropsWithChildren<{ - blockSuiteWorkspace: BlockSuiteWorkspace; - pageId: string; - isPublic?: boolean; - isPreview?: boolean; -}>; - -export const BlockSuiteEditorHeader = forwardRef< - HTMLDivElement, - BlockSuiteEditorHeaderProps & HTMLAttributes ->( - ( - { blockSuiteWorkspace, pageId, children, isPublic, isPreview, ...props }, - ref - ) => { - const page = blockSuiteWorkspace.getPage(pageId); - // fixme(himself65): remove this atom and move it to props - const setOpenQuickSearch = useSetAtom(openQuickSearchModalAtom); - if (!page) { - throw new PageNotFoundError(blockSuiteWorkspace, pageId); - } - const pageMeta = usePageMeta(blockSuiteWorkspace).find( - meta => meta.id === pageId - ); - assertExists(pageMeta); - const title = pageMeta.title; - const { trash: isTrash } = pageMeta; - const [isTipsHidden, setTipsHidden] = useGuideHidden(); - const isMac = () => { - const env = getEnvironment(); - return env.isBrowser && env.isMacOs; - }; - - const popperRef: PopperProps['popperRef'] = useRef(null); - - useElementResizeEffect( - useAtomValue(currentEditorAtom), - useCallback(() => { - if (isTipsHidden.quickSearchTips || !popperRef.current) { - return; - } - popperRef.current.update(); - }, [isTipsHidden.quickSearchTips]) - ); - - const TipsContent = ( - -
- Click button - { - - - - } - or use - {isMac() ? ' ⌘ + K' : ' Ctrl + K'} to activate Quick Search. Then you - can search keywords or quickly open recently viewed pages. -
- - setTipsHidden({ ...isTipsHidden, quickSearchTips: true }) - } - > - Got it - -
- ); - - return ( -
- {children} - {!isPublic && ( - - - - - - {title || 'Untitled'} - - - { - setOpenQuickSearch(true); - }} - /> - - - - - )} -
- ); - } -); - -BlockSuiteEditorHeader.displayName = 'BlockSuiteEditorHeader'; diff --git a/apps/web/src/components/blocksuite/header/editor-mode-switch/CustomLottie.tsx b/apps/web/src/components/blocksuite/workspace-header/editor-mode-switch/CustomLottie.tsx similarity index 100% rename from apps/web/src/components/blocksuite/header/editor-mode-switch/CustomLottie.tsx rename to apps/web/src/components/blocksuite/workspace-header/editor-mode-switch/CustomLottie.tsx diff --git a/apps/web/src/components/blocksuite/workspace-header/editor-mode-switch/animation-data/edgeless-hover.json b/apps/web/src/components/blocksuite/workspace-header/editor-mode-switch/animation-data/edgeless-hover.json new file mode 100644 index 000000000..eefa728aa --- /dev/null +++ b/apps/web/src/components/blocksuite/workspace-header/editor-mode-switch/animation-data/edgeless-hover.json @@ -0,0 +1,669 @@ +{ + "v": "5.9.0", + "fr": 29.9700012207031, + "ip": 0, + "op": 60.0000024438501, + "w": 500, + "h": 500, + "nm": "edgeless-hover", + "ddd": 0, + "assets": [], + "layers": [ + { + "ddd": 0, + "ind": 1, + "ty": 4, + "nm": "Layer 3/paper-edgeless-icons Outlines", + "sr": 1, + "ks": { + "o": { "a": 0, "k": 100, "ix": 11 }, + "r": { "a": 0, "k": 0, "ix": 10 }, + "p": { "a": 0, "k": [250, 250, 0], "ix": 2, "l": 2 }, + "a": { "a": 0, "k": [183.5, 183.5, 0], "ix": 1, "l": 2 }, + "s": { "a": 0, "k": [100, 100, 100], "ix": 6, "l": 2 } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [0, 0], + [0, -5.604], + [0, 0], + [-5.614, 0], + [0, 0], + [0, 5.605], + [0, 0], + [5.615, 0] + ], + "o": [ + [-5.614, 0], + [0, 0], + [0, 5.605], + [0, 0], + [5.615, 0], + [0, 0], + [0, -5.604], + [0, 0] + ], + "v": [ + [-30.525, -40.7], + [-40.699, -30.525], + [-40.699, 30.524], + [-30.525, 40.699], + [30.525, 40.699], + [40.699, 30.524], + [40.699, -30.525], + [30.525, -40.7] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ind": 1, + "ty": "sh", + "ix": 2, + "ks": { + "a": 0, + "k": { + "i": [ + [22.447, 0], + [0, 0], + [0, 22.437], + [0, 0], + [-22.446, 0], + [0, 0], + [0, -22.437], + [0, 0] + ], + "o": [ + [0, 0], + [-22.446, 0], + [0, 0], + [0, -22.437], + [0, 0], + [22.447, 0], + [0, 0], + [0, 22.437] + ], + "v": [ + [30.525, 71.224], + [-30.525, 71.224], + [-71.225, 30.524], + [-71.225, -30.525], + [-30.525, -71.225], + [30.525, -71.225], + [71.224, -30.525], + [71.224, 30.524] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 2", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "mm", + "mm": 1, + "nm": "Merge Paths 1", + "mn": "ADBE Vector Filter - Merge", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.466666696586, 0.458823559331, 0.490196108351, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { + "a": 1, + "k": [ + { + "i": { "x": 0.833, "y": 0.833 }, + "o": { "x": 0.167, "y": 0.167 }, + "t": 0, + "s": [295.322, 295.323], + "to": [0, 0], + "ti": [0, 0] + }, + { + "i": { "x": 0.833, "y": 0.833 }, + "o": { "x": 0.167, "y": 0.167 }, + "t": 30, + "s": [315.322, 315.323], + "to": [0, 0], + "ti": [0, 0] + }, + { "t": 58.0000023623884, "s": [295.322, 295.323] } + ], + "ix": 2 + }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 4, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [8.426, 0], + [0, 8.426], + [0, 0], + [-8.426, 0], + [0, -8.426], + [0, 0] + ], + "o": [ + [-8.426, 0], + [0, 0], + [0, -8.426], + [8.426, 0], + [0, 0], + [0, 8.426] + ], + "v": [ + [0, 30.525], + [-15.262, 15.263], + [-15.262, -15.262], + [0, -30.525], + [15.262, -15.262], + [15.262, 15.263] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.466666696586, 0.458823559331, 0.490196108351, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { + "a": 1, + "k": [ + { + "i": { "x": 0.833, "y": 0.833 }, + "o": { "x": 0.167, "y": 0.167 }, + "t": 0, + "s": [76.561, 183.399], + "to": [0, 0], + "ti": [0, 0] + }, + { + "i": { "x": 0.833, "y": 0.833 }, + "o": { "x": 0.167, "y": 0.167 }, + "t": 30, + "s": [56.561, 183.399], + "to": [0, 0], + "ti": [0, 0] + }, + { "t": 58.0000023623884, "s": [76.561, 183.399] } + ], + "ix": 2 + }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 2", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 2, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [8.426, 0], + [0, 8.426], + [5.395, 13.057], + [9.956, 9.956], + [13.037, 5.406], + [14.1, 0], + [0, 8.426], + [-8.426, 0], + [-16.753, -6.955], + [-12.808, -12.818], + [-6.955, -16.773], + [0, -18.105] + ], + "o": [ + [-8.426, 0], + [0, -14.09], + [-5.416, -13.016], + [-9.957, -9.956], + [-13.026, -5.385], + [-8.426, 0], + [0, -8.426], + [18.134, 0], + [16.763, 6.936], + [12.788, 12.778], + [6.936, 16.773], + [0, 8.426] + ], + "v": [ + [61.049, 76.312], + [45.788, 61.05], + [37.66, 20.151], + [14.497, -14.487], + [-20.161, -37.659], + [-61.049, -45.787], + [-76.311, -61.049], + [-61.049, -76.312], + [-8.475, -65.839], + [36.09, -36.069], + [65.858, 8.486], + [76.311, 61.05] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.466666696586, 0.458823559331, 0.490196108351, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { + "a": 1, + "k": [ + { + "i": { "x": 0.833, "y": 0.833 }, + "o": { "x": 0.167, "y": 0.167 }, + "t": 0, + "s": [254.447, 112.349], + "to": [0, 0], + "ti": [0, 0] + }, + { + "i": { "x": 0.833, "y": 0.833 }, + "o": { "x": 0.167, "y": 0.167 }, + "t": 30, + "s": [274.447, 92.349], + "to": [0, 0], + "ti": [0, 0] + }, + { "t": 58.0000023623884, "s": [254.447, 112.349] } + ], + "ix": 2 + }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 3", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 3, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [22.446, 0], + [0, -22.437], + [-22.446, 0], + [0, 22.436] + ], + "o": [ + [-22.446, 0], + [0, 22.436], + [22.446, 0], + [0, -22.437] + ], + "v": [ + [0, -40.7], + [-40.7, 0], + [0, 40.699], + [40.7, 0] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ind": 1, + "ty": "sh", + "ix": 2, + "ks": { + "a": 0, + "k": { + "i": [ + [39.269, 0], + [0, 39.268], + [-39.269, 0], + [0, -39.269] + ], + "o": [ + [-39.269, 0], + [0, -39.269], + [39.269, 0], + [0, 39.268] + ], + "v": [ + [0, 71.224], + [-71.224, 0], + [0, -71.225], + [71.224, 0] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 2", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "mm", + "mm": 1, + "nm": "Merge Paths 1", + "mn": "ADBE Vector Filter - Merge", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.466666696586, 0.458823559331, 0.490196108351, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { + "a": 1, + "k": [ + { + "i": { "x": 0.833, "y": 0.833 }, + "o": { "x": 0.167, "y": 0.167 }, + "t": 0, + "s": [71.474, 295.323], + "to": [0, 0], + "ti": [0, 0] + }, + { + "i": { "x": 0.833, "y": 0.833 }, + "o": { "x": 0.167, "y": 0.167 }, + "t": 30, + "s": [51.474, 315.323], + "to": [0, 0], + "ti": [0, 0] + }, + { "t": 58.0000023623884, "s": [71.474, 295.323] } + ], + "ix": 2 + }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 4", + "np": 4, + "cix": 2, + "bm": 0, + "ix": 4, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [22.446, 0], + [0, -22.437], + [-22.446, 0], + [0, 22.436] + ], + "o": [ + [-22.446, 0], + [0, 22.436], + [22.446, 0], + [0, -22.437] + ], + "v": [ + [0, -40.7], + [-40.7, 0.001], + [0, 40.7], + [40.7, 0.001] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ind": 1, + "ty": "sh", + "ix": 2, + "ks": { + "a": 0, + "k": { + "i": [ + [39.269, 0], + [0, 39.268], + [-39.269, 0], + [0, -39.269] + ], + "o": [ + [-39.269, 0], + [0, -39.269], + [39.269, 0], + [0, 39.268] + ], + "v": [ + [0, 71.225], + [-71.224, 0.001], + [0, -71.225], + [71.224, 0.001] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 2", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "mm", + "mm": 1, + "nm": "Merge Paths 1", + "mn": "ADBE Vector Filter - Merge", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.466666696586, 0.458823559331, 0.490196108351, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { + "a": 1, + "k": [ + { + "i": { "x": 0.833, "y": 0.833 }, + "o": { "x": 0.167, "y": 0.167 }, + "t": 0, + "s": [71.474, 71.475], + "to": [0, 0], + "ti": [0, 0] + }, + { + "i": { "x": 0.833, "y": 0.833 }, + "o": { "x": 0.167, "y": 0.167 }, + "t": 30, + "s": [51.474, 51.475], + "to": [0, 0], + "ti": [0, 0] + }, + { "t": 58.0000023623884, "s": [71.474, 71.475] } + ], + "ix": 2 + }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 5", + "np": 4, + "cix": 2, + "bm": 0, + "ix": 5, + "mn": "ADBE Vector Group", + "hd": false + } + ], + "ip": 0, + "op": 60.0000024438501, + "st": 0, + "bm": 0 + } + ], + "markers": [] +} diff --git a/apps/web/src/components/blocksuite/workspace-header/editor-mode-switch/animation-data/page-hover.json b/apps/web/src/components/blocksuite/workspace-header/editor-mode-switch/animation-data/page-hover.json new file mode 100644 index 000000000..cb034bbb6 --- /dev/null +++ b/apps/web/src/components/blocksuite/workspace-header/editor-mode-switch/animation-data/page-hover.json @@ -0,0 +1,521 @@ +{ + "v": "5.9.0", + "fr": 29.9700012207031, + "ip": 0, + "op": 60.0000024438501, + "w": 500, + "h": 500, + "nm": "page-hover", + "ddd": 0, + "assets": [], + "layers": [ + { + "ddd": 0, + "ind": 1, + "ty": 4, + "nm": "Layer 1/paper-edgeless-icons Outlines", + "sr": 1, + "ks": { + "o": { "a": 0, "k": 100, "ix": 11 }, + "r": { "a": 0, "k": 0, "ix": 10 }, + "p": { "a": 0, "k": [250, 250, 0], "ix": 2, "l": 2 }, + "a": { "a": 0, "k": [183, 183, 0], "ix": 1, "l": 2 }, + "s": { "a": 0, "k": [100, 100, 100], "ix": 6, "l": 2 } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [22.557, 0], + [0, 0], + [0, 8.639], + [-8.64, 0], + [0, 0], + [-2.201, 1.651], + [0, 9.536], + [0, 0], + [-8.64, 0], + [0, -8.64], + [0, 0], + [16.892, -16.892] + ], + "o": [ + [0, 0], + [-8.64, 0], + [0, -8.64], + [0, 0], + [17.442, 0], + [10.412, -10.453], + [0, 0], + [0, -8.64], + [8.639, 0], + [0, 0], + [0, 18.155], + [-9.027, 8.987] + ], + "v": [ + [46.947, 182.579], + [-109.545, 182.579], + [-125.194, 166.93], + [-109.545, 151.281], + [46.947, 151.281], + [78.001, 145.086], + [93.895, 114.766], + [93.895, -166.93], + [109.545, -182.579], + [125.194, -166.93], + [125.194, 114.766], + [99.743, 167.561] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.466666696586, 0.458823559331, 0.490196108351, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { + "a": 1, + "k": [ + { + "i": { "x": 0.833, "y": 0.833 }, + "o": { "x": 0.167, "y": 0.167 }, + "t": 0, + "s": [240.204, 182.829], + "to": [0, 0], + "ti": [0, 0] + }, + { + "i": { "x": 0.833, "y": 0.833 }, + "o": { "x": 0.167, "y": 0.167 }, + "t": 30, + "s": [260.204, 202.829], + "to": [0, 0], + "ti": [0, 0] + }, + { "t": 58.0000023623884, "s": [240.204, 182.829] } + ], + "ix": 2 + }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [8.64, 0], + [0, 8.639], + [0, 0], + [-16.892, 16.882], + [-22.598, 0], + [0, 0], + [0, -8.64], + [8.639, 0], + [0, 0], + [2.171, -1.65], + [0, -9.546], + [0, 0] + ], + "o": [ + [-8.64, 0], + [0, 0], + [0, -18.145], + [8.976, -8.986], + [0, 0], + [8.639, 0], + [0, 8.64], + [0, 0], + [-17.453, 0], + [-10.443, 10.484], + [0, 0], + [0, 8.639] + ], + "v": [ + [-109.545, 182.579], + [-125.194, 166.93], + [-125.194, -114.766], + [-99.743, -167.562], + [-46.948, -182.579], + [109.545, -182.579], + [125.194, -166.93], + [109.545, -151.281], + [-46.948, -151.281], + [-77.972, -145.107], + [-93.896, -114.766], + [-93.896, 166.93] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.466666696586, 0.458823559331, 0.490196108351, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { + "a": 1, + "k": [ + { + "i": { "x": 0.833, "y": 0.833 }, + "o": { "x": 0.167, "y": 0.167 }, + "t": 0, + "s": [125.443, 182.829], + "to": [0, 0], + "ti": [0, 0] + }, + { + "i": { "x": 0.833, "y": 0.833 }, + "o": { "x": 0.167, "y": 0.167 }, + "t": 30, + "s": [105.443, 162.829], + "to": [0, 0], + "ti": [0, 0] + }, + { "t": 58.0000023623884, "s": [125.443, 182.829] } + ], + "ix": 2 + }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 2", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 2, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [8.64, 0], + [0, 0], + [0, 8.639], + [-8.64, 0], + [0, 0], + [0, -8.64] + ], + "o": [ + [0, 0], + [-8.64, 0], + [0, -8.64], + [0, 0], + [8.64, 0], + [0, 8.639] + ], + "v": [ + [67.813, 15.649], + [-67.813, 15.649], + [-83.463, 0], + [-67.813, -15.649], + [67.813, -15.649], + [83.462, 0] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.466666696586, 0.458823559331, 0.490196108351, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { + "a": 1, + "k": [ + { + "i": { "x": 0.833, "y": 0.833 }, + "o": { "x": 0.167, "y": 0.167 }, + "t": 0, + "s": [182.824, 271.513], + "to": [0, 0], + "ti": [0, 0] + }, + { + "i": { "x": 0.833, "y": 0.833 }, + "o": { "x": 0.167, "y": 0.167 }, + "t": 30, + "s": [212.824, 281.513], + "to": [0, 0], + "ti": [0, 0] + }, + { "t": 58.0000023623884, "s": [182.824, 271.513] } + ], + "ix": 2 + }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 3", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 3, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [0, 0], + [0, -5.757], + [0, 0], + [-5.756, 0], + [0, 0], + [0, 5.756], + [0, 0], + [5.747, 0] + ], + "o": [ + [-5.756, 0], + [0, 0], + [0, 5.756], + [0, 0], + [5.747, 0], + [0, 0], + [0, -5.757], + [0, 0] + ], + "v": [ + [-41.732, -31.294], + [-52.165, -20.86], + [-52.165, 20.87], + [-41.732, 31.303], + [41.73, 31.303], + [52.163, 20.87], + [52.163, -20.86], + [41.73, -31.294] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ind": 1, + "ty": "sh", + "ix": 2, + "ks": { + "a": 0, + "k": { + "i": [ + [23.006, 0], + [0, 0], + [0, 23.015], + [0, 0], + [-23.015, 0], + [0, 0], + [0, -23.016], + [0, 0] + ], + "o": [ + [0, 0], + [-23.015, 0], + [0, 0], + [0, -23.016], + [0, 0], + [23.006, 0], + [0, 0], + [0, 23.015] + ], + "v": [ + [41.73, 62.592], + [-41.732, 62.592], + [-83.463, 20.87], + [-83.463, -20.86], + [-41.732, -62.592], + [41.73, -62.592], + [83.463, -20.86], + [83.463, 20.87] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 2", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "mm", + "mm": 1, + "nm": "Merge Paths 1", + "mn": "ADBE Vector Filter - Merge", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.466666696586, 0.458823559331, 0.490196108351, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { + "a": 1, + "k": [ + { + "i": { "x": 0.833, "y": 0.833 }, + "o": { "x": 0.167, "y": 0.167 }, + "t": 0, + "s": [182.824, 141.088], + "to": [0, 0], + "ti": [0, 0] + }, + { + "i": { "x": 0.833, "y": 0.833 }, + "o": { "x": 0.167, "y": 0.167 }, + "t": 30, + "s": [152.824, 131.088], + "to": [0, 0], + "ti": [0, 0] + }, + { "t": 58.0000023623884, "s": [182.824, 141.088] } + ], + "ix": 2 + }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 4", + "np": 4, + "cix": 2, + "bm": 0, + "ix": 4, + "mn": "ADBE Vector Group", + "hd": false + } + ], + "ip": 0, + "op": 60.0000024438501, + "st": 0, + "bm": 0 + } + ], + "markers": [] +} diff --git a/apps/web/src/components/blocksuite/header/editor-mode-switch/index.tsx b/apps/web/src/components/blocksuite/workspace-header/editor-mode-switch/index.tsx similarity index 100% rename from apps/web/src/components/blocksuite/header/editor-mode-switch/index.tsx rename to apps/web/src/components/blocksuite/workspace-header/editor-mode-switch/index.tsx diff --git a/apps/web/src/components/blocksuite/header/editor-mode-switch/style.ts b/apps/web/src/components/blocksuite/workspace-header/editor-mode-switch/style.ts similarity index 100% rename from apps/web/src/components/blocksuite/header/editor-mode-switch/style.ts rename to apps/web/src/components/blocksuite/workspace-header/editor-mode-switch/style.ts diff --git a/apps/web/src/components/blocksuite/header/editor-mode-switch/switch-items.tsx b/apps/web/src/components/blocksuite/workspace-header/editor-mode-switch/switch-items.tsx similarity index 100% rename from apps/web/src/components/blocksuite/header/editor-mode-switch/switch-items.tsx rename to apps/web/src/components/blocksuite/workspace-header/editor-mode-switch/switch-items.tsx diff --git a/apps/web/src/components/blocksuite/header/header-right-items/EditorOptionMenu.tsx b/apps/web/src/components/blocksuite/workspace-header/header-right-items/EditorOptionMenu.tsx similarity index 100% rename from apps/web/src/components/blocksuite/header/header-right-items/EditorOptionMenu.tsx rename to apps/web/src/components/blocksuite/workspace-header/header-right-items/EditorOptionMenu.tsx diff --git a/apps/web/src/components/blocksuite/header/header-right-items/SyncUser.tsx b/apps/web/src/components/blocksuite/workspace-header/header-right-items/SyncUser.tsx similarity index 100% rename from apps/web/src/components/blocksuite/header/header-right-items/SyncUser.tsx rename to apps/web/src/components/blocksuite/workspace-header/header-right-items/SyncUser.tsx diff --git a/apps/web/src/components/blocksuite/header/header-right-items/TrashButtonGroup.tsx b/apps/web/src/components/blocksuite/workspace-header/header-right-items/TrashButtonGroup.tsx similarity index 100% rename from apps/web/src/components/blocksuite/header/header-right-items/TrashButtonGroup.tsx rename to apps/web/src/components/blocksuite/workspace-header/header-right-items/TrashButtonGroup.tsx diff --git a/apps/web/src/components/blocksuite/header/header-right-items/theme-mode-switch/Icons.tsx b/apps/web/src/components/blocksuite/workspace-header/header-right-items/theme-mode-switch/Icons.tsx similarity index 100% rename from apps/web/src/components/blocksuite/header/header-right-items/theme-mode-switch/Icons.tsx rename to apps/web/src/components/blocksuite/workspace-header/header-right-items/theme-mode-switch/Icons.tsx diff --git a/apps/web/src/components/blocksuite/header/header-right-items/theme-mode-switch/index.tsx b/apps/web/src/components/blocksuite/workspace-header/header-right-items/theme-mode-switch/index.tsx similarity index 100% rename from apps/web/src/components/blocksuite/header/header-right-items/theme-mode-switch/index.tsx rename to apps/web/src/components/blocksuite/workspace-header/header-right-items/theme-mode-switch/index.tsx diff --git a/apps/web/src/components/blocksuite/header/header-right-items/theme-mode-switch/style.ts b/apps/web/src/components/blocksuite/workspace-header/header-right-items/theme-mode-switch/style.ts similarity index 100% rename from apps/web/src/components/blocksuite/header/header-right-items/theme-mode-switch/style.ts rename to apps/web/src/components/blocksuite/workspace-header/header-right-items/theme-mode-switch/style.ts diff --git a/apps/web/src/components/blocksuite/workspace-header/header.tsx b/apps/web/src/components/blocksuite/workspace-header/header.tsx new file mode 100644 index 000000000..3504f12a5 --- /dev/null +++ b/apps/web/src/components/blocksuite/workspace-header/header.tsx @@ -0,0 +1,177 @@ +import { useTranslation } from '@affine/i18n'; +import { CloseIcon } from '@blocksuite/icons'; +import type { Page } from '@blocksuite/store'; +import type { HTMLAttributes, PropsWithChildren } from 'react'; +import type React from 'react'; +import { forwardRef, useEffect, useMemo, useState } from 'react'; + +import { + useSidebarFloating, + useSidebarStatus, +} from '../../../hooks/use-sidebar-status'; +import type { AffineOfficialWorkspace } from '../../../shared'; +import { SidebarSwitch } from '../../affine/sidebar-switch'; +import { EditorOptionMenu } from './header-right-items/EditorOptionMenu'; +import SyncUser from './header-right-items/SyncUser'; +import ThemeModeSwitch from './header-right-items/theme-mode-switch'; +import TrashButtonGroup from './header-right-items/TrashButtonGroup'; +import { + StyledBrowserWarning, + StyledCloseButton, + StyledHeader, + StyledHeaderContainer, + StyledHeaderRightSide, +} from './styles'; +import { OSWarningMessage, shouldShowWarning } from './utils'; + +const BrowserWarning = ({ + show, + onClose, +}: { + show: boolean; + onClose: () => void; +}) => { + return ( + + + + + + + ); +}; + +export type BaseHeaderProps< + Workspace extends AffineOfficialWorkspace = AffineOfficialWorkspace +> = { + workspace: Workspace; + currentPage: Page | null; + isPublic: boolean; + isPreview: boolean; +}; + +export const enum HeaderRightItemName { + EditorOptionMenu = 'editorOptionMenu', + TrashButtonGroup = 'trashButtonGroup', + ThemeModeSwitch = 'themeModeSwitch', + SyncUser = 'syncUser', + ShareMenu = 'shareMenu', +} + +type HeaderItem = { + Component: React.FC; + // todo: public workspace should be one of the flavour + availableWhen: ( + workspace: AffineOfficialWorkspace, + currentPage: Page | null, + status: { + isPublic: boolean; + isPreview: boolean; + } + ) => boolean; +}; + +const HeaderRightItems: Record = { + [HeaderRightItemName.TrashButtonGroup]: { + Component: TrashButtonGroup, + availableWhen: (_, currentPage) => { + return currentPage?.meta.trash === true; + }, + }, + [HeaderRightItemName.SyncUser]: { + Component: SyncUser, + availableWhen: (_, currentPage, { isPublic, isPreview }) => { + return !isPublic && !isPreview; + }, + }, + [HeaderRightItemName.ThemeModeSwitch]: { + Component: ThemeModeSwitch, + availableWhen: (_, currentPage) => { + return currentPage?.meta.trash !== true; + }, + }, + [HeaderRightItemName.EditorOptionMenu]: { + Component: EditorOptionMenu, + availableWhen: (_, currentPage, { isPublic, isPreview }) => { + return !!currentPage && !isPublic && !isPreview; + }, + }, + [HeaderRightItemName.ShareMenu]: { + Component: () => null, + availableWhen: (_, currentPage, { isPublic, isPreview }) => { + return false; + }, + }, +}; + +export type HeaderProps = BaseHeaderProps; + +export const Header = forwardRef< + HTMLDivElement, + PropsWithChildren & HTMLAttributes +>((props, ref) => { + const [showWarning, setShowWarning] = useState(false); + useEffect(() => { + setShowWarning(shouldShowWarning()); + }, []); + const [open] = useSidebarStatus(); + const sidebarFloating = useSidebarFloating(); + const { t } = useTranslation(); + + return ( + + { + setShowWarning(false); + }} + /> + + + + {props.children} + + {useMemo(() => { + return Object.entries(HeaderRightItems).map( + ([name, { availableWhen, Component }]) => { + if ( + availableWhen(props.workspace, props.currentPage, { + isPreview: props.isPreview, + isPublic: props.isPublic, + }) + ) { + return ( + + ); + } + return null; + } + ); + }, [props])} + {/**/} + + + + ); +}); + +Header.displayName = 'Header'; diff --git a/apps/web/src/components/blocksuite/workspace-header/index.tsx b/apps/web/src/components/blocksuite/workspace-header/index.tsx new file mode 100644 index 000000000..1a25af588 --- /dev/null +++ b/apps/web/src/components/blocksuite/workspace-header/index.tsx @@ -0,0 +1,128 @@ +import type { PopperProps } from '@affine/component'; +import { QuickSearchTips } from '@affine/component'; +import { getEnvironment } from '@affine/env'; +import { ArrowDownSmallIcon } from '@blocksuite/icons'; +import { assertExists } from '@blocksuite/store'; +import { useAtomValue, useSetAtom } from 'jotai'; +import type { HTMLAttributes, PropsWithChildren } from 'react'; +import { forwardRef, useCallback, useRef } from 'react'; + +import { currentEditorAtom, openQuickSearchModalAtom } from '../../../atoms'; +import { useGuideHidden } from '../../../hooks/use-is-first-load'; +import { usePageMeta } from '../../../hooks/use-page-meta'; +import { useElementResizeEffect } from '../../../hooks/use-workspaces'; +import { QuickSearchButton } from '../../pure/quick-search-button'; +import { EditorModeSwitch } from './editor-mode-switch'; +import type { BaseHeaderProps } from './header'; +import { Header } from './header'; +import { + StyledQuickSearchTipButton, + StyledQuickSearchTipContent, + StyledSearchArrowWrapper, + StyledSwitchWrapper, + StyledTitle, + StyledTitleContainer, + StyledTitleWrapper, +} from './styles'; + +export type WorkspaceHeaderProps = BaseHeaderProps; + +export const WorkspaceHeader = forwardRef< + HTMLDivElement, + PropsWithChildren & HTMLAttributes +>((props, ref) => { + const { workspace, currentPage, children, isPublic } = props; + // fixme(himself65): remove this atom and move it to props + const setOpenQuickSearch = useSetAtom(openQuickSearchModalAtom); + const pageMeta = usePageMeta(workspace.blockSuiteWorkspace).find( + meta => meta.id === currentPage?.id + ); + assertExists(pageMeta); + const title = pageMeta.title; + const [isTipsHidden, setTipsHidden] = useGuideHidden(); + const isMac = () => { + const env = getEnvironment(); + return env.isBrowser && env.isMacOs; + }; + + const popperRef: PopperProps['popperRef'] = useRef(null); + + useElementResizeEffect( + useAtomValue(currentEditorAtom), + useCallback(() => { + if (isTipsHidden.quickSearchTips || !popperRef.current) { + return; + } + popperRef.current.update(); + }, [isTipsHidden.quickSearchTips]) + ); + + const TipsContent = ( + +
+ Click button + { + + + + } + or use + {isMac() ? ' ⌘ + K' : ' Ctrl + K'} to activate Quick Search. Then you + can search keywords or quickly open recently viewed pages. +
+ + setTipsHidden({ ...isTipsHidden, quickSearchTips: true }) + } + > + Got it + +
+ ); + + return ( +
+ {children} + {!isPublic && currentPage && ( + + + + + + {title || 'Untitled'} + + + { + setOpenQuickSearch(true); + }} + /> + + + + + )} +
+ ); +}); + +WorkspaceHeader.displayName = 'BlockSuiteEditorHeader'; diff --git a/apps/web/src/components/blocksuite/header/styles.ts b/apps/web/src/components/blocksuite/workspace-header/styles.ts similarity index 100% rename from apps/web/src/components/blocksuite/header/styles.ts rename to apps/web/src/components/blocksuite/workspace-header/styles.ts diff --git a/apps/web/src/components/blocksuite/header/utils.tsx b/apps/web/src/components/blocksuite/workspace-header/utils.tsx similarity index 100% rename from apps/web/src/components/blocksuite/header/utils.tsx rename to apps/web/src/components/blocksuite/workspace-header/utils.tsx diff --git a/apps/web/src/components/page-detail-editor.tsx b/apps/web/src/components/page-detail-editor.tsx index 5eb3fe3bb..e339a977c 100644 --- a/apps/web/src/components/page-detail-editor.tsx +++ b/apps/web/src/components/page-detail-editor.tsx @@ -10,14 +10,14 @@ import { useCallback } from 'react'; import { currentEditorAtom, workspacePreferredModeAtom } from '../atoms'; import { usePageMeta } from '../hooks/use-page-meta'; -import type { BlockSuiteWorkspace } from '../shared'; +import type { AffineOfficialWorkspace } from '../shared'; import { PageNotFoundError } from './affine/affine-error-eoundary'; -import { BlockSuiteEditorHeader } from './blocksuite/header'; +import { WorkspaceHeader } from './blocksuite/workspace-header'; export type PageDetailEditorProps = { isPublic?: boolean; isPreview?: boolean; - blockSuiteWorkspace: BlockSuiteWorkspace; + workspace: AffineOfficialWorkspace; pageId: string; onInit: (page: Page, editor: Readonly) => void; onLoad?: (page: Page, editor: EditorContainer) => void; @@ -33,7 +33,7 @@ const Editor = dynamic( ); export const PageDetailEditor: React.FC = ({ - blockSuiteWorkspace, + workspace, pageId, onInit, onLoad, @@ -41,6 +41,7 @@ export const PageDetailEditor: React.FC = ({ isPublic, isPreview, }) => { + const blockSuiteWorkspace = workspace.blockSuiteWorkspace; const page = blockSuiteWorkspace.getPage(pageId); if (!page) { throw new PageNotFoundError(blockSuiteWorkspace, pageId); @@ -58,14 +59,14 @@ export const PageDetailEditor: React.FC = ({ {title} - {header} - + flavour !== WorkspaceFlavour.PUBLIC + ) as (AffineWorkspace | LocalWorkspace)[] + } currentWorkspaceId={currentWorkspaceId} onClick={onClickWorkspace} onSettingClick={onClickWorkspaceSetting} diff --git a/apps/web/src/components/pure/workspace-title/index.tsx b/apps/web/src/components/pure/workspace-title/index.tsx index 619214eef..29a613f50 100644 --- a/apps/web/src/components/pure/workspace-title/index.tsx +++ b/apps/web/src/components/pure/workspace-title/index.tsx @@ -3,21 +3,25 @@ import type { ReactNode } from 'react'; import type React from 'react'; import { openQuickSearchModalAtom } from '../../../atoms'; -import Header from '../../blocksuite/header/header'; -import { StyledPageListTittleWrapper } from '../../blocksuite/header/styles'; +import type { HeaderProps } from '../../blocksuite/workspace-header/header'; +import { Header } from '../../blocksuite/workspace-header/header'; +import { StyledPageListTittleWrapper } from '../../blocksuite/workspace-header/styles'; import { QuickSearchButton } from '../quick-search-button'; -export type WorkspaceTitleProps = React.PropsWithChildren<{ - icon?: ReactNode; -}>; +export type WorkspaceTitleProps = React.PropsWithChildren< + HeaderProps & { + icon?: ReactNode; + } +>; export const WorkspaceTitle: React.FC = ({ icon, children, + ...props }) => { const setOpenQuickSearch = useSetAtom(openQuickSearchModalAtom); return ( -
+
{icon} {children} diff --git a/apps/web/src/hooks/affine/use-is-workspace-owner.ts b/apps/web/src/hooks/affine/use-is-workspace-owner.ts index f8dc9c38c..c943016c3 100644 --- a/apps/web/src/hooks/affine/use-is-workspace-owner.ts +++ b/apps/web/src/hooks/affine/use-is-workspace-owner.ts @@ -1,8 +1,10 @@ import { PermissionType } from '@affine/workspace/affine/api'; +import { WorkspaceFlavour } from '@affine/workspace/type'; import type { AffineOfficialWorkspace } from '../../shared'; export function useIsWorkspaceOwner(workspace: AffineOfficialWorkspace) { - if (workspace.flavour === 'local') return true; + if (workspace.flavour === WorkspaceFlavour.LOCAL) return true; + if (workspace.flavour === WorkspaceFlavour.PUBLIC) return false; return workspace.permission === PermissionType.Owner; } diff --git a/apps/web/src/hooks/use-sync-router-with-current-workspace-and-page.ts b/apps/web/src/hooks/use-sync-router-with-current-workspace-and-page.ts index e76ba1a16..81bcce32d 100644 --- a/apps/web/src/hooks/use-sync-router-with-current-workspace-and-page.ts +++ b/apps/web/src/hooks/use-sync-router-with-current-workspace-and-page.ts @@ -34,6 +34,9 @@ export function findSuitablePageId( null ); } + case WorkspaceFlavour.PUBLIC: { + return null; + } } } diff --git a/apps/web/src/layouts/index.tsx b/apps/web/src/layouts/index.tsx index 5a1947716..a6f9b1b9e 100644 --- a/apps/web/src/layouts/index.tsx +++ b/apps/web/src/layouts/index.tsx @@ -19,7 +19,7 @@ import { openWorkspacesModalAtom, } from '../atoms'; import { - publicBlockSuiteAtom, + publicWorkspaceAtom, publicWorkspaceIdAtom, } from '../atoms/public-workspace'; import { HelpIsland } from '../components/pure/help-island'; @@ -62,14 +62,14 @@ const QuickSearchModal = dynamic( ); export const PublicQuickSearch: FC = () => { - const blockSuiteWorkspace = useAtomValue(publicBlockSuiteAtom); + const publicWorkspace = useAtomValue(publicWorkspaceAtom); const router = useRouter(); const [openQuickSearchModal, setOpenQuickSearchModalAtom] = useAtom( openQuickSearchModalAtom ); return ( { - const blockSuiteWorkspace = useAtomValue(publicBlockSuiteAtom); + const publicWorkspace = useAtomValue(publicWorkspaceAtom); const router = useRouter(); const [openQuickSearchModal, setOpenQuickSearchModalAtom] = useAtom( openQuickSearchModalAtom ); return ( = ({ - text, - title, -}: InferGetStaticPropsType) => { - const [blockSuiteWorkspace, setBlockSuiteWorkspace] = - useState(null); - useEffect(() => { - const blockSuiteWorkspace = createEmptyBlockSuiteWorkspace( - 'preview', - (_: string) => undefined - ); - blockSuiteWorkspace.slots.pageAdded.once(() => { - setBlockSuiteWorkspace(blockSuiteWorkspace); - }); - blockSuiteWorkspace.createPage('preview'); - return () => { - blockSuiteWorkspace.removePage('preview'); - }; - }, []); - if (!blockSuiteWorkspace || !blockSuiteWorkspace.getPage('preview')) { - return ; - } - return ( - <> - - {title} - - - - { - blockSuiteWorkspace.setPageMeta(page.id, { title }); - const pageBlockId = page.addBlock('affine:page', { - title: new page.Text(title), - }); - page.addBlock('affine:surface', {}, null); - const frameId = page.addBlock('affine:frame', {}, pageBlockId); - page.addBlock('affine:paragraph', {}, frameId); - const contentParser = new ContentParser(page); - contentParser.importMarkdown(text, frameId).then(() => { - page.resetHistory(); - }); - }} - /> - - {/* fixme(himself65): remove this */} -
- {/* Slot for block hub */} -
-
-
-
- - ); -}; - -export default PreviewPage; - -export const getStaticProps: GetStaticProps< - PreviewPageProps, - PreviewPageParams -> = async context => { - const name = context.params?.previewId; - const fs = await import('node:fs/promises'); - const path = await import('node:path'); - const markdown: string = await fs.readFile( - path.resolve( - process.cwd(), - '..', - '..', - 'packages', - 'templates', - 'src', - `${name}.md` - ), - 'utf8' - ); - const title = markdown - .split('\n') - .splice(0, 1) - .join('') - .replaceAll('#', '') - .trim(); - if (!name) { - return { - redirect: { - destination: '/404', - }, - props: { - text: '', - title: '', - }, - }; - } - return { - props: { - text: markdown.split('\n').slice(1).join('\n'), - title, - }, - }; -}; - -export const getStaticPaths: GetStaticPaths = () => { - return { - paths: [ - { params: { previewId: 'AFFiNE-Docs' } }, - { params: { previewId: 'Welcome-to-AFFiNE-Abbey-Alpha-Wood' } }, - { params: { previewId: 'Welcome-to-AFFiNE-Alpha-Downhills' } }, - { params: { previewId: 'Welcome-to-the-AFFiNE-Alpha' } }, - ], - fallback: false, - }; -}; diff --git a/apps/web/src/pages/public-workspace/[workspaceId].tsx b/apps/web/src/pages/public-workspace/[workspaceId].tsx index 897536d94..7816d104d 100644 --- a/apps/web/src/pages/public-workspace/[workspaceId].tsx +++ b/apps/web/src/pages/public-workspace/[workspaceId].tsx @@ -10,7 +10,7 @@ import { Suspense, useCallback, useEffect } from 'react'; import { currentWorkspaceIdAtom, openQuickSearchModalAtom } from '../../atoms'; import { - publicBlockSuiteAtom, + publicWorkspaceAtom, publicWorkspaceIdAtom, } from '../../atoms/public-workspace'; import { QueryParamError } from '../../components/affine/affine-error-eoundary'; @@ -31,7 +31,8 @@ const ListPageInner: React.FC<{ workspaceId: string; }> = ({ workspaceId }) => { const router = useRouter(); - const blockSuiteWorkspace = useAtomValue(publicBlockSuiteAtom); + const publicWorkspace = useAtomValue(publicWorkspaceAtom); + const blockSuiteWorkspace = publicWorkspace.blockSuiteWorkspace; const handleClickPage = useCallback( (pageId: string) => { return router.push({ @@ -84,6 +85,7 @@ const ListPage: NextPageWithLayout = () => { const router = useRouter(); const workspaceId = router.query.workspaceId; const setWorkspaceId = useSetAtom(publicWorkspaceIdAtom); + // todo: remove this atom usage here const setCurrentWorkspaceId = useSetAtom(currentWorkspaceIdAtom); useEffect(() => { if (!router.isReady) { diff --git a/apps/web/src/pages/public-workspace/[workspaceId]/[pageId].tsx b/apps/web/src/pages/public-workspace/[workspaceId]/[pageId].tsx index ae09ea31b..66b455a0a 100644 --- a/apps/web/src/pages/public-workspace/[workspaceId]/[pageId].tsx +++ b/apps/web/src/pages/public-workspace/[workspaceId]/[pageId].tsx @@ -55,7 +55,8 @@ export const StyledBreadcrumbs = styled(Link)(({ theme }) => { const PublicWorkspaceDetailPageInner: React.FC<{ pageId: string; }> = ({ pageId }) => { - const blockSuiteWorkspace = useAtomValue(publicPageBlockSuiteAtom); + const publicWorkspace = useAtomValue(publicPageBlockSuiteAtom); + const blockSuiteWorkspace = publicWorkspace.blockSuiteWorkspace; if (!blockSuiteWorkspace) { throw new Error('cannot find workspace'); } @@ -83,7 +84,7 @@ const PublicWorkspaceDetailPageInner: React.FC<{ { const { page } = editor; page.awarenessStore.setReadonly(page, true); diff --git a/apps/web/src/pages/workspace/[workspaceId]/all.tsx b/apps/web/src/pages/workspace/[workspaceId]/all.tsx index f505d94c4..65751e15e 100644 --- a/apps/web/src/pages/workspace/[workspaceId]/all.tsx +++ b/apps/web/src/pages/workspace/[workspaceId]/all.tsx @@ -92,7 +92,15 @@ const AllPage: NextPageWithLayout = () => { {t('All Pages')} - AFFiNE - }>{t('All pages')} + } + > + {t('All pages')} + { {t('All Pages')} - AFFiNE - }>{t('All pages')} + } + > + {t('All pages')} + { {t('Favorites')} - AFFiNE - }>{t('Favorites')} + } + > + {t('Favorites')} + { {t('Settings')} - AFFiNE - }> + } + > {t('Workspace Settings')} { {t('Settings')} - AFFiNE - }> + } + > {t('Workspace Settings')} { {t('Trash')} - AFFiNE - }> + } + > {t('Trash')} = { <> diff --git a/apps/web/src/plugins/index.tsx b/apps/web/src/plugins/index.tsx index 7eec0a95c..e6d12cdf2 100644 --- a/apps/web/src/plugins/index.tsx +++ b/apps/web/src/plugins/index.tsx @@ -1,10 +1,9 @@ import type { AppEvents, - LoadPriority, WorkspaceCRUD, WorkspaceUISchema, } from '@affine/workspace/type'; -import { WorkspaceFlavour } from '@affine/workspace/type'; +import { LoadPriority, WorkspaceFlavour } from '@affine/workspace/type'; import { AffinePlugin } from './affine'; import { LocalPlugin } from './local'; @@ -19,9 +18,33 @@ export interface WorkspacePlugin { UI: WorkspaceUISchema; } +const unimplemented = () => { + throw new Error('Not implemented'); +}; export const WorkspacePlugins = { [WorkspaceFlavour.AFFINE]: AffinePlugin, [WorkspaceFlavour.LOCAL]: LocalPlugin, + [WorkspaceFlavour.PUBLIC]: { + flavour: WorkspaceFlavour.PUBLIC, + loadPriority: LoadPriority.LOW, + Events: { + 'app:first-init': async () => {}, + }, + // todo: implement this + CRUD: { + get: unimplemented, + list: unimplemented, + delete: unimplemented, + create: unimplemented, + }, + // todo: implement this + UI: { + Provider: unimplemented, + PageDetail: unimplemented, + PageList: unimplemented, + SettingsDetail: unimplemented, + }, + }, } satisfies { [Key in WorkspaceFlavour]: WorkspacePlugin; }; diff --git a/apps/web/src/plugins/local/index.tsx b/apps/web/src/plugins/local/index.tsx index bb46df937..3347e5718 100644 --- a/apps/web/src/plugins/local/index.tsx +++ b/apps/web/src/plugins/local/index.tsx @@ -59,7 +59,7 @@ export const LocalPlugin: WorkspacePlugin = { ); diff --git a/apps/web/src/shared/index.ts b/apps/web/src/shared/index.ts index 62ce1e767..38e26602c 100644 --- a/apps/web/src/shared/index.ts +++ b/apps/web/src/shared/index.ts @@ -1,11 +1,15 @@ import type { AffineWorkspace, LocalWorkspace } from '@affine/workspace/type'; +import type { AffinePublicWorkspace } from '@affine/workspace/type'; import { Workspace as BlockSuiteWorkspace } from '@blocksuite/store'; import type { NextPage } from 'next'; import type { ReactElement, ReactNode } from 'react'; export { BlockSuiteWorkspace }; -export type AffineOfficialWorkspace = AffineWorkspace | LocalWorkspace; +export type AffineOfficialWorkspace = + | AffineWorkspace + | LocalWorkspace + | AffinePublicWorkspace; export type AllWorkspace = AffineOfficialWorkspace; diff --git a/packages/component/src/components/workspace-avatar/index.tsx b/packages/component/src/components/workspace-avatar/index.tsx index ab5ff98e8..8eafdf7b3 100644 --- a/packages/component/src/components/workspace-avatar/index.tsx +++ b/packages/component/src/components/workspace-avatar/index.tsx @@ -1,4 +1,8 @@ -import type { AffineWorkspace, LocalWorkspace } from '@affine/workspace/type'; +import type { + AffinePublicWorkspace, + AffineWorkspace, + LocalWorkspace, +} from '@affine/workspace/type'; import type { Workspace } from '@blocksuite/store'; import * as RadixAvatar from '@radix-ui/react-avatar'; import { useBlockSuiteWorkspaceAvatarUrl } from '@toeverything/hooks/use-blocksuite-workspace-avatar-url'; @@ -31,7 +35,7 @@ function stringToColour(str: string) { export type WorkspaceAvatarProps = { size?: number; - workspace: LocalWorkspace | AffineWorkspace | null; + workspace: AffineWorkspace | LocalWorkspace | AffinePublicWorkspace | null; className?: string; }; diff --git a/packages/workspace/src/type.ts b/packages/workspace/src/type.ts index 1ca515c9a..4efb1b88c 100644 --- a/packages/workspace/src/type.ts +++ b/packages/workspace/src/type.ts @@ -54,6 +54,13 @@ export interface LocalWorkspace { providers: Provider[]; } +export interface AffinePublicWorkspace { + flavour: WorkspaceFlavour.PUBLIC; + id: string; + blockSuiteWorkspace: BlockSuiteWorkspace; + providers: Provider[]; +} + export const enum LoadPriority { HIGH = 1, MEDIUM = 2, @@ -63,6 +70,7 @@ export const enum LoadPriority { export const enum WorkspaceFlavour { AFFINE = 'affine', LOCAL = 'local', + PUBLIC = 'affine-public', } export const settingPanel = { @@ -79,6 +87,7 @@ export type SettingPanel = (typeof settingPanel)[keyof typeof settingPanel]; export interface WorkspaceRegistry { [WorkspaceFlavour.AFFINE]: AffineWorkspace; [WorkspaceFlavour.LOCAL]: LocalWorkspace; + [WorkspaceFlavour.PUBLIC]: AffinePublicWorkspace; } export interface WorkspaceCRUD { diff --git a/tests/parallels/local-first-favorite-page.spec.ts b/tests/parallels/local-first-favorite-page.spec.ts index 671170598..785a9152b 100644 --- a/tests/parallels/local-first-favorite-page.spec.ts +++ b/tests/parallels/local-first-favorite-page.spec.ts @@ -10,7 +10,7 @@ import { import { test } from '../libs/playwright'; import { assertCurrentWorkspaceFlavour } from '../libs/workspace'; -test.describe('Local first favorite and cancel favorite page', () => { +test.describe('Local first favorite and cancel favorite page', () => { test('New a page and open it ,then favorite it', async ({ page }) => { await openHomePage(page); await waitMarkdownImported(page);