mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-14 21:27:20 +00:00
feat(core): pdf preview (#8569)
Co-authored-by: forehalo <forehalo@gmail.com>
This commit is contained in:
@@ -0,0 +1,10 @@
|
||||
import { style } from '@vanilla-extract/css';
|
||||
|
||||
export const attachmentSkeletonStyle = style({
|
||||
margin: '20px',
|
||||
});
|
||||
|
||||
export const attachmentSkeletonItemStyle = style({
|
||||
marginTop: '20px',
|
||||
marginBottom: '20px',
|
||||
});
|
||||
@@ -0,0 +1,122 @@
|
||||
import { Skeleton } from '@affine/component';
|
||||
import { type AttachmentBlockModel } from '@blocksuite/affine/blocks';
|
||||
import {
|
||||
type Doc,
|
||||
DocsService,
|
||||
FrameworkScope,
|
||||
useLiveData,
|
||||
useService,
|
||||
} from '@toeverything/infra';
|
||||
import { type ReactElement, useLayoutEffect, useState } from 'react';
|
||||
import { useParams } from 'react-router-dom';
|
||||
|
||||
import { AttachmentViewerView } from '../../../../components/attachment-viewer';
|
||||
import { ViewIcon, ViewTitle } from '../../../../modules/workbench';
|
||||
import { PageNotFound } from '../../404';
|
||||
import * as styles from './index.css';
|
||||
|
||||
type AttachmentPageProps = {
|
||||
pageId: string;
|
||||
attachmentId: string;
|
||||
};
|
||||
|
||||
const useLoadAttachment = (pageId: string, attachmentId: string) => {
|
||||
const docsService = useService(DocsService);
|
||||
const docRecord = useLiveData(docsService.list.doc$(pageId));
|
||||
const [doc, setDoc] = useState<Doc | null>(null);
|
||||
const [model, setModel] = useState<AttachmentBlockModel | null>(null);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
if (!docRecord) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { doc, release } = docsService.open(pageId);
|
||||
|
||||
setDoc(doc);
|
||||
|
||||
if (!doc.blockSuiteDoc.ready) {
|
||||
doc.blockSuiteDoc.load();
|
||||
}
|
||||
doc.setPriorityLoad(10);
|
||||
|
||||
doc
|
||||
.waitForSyncReady()
|
||||
.then(() => {
|
||||
const block = doc.blockSuiteDoc.getBlock(attachmentId);
|
||||
if (block) {
|
||||
setModel(block.model as AttachmentBlockModel);
|
||||
}
|
||||
})
|
||||
.catch(console.error);
|
||||
|
||||
return () => {
|
||||
release();
|
||||
};
|
||||
}, [docRecord, docsService, pageId, attachmentId]);
|
||||
|
||||
return { doc, model };
|
||||
};
|
||||
|
||||
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.name} />
|
||||
<ViewIcon icon={model.type.endsWith('pdf') ? 'pdf' : 'attachment'} />
|
||||
<AttachmentViewerView model={model} />
|
||||
</FrameworkScope>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={styles.attachmentSkeletonStyle}>
|
||||
<Skeleton
|
||||
className={styles.attachmentSkeletonItemStyle}
|
||||
animation="wave"
|
||||
height={30}
|
||||
/>
|
||||
<Skeleton
|
||||
className={styles.attachmentSkeletonItemStyle}
|
||||
animation="wave"
|
||||
height={30}
|
||||
width="80%"
|
||||
/>
|
||||
<Skeleton
|
||||
className={styles.attachmentSkeletonItemStyle}
|
||||
animation="wave"
|
||||
height={30}
|
||||
/>
|
||||
<Skeleton
|
||||
className={styles.attachmentSkeletonItemStyle}
|
||||
animation="wave"
|
||||
height={30}
|
||||
width="70%"
|
||||
/>
|
||||
<Skeleton
|
||||
className={styles.attachmentSkeletonItemStyle}
|
||||
animation="wave"
|
||||
height={30}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export const Component = () => {
|
||||
const { pageId, attachmentId } = useParams();
|
||||
|
||||
if (!pageId || !attachmentId) {
|
||||
return <PageNotFound noPermission />;
|
||||
}
|
||||
|
||||
return <AttachmentPage pageId={pageId} attachmentId={attachmentId} />;
|
||||
};
|
||||
@@ -29,6 +29,10 @@ export const workbenchRoutes = [
|
||||
path: '/:pageId',
|
||||
lazy: () => import('./pages/workspace/detail-page/detail-page'),
|
||||
},
|
||||
{
|
||||
path: '/:pageId/attachments/:attachmentId',
|
||||
lazy: () => import('./pages/workspace/attachment/index'),
|
||||
},
|
||||
{
|
||||
path: '*',
|
||||
lazy: () => import('./pages/404'),
|
||||
|
||||
Reference in New Issue
Block a user