mirror of https://github.com/fantasticit/think.git
feat: use lazyload image
This commit is contained in:
parent
f1b039a687
commit
0337629d75
|
@ -1,7 +1,8 @@
|
||||||
|
import Image from 'next/image';
|
||||||
|
import cls from 'classnames';
|
||||||
|
import { useCallback, useEffect, useMemo, useRef } from 'react';
|
||||||
import { NodeViewWrapper, NodeViewContent } from '@tiptap/react';
|
import { NodeViewWrapper, NodeViewContent } from '@tiptap/react';
|
||||||
import { Resizeable } from 'components/resizeable';
|
import { Resizeable } from 'components/resizeable';
|
||||||
import { useEffect, useRef } from 'react';
|
|
||||||
import cls from 'classnames';
|
|
||||||
import { Typography, Spin } from '@douyinfe/semi-ui';
|
import { Typography, Spin } from '@douyinfe/semi-ui';
|
||||||
import { useToggle } from 'hooks/use-toggle';
|
import { useToggle } from 'hooks/use-toggle';
|
||||||
import { uploadFile } from 'services/file';
|
import { uploadFile } from 'services/file';
|
||||||
|
@ -10,30 +11,35 @@ import styles from './index.module.scss';
|
||||||
|
|
||||||
const { Text } = Typography;
|
const { Text } = Typography;
|
||||||
|
|
||||||
|
const isNumber = (v) => typeof v === 'number';
|
||||||
|
|
||||||
export const ImageWrapper = ({ editor, node, updateAttributes }) => {
|
export const ImageWrapper = ({ editor, node, updateAttributes }) => {
|
||||||
const isEditable = editor.isEditable;
|
const isEditable = editor.isEditable;
|
||||||
const { hasTrigger, error, src, alt, title, width, height, textAlign } = node.attrs;
|
const { hasTrigger, error, src, alt, title, width, height, textAlign } = node.attrs;
|
||||||
const $upload = useRef<HTMLInputElement>();
|
const $upload = useRef<HTMLInputElement>();
|
||||||
const [loading, toggleLoading] = useToggle(false);
|
const [loading, toggleLoading] = useToggle(false);
|
||||||
|
|
||||||
const onResize = (size) => {
|
const onResize = useCallback((size) => {
|
||||||
updateAttributes({ height: size.height, width: size.width });
|
updateAttributes({ height: size.height, width: size.width });
|
||||||
};
|
}, []);
|
||||||
|
|
||||||
const selectFile = () => {
|
const selectFile = useCallback(() => {
|
||||||
if (!isEditable || error || src) return;
|
if (!isEditable || error || src) return;
|
||||||
isEditable && $upload.current.click();
|
isEditable && $upload.current.click();
|
||||||
};
|
}, [isEditable, error, src]);
|
||||||
|
|
||||||
const handleFile = async (e) => {
|
const handleFile = useCallback(async (e) => {
|
||||||
const file = e.target.files && e.target.files[0];
|
const file = e.target.files && e.target.files[0];
|
||||||
|
|
||||||
const fileInfo = {
|
const fileInfo = {
|
||||||
fileName: extractFilename(file.name),
|
fileName: extractFilename(file.name),
|
||||||
fileSize: file.size,
|
fileSize: file.size,
|
||||||
fileType: file.type,
|
fileType: file.type,
|
||||||
fileExt: extractFileExtension(file.name),
|
fileExt: extractFileExtension(file.name),
|
||||||
};
|
};
|
||||||
|
|
||||||
toggleLoading(true);
|
toggleLoading(true);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const src = await uploadFile(file);
|
const src = await uploadFile(file);
|
||||||
const size = await getImageWidthHeight(file);
|
const size = await getImageWidthHeight(file);
|
||||||
|
@ -43,7 +49,7 @@ export const ImageWrapper = ({ editor, node, updateAttributes }) => {
|
||||||
updateAttributes({ error: '图片上传失败:' + (error && error.message) || '未知错误' });
|
updateAttributes({ error: '图片上传失败:' + (error && error.message) || '未知错误' });
|
||||||
toggleLoading(false);
|
toggleLoading(false);
|
||||||
}
|
}
|
||||||
};
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!src && !hasTrigger) {
|
if (!src && !hasTrigger) {
|
||||||
|
@ -52,7 +58,7 @@ export const ImageWrapper = ({ editor, node, updateAttributes }) => {
|
||||||
}
|
}
|
||||||
}, [src, hasTrigger]);
|
}, [src, hasTrigger]);
|
||||||
|
|
||||||
const content = (() => {
|
const content = useMemo(() => {
|
||||||
if (error) {
|
if (error) {
|
||||||
return (
|
return (
|
||||||
<div className={cls(styles.wrap, 'render-wrapper')}>
|
<div className={cls(styles.wrap, 'render-wrapper')}>
|
||||||
|
@ -72,7 +78,12 @@ export const ImageWrapper = ({ editor, node, updateAttributes }) => {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const img = <img src={src} alt={alt} width={width} height={height} />;
|
const img =
|
||||||
|
isNumber(width) && isNumber(height) ? (
|
||||||
|
<Image src={src} alt={alt} width={width} height={height} layout="responsive" />
|
||||||
|
) : (
|
||||||
|
<img src={src} alt={alt} width={width} height={height} />
|
||||||
|
);
|
||||||
|
|
||||||
if (isEditable) {
|
if (isEditable) {
|
||||||
return (
|
return (
|
||||||
|
@ -87,7 +98,7 @@ export const ImageWrapper = ({ editor, node, updateAttributes }) => {
|
||||||
{img}
|
{img}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
})();
|
}, [error, src, isEditable]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NodeViewWrapper as="div" style={{ textAlign, fontSize: 0, maxWidth: '100%' }}>
|
<NodeViewWrapper as="div" style={{ textAlign, fontSize: 0, maxWidth: '100%' }}>
|
||||||
|
|
Loading…
Reference in New Issue