mirror of
https://github.com/muerwre/vault-frontend.git
synced 2025-04-24 20:36:40 +07:00
(nextjs) fixed image preloaders for SSR
This commit is contained in:
parent
7e14b52bf9
commit
d30cad9caa
4 changed files with 27 additions and 2 deletions
20
src/components/common/ImageWithSSRLoad/index.tsx
Normal file
20
src/components/common/ImageWithSSRLoad/index.tsx
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
import React, { useEffect, useRef, VFC } from 'react';
|
||||||
|
|
||||||
|
interface ImgProps
|
||||||
|
extends React.DetailedHTMLProps<React.ImgHTMLAttributes<HTMLImageElement>, HTMLImageElement> {
|
||||||
|
onLoad?: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** fixes the situation when img not fires onLoad at SSR */
|
||||||
|
const ImageWithSSRLoad: VFC<ImgProps> = ({ onLoad, ...rest }) => {
|
||||||
|
const ref = useRef<HTMLImageElement>(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!ref.current?.complete || !onLoad) return;
|
||||||
|
onLoad();
|
||||||
|
}, [ref, onLoad]);
|
||||||
|
|
||||||
|
return <img {...rest} onLoad={onLoad} alt={rest.alt} ref={ref} />;
|
||||||
|
};
|
||||||
|
|
||||||
|
export { ImageWithSSRLoad };
|
|
@ -33,6 +33,9 @@ const CoverBackdrop: FC<IProps> = ({ cover }) => {
|
||||||
className={classNames(styles.cover, { [styles.active]: is_loaded })}
|
className={classNames(styles.cover, { [styles.active]: is_loaded })}
|
||||||
style={{ backgroundImage: `url("${image}")` }}
|
style={{ backgroundImage: `url("${image}")` }}
|
||||||
>
|
>
|
||||||
|
{
|
||||||
|
// TODO: use ImageWithSSRLoad here if you will face any bugs
|
||||||
|
}
|
||||||
<img onLoad={onLoad} ref={ref} alt="" />
|
<img onLoad={onLoad} ref={ref} alt="" />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -8,6 +8,7 @@ import { LoaderCircle } from '~/components/input/LoaderCircle';
|
||||||
import { Icon } from '~/components/input/Icon';
|
import { Icon } from '~/components/input/Icon';
|
||||||
import { useResizeHandler } from '~/hooks/dom/useResizeHandler';
|
import { useResizeHandler } from '~/hooks/dom/useResizeHandler';
|
||||||
import { DEFAULT_DOMINANT_COLOR } from '~/constants/node';
|
import { DEFAULT_DOMINANT_COLOR } from '~/constants/node';
|
||||||
|
import { ImageWithSSRLoad } from '~/components/common/ImageWithSSRLoad';
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
file: IFile;
|
file: IFile;
|
||||||
|
@ -83,7 +84,7 @@ const ImagePreloader: FC<IProps> = ({ file, color, onLoad, onClick, className })
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
||||||
<img
|
<ImageWithSSRLoad
|
||||||
className={classNames(styles.image, { [styles.is_loaded]: loaded }, className)}
|
className={classNames(styles.image, { [styles.is_loaded]: loaded }, className)}
|
||||||
src={getURL(file, PRESETS['1600'])}
|
src={getURL(file, PRESETS['1600'])}
|
||||||
alt=""
|
alt=""
|
||||||
|
|
|
@ -8,6 +8,7 @@ import { getURL, getURLFromString } from '~/utils/dom';
|
||||||
import { useColorGradientFromString } from '~/hooks/color/useColorGradientFromString';
|
import { useColorGradientFromString } from '~/hooks/color/useColorGradientFromString';
|
||||||
import { Square } from '~/components/common/Square';
|
import { Square } from '~/components/common/Square';
|
||||||
import { useGotoNode } from '~/hooks/node/useGotoNode';
|
import { useGotoNode } from '~/hooks/node/useGotoNode';
|
||||||
|
import { ImageWithSSRLoad } from '~/components/common/ImageWithSSRLoad';
|
||||||
|
|
||||||
type IProps = {
|
type IProps = {
|
||||||
item: Partial<INode>;
|
item: Partial<INode>;
|
||||||
|
@ -89,7 +90,7 @@ const NodeRelatedItem: FC<IProps> = memo(({ item }) => {
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<img src={image} alt="loader" onLoad={() => setIsLoaded(true)} />
|
<ImageWithSSRLoad src={image} alt="loader" onLoad={() => setIsLoaded(true)} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue