feat: lazy image load
This commit is contained in:
parent
e889f98530
commit
4e77586821
@ -93,6 +93,7 @@ export const ContentInfo = (props: {
|
||||
const url = props.gallery === undefined ? makeContentReaderUrl(document.id) : makeContentInfoUrl(document.id);
|
||||
return (<Paper sx={{
|
||||
display: "flex",
|
||||
height: "400px",
|
||||
[theme.breakpoints.down("sm")]: {
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
@ -102,11 +103,7 @@ export const ContentInfo = (props: {
|
||||
pathname: makeContentReaderUrl(document.id)
|
||||
}}>
|
||||
{document.deleted_at === null ?
|
||||
(<ThumbnailContainer content={document}
|
||||
style={{
|
||||
maxHeight: '400px',
|
||||
maxWidth: 'min(400px, 100vw)',
|
||||
}}/>)
|
||||
(<ThumbnailContainer content={document}/>)
|
||||
: (<Typography/* className={propclasses.thumbnail_content ?? thumbnail_content} */ variant='h4'>Deleted</Typography>)}
|
||||
</Link>
|
||||
<Box /*className={propclasses.infoContainer ?? classes.infoContainer}*/>
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Typography } from '@mui/material';
|
||||
import { Typography, styled } from '@mui/material';
|
||||
import React from 'react';
|
||||
import { Document, makeThumbnailUrl } from '../../accessor/document';
|
||||
import {ComicReader} from './comic';
|
||||
@ -21,15 +21,60 @@ export const getPresenter = (content:Document):PagePresenter => {
|
||||
}
|
||||
return ()=><Typography variant='h2'>Not implemented reader</Typography>;
|
||||
}
|
||||
const BackgroundDiv = styled("div")({
|
||||
height: '400px',
|
||||
width:'300px',
|
||||
backgroundColor:"#272733",
|
||||
display:"flex",
|
||||
alignItems:"center",
|
||||
justifyContent:"center"}
|
||||
);
|
||||
|
||||
|
||||
import { useRef, useState, useEffect } from 'react';
|
||||
import "./thumbnail.css"
|
||||
|
||||
export function useIsElementInViewport<T extends HTMLElement>(options?: IntersectionObserverInit) {
|
||||
const elementRef = useRef<T>(null);
|
||||
const [isVisible, setIsVisible] = useState(false);
|
||||
|
||||
const callback = (entries: IntersectionObserverEntry[]) => {
|
||||
const [entry] = entries;
|
||||
setIsVisible(entry.isIntersecting);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const observer = new IntersectionObserver(callback, options);
|
||||
elementRef.current && observer.observe(elementRef.current);
|
||||
return () => observer.disconnect();
|
||||
}, [elementRef, options]);
|
||||
|
||||
return { elementRef, isVisible };
|
||||
};
|
||||
|
||||
export function ThumbnailContainer(props:{
|
||||
content:Document,
|
||||
className?:string,
|
||||
style?:React.CSSProperties,
|
||||
}){
|
||||
const {elementRef, isVisible} = useIsElementInViewport<HTMLDivElement>({});
|
||||
const [loaded, setLoaded] = useState(false);
|
||||
useEffect(()=>{
|
||||
if(isVisible){
|
||||
setLoaded(true);
|
||||
}
|
||||
},[isVisible])
|
||||
const style = {
|
||||
maxHeight: '400px',
|
||||
maxWidth: 'min(400px, 100vw)',
|
||||
};
|
||||
const thumbnailurl = makeThumbnailUrl(props.content);
|
||||
if(props.content.content_type === "video"){
|
||||
return (<video src={thumbnailurl} muted autoPlay loop className={props.className} style={props.style} loading="lazy"></video>)
|
||||
return (<video src={thumbnailurl} muted autoPlay loop className={props.className} style={style}></video>)
|
||||
}
|
||||
else return (<img src={thumbnailurl} className={props.className} style={props.style} loading="lazy"></img>)
|
||||
else return (<BackgroundDiv ref={elementRef}>
|
||||
{loaded && <img src={thumbnailurl}
|
||||
className={props.className + " thumbnail_img"}
|
||||
|
||||
loading="lazy"></img>}
|
||||
</BackgroundDiv>)
|
||||
}
|
15
src/client/page/reader/thumbnail.css
Normal file
15
src/client/page/reader/thumbnail.css
Normal file
@ -0,0 +1,15 @@
|
||||
.thumbnail_img{
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
animation: slideop 0.4s ease;
|
||||
}
|
||||
|
||||
@keyframes slideop {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user