mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-15 05:37:32 +00:00
feat(core): add status to pdf viewer (#12349)
Closes: [BS-3439](https://linear.app/affine-design/issue/BS-3439/pdf-独立页面split-view-中的-status-组件) Related to: [BS-3143](https://linear.app/affine-design/issue/BS-3143/更新-loading-和错误样式) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Added a dedicated error handling and reload interface for PDF attachments, allowing users to retry loading PDFs when errors occur. - **Refactor** - Improved PDF viewer interface with clearer loading and error states. - Enhanced attachment type detection for better performance and maintainability. - Streamlined attachment preview logic for more direct and efficient model retrieval. - Simplified internal PDF metadata handling and control flow for improved clarity. - Clarified conditional rendering logic in attachment viewer components. - Introduced explicit loading state management and refined rendering logic in attachment pages. - **Style** - Updated and added styles for PDF viewer controls and error status display. - **Tests** - Added end-to-end tests validating PDF preview error handling and attachment not-found scenarios. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
@@ -16,6 +16,7 @@ type AttachmentPageProps = {
|
||||
};
|
||||
|
||||
const useLoadAttachment = (pageId: string, attachmentId: string) => {
|
||||
const [loading, setLoading] = useState(true);
|
||||
const docsService = useService(DocsService);
|
||||
const docRecord = useLiveData(docsService.list.doc$(pageId));
|
||||
const [doc, setDoc] = useState<Doc | null>(null);
|
||||
@@ -23,6 +24,7 @@ const useLoadAttachment = (pageId: string, attachmentId: string) => {
|
||||
|
||||
useLayoutEffect(() => {
|
||||
if (!docRecord) {
|
||||
setLoading(false);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -38,44 +40,23 @@ const useLoadAttachment = (pageId: string, attachmentId: string) => {
|
||||
doc
|
||||
.waitForSyncReady()
|
||||
.then(() => {
|
||||
const block = doc.blockSuiteDoc.getBlock(attachmentId);
|
||||
if (block) {
|
||||
setModel(block.model as AttachmentBlockModel);
|
||||
}
|
||||
const model =
|
||||
doc.blockSuiteDoc.getModelById<AttachmentBlockModel>(attachmentId);
|
||||
setModel(model);
|
||||
})
|
||||
.catch(console.error);
|
||||
.catch(console.error)
|
||||
.finally(() => setLoading(false));
|
||||
|
||||
return () => {
|
||||
release();
|
||||
dispose();
|
||||
};
|
||||
}, [docRecord, docsService, pageId, attachmentId]);
|
||||
}, [docRecord, docsService, pageId, attachmentId, setLoading]);
|
||||
|
||||
return { doc, model };
|
||||
return { doc, model, loading };
|
||||
};
|
||||
|
||||
export const AttachmentPage = ({
|
||||
pageId,
|
||||
attachmentId,
|
||||
}: AttachmentPageProps): ReactElement => {
|
||||
const { doc, model } = useLoadAttachment(pageId, attachmentId);
|
||||
|
||||
if (!doc) {
|
||||
return <PageNotFound noPermission={false} />;
|
||||
}
|
||||
|
||||
if (doc && model) {
|
||||
return (
|
||||
<FrameworkScope scope={doc.scope}>
|
||||
<ViewTitle title={model.props.name} />
|
||||
<ViewIcon
|
||||
icon={model.props.type.endsWith('pdf') ? 'pdf' : 'attachment'}
|
||||
/>
|
||||
<AttachmentViewerView model={model} />
|
||||
</FrameworkScope>
|
||||
);
|
||||
}
|
||||
|
||||
const Loading = () => {
|
||||
return (
|
||||
<div className={styles.attachmentSkeletonStyle}>
|
||||
<Skeleton
|
||||
@@ -109,12 +90,37 @@ export const AttachmentPage = ({
|
||||
);
|
||||
};
|
||||
|
||||
export const AttachmentPage = ({
|
||||
pageId,
|
||||
attachmentId,
|
||||
}: AttachmentPageProps): ReactElement => {
|
||||
const { doc, model, loading } = useLoadAttachment(pageId, attachmentId);
|
||||
|
||||
if (loading) {
|
||||
return <Loading />;
|
||||
}
|
||||
|
||||
if (doc && model) {
|
||||
return (
|
||||
<FrameworkScope scope={doc.scope}>
|
||||
<ViewTitle title={model.props.name} />
|
||||
<ViewIcon
|
||||
icon={model.props.type.endsWith('pdf') ? 'pdf' : 'attachment'}
|
||||
/>
|
||||
<AttachmentViewerView model={model} />
|
||||
</FrameworkScope>
|
||||
);
|
||||
}
|
||||
|
||||
return <PageNotFound noPermission={false} />;
|
||||
};
|
||||
|
||||
export const Component = () => {
|
||||
const { pageId, attachmentId } = useParams();
|
||||
|
||||
if (!pageId || !attachmentId) {
|
||||
return <PageNotFound noPermission />;
|
||||
if (pageId && attachmentId) {
|
||||
return <AttachmentPage pageId={pageId} attachmentId={attachmentId} />;
|
||||
}
|
||||
|
||||
return <AttachmentPage pageId={pageId} attachmentId={attachmentId} />;
|
||||
return <PageNotFound noPermission />;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user