mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-14 21:27:20 +00:00
116 lines
3.7 KiB
TypeScript
116 lines
3.7 KiB
TypeScript
import { AttachmentBlockSchema } from '@blocksuite/affine-model';
|
|
import {
|
|
BlockNotionHtmlAdapterExtension,
|
|
type BlockNotionHtmlAdapterMatcher,
|
|
FetchUtils,
|
|
HastUtils,
|
|
} from '@blocksuite/affine-shared/adapters';
|
|
import { getFilenameFromContentDisposition } from '@blocksuite/affine-shared/utils';
|
|
import { sha } from '@blocksuite/global/utils';
|
|
import { getAssetName, nanoid } from '@blocksuite/store';
|
|
|
|
export const attachmentBlockNotionHtmlAdapterMatcher: BlockNotionHtmlAdapterMatcher =
|
|
{
|
|
flavour: AttachmentBlockSchema.model.flavour,
|
|
toMatch: o => {
|
|
return (
|
|
HastUtils.isElement(o.node) &&
|
|
o.node.tagName === 'figure' &&
|
|
!!HastUtils.querySelector(o.node, '.source')
|
|
);
|
|
},
|
|
fromMatch: () => false,
|
|
toBlockSnapshot: {
|
|
enter: async (o, context) => {
|
|
if (!HastUtils.isElement(o.node)) {
|
|
return;
|
|
}
|
|
const { assets, walkerContext } = context;
|
|
if (!assets) {
|
|
return;
|
|
}
|
|
|
|
const embededFigureWrapper = HastUtils.querySelector(o.node, '.source');
|
|
let embededURL = '';
|
|
if (embededFigureWrapper) {
|
|
const embedA = HastUtils.querySelector(embededFigureWrapper, 'a');
|
|
embededURL =
|
|
typeof embedA?.properties.href === 'string'
|
|
? embedA.properties.href
|
|
: '';
|
|
}
|
|
if (embededURL) {
|
|
let blobId = '';
|
|
let name = '';
|
|
let type = '';
|
|
let size = 0;
|
|
if (!FetchUtils.fetchable(embededURL)) {
|
|
const embededURLSplit = embededURL.split('/');
|
|
while (embededURLSplit.length > 0) {
|
|
const key = assets
|
|
.getPathBlobIdMap()
|
|
.get(decodeURIComponent(embededURLSplit.join('/')));
|
|
if (key) {
|
|
blobId = key;
|
|
break;
|
|
}
|
|
embededURLSplit.shift();
|
|
}
|
|
const value = assets.getAssets().get(blobId);
|
|
if (value) {
|
|
name = getAssetName(assets.getAssets(), blobId);
|
|
size = value.size;
|
|
type = value.type;
|
|
}
|
|
} else {
|
|
const res = await fetch(embededURL).catch(error => {
|
|
console.warn('Error fetching embed:', error);
|
|
return null;
|
|
});
|
|
if (!res) {
|
|
return;
|
|
}
|
|
const resCloned = res.clone();
|
|
name =
|
|
getFilenameFromContentDisposition(
|
|
res.headers.get('Content-Disposition') ?? ''
|
|
) ??
|
|
(embededURL.split('/').at(-1) ?? 'file') +
|
|
'.' +
|
|
(res.headers.get('Content-Type')?.split('/').at(-1) ?? 'blob');
|
|
const file = new File([await res.blob()], name, {
|
|
type: res.headers.get('Content-Type') ?? '',
|
|
});
|
|
size = file.size;
|
|
type = file.type;
|
|
blobId = await sha(await resCloned.arrayBuffer());
|
|
assets?.getAssets().set(blobId, file);
|
|
await assets?.writeToBlob(blobId);
|
|
}
|
|
walkerContext
|
|
.openNode(
|
|
{
|
|
type: 'block',
|
|
id: nanoid(),
|
|
flavour: AttachmentBlockSchema.model.flavour,
|
|
props: {
|
|
name,
|
|
size,
|
|
type,
|
|
sourceId: blobId,
|
|
},
|
|
children: [],
|
|
},
|
|
'children'
|
|
)
|
|
.closeNode();
|
|
walkerContext.skipAllChildren();
|
|
}
|
|
},
|
|
},
|
|
fromBlockSnapshot: {},
|
|
};
|
|
|
|
export const AttachmentBlockNotionHtmlAdapterExtension =
|
|
BlockNotionHtmlAdapterExtension(attachmentBlockNotionHtmlAdapterMatcher);
|