import { html, type TemplateResult } from 'lit'; import type { AttachmentBlockModel } from './attachment-model.js'; import { turnIntoImage } from './utils.js'; type EmbedConfig = { name: string; /** * Check if the attachment can be turned into embed view. */ check: (model: AttachmentBlockModel) => boolean; /** * The action will be executed when the 「Turn into embed view」 button is clicked. */ action?: (model: AttachmentBlockModel) => Promise | void; /** * The template will be used to render the embed view. */ template?: ( model: AttachmentBlockModel, blobUrl: string ) => TemplateResult<1>; }; // 10MB const MAX_EMBED_SIZE = 10 * 1024 * 1024; const embedConfig: EmbedConfig[] = [ { name: 'image', check: model => model.page.schema.flavourSchemaMap.has('affine:image') && model.type.startsWith('image/'), action: model => turnIntoImage(model), }, { name: 'pdf', check: model => model.type === 'application/pdf' && model.size <= MAX_EMBED_SIZE, template: (_, blobUrl) => { // More options: https://tinytip.co/tips/html-pdf-params/ // https://chromium.googlesource.com/chromium/src/+/refs/tags/121.0.6153.1/chrome/browser/resources/pdf/open_pdf_params_parser.ts const parameters = '#toolbar=0'; return html``; }, }, { name: 'video', check: model => model.type.startsWith('video/') && model.size <= MAX_EMBED_SIZE, template: (_, blobUrl) => html``, }, { name: 'audio', check: model => model.type.startsWith('audio/') && model.size <= MAX_EMBED_SIZE, template: (_, blobUrl) => html``, }, ]; export function allowEmbed(model: AttachmentBlockModel) { return embedConfig.some(config => config.check(model)); } export function turnIntoEmbedAction(model: AttachmentBlockModel) { const config = embedConfig.find(config => config.check(model)); if (!config || !config.action) { model.page.updateBlock>(model, { embed: true, }); return; } config.action(model)?.catch(console.error); } export function renderEmbedView(model: AttachmentBlockModel, blobUrl: string) { const config = embedConfig.find(config => config.check(model)); if (!config || !config.template) { console.error('No embed view template found!', model, embedConfig); return null; } return config.template(model, blobUrl); }