feat: support pdf zoom in mobile (#990)
Reviewed-on: daoyoucloud/tachybase#990
This commit is contained in:
parent
04a6f3f09a
commit
d0bb8038ab
@ -36,6 +36,7 @@
|
||||
"react-pdf": "^7.5.1",
|
||||
"react-router-dom": "^6.11.2",
|
||||
"react-transition-group": "^4.4.5",
|
||||
"react-zoom-pan-pinch": "^3.4.4",
|
||||
"redis": "^4.6.11",
|
||||
"signature_pad": "4.1.7",
|
||||
"throttle-debounce": "^5.0.0",
|
||||
|
@ -1,13 +1,14 @@
|
||||
import React, { forwardRef, useEffect, useImperativeHandle, useState } from 'react';
|
||||
import { Spin } from 'antd';
|
||||
import { Spin, Tag } from 'antd';
|
||||
import { LoadingOutlined } from '@ant-design/icons';
|
||||
import { Document, Page, pdfjs } from 'react-pdf';
|
||||
import { saveAs } from 'file-saver';
|
||||
import 'react-pdf/dist/Page/AnnotationLayer.css';
|
||||
import 'react-pdf/dist/Page/TextLayer.css';
|
||||
import { uid } from '@tachybase/schema';
|
||||
import { useRequest } from '@tachybase/client';
|
||||
import { css, useRequest } from '@tachybase/client';
|
||||
import { useTranslation } from '../locale';
|
||||
import { TransformWrapper, TransformComponent } from 'react-zoom-pan-pinch';
|
||||
|
||||
const options = {
|
||||
cMapUrl: '/cmaps/',
|
||||
@ -79,28 +80,48 @@ export const PDFViewer = forwardRef<PDFViewerRef, PDFViewerProps>((props, ref) =
|
||||
|
||||
return (
|
||||
<LoadingSpin spinning={loading}>
|
||||
<Document
|
||||
options={options}
|
||||
file={data as ArrayBuffer}
|
||||
loading={() => (
|
||||
<LoadingSpin spinning={true}>
|
||||
<div style={{ height: '100vh' }}></div>
|
||||
</LoadingSpin>
|
||||
)}
|
||||
onLoadSuccess={async (doc) => {
|
||||
setNumPages(doc.numPages);
|
||||
}}
|
||||
noData={<div style={{ height: '100vh' }}></div>}
|
||||
error={<div>{t('error')}</div>}
|
||||
<TransformWrapper
|
||||
wheel={{ disabled: true }}
|
||||
doubleClick={{ disabled: true }}
|
||||
panning={{ allowLeftClickPan: false }}
|
||||
>
|
||||
{Array.from(new Array(numPages), (el, index) => (
|
||||
<Page key={`page_${index + 1}`} pageNumber={index + 1} width={width}>
|
||||
<p style={{ marginLeft: '92%', marginBottom: '30pt', fontSize: '14px', fontFamily: 'source-han-sans' }}>
|
||||
{index + 1}/{numPages}页
|
||||
</p>
|
||||
</Page>
|
||||
))}
|
||||
</Document>
|
||||
<TransformComponent>
|
||||
<Document
|
||||
options={options}
|
||||
file={data as ArrayBuffer}
|
||||
loading={() => (
|
||||
<LoadingSpin spinning={true}>
|
||||
<div style={{ height: '100vh' }}></div>
|
||||
</LoadingSpin>
|
||||
)}
|
||||
onLoadSuccess={async (doc) => {
|
||||
setNumPages(doc.numPages);
|
||||
}}
|
||||
noData={<div style={{ height: '100vh' }}></div>}
|
||||
error={<div>{t('error')}</div>}
|
||||
>
|
||||
{Array.from(new Array(numPages), (el, index) => (
|
||||
<Page key={`page_${index + 1}`} pageNumber={index + 1} width={width}>
|
||||
<div
|
||||
className={css`
|
||||
text-align: center;
|
||||
border-bottom: 1px dashed;
|
||||
`}
|
||||
>
|
||||
<Tag
|
||||
className={css`
|
||||
margin-bottom: 2px;
|
||||
`}
|
||||
bordered={false}
|
||||
>
|
||||
第 {index + 1}/{numPages} 页
|
||||
</Tag>
|
||||
</div>
|
||||
</Page>
|
||||
))}
|
||||
</Document>
|
||||
</TransformComponent>
|
||||
</TransformWrapper>
|
||||
</LoadingSpin>
|
||||
);
|
||||
});
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import { Plugin, EditTitleField } from '@tachybase/client';
|
||||
import { Plugin, EditTitleField, CollectionProvider, CollectionRecordProvider } from '@tachybase/client';
|
||||
import { useFieldSchema } from '@tachybase/schema';
|
||||
import { isValid } from '@tachybase/schema';
|
||||
import { autorun } from '@tachybase/schema';
|
||||
|
@ -3,6 +3,7 @@ import { PDFViewer } from '../../components/PDFViewer';
|
||||
import { Space } from 'antd';
|
||||
import { css } from '@tachybase/client';
|
||||
import { usePDFViewerRef } from '../../schema-initializer/blocks/PDFVIewerBlockInitializer';
|
||||
import { debounce } from 'lodash';
|
||||
|
||||
export const InternalPDFViewer = (props) => {
|
||||
const { usePdfPath: useMaybePdfPath } = props;
|
||||
@ -10,10 +11,19 @@ export const InternalPDFViewer = (props) => {
|
||||
const [width, setWidth] = useState(0);
|
||||
const [, setHeight] = useState(0);
|
||||
useEffect(() => {
|
||||
if (containerRef.current) {
|
||||
const updateUI = debounce(() => {
|
||||
setWidth(containerRef.current.offsetWidth);
|
||||
setHeight(containerRef.current.offsetHeight);
|
||||
}, 200);
|
||||
const observer = new ResizeObserver(() => {
|
||||
updateUI();
|
||||
});
|
||||
if (containerRef.current) {
|
||||
observer.observe(containerRef.current);
|
||||
}
|
||||
return () => {
|
||||
observer.disconnect();
|
||||
};
|
||||
}, [containerRef]);
|
||||
const ref = usePDFViewerRef();
|
||||
const usePdfPath = useMaybePdfPath ?? (() => '');
|
||||
|
@ -1610,6 +1610,9 @@ importers:
|
||||
react-transition-group:
|
||||
specifier: ^4.4.5
|
||||
version: 4.4.5(react-dom@18.2.0)(react@18.2.0)
|
||||
react-zoom-pan-pinch:
|
||||
specifier: ^3.4.4
|
||||
version: 3.4.4(react-dom@18.2.0)(react@18.2.0)
|
||||
redis:
|
||||
specifier: ^4.6.11
|
||||
version: 4.6.13
|
||||
@ -26700,6 +26703,17 @@ packages:
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
dev: true
|
||||
|
||||
/react-zoom-pan-pinch@3.4.4(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-lGTu7D9lQpYEQ6sH+NSlLA7gicgKRW8j+D/4HO1AbSV2POvKRFzdWQ8eI0r3xmOsl4dYQcY+teV6MhULeg1xBw==}
|
||||
engines: {node: '>=8', npm: '>=5'}
|
||||
peerDependencies:
|
||||
react: '*'
|
||||
react-dom: '*'
|
||||
dependencies:
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
dev: true
|
||||
|
||||
/react@18.1.0:
|
||||
resolution: {integrity: sha512-4oL8ivCz5ZEPyclFQXaNksK3adutVS8l2xzZU0cqEFrE9Sb7fC0EFK5uEk74wIreL1DERyjvsU915j1pcT2uEQ==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
Loading…
Reference in New Issue
Block a user