From 05025bf59a53085237b8136c1f28cdf6c2a3b691 Mon Sep 17 00:00:00 2001 From: EYHN Date: Mon, 25 Dec 2023 03:24:12 +0000 Subject: [PATCH] refactor(core): remove outline plugin and layout atom (#5326) @affine/outline is no longer used, this PR deletes this plugin and deletes the code that is no longer used --- README.md | 1 - .../common/infra/src/__internal__/plugin.ts | 1 - packages/common/infra/src/atom/index.ts | 1 - packages/common/infra/src/atom/layout.ts | 34 ------ packages/common/infra/src/type.ts | 10 -- .../frontend/core/.webpack/runtime-config.ts | 2 - .../core/src/bootstrap/plugins/setup.ts | 95 +--------------- packages/frontend/electron/package.json | 1 - packages/plugins/outline/package.json | 28 ----- packages/plugins/outline/project.json | 26 ----- packages/plugins/outline/src/app.tsx | 107 ------------------ packages/plugins/outline/src/index.ts | 41 ------- packages/plugins/outline/tsconfig.json | 17 --- tests/affine-cloud/e2e/collaboration.spec.ts | 3 +- tests/affine-plugin/e2e/basic.spec.ts | 1 - yarn.lock | 15 --- 16 files changed, 3 insertions(+), 380 deletions(-) delete mode 100644 packages/common/infra/src/atom/layout.ts delete mode 100644 packages/plugins/outline/package.json delete mode 100644 packages/plugins/outline/project.json delete mode 100644 packages/plugins/outline/src/app.tsx delete mode 100644 packages/plugins/outline/src/index.ts delete mode 100644 packages/plugins/outline/tsconfig.json diff --git a/README.md b/README.md index c73b6c911a..c33ee9b262 100644 --- a/README.md +++ b/README.md @@ -126,7 +126,6 @@ If you have questions, you are welcome to contact us. One of the best places to | ---------------------------------------------------------------- | ----------------------------------------- | ------ | | [@affine/copilot-plugin](./packages/plugins/copilot) | AI Copilot that help you document writing | 🚧 | | [@affine/image-preview-plugin](./packages/plugins/image-preview) | Component for previewing an image | ✅ | -| [@affine/outline](./packages/plugins/outline) | Outline for your document | ✅ | ## Upstreams diff --git a/packages/common/infra/src/__internal__/plugin.ts b/packages/common/infra/src/__internal__/plugin.ts index 9e2840939a..7071e8b9df 100644 --- a/packages/common/infra/src/__internal__/plugin.ts +++ b/packages/common/infra/src/__internal__/plugin.ts @@ -36,7 +36,6 @@ export const pluginPackageJson = atom< export const enabledPluginAtom = atomWithStorage('affine-enabled-plugin', [ '@affine/image-preview-plugin', - '@affine/outline-plugin', ]); export const pluginHeaderItemAtom = atom< diff --git a/packages/common/infra/src/atom/index.ts b/packages/common/infra/src/atom/index.ts index 8b5f2a3104..30785f552b 100644 --- a/packages/common/infra/src/atom/index.ts +++ b/packages/common/infra/src/atom/index.ts @@ -2,7 +2,6 @@ import { atom } from 'jotai'; export const loadedPluginNameAtom = atom([]); -export * from './layout'; export * from './root-store'; export * from './settings'; export * from './workspace'; diff --git a/packages/common/infra/src/atom/layout.ts b/packages/common/infra/src/atom/layout.ts deleted file mode 100644 index ed6ec20fe7..0000000000 --- a/packages/common/infra/src/atom/layout.ts +++ /dev/null @@ -1,34 +0,0 @@ -import type { ExpectedLayout } from '@affine/sdk/entry'; -import { atom } from 'jotai'; - -const contentLayoutBaseAtom = atom('editor'); - -type SetStateAction = Value | ((prev: Value) => Value); -export const contentLayoutAtom = atom< - ExpectedLayout, - [SetStateAction], - void ->( - get => get(contentLayoutBaseAtom), - (_, set, layout) => { - set(contentLayoutBaseAtom, prev => { - let setV: (prev: ExpectedLayout) => ExpectedLayout; - if (typeof layout !== 'function') { - setV = () => layout; - } else { - setV = layout; - } - const nextValue = setV(prev); - if (nextValue === 'editor') { - return nextValue; - } - if (nextValue.first !== 'editor') { - throw new Error('The first element of the layout should be editor.'); - } - if (nextValue.splitPercentage && nextValue.splitPercentage < 70) { - throw new Error('The split percentage should be greater than 70.'); - } - return nextValue; - }); - } -); diff --git a/packages/common/infra/src/type.ts b/packages/common/infra/src/type.ts index cdda8bfe28..b08e8c2f0c 100644 --- a/packages/common/infra/src/type.ts +++ b/packages/common/infra/src/type.ts @@ -1,6 +1,4 @@ -import type { ExpectedLayout } from '@affine/sdk/entry'; import type Buffer from 'buffer'; -import type { WritableAtom } from 'jotai'; import { z } from 'zod'; import type { AppConfigSchema } from './app-config-storage.js'; @@ -33,14 +31,6 @@ export const packageJsonOutputSchema = z.object({ }), }); -type SetStateAction = Value | ((prev: Value) => Value); - -export type ContentLayoutAtom = WritableAtom< - ExpectedLayout, - [SetStateAction], - void ->; - export abstract class HandlerManager< Namespace extends string, Handlers extends Record, diff --git a/packages/frontend/core/.webpack/runtime-config.ts b/packages/frontend/core/.webpack/runtime-config.ts index 6faf651feb..4921c3191b 100644 --- a/packages/frontend/core/.webpack/runtime-config.ts +++ b/packages/frontend/core/.webpack/runtime-config.ts @@ -63,7 +63,6 @@ export function getRuntimeConfig(buildFlags: BuildFlags): RuntimeConfig { '/plugins/hello-world', '/plugins/image-preview', '/plugins/vue-hello-world', - '/plugins/outline', ], enableTestProperties: true, enableBroadcastChannelProvider: true, @@ -105,7 +104,6 @@ export function getRuntimeConfig(buildFlags: BuildFlags): RuntimeConfig { '/plugins/hello-world', '/plugins/image-preview', '/plugins/vue-hello-world', - '/plugins/outline', ], enablePlugin: process.env.ENABLE_PLUGIN ? process.env.ENABLE_PLUGIN === 'true' diff --git a/packages/frontend/core/src/bootstrap/plugins/setup.ts b/packages/frontend/core/src/bootstrap/plugins/setup.ts index eb848ce174..15c473a899 100644 --- a/packages/frontend/core/src/bootstrap/plugins/setup.ts +++ b/packages/frontend/core/src/bootstrap/plugins/setup.ts @@ -1,10 +1,5 @@ import { DebugLogger } from '@affine/debug'; -import type { - CallbackMap, - ExpectedLayout, - LayoutNode, - PluginContext, -} from '@affine/sdk/entry'; +import type { CallbackMap, PluginContext } from '@affine/sdk/entry'; import { AffineFormatBarWidget } from '@blocksuite/blocks'; import { assertExists } from '@blocksuite/global/utils'; import { @@ -12,10 +7,7 @@ import { pluginEditorAtom, pluginHeaderItemAtom, pluginSettingAtom, - pluginWindowAtom, } from '@toeverything/infra/__internal__/plugin'; -import { contentLayoutAtom, currentPageIdAtom } from '@toeverything/infra/atom'; -import { atom } from 'jotai'; import { Provider } from 'jotai/react'; import type { createStore } from 'jotai/vanilla'; import { createElement, type PropsWithChildren } from 'react'; @@ -31,83 +23,6 @@ const permissionLogger = new DebugLogger('plugins:permission'); const importLogger = new DebugLogger('plugins:import'); const entryLogger = new DebugLogger('plugins:entry'); -const pushLayoutAtom = atom< - null, - // fixme: check plugin name here - [ - pluginName: string, - create: (root: HTMLElement) => () => void, - options: - | { - maxWidth: (number | undefined)[]; - } - | undefined, - ], - void ->(null, (_, set, pluginName, callback, options) => { - set(pluginWindowAtom, items => ({ - ...items, - [pluginName]: callback, - })); - set(contentLayoutAtom, layout => { - if (layout === 'editor') { - return { - direction: 'horizontal', - first: 'editor', - second: pluginName, - splitPercentage: 70, - maxWidth: options?.maxWidth, - }; - } else { - return { - direction: 'horizontal', - first: 'editor', - splitPercentage: 70, - second: { - direction: 'horizontal', - first: pluginName, - second: layout.second, - splitPercentage: 50, - }, - } satisfies ExpectedLayout; - } - }); - addCleanup(pluginName, () => { - set(deleteLayoutAtom, pluginName); - }); -}); - -const deleteLayoutAtom = atom(null, (_, set, id) => { - set(pluginWindowAtom, items => { - const newItems = { ...items }; - delete newItems[id]; - return newItems; - }); - const removeLayout = (layout: LayoutNode): LayoutNode | string => { - if (typeof layout === 'string') { - return layout; - } - if (layout.first === id) { - return layout.second; - } else if (layout.second === id) { - return layout.first; - } else { - return { - ...layout, - second: removeLayout(layout.second), - }; - } - }; - - set(contentLayoutAtom, layout => { - if (layout === 'editor') { - return 'editor'; - } else { - return removeLayout(layout) as ExpectedLayout; - } - }); -}); - const setupWeakMap = new WeakMap< ReturnType, ReturnType @@ -124,11 +39,6 @@ export function createSetup(rootStore: ReturnType) { } function createSetupImpl(rootStore: ReturnType) { - // clean up plugin windows when switching to other pages - rootStore.sub(currentPageIdAtom, () => { - rootStore.set(contentLayoutAtom, 'editor'); - }); - // module -> importName -> updater[] const _rootImportsMap = new Map>(); const rootImportsMapSetupPromise = setupImportsMap(_rootImportsMap, { @@ -145,9 +55,6 @@ function createSetupImpl(rootStore: ReturnType) { '@blocksuite/inline': import('@blocksuite/inline'), '@affine/sdk/entry': { rootStore, - currentPageIdAtom: currentPageIdAtom, - pushLayoutAtom: pushLayoutAtom, - deleteLayoutAtom: deleteLayoutAtom, }, '@blocksuite/global/utils': import('@blocksuite/global/utils'), '@toeverything/infra/atom': import('@toeverything/infra/atom'), diff --git a/packages/frontend/electron/package.json b/packages/frontend/electron/package.json index 7a755f9ca1..6928300a75 100644 --- a/packages/frontend/electron/package.json +++ b/packages/frontend/electron/package.json @@ -28,7 +28,6 @@ "@affine/hello-world-plugin": "workspace:*", "@affine/image-preview-plugin": "workspace:*", "@affine/native": "workspace:*", - "@affine/outline-plugin": "workspace:*", "@affine/sdk": "workspace:*", "@affine/templates": "workspace:*", "@affine/vue-hello-world-plugin": "workspace:*", diff --git a/packages/plugins/outline/package.json b/packages/plugins/outline/package.json deleted file mode 100644 index a0c0b333d4..0000000000 --- a/packages/plugins/outline/package.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "name": "@affine/outline-plugin", - "type": "module", - "private": true, - "description": "Outline plugin", - "version": "0.11.0", - "scripts": { - "dev": "af dev", - "build": "af build" - }, - "affinePlugin": { - "release": "development", - "entry": { - "core": "./src/index.ts" - } - }, - "dependencies": { - "@affine/component": "workspace:*", - "@affine/sdk": "workspace:*", - "@blocksuite/icons": "2.1.36" - }, - "devDependencies": { - "@affine/plugin-cli": "workspace:*", - "jotai": "^2.5.1", - "react": "18.2.0", - "react-dom": "18.2.0" - } -} diff --git a/packages/plugins/outline/project.json b/packages/plugins/outline/project.json deleted file mode 100644 index 2f09ea1644..0000000000 --- a/packages/plugins/outline/project.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "name": "@affine/outline-plugin", - "$schema": "../../../node_modules/nx/schemas/project-schema.json", - "namedInputs": { - "default": [ - "{projectRoot}/**/*", - "{workspaceRoot}/tools/plugin-cli/src/**/*", - "sharedGlobals" - ] - }, - "targets": { - "build": { - "executor": "nx:run-script", - "options": { - "script": "build" - }, - "dependsOn": ["^build"], - "inputs": ["default"], - "outputs": [ - "{workspaceRoot}/packages/frontend/core/public/plugins/outline", - "{workspaceRoot}/packages/frontend/electron/dist/plugins/outline" - ] - } - }, - "tags": ["plugin"] -} diff --git a/packages/plugins/outline/src/app.tsx b/packages/plugins/outline/src/app.tsx deleted file mode 100644 index c22b0a2c61..0000000000 --- a/packages/plugins/outline/src/app.tsx +++ /dev/null @@ -1,107 +0,0 @@ -import { IconButton } from '@affine/component/ui/button'; -import { Tooltip } from '@affine/component/ui/tooltip'; -import { - currentPageIdAtom, - currentWorkspaceAtom, - deleteLayoutAtom, - pushLayoutAtom, -} from '@affine/sdk/entry'; -import { TOCNotesPanel } from '@blocksuite/blocks'; -import { assertExists } from '@blocksuite/global/utils'; -import { RightSidebarIcon } from '@blocksuite/icons'; -import { useAtomValue, useSetAtom } from 'jotai'; -import type { ComponentType, PropsWithChildren } from 'react'; -import { useCallback, useRef, useState } from 'react'; -import { createRoot } from 'react-dom/client'; - -const Outline = () => { - const tocPanelRef = useRef(null); - const currentPageId = useAtomValue(currentPageIdAtom); - assertExists(currentPageId, 'current page id'); - const currentWorkspace = useAtomValue(currentWorkspaceAtom); - const currentPage = currentWorkspace.getPage(currentPageId); - assertExists(currentPage, 'current page'); - - if (!tocPanelRef.current) { - tocPanelRef.current = new TOCNotesPanel(); - } - - if (currentPage !== tocPanelRef.current?.page) { - (tocPanelRef.current as TOCNotesPanel).page = currentPage; - } - - return ( -
{ - if (container) { - assertExists(tocPanelRef.current); - container.append(tocPanelRef.current); - } - }, [])} - /> - ); -}; - -export const HeaderItem = ({ - Provider, -}: { - Provider: ComponentType; -}) => { - const [open, setOpen] = useState(false); - const pushLayout = useSetAtom(pushLayoutAtom); - const deleteLayout = useSetAtom(deleteLayoutAtom); - const [container, setContainer] = useState(null); - - return ( - - { - if (!open) { - setOpen(true); - pushLayout( - '@affine/outline-plugin', - div => { - const root = createRoot(div); - - div.style.height = '100%'; - - root.render( - - - - ); - return () => { - root.unmount(); - }; - }, - { - maxWidth: [undefined, 300], - } - ); - } else { - setOpen(false); - deleteLayout('@affine/outline-plugin'); - } - }, [Provider, deleteLayout, open, pushLayout])} - > - - - - ); -}; diff --git a/packages/plugins/outline/src/index.ts b/packages/plugins/outline/src/index.ts deleted file mode 100644 index 30eacb92f0..0000000000 --- a/packages/plugins/outline/src/index.ts +++ /dev/null @@ -1,41 +0,0 @@ -import type { PluginContext } from '@affine/sdk/entry'; -import { registerTOCComponents } from '@blocksuite/blocks'; -import { createElement } from 'react'; -import { createRoot } from 'react-dom/client'; - -import { HeaderItem } from './app'; - -export const entry = (context: PluginContext) => { - console.log('register outline'); - - context.register('headerItem', div => { - registerTOCComponents(components => { - for (const compName in components) { - if (window.customElements.get(compName)) continue; - - window.customElements.define( - compName, - components[compName as keyof typeof components] - ); - } - }); - - div.style.height = '100%'; - - const root = createRoot(div); - root.render( - createElement( - context.utils.PluginProvider, - {}, - createElement(HeaderItem, { - Provider: context.utils.PluginProvider, - }) - ) - ); - return () => { - root.unmount(); - }; - }); - - return () => {}; -}; diff --git a/packages/plugins/outline/tsconfig.json b/packages/plugins/outline/tsconfig.json deleted file mode 100644 index ab06e69674..0000000000 --- a/packages/plugins/outline/tsconfig.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "extends": "../../../tsconfig.json", - "include": ["./src"], - "compilerOptions": { - "noEmit": false, - "outDir": "lib", - "jsx": "preserve" - }, - "references": [ - { - "path": "../../common/sdk" - }, - { - "path": "../../frontend/component" - } - ] -} diff --git a/tests/affine-cloud/e2e/collaboration.spec.ts b/tests/affine-cloud/e2e/collaboration.spec.ts index 8c065aea13..f167cdb650 100644 --- a/tests/affine-cloud/e2e/collaboration.spec.ts +++ b/tests/affine-cloud/e2e/collaboration.spec.ts @@ -236,7 +236,8 @@ test('can sync svg between different browsers', async ({ page, browser }) => { const image = page.locator('affine-image'); page.evaluate(async () => { - window.showOpenFilePicker = undefined; + // https://github.com/toeverything/blocksuite/blob/master/packages/blocks/src/_common/utils/filesys.ts#L20 + (window as any).showOpenFilePicker = undefined; }); const title = getBlockSuiteEditorTitle(page); diff --git a/tests/affine-plugin/e2e/basic.spec.ts b/tests/affine-plugin/e2e/basic.spec.ts index d2fa6de3a1..b554d1d0d3 100644 --- a/tests/affine-plugin/e2e/basic.spec.ts +++ b/tests/affine-plugin/e2e/basic.spec.ts @@ -26,7 +26,6 @@ test('plugin should exist', async ({ page }) => { '@affine/hello-world-plugin', '@affine/image-preview-plugin', '@affine/vue-hello-world-plugin', - '@affine/outline-plugin', ]; expect(packageJson).toEqual( plugins diff --git a/yarn.lock b/yarn.lock index 5b92dcfbe3..4108de4783 100644 --- a/yarn.lock +++ b/yarn.lock @@ -464,7 +464,6 @@ __metadata: "@affine/hello-world-plugin": "workspace:*" "@affine/image-preview-plugin": "workspace:*" "@affine/native": "workspace:*" - "@affine/outline-plugin": "workspace:*" "@affine/sdk": "workspace:*" "@affine/templates": "workspace:*" "@affine/vue-hello-world-plugin": "workspace:*" @@ -675,20 +674,6 @@ __metadata: languageName: unknown linkType: soft -"@affine/outline-plugin@workspace:*, @affine/outline-plugin@workspace:packages/plugins/outline": - version: 0.0.0-use.local - resolution: "@affine/outline-plugin@workspace:packages/plugins/outline" - dependencies: - "@affine/component": "workspace:*" - "@affine/plugin-cli": "workspace:*" - "@affine/sdk": "workspace:*" - "@blocksuite/icons": "npm:2.1.36" - jotai: "npm:^2.5.1" - react: "npm:18.2.0" - react-dom: "npm:18.2.0" - languageName: unknown - linkType: soft - "@affine/plugin-cli@workspace:*, @affine/plugin-cli@workspace:tools/plugin-cli": version: 0.0.0-use.local resolution: "@affine/plugin-cli@workspace:tools/plugin-cli"