mirror of https://github.com/fantasticit/think.git
feat: add image viewer support
This commit is contained in:
parent
60a330cdfa
commit
8949af5715
|
@ -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"
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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} />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
|
@ -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;
|
||||||
|
};
|
|
@ -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>
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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'}
|
||||||
|
|
Loading…
Reference in New Issue