1
0
Fork 0
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:
Fedor Katurov 2022-01-19 10:04:23 +07:00
parent 7e14b52bf9
commit d30cad9caa
4 changed files with 27 additions and 2 deletions

View 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 };

View file

@ -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>
); );

View file

@ -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=""

View file

@ -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>
); );
}); });