feat: add image viewer support

This commit is contained in:
fantasticit 2022-03-27 14:18:19 +08:00
parent 60a330cdfa
commit 8949af5715
7 changed files with 44 additions and 0 deletions

View File

@ -80,6 +80,7 @@
"scroll-into-view-if-needed": "^2.2.29", "scroll-into-view-if-needed": "^2.2.29",
"swr": "^1.2.0", "swr": "^1.2.0",
"tippy.js": "^6.3.7", "tippy.js": "^6.3.7",
"viewerjs": "^1.10.4",
"y-indexeddb": "^9.0.7", "y-indexeddb": "^9.0.7",
"y-prosemirror": "^1.0.14", "y-prosemirror": "^1.0.14",
"yjs": "^13.5.24" "yjs": "^13.5.24"

View File

@ -12,6 +12,7 @@ import {
destoryProvider, destoryProvider,
} from 'components/tiptap'; } from 'components/tiptap';
import { DataRender } from 'components/data-render'; import { DataRender } from 'components/data-render';
import { ImageViewer } from 'components/image-viewer';
import { joinUser } from 'components/document/collaboration'; import { joinUser } from 'components/document/collaboration';
import { CreateUser } from './user'; import { CreateUser } from './user';
import styles from './index.module.scss'; import styles from './index.module.scss';
@ -72,6 +73,7 @@ export const Editor: React.FC<IProps> = ({ user, documentId, document }) => {
<> <>
<Content className={styles.editorWrap}> <Content className={styles.editorWrap}>
<div id="js-reader-container"> <div id="js-reader-container">
<ImageViewer containerSelector="#js-reader-container" />
<EditorContent editor={editor} /> <EditorContent editor={editor} />
</div> </div>
<CreateUser <CreateUser

View File

@ -8,6 +8,7 @@ import { DataRender } from 'components/data-render';
import { DocumentStyle } from 'components/document/style'; import { DocumentStyle } from 'components/document/style';
import { User } from 'components/user'; import { User } from 'components/user';
import { Theme } from 'components/theme'; import { Theme } from 'components/theme';
import { ImageViewer } from 'components/image-viewer';
import { useDocumentStyle } from 'hooks/useDocumentStyle'; import { useDocumentStyle } from 'hooks/useDocumentStyle';
import { useWindowSize } from 'hooks/useWindowSize'; import { useWindowSize } from 'hooks/useWindowSize';
import { usePublicDocument } from 'data/document'; import { usePublicDocument } from 'data/document';
@ -120,6 +121,7 @@ export const DocumentPublicReader: React.FC<IProps> = ({ documentId, hideLogo =
createUserContainerSelector="#js-share-document-editor-container .ProseMirror .title" createUserContainerSelector="#js-share-document-editor-container .ProseMirror .title"
/> />
</div> </div>
<ImageViewer containerSelector="#js-share-document-editor-container" />
<BackTop target={() => document.querySelector('#js-share-document-editor-container').parentNode} /> <BackTop target={() => document.querySelector('#js-share-document-editor-container').parentNode} />
</> </>
); );

View File

@ -0,0 +1,30 @@
import { useEffect } from 'react';
import Viewer from 'viewerjs';
interface IProps {
containerSelector: string;
}
export const ImageViewer: React.FC<IProps> = ({ containerSelector }) => {
useEffect(() => {
const el = document.querySelector(containerSelector);
if (!el) {
return null;
}
const viewer = new Viewer(el as HTMLElement, { inline: false });
const io = new MutationObserver(() => {
viewer.update();
});
io.observe(el, {
childList: true,
subtree: true,
});
return () => {
io.disconnect();
viewer.destroy();
};
}, [containerSelector]);
return null;
};

View File

@ -5,6 +5,7 @@ import { Layout, Spin, Typography } from '@douyinfe/semi-ui';
import { IUser, ITemplate } from '@think/domains'; import { IUser, ITemplate } from '@think/domains';
import { DEFAULT_EXTENSION, DocumentWithTitle } from 'components/tiptap'; import { DEFAULT_EXTENSION, DocumentWithTitle } from 'components/tiptap';
import { DataRender } from 'components/data-render'; import { DataRender } from 'components/data-render';
import { ImageViewer } from 'components/image-viewer';
import { useDocumentStyle } from 'hooks/useDocumentStyle'; import { useDocumentStyle } from 'hooks/useDocumentStyle';
import { safeJSONParse } from 'helpers/json'; import { safeJSONParse } from 'helpers/json';
import styles from './index.module.scss'; import styles from './index.module.scss';
@ -61,6 +62,7 @@ export const Editor: React.FC<IProps> = ({ user, data, loading, error }) => {
<Title>{data.title}</Title> <Title>{data.title}</Title>
<EditorContent editor={editor} /> <EditorContent editor={editor} />
</div> </div>
<ImageViewer containerSelector={`.${styles.editorWrap}`} />
</Content> </Content>
); );
}} }}

View File

@ -1,5 +1,6 @@
import type { AppProps } from 'next/app'; import type { AppProps } from 'next/app';
import { useSafari100vh } from 'hooks/use-safari-100vh'; import { useSafari100vh } from 'hooks/use-safari-100vh';
import 'viewerjs/dist/viewer.css';
import 'styles/globals.scss'; import 'styles/globals.scss';
function MyApp({ Component, pageProps }: AppProps) { function MyApp({ Component, pageProps }: AppProps) {

View File

@ -118,6 +118,7 @@ importers:
tippy.js: ^6.3.7 tippy.js: ^6.3.7
tsconfig-paths-webpack-plugin: ^3.5.2 tsconfig-paths-webpack-plugin: ^3.5.2
typescript: 4.5.5 typescript: 4.5.5
viewerjs: ^1.10.4
y-indexeddb: ^9.0.7 y-indexeddb: ^9.0.7
y-prosemirror: ^1.0.14 y-prosemirror: ^1.0.14
yjs: ^13.5.24 yjs: ^13.5.24
@ -193,6 +194,7 @@ importers:
scroll-into-view-if-needed: 2.2.29 scroll-into-view-if-needed: 2.2.29
swr: 1.2.0_react@17.0.2 swr: 1.2.0_react@17.0.2
tippy.js: 6.3.7 tippy.js: 6.3.7
viewerjs: 1.10.4
y-indexeddb: 9.0.7_yjs@13.5.24 y-indexeddb: 9.0.7_yjs@13.5.24
y-prosemirror: 1.0.14_0fedec857d2fb730ad5b02a71124bf2a y-prosemirror: 1.0.14_0fedec857d2fb730ad5b02a71124bf2a
yjs: 13.5.24 yjs: 13.5.24
@ -8258,6 +8260,10 @@ packages:
engines: {node: '>= 0.8'} engines: {node: '>= 0.8'}
dev: false dev: false
/viewerjs/1.10.4:
resolution: {integrity: sha512-CjMt64yC9D+XUx2t3F0TPbh/Yt5+/ke8/s3IizXa6NtksdJUFDoCcNxi/KRZ9eiZPR/D77pHnnQzAtCoLDaGIw==}
dev: false
/vm2/3.9.5: /vm2/3.9.5:
resolution: {integrity: sha512-LuCAHZN75H9tdrAiLFf030oW7nJV5xwNMuk1ymOZwopmuK3d2H4L1Kv4+GFHgarKiLfXXLFU+7LDABHnwOkWng==} resolution: {integrity: sha512-LuCAHZN75H9tdrAiLFf030oW7nJV5xwNMuk1ymOZwopmuK3d2H4L1Kv4+GFHgarKiLfXXLFU+7LDABHnwOkWng==}
engines: {node: '>=6.0'} engines: {node: '>=6.0'}