diff --git a/packages/frontend/core/src/components/attachment-viewer/pdf-viewer.tsx b/packages/frontend/core/src/components/attachment-viewer/pdf-viewer.tsx index a60926c7f6..4de7630160 100644 --- a/packages/frontend/core/src/components/attachment-viewer/pdf-viewer.tsx +++ b/packages/frontend/core/src/components/attachment-viewer/pdf-viewer.tsx @@ -15,13 +15,18 @@ import { type PDFVirtuosoContext, type PDFVirtuosoProps, Scroller, + ScrollSeekPlaceholder, } from '@affine/core/modules/pdf/views'; import type { AttachmentBlockModel } from '@blocksuite/affine/blocks'; import { CollapseIcon, ExpandIcon } from '@blocksuite/icons/rc'; import { useLiveData, useService } from '@toeverything/infra'; import clsx from 'clsx'; import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; -import { Virtuoso, type VirtuosoHandle } from 'react-virtuoso'; +import { + type ScrollSeekConfiguration, + Virtuoso, + type VirtuosoHandle, +} from 'react-virtuoso'; import * as styles from './styles.css'; import { calculatePageNum } from './utils'; @@ -112,6 +117,13 @@ const PDFViewerInner = ({ pdf, state }: PDFViewerInnerProps) => { }; }, [state, viewportInfo, onPageSelect]); + const scrollSeekConfig = useMemo(() => { + return { + enter: velocity => Math.abs(velocity) > 1024, + exit: velocity => Math.abs(velocity) < 10, + }; + }, []); + useEffect(() => { const viewer = viewerRef.current; if (!viewer) return; @@ -142,12 +154,14 @@ const PDFViewerInner = ({ pdf, state }: PDFViewerInnerProps) => { Scroller, Header: ListPadding, Footer: ListPadding, + ScrollSeekPlaceholder, }} context={{ width: state.meta.width, height: state.meta.height, pageClassName: styles.pdfPage, }} + scrollSeekConfiguration={scrollSeekConfig} />
@@ -159,9 +173,11 @@ const PDFViewerInner = ({ pdf, state }: PDFViewerInnerProps) => { itemContent={pageContent} components={{ Item, - Scroller, List: ListWithSmallGap, + Scroller, + ScrollSeekPlaceholder, }} + scrollSeekConfiguration={scrollSeekConfig} style={thumbnailsConfig.style} context={thumbnailsConfig.context} /> diff --git a/packages/frontend/core/src/components/attachment-viewer/styles.css.ts b/packages/frontend/core/src/components/attachment-viewer/styles.css.ts index 65525db4af..b1abeaa6c0 100644 --- a/packages/frontend/core/src/components/attachment-viewer/styles.css.ts +++ b/packages/frontend/core/src/components/attachment-viewer/styles.css.ts @@ -84,7 +84,7 @@ export const viewer = style({ display: 'flex', flex: 1, overflow: 'hidden', - resize: 'both', + resize: 'none', selectors: { '&:before': { position: 'absolute', diff --git a/packages/frontend/core/src/modules/pdf/views/components.tsx b/packages/frontend/core/src/modules/pdf/views/components.tsx index abffd86fdc..05c5fa87f6 100644 --- a/packages/frontend/core/src/modules/pdf/views/components.tsx +++ b/packages/frontend/core/src/modules/pdf/views/components.tsx @@ -1,7 +1,7 @@ import { Scrollable } from '@affine/component'; import clsx from 'clsx'; import { type CSSProperties, forwardRef, memo } from 'react'; -import type { VirtuosoProps } from 'react-virtuoso'; +import type { ScrollSeekPlaceholderProps, VirtuosoProps } from 'react-virtuoso'; import * as styles from './styles.css'; @@ -27,6 +27,26 @@ export const Scroller = forwardRef( Scroller.displayName = 'pdf-virtuoso-scroller'; +export const ScrollSeekPlaceholder = forwardRef< + HTMLDivElement, + ScrollSeekPlaceholderProps & { + context?: PDFVirtuosoContext; + } +>(({ context }, ref) => { + const className = context?.pageClassName; + const width = context?.width ?? 537; + const height = context?.height ?? 759; + const style = { width, aspectRatio: `${width} / ${height}` }; + + return ( +
+ +
+ ); +}); + +ScrollSeekPlaceholder.displayName = 'pdf-virtuoso-scroll-seek-placeholder'; + export const List = forwardRef( ({ context: _, className, ...props }, ref) => { return ( @@ -63,123 +83,33 @@ export const ListPadding = () => (
); -export const LoadingSvg = memo(function LoadingSvg({ - style, - className, -}: { - style?: CSSProperties; - className?: string; -}) { - return ( - - - { + return ( + - - - - - - - - - - - - ); -}); + > + + + + + + + + + + + + + ); + } +); + +LoadingSvg.displayName = 'pdf-loading'; diff --git a/packages/frontend/core/src/modules/pdf/views/index.ts b/packages/frontend/core/src/modules/pdf/views/index.ts index 09e3135cad..7314709cc2 100644 --- a/packages/frontend/core/src/modules/pdf/views/index.ts +++ b/packages/frontend/core/src/modules/pdf/views/index.ts @@ -7,5 +7,6 @@ export { type PDFVirtuosoContext, type PDFVirtuosoProps, Scroller, + ScrollSeekPlaceholder, } from './components'; export { PDFPageRenderer } from './page-renderer'; diff --git a/packages/frontend/core/src/modules/pdf/views/styles.css.ts b/packages/frontend/core/src/modules/pdf/views/styles.css.ts index 7ded9648ad..0b45c32164 100644 --- a/packages/frontend/core/src/modules/pdf/views/styles.css.ts +++ b/packages/frontend/core/src/modules/pdf/views/styles.css.ts @@ -58,6 +58,7 @@ export const pdfPageCanvas = style({ export const pdfLoading = style({ display: 'flex', alignSelf: 'center', + margin: 'auto', width: '100%', height: '100%', maxWidth: '537px',