Files
AFFiNE-Mirror/blocksuite/affine/model/src/blocks/attachment/attachment-model.ts
T
donteatfriedrice 83670ab335 feat(editor): add experimental feature citation (#11984)
Closes: [BS-3122](https://linear.app/affine-design/issue/BS-3122/footnote-definition-adapter-适配)
Closes: [BS-3123](https://linear.app/affine-design/issue/BS-3123/几个-block-card-view-适配-footnote-态)

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
  - Introduced a new citation card component and web element for displaying citations.
  - Added support for citation-style rendering in attachment, bookmark, and linked document blocks.
  - Enabled citation parsing from footnote definitions in markdown for attachments, bookmarks, and linked docs.
  - Added a feature flag to enable or disable citation features.
  - Provided new toolbar logic to disable downloads for citation-style attachments.

- **Improvements**
  - Updated block models and properties to support citation identifiers.
  - Added localization and settings for the citation experimental feature.
  - Enhanced markdown adapters to recognize and process citation footnotes.
  - Included new constants and styles for citation card display.

- **Bug Fixes**
  - Ensured readonly state is respected in block interactions and rendering for citation blocks.

- **Documentation**
  - Added exports and effects for new citation components and features.

- **Tests**
  - Updated snapshots to include citation-related properties in block data.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-04-29 06:59:27 +00:00

109 lines
2.9 KiB
TypeScript

import type {
GfxCommonBlockProps,
GfxElementGeometry,
} from '@blocksuite/std/gfx';
import { GfxCompatible } from '@blocksuite/std/gfx';
import {
BlockModel,
BlockSchemaExtension,
defineBlockSchema,
} from '@blocksuite/store';
import type { BlockMeta, EmbedCardStyle } from '../../utils/index.js';
import { AttachmentBlockTransformer } from './attachment-transformer.js';
/**
* When the attachment is uploading, the `sourceId` is `undefined`.
* And we can query the upload status by the `isAttachmentLoading` function.
*
* Other collaborators will see an error attachment block when the blob has not finished uploading.
* This issue can be resolve by sync the upload status through the awareness system in the future.
*
* When the attachment is uploaded, the `sourceId` is the id of the blob.
*
* If there are no `sourceId` and the `isAttachmentLoading` function returns `false`,
* it means that the attachment is failed to upload.
*/
/**
* @deprecated
*/
type BackwardCompatibleUndefined = undefined;
export const AttachmentBlockStyles: EmbedCardStyle[] = [
'cubeThick',
'horizontalThin',
'pdf',
] as const;
export type AttachmentBlockProps = {
name: string;
size: number;
/**
* MIME type
*/
type: string;
caption?: string;
// `loadingKey` was used to indicate whether the attachment is loading,
// which is currently unused but no breaking change is needed.
// The `loadingKey` and `sourceId` should not be existed at the same time.
// loadingKey?: string | null;
sourceId?: string;
/**
* Whether to show the attachment as an embed view.
*/
embed: boolean | BackwardCompatibleUndefined;
style?: (typeof AttachmentBlockStyles)[number];
footnoteIdentifier: string | null;
} & Omit<GfxCommonBlockProps, 'scale'> &
BlockMeta;
export const defaultAttachmentProps: AttachmentBlockProps = {
name: '',
size: 0,
type: 'application/octet-stream',
sourceId: undefined,
caption: undefined,
embed: false,
style: AttachmentBlockStyles[1],
index: 'a0',
xywh: '[0,0,0,0]',
lockedBySelf: false,
rotate: 0,
'meta:createdAt': undefined,
'meta:updatedAt': undefined,
'meta:createdBy': undefined,
'meta:updatedBy': undefined,
footnoteIdentifier: null,
};
export const AttachmentBlockSchema = defineBlockSchema({
flavour: 'affine:attachment',
props: (): AttachmentBlockProps => defaultAttachmentProps,
metadata: {
version: 1,
role: 'content',
parent: [
'affine:note',
'affine:surface',
'affine:edgeless-text',
'affine:paragraph',
'affine:list',
],
children: ['@attachment-viewer'],
},
transformer: transformerConfigs =>
new AttachmentBlockTransformer(transformerConfigs),
toModel: () => new AttachmentBlockModel(),
});
export const AttachmentBlockSchemaExtension = BlockSchemaExtension(
AttachmentBlockSchema
);
export class AttachmentBlockModel
extends GfxCompatible<AttachmentBlockProps>(BlockModel)
implements GfxElementGeometry {}