mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-08-01 01:29:31 +08:00
refactor(editor): refactor linkPreviewer as an extension and remove bookmark service (#9754)
[BS-2427](https://linear.app/affine-design/issue/BS-2427/移除-bookmark-block-service) [BS-2418](https://linear.app/affine-design/issue/BS-2418/linkpreviewer-重构成插件)
This commit is contained in:
@@ -7,6 +7,7 @@ export * from './embed-option-service';
|
||||
export * from './feature-flag-service';
|
||||
export * from './font-loader';
|
||||
export * from './generate-url-service';
|
||||
export * from './link-previewer-service';
|
||||
export * from './native-clipboard-service';
|
||||
export * from './notification-service';
|
||||
export * from './open-doc-config';
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
import type { LinkPreviewData } from '@blocksuite/affine-model';
|
||||
import { BlockSuiteError, ErrorCode } from '@blocksuite/global/exceptions';
|
||||
import { StoreExtension } from '@blocksuite/store';
|
||||
|
||||
import { DEFAULT_LINK_PREVIEW_ENDPOINT } from '../consts';
|
||||
import { isAbortError } from '../utils/is-abort-error';
|
||||
|
||||
export type LinkPreviewResponseData = {
|
||||
url: string;
|
||||
title?: string;
|
||||
siteName?: string;
|
||||
description?: string;
|
||||
images?: string[];
|
||||
mediaType?: string;
|
||||
contentType?: string;
|
||||
charset?: string;
|
||||
videos?: string[];
|
||||
favicons?: string[];
|
||||
};
|
||||
|
||||
export class LinkPreviewerService extends StoreExtension {
|
||||
static override key = 'link-previewer';
|
||||
|
||||
private _endpoint = DEFAULT_LINK_PREVIEW_ENDPOINT;
|
||||
|
||||
query = async (
|
||||
url: string,
|
||||
signal?: AbortSignal
|
||||
): Promise<Partial<LinkPreviewData>> => {
|
||||
if (
|
||||
(url.startsWith('https://x.com/') ||
|
||||
url.startsWith('https://www.x.com/') ||
|
||||
url.startsWith('https://www.twitter.com/') ||
|
||||
url.startsWith('https://twitter.com/')) &&
|
||||
url.includes('/status/')
|
||||
) {
|
||||
// use api.fxtwitter.com
|
||||
url =
|
||||
'https://api.fxtwitter.com/status/' + /\/status\/(.*)/.exec(url)?.[1];
|
||||
try {
|
||||
const { tweet } = await fetch(url, { signal }).then(res => res.json());
|
||||
return {
|
||||
title: tweet.author.name,
|
||||
icon: tweet.author.avatar_url,
|
||||
description: tweet.text,
|
||||
image: tweet.media?.photos?.[0].url || tweet.author.banner_url,
|
||||
};
|
||||
} catch (e) {
|
||||
console.error(`Failed to fetch tweet: ${url}`);
|
||||
console.error(e);
|
||||
return {};
|
||||
}
|
||||
} else {
|
||||
const response = await fetch(this._endpoint, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
url,
|
||||
}),
|
||||
signal,
|
||||
})
|
||||
.then(r => {
|
||||
if (!r || !r.ok) {
|
||||
throw new BlockSuiteError(
|
||||
ErrorCode.DefaultRuntimeError,
|
||||
`Failed to fetch link preview: ${url}`
|
||||
);
|
||||
}
|
||||
return r;
|
||||
})
|
||||
.catch(err => {
|
||||
if (isAbortError(err)) return null;
|
||||
console.error(`Failed to fetch link preview: ${url}`);
|
||||
console.error(err);
|
||||
return null;
|
||||
});
|
||||
|
||||
if (!response) return {};
|
||||
|
||||
const data: LinkPreviewResponseData = await response.json();
|
||||
return {
|
||||
title: data.title ?? null,
|
||||
description: data.description ?? null,
|
||||
icon: data.favicons?.[0],
|
||||
image: data.images?.[0],
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
get endpoint() {
|
||||
return this._endpoint;
|
||||
}
|
||||
|
||||
setEndpoint = (endpoint: string) => {
|
||||
this._endpoint = endpoint;
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user