mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-04 08:38:34 +00:00
refactor: remove bookmark plugin (#4544)
This commit is contained in:
@@ -125,7 +125,6 @@ If you have questions, you are welcome to contact us. One of the best places to
|
|||||||
|
|
||||||
| Official Plugin | Description | Status |
|
| Official Plugin | Description | Status |
|
||||||
| ----------------------------------------------------- | ----------------------------------------- | ------ |
|
| ----------------------------------------------------- | ----------------------------------------- | ------ |
|
||||||
| [@affine/bookmark-plugin](plugins/bookmark) | A block for bookmarking a website | ✅ |
|
|
||||||
| [@affine/copilot-plugin](plugins/copilot) | AI Copilot that help you document writing | 🚧 |
|
| [@affine/copilot-plugin](plugins/copilot) | AI Copilot that help you document writing | 🚧 |
|
||||||
| [@affine/image-preview-plugin](plugins/image-preview) | Component for previewing an image | ✅ |
|
| [@affine/image-preview-plugin](plugins/image-preview) | Component for previewing an image | ✅ |
|
||||||
| [@affine/outline](plugins/outline) | Outline for your document | ✅ |
|
| [@affine/outline](plugins/outline) | Outline for your document | ✅ |
|
||||||
|
|||||||
@@ -4,14 +4,8 @@ import type { SerializedBlock } from '@blocksuite/blocks';
|
|||||||
import type { BaseBlockModel } from '@blocksuite/store';
|
import type { BaseBlockModel } from '@blocksuite/store';
|
||||||
import type { Page } from '@blocksuite/store';
|
import type { Page } from '@blocksuite/store';
|
||||||
import type { VEditor } from '@blocksuite/virgo';
|
import type { VEditor } from '@blocksuite/virgo';
|
||||||
import type { ReactElement } from 'react';
|
|
||||||
import { StrictMode } from 'react';
|
|
||||||
import { useCallback, useEffect, useMemo, useState } from 'react';
|
import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||||
|
|
||||||
export type BookMarkProps = {
|
|
||||||
page: Page;
|
|
||||||
};
|
|
||||||
|
|
||||||
type ShortcutMap = {
|
type ShortcutMap = {
|
||||||
[key: string]: (e: KeyboardEvent, page: Page) => void;
|
[key: string]: (e: KeyboardEvent, page: Page) => void;
|
||||||
};
|
};
|
||||||
@@ -121,7 +115,11 @@ const shouldShowBookmarkMenu = (pastedBlocks: Record<string, unknown>[]) => {
|
|||||||
return !!firstBlock.text[0].attributes?.link;
|
return !!firstBlock.text[0].attributes?.link;
|
||||||
};
|
};
|
||||||
|
|
||||||
const BookMarkUI = ({ page }: BookMarkProps) => {
|
export type BookmarkProps = {
|
||||||
|
page: Page;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Bookmark = ({ page }: BookmarkProps) => {
|
||||||
const [anchor, setAnchor] = useState<Range | null>(null);
|
const [anchor, setAnchor] = useState<Range | null>(null);
|
||||||
const [selectedOption, setSelectedOption] = useState<string>(
|
const [selectedOption, setSelectedOption] = useState<string>(
|
||||||
menuOptions[0].id
|
menuOptions[0].id
|
||||||
@@ -244,15 +242,3 @@ const BookMarkUI = ({ page }: BookMarkProps) => {
|
|||||||
</MuiClickAwayListener>
|
</MuiClickAwayListener>
|
||||||
) : null;
|
) : null;
|
||||||
};
|
};
|
||||||
|
|
||||||
type AppProps = {
|
|
||||||
page: Page;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const App = (props: AppProps): ReactElement => {
|
|
||||||
return (
|
|
||||||
<StrictMode>
|
|
||||||
<BookMarkUI page={props.page} />
|
|
||||||
</StrictMode>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -31,6 +31,7 @@ import { Panel, PanelGroup, PanelResizeHandle } from 'react-resizable-panels';
|
|||||||
import { pageSettingFamily } from '../atoms';
|
import { pageSettingFamily } from '../atoms';
|
||||||
import { fontStyleOptions, useAppSetting } from '../atoms/settings';
|
import { fontStyleOptions, useAppSetting } from '../atoms/settings';
|
||||||
import { BlockSuiteEditor as Editor } from './blocksuite/block-suite-editor';
|
import { BlockSuiteEditor as Editor } from './blocksuite/block-suite-editor';
|
||||||
|
import { Bookmark } from './bookmark';
|
||||||
import * as styles from './page-detail-editor.css';
|
import * as styles from './page-detail-editor.css';
|
||||||
import { editorContainer, pluginContainer } from './page-detail-editor.css';
|
import { editorContainer, pluginContainer } from './page-detail-editor.css';
|
||||||
import { TrashButtonGroup } from './pure/trash-button-group';
|
import { TrashButtonGroup } from './pure/trash-button-group';
|
||||||
@@ -139,6 +140,7 @@ const EditorWrapper = memo(function EditorWrapper({
|
|||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
{meta.trash && <TrashButtonGroup />}
|
{meta.trash && <TrashButtonGroup />}
|
||||||
|
<Bookmark page={page} />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -26,7 +26,6 @@
|
|||||||
"main": "./dist/main.js",
|
"main": "./dist/main.js",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@affine-test/kit": "workspace:*",
|
"@affine-test/kit": "workspace:*",
|
||||||
"@affine/bookmark-plugin": "workspace:*",
|
|
||||||
"@affine/copilot-plugin": "workspace:*",
|
"@affine/copilot-plugin": "workspace:*",
|
||||||
"@affine/env": "workspace:*",
|
"@affine/env": "workspace:*",
|
||||||
"@affine/hello-world-plugin": "workspace:*",
|
"@affine/hello-world-plugin": "workspace:*",
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ export const config = () => {
|
|||||||
resolve(electronDir, './src/main/index.ts'),
|
resolve(electronDir, './src/main/index.ts'),
|
||||||
resolve(electronDir, './src/preload/index.ts'),
|
resolve(electronDir, './src/preload/index.ts'),
|
||||||
resolve(electronDir, './src/helper/index.ts'),
|
resolve(electronDir, './src/helper/index.ts'),
|
||||||
resolve(electronDir, './src/worker/plugin.ts'),
|
|
||||||
],
|
],
|
||||||
entryNames: '[dir]',
|
entryNames: '[dir]',
|
||||||
outdir: resolve(electronDir, './dist'),
|
outdir: resolve(electronDir, './dist'),
|
||||||
|
|||||||
@@ -64,7 +64,6 @@ export const registerHandlers = () => {
|
|||||||
ipcMain.handle(chan, async (e, ...args) => {
|
ipcMain.handle(chan, async (e, ...args) => {
|
||||||
const start = performance.now();
|
const start = performance.now();
|
||||||
try {
|
try {
|
||||||
// @ts-expect-error - TODO: fix this
|
|
||||||
const result = await handler(e, ...args);
|
const result = await handler(e, ...args);
|
||||||
logger.info(
|
logger.info(
|
||||||
'[ipc-api]',
|
'[ipc-api]',
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import { registerHandlers } from './handlers';
|
|||||||
import { ensureHelperProcess } from './helper-process';
|
import { ensureHelperProcess } from './helper-process';
|
||||||
import { logger } from './logger';
|
import { logger } from './logger';
|
||||||
import { restoreOrCreateWindow } from './main-window';
|
import { restoreOrCreateWindow } from './main-window';
|
||||||
import { registerPlugin } from './plugin';
|
|
||||||
import { registerProtocol } from './protocol';
|
import { registerProtocol } from './protocol';
|
||||||
import { registerUpdater } from './updater';
|
import { registerUpdater } from './updater';
|
||||||
|
|
||||||
@@ -59,7 +58,6 @@ setupDeepLink(app);
|
|||||||
app
|
app
|
||||||
.whenReady()
|
.whenReady()
|
||||||
.then(registerProtocol)
|
.then(registerProtocol)
|
||||||
.then(registerPlugin)
|
|
||||||
.then(registerHandlers)
|
.then(registerHandlers)
|
||||||
.then(registerEvents)
|
.then(registerEvents)
|
||||||
.then(ensureHelperProcess)
|
.then(ensureHelperProcess)
|
||||||
|
|||||||
@@ -1,57 +0,0 @@
|
|||||||
import { join, resolve } from 'node:path';
|
|
||||||
import { Worker } from 'node:worker_threads';
|
|
||||||
|
|
||||||
import { logger, pluginLogger } from '@affine/electron/main/logger';
|
|
||||||
import { AsyncCall } from 'async-call-rpc';
|
|
||||||
import { ipcMain } from 'electron';
|
|
||||||
import { readFile } from 'fs/promises';
|
|
||||||
|
|
||||||
import { MessageEventChannel } from '../shared/utils';
|
|
||||||
|
|
||||||
const builtInPlugins = ['bookmark'];
|
|
||||||
|
|
||||||
declare global {
|
|
||||||
// fixme(himself65):
|
|
||||||
// remove this when bookmark block plugin is migrated to plugin-infra
|
|
||||||
// eslint-disable-next-line no-var
|
|
||||||
var asyncCall: Record<string, (...args: any) => PromiseLike<any>>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function registerPlugin() {
|
|
||||||
logger.info('import plugin manager');
|
|
||||||
const asyncCall = AsyncCall<
|
|
||||||
Record<string, (...args: any) => PromiseLike<any>>
|
|
||||||
>(
|
|
||||||
{
|
|
||||||
log: (...args: any[]) => {
|
|
||||||
pluginLogger.log(...args);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
channel: new MessageEventChannel(
|
|
||||||
new Worker(resolve(__dirname, './worker.js'), {})
|
|
||||||
),
|
|
||||||
}
|
|
||||||
);
|
|
||||||
globalThis.asyncCall = asyncCall;
|
|
||||||
await Promise.all(
|
|
||||||
builtInPlugins.map(async plugin => {
|
|
||||||
const pluginPackageJsonPath = join(
|
|
||||||
process.env.PLUGIN_DIR ?? resolve(__dirname, './plugins'),
|
|
||||||
`./${plugin}/package.json`
|
|
||||||
);
|
|
||||||
logger.info(`${plugin} plugin path:`, pluginPackageJsonPath);
|
|
||||||
const packageJson = JSON.parse(
|
|
||||||
await readFile(pluginPackageJsonPath, 'utf-8')
|
|
||||||
);
|
|
||||||
console.log('packageJson', packageJson);
|
|
||||||
const serverCommand: string[] = packageJson.affinePlugin.serverCommand;
|
|
||||||
serverCommand.forEach(command => {
|
|
||||||
ipcMain.handle(command, async (_, ...args) => {
|
|
||||||
logger.info(`plugin ${plugin} called`);
|
|
||||||
return asyncCall[command](...args);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
import { app, BrowserWindow, nativeTheme } from 'electron';
|
import { app, BrowserWindow, nativeTheme } from 'electron';
|
||||||
|
import { getLinkPreview } from 'link-preview-js';
|
||||||
|
|
||||||
import { isMacOS } from '../../shared/utils';
|
import { isMacOS } from '../../shared/utils';
|
||||||
import type { NamespaceHandlers } from '../type';
|
import type { NamespaceHandlers } from '../type';
|
||||||
@@ -43,12 +44,30 @@ export const uiHandlers = {
|
|||||||
getGoogleOauthCode: async () => {
|
getGoogleOauthCode: async () => {
|
||||||
return getGoogleOauthCode();
|
return getGoogleOauthCode();
|
||||||
},
|
},
|
||||||
/**
|
|
||||||
* @deprecated Remove this when bookmark block plugin is migrated to plugin-infra
|
|
||||||
*/
|
|
||||||
getBookmarkDataByLink: async (_, link: string) => {
|
getBookmarkDataByLink: async (_, link: string) => {
|
||||||
return globalThis.asyncCall[
|
const previewData = (await getLinkPreview(link, {
|
||||||
'com.blocksuite.bookmark-block.get-bookmark-data-by-link'
|
timeout: 6000,
|
||||||
](link);
|
headers: {
|
||||||
|
'user-agent': 'googlebot',
|
||||||
|
},
|
||||||
|
followRedirects: 'follow',
|
||||||
|
}).catch(() => {
|
||||||
|
return {
|
||||||
|
title: '',
|
||||||
|
siteName: '',
|
||||||
|
description: '',
|
||||||
|
images: [],
|
||||||
|
videos: [],
|
||||||
|
contentType: `text/html`,
|
||||||
|
favicons: [],
|
||||||
|
};
|
||||||
|
})) as any;
|
||||||
|
|
||||||
|
return {
|
||||||
|
title: previewData.title,
|
||||||
|
description: previewData.description,
|
||||||
|
icon: previewData.favicons[0],
|
||||||
|
image: previewData.images[0],
|
||||||
|
};
|
||||||
},
|
},
|
||||||
} satisfies NamespaceHandlers;
|
} satisfies NamespaceHandlers;
|
||||||
|
|||||||
@@ -1,52 +0,0 @@
|
|||||||
import { join, resolve } from 'node:path';
|
|
||||||
import { parentPort } from 'node:worker_threads';
|
|
||||||
|
|
||||||
import type { ServerContext } from '@affine/sdk/server';
|
|
||||||
import { AsyncCall } from 'async-call-rpc';
|
|
||||||
|
|
||||||
import { MessageEventChannel } from '../shared/utils';
|
|
||||||
|
|
||||||
if (!parentPort) {
|
|
||||||
throw new Error('parentPort is null');
|
|
||||||
}
|
|
||||||
const commandProxy: Record<string, (...args: any[]) => Promise<any>> = {};
|
|
||||||
|
|
||||||
parentPort.start();
|
|
||||||
|
|
||||||
const mainThread = AsyncCall<{
|
|
||||||
log: (...args: any[]) => Promise<void>;
|
|
||||||
}>(commandProxy, {
|
|
||||||
channel: new MessageEventChannel(parentPort),
|
|
||||||
});
|
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
||||||
globalThis.console.log = mainThread.log;
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
||||||
globalThis.console.error = mainThread.log;
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
||||||
globalThis.console.info = mainThread.log;
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
||||||
globalThis.console.debug = mainThread.log;
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
||||||
globalThis.console.warn = mainThread.log;
|
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
||||||
const bookmarkPluginModule = require(
|
|
||||||
join(
|
|
||||||
process.env.PLUGIN_DIR ?? resolve(__dirname, './plugins'),
|
|
||||||
'./bookmark/index.cjs'
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
const serverContext: ServerContext = {
|
|
||||||
registerCommand: (command, fn) => {
|
|
||||||
console.log('register command', command);
|
|
||||||
commandProxy[command] = fn;
|
|
||||||
},
|
|
||||||
unregisterCommand: command => {
|
|
||||||
console.log('unregister command', command);
|
|
||||||
delete commandProxy[command];
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
bookmarkPluginModule.entry(serverContext);
|
|
||||||
@@ -42,7 +42,6 @@ export const pluginPackageJson = atom<
|
|||||||
>([]);
|
>([]);
|
||||||
|
|
||||||
export const enabledPluginAtom = atomWithStorage('affine-enabled-plugin', [
|
export const enabledPluginAtom = atomWithStorage('affine-enabled-plugin', [
|
||||||
'@affine/bookmark-plugin',
|
|
||||||
'@affine/image-preview-plugin',
|
'@affine/image-preview-plugin',
|
||||||
'@affine/outline-plugin',
|
'@affine/outline-plugin',
|
||||||
]);
|
]);
|
||||||
|
|||||||
@@ -15,9 +15,7 @@ export const packageJsonInputSchema = z.object({
|
|||||||
release: z.union([z.boolean(), z.enum(['development'])]),
|
release: z.union([z.boolean(), z.enum(['development'])]),
|
||||||
entry: z.object({
|
entry: z.object({
|
||||||
core: z.string(),
|
core: z.string(),
|
||||||
server: z.string().optional(),
|
|
||||||
}),
|
}),
|
||||||
serverCommand: z.array(z.string()).optional(),
|
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -31,7 +29,6 @@ export const packageJsonOutputSchema = z.object({
|
|||||||
core: z.string(),
|
core: z.string(),
|
||||||
}),
|
}),
|
||||||
assets: z.array(z.string()),
|
assets: z.array(z.string()),
|
||||||
serverCommand: z.array(z.string()).optional(),
|
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -64,9 +64,6 @@ const external = [
|
|||||||
|
|
||||||
// css
|
// css
|
||||||
/^@vanilla-extract/,
|
/^@vanilla-extract/,
|
||||||
|
|
||||||
// remove this when bookmark plugin is ready
|
|
||||||
'link-preview-js',
|
|
||||||
];
|
];
|
||||||
|
|
||||||
const allPluginDir = path.resolve(projectRoot, 'plugins');
|
const allPluginDir = path.resolve(projectRoot, 'plugins');
|
||||||
@@ -103,15 +100,6 @@ const outDir = path.resolve(projectRoot, 'apps', 'core', 'public', 'plugins');
|
|||||||
|
|
||||||
const coreOutDir = path.resolve(outDir, plugin);
|
const coreOutDir = path.resolve(outDir, plugin);
|
||||||
|
|
||||||
const serverOutDir = path.resolve(
|
|
||||||
projectRoot,
|
|
||||||
'apps',
|
|
||||||
'electron',
|
|
||||||
'dist',
|
|
||||||
'plugins',
|
|
||||||
plugin
|
|
||||||
);
|
|
||||||
|
|
||||||
const coreEntry = path.resolve(pluginDir, json.affinePlugin.entry.core);
|
const coreEntry = path.resolve(pluginDir, json.affinePlugin.entry.core);
|
||||||
|
|
||||||
const generatePackageJson: PluginOption = {
|
const generatePackageJson: PluginOption = {
|
||||||
@@ -127,7 +115,6 @@ const generatePackageJson: PluginOption = {
|
|||||||
core: 'index.js',
|
core: 'index.js',
|
||||||
},
|
},
|
||||||
assets: [...metadata.assets],
|
assets: [...metadata.assets],
|
||||||
serverCommand: json.affinePlugin.serverCommand,
|
|
||||||
},
|
},
|
||||||
} satisfies z.infer<typeof packageJsonOutputSchema>;
|
} satisfies z.infer<typeof packageJsonOutputSchema>;
|
||||||
packageJsonOutputSchema.parse(packageJson);
|
packageJsonOutputSchema.parse(packageJson);
|
||||||
@@ -191,25 +178,3 @@ await build({
|
|||||||
generatePackageJson,
|
generatePackageJson,
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
// step 2: generate server bundle
|
|
||||||
if (json.affinePlugin.entry.server) {
|
|
||||||
const serverEntry = path.resolve(pluginDir, json.affinePlugin.entry.server);
|
|
||||||
await build({
|
|
||||||
build: {
|
|
||||||
watch: isWatch ? {} : undefined,
|
|
||||||
minify: false,
|
|
||||||
outDir: serverOutDir,
|
|
||||||
emptyOutDir: true,
|
|
||||||
lib: {
|
|
||||||
entry: serverEntry,
|
|
||||||
fileName: 'index',
|
|
||||||
formats: ['cjs'],
|
|
||||||
},
|
|
||||||
rollupOptions: {
|
|
||||||
external,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
plugins: [generatePackageJson],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
# AFFiNE Bookmark
|
|
||||||
|
|
||||||
> Bookmark plugin
|
|
||||||
|
|
||||||

|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 68 KiB |
@@ -1,30 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "@affine/bookmark-plugin",
|
|
||||||
"type": "module",
|
|
||||||
"version": "0.9.0-canary.13",
|
|
||||||
"description": "Bookmark Plugin",
|
|
||||||
"affinePlugin": {
|
|
||||||
"release": true,
|
|
||||||
"entry": {
|
|
||||||
"core": "./src/index.ts",
|
|
||||||
"server": "./src/server.ts"
|
|
||||||
},
|
|
||||||
"serverCommand": [
|
|
||||||
"com.blocksuite.bookmark-block.get-bookmark-data-by-link"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"scripts": {
|
|
||||||
"dev": "af dev",
|
|
||||||
"build": "af build"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"@affine/component": "workspace:*",
|
|
||||||
"@affine/sdk": "workspace:*",
|
|
||||||
"@blocksuite/icons": "^2.1.33",
|
|
||||||
"foxact": "^0.2.20",
|
|
||||||
"link-preview-js": "^3.0.5"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@affine/plugin-cli": "workspace:*"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "@affine/bookmark-plugin",
|
|
||||||
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
|
||||||
"namedInputs": {
|
|
||||||
"default": [
|
|
||||||
"{projectRoot}/**/*",
|
|
||||||
"{workspaceRoot}/packages/plugin-cli/**/*",
|
|
||||||
"sharedGlobals"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"targets": {
|
|
||||||
"build": {
|
|
||||||
"executor": "nx:run-script",
|
|
||||||
"options": {
|
|
||||||
"script": "build"
|
|
||||||
},
|
|
||||||
"dependsOn": ["^build"],
|
|
||||||
"inputs": ["default"],
|
|
||||||
"outputs": [
|
|
||||||
"{workspaceRoot}/apps/core/public/plugins/bookmark",
|
|
||||||
"{workspaceRoot}/apps/electron/dist/plugins/bookmark"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"tags": ["plugin"]
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
import type { PluginContext } from '@affine/sdk/entry';
|
|
||||||
import { createElement } from 'react';
|
|
||||||
import { createRoot } from 'react-dom/client';
|
|
||||||
|
|
||||||
import { App } from './app';
|
|
||||||
|
|
||||||
export const entry = (context: PluginContext) => {
|
|
||||||
console.log('register');
|
|
||||||
|
|
||||||
context.register('editor', (div, editor) => {
|
|
||||||
const root = createRoot(div);
|
|
||||||
root.render(createElement(App, { page: editor.page }));
|
|
||||||
return () => {
|
|
||||||
root.unmount();
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
console.log('unregister');
|
|
||||||
};
|
|
||||||
};
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
import type { ServerContext } from '@affine/sdk/server';
|
|
||||||
import { getLinkPreview } from 'link-preview-js';
|
|
||||||
|
|
||||||
type MetaData = {
|
|
||||||
title?: string;
|
|
||||||
description?: string;
|
|
||||||
icon?: string;
|
|
||||||
image?: string;
|
|
||||||
[x: string]: string | string[] | undefined;
|
|
||||||
};
|
|
||||||
|
|
||||||
export interface PreviewType {
|
|
||||||
url: string;
|
|
||||||
title: string;
|
|
||||||
siteName: string | undefined;
|
|
||||||
description: string | undefined;
|
|
||||||
mediaType: string;
|
|
||||||
contentType: string | undefined;
|
|
||||||
images: string[];
|
|
||||||
videos: {
|
|
||||||
url: string | undefined;
|
|
||||||
secureUrl: string | null | undefined;
|
|
||||||
type: string | null | undefined;
|
|
||||||
width: string | undefined;
|
|
||||||
height: string | undefined;
|
|
||||||
}[];
|
|
||||||
favicons: string[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export const entry = (context: ServerContext) => {
|
|
||||||
context.registerCommand(
|
|
||||||
'com.blocksuite.bookmark-block.get-bookmark-data-by-link',
|
|
||||||
async (url: string): Promise<MetaData> => {
|
|
||||||
const previewData = (await getLinkPreview(url, {
|
|
||||||
timeout: 6000,
|
|
||||||
headers: {
|
|
||||||
'user-agent': 'googlebot',
|
|
||||||
},
|
|
||||||
followRedirects: 'follow',
|
|
||||||
}).catch(() => {
|
|
||||||
return {
|
|
||||||
title: '',
|
|
||||||
siteName: '',
|
|
||||||
description: '',
|
|
||||||
images: [],
|
|
||||||
videos: [],
|
|
||||||
contentType: `text/html`,
|
|
||||||
favicons: [],
|
|
||||||
};
|
|
||||||
})) as PreviewType;
|
|
||||||
|
|
||||||
return {
|
|
||||||
title: previewData.title,
|
|
||||||
description: previewData.description,
|
|
||||||
icon: previewData.favicons[0],
|
|
||||||
image: previewData.images[0],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
);
|
|
||||||
return () => {
|
|
||||||
context.unregisterCommand(
|
|
||||||
'com.blocksuite.bookmark-block.get-bookmark-data-by-link'
|
|
||||||
);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
{
|
|
||||||
"extends": "../../tsconfig.json",
|
|
||||||
"include": ["./src"],
|
|
||||||
"compilerOptions": {
|
|
||||||
"noEmit": false,
|
|
||||||
"outDir": "lib",
|
|
||||||
"jsx": "preserve"
|
|
||||||
},
|
|
||||||
"references": [
|
|
||||||
{
|
|
||||||
"path": "../../packages/sdk"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "../../packages/component"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -22,7 +22,6 @@ test('plugin should exist', async ({ page }) => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
const plugins = [
|
const plugins = [
|
||||||
'@affine/bookmark-plugin',
|
|
||||||
'@affine/copilot-plugin',
|
'@affine/copilot-plugin',
|
||||||
'@affine/hello-world-plugin',
|
'@affine/hello-world-plugin',
|
||||||
'@affine/image-preview-plugin',
|
'@affine/image-preview-plugin',
|
||||||
|
|||||||
@@ -119,9 +119,6 @@
|
|||||||
{
|
{
|
||||||
"path": "./packages/sdk"
|
"path": "./packages/sdk"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"path": "./plugins/bookmark"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"path": "./plugins/copilot"
|
"path": "./plugins/copilot"
|
||||||
},
|
},
|
||||||
|
|||||||
14
yarn.lock
14
yarn.lock
@@ -146,19 +146,6 @@ __metadata:
|
|||||||
languageName: unknown
|
languageName: unknown
|
||||||
linkType: soft
|
linkType: soft
|
||||||
|
|
||||||
"@affine/bookmark-plugin@workspace:*, @affine/bookmark-plugin@workspace:plugins/bookmark":
|
|
||||||
version: 0.0.0-use.local
|
|
||||||
resolution: "@affine/bookmark-plugin@workspace:plugins/bookmark"
|
|
||||||
dependencies:
|
|
||||||
"@affine/component": "workspace:*"
|
|
||||||
"@affine/plugin-cli": "workspace:*"
|
|
||||||
"@affine/sdk": "workspace:*"
|
|
||||||
"@blocksuite/icons": ^2.1.33
|
|
||||||
foxact: ^0.2.20
|
|
||||||
link-preview-js: ^3.0.5
|
|
||||||
languageName: unknown
|
|
||||||
linkType: soft
|
|
||||||
|
|
||||||
"@affine/cli@workspace:*, @affine/cli@workspace:packages/cli":
|
"@affine/cli@workspace:*, @affine/cli@workspace:packages/cli":
|
||||||
version: 0.0.0-use.local
|
version: 0.0.0-use.local
|
||||||
resolution: "@affine/cli@workspace:packages/cli"
|
resolution: "@affine/cli@workspace:packages/cli"
|
||||||
@@ -368,7 +355,6 @@ __metadata:
|
|||||||
resolution: "@affine/electron@workspace:apps/electron"
|
resolution: "@affine/electron@workspace:apps/electron"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@affine-test/kit": "workspace:*"
|
"@affine-test/kit": "workspace:*"
|
||||||
"@affine/bookmark-plugin": "workspace:*"
|
|
||||||
"@affine/copilot-plugin": "workspace:*"
|
"@affine/copilot-plugin": "workspace:*"
|
||||||
"@affine/env": "workspace:*"
|
"@affine/env": "workspace:*"
|
||||||
"@affine/hello-world-plugin": "workspace:*"
|
"@affine/hello-world-plugin": "workspace:*"
|
||||||
|
|||||||
Reference in New Issue
Block a user