feat(editor): improve status display in attachment embed view (#12180)

Closes: [BS-3438](https://linear.app/affine-design/issue/BS-3438/attachment-embed-view-中的-status-组件)
Closes: [BS-3447](https://linear.app/affine-design/issue/BS-3447/触发-litportal-re-render)

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

- **New Features**
  - Introduced a visual status indicator for embedded attachments with reload capability.
  - Added a new resource status component to display error messages and reload actions.
- **Improvements**
  - Enhanced attachment rendering flow with reactive state and unified embed handling.
  - Simplified resource state and blob URL lifecycle management.
  - Added status visibility flags for PDF and video embeds.
- **Bug Fixes**
  - Improved error handling and refresh support for embedded content including PDFs, videos, and audio.
- **Style**
  - Added styles for the attachment embed status indicator positioning.
- **Refactor**
  - Streamlined attachment and resource controller implementations for better maintainability.
- **Tests**
  - Added end-to-end test verifying PDF viewer reload and re-rendering in embed mode.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
fundon
2025-05-10 08:34:47 +00:00
parent 66500669c8
commit b3f0f38b41
11 changed files with 567 additions and 281 deletions

View File

@@ -13,6 +13,7 @@ export function patchForPDFEmbedView(reactToLit: ReactToLit): ExtensionType {
setup: di => {
di.override(AttachmentEmbedConfigIdentifier('pdf'), () => ({
name: 'pdf',
shouldShowStatus: true,
check: (model, maxFileSize) =>
model.props.type === 'application/pdf' &&
model.props.size <= maxFileSize,
@@ -26,8 +27,8 @@ export function patchForPDFEmbedView(reactToLit: ReactToLit): ExtensionType {
xywh: bound.serialize(),
});
},
template: (model, _blobUrl) =>
reactToLit(<AttachmentEmbedPreview model={model} />, false),
render: (model, _) =>
reactToLit(<AttachmentEmbedPreview model={model} />, true),
}));
},
};
@@ -41,7 +42,7 @@ export function patchForAudioEmbedView(reactToLit: ReactToLit): ExtensionType {
check: (model, maxFileSize) =>
model.props.type.startsWith('audio/') &&
model.props.size <= maxFileSize,
template: (model, _blobUrl) =>
render: (model, _) =>
reactToLit(<AttachmentEmbedPreview model={model} />, false),
}));
},