ionian/src/client/page/reader/reader.tsx
2022-08-31 04:52:59 +09:00

80 lines
No EOL
2.4 KiB
TypeScript

import { Typography, styled } from '@mui/material';
import React from 'react';
import { Document, makeThumbnailUrl } from '../../accessor/document';
import {ComicReader} from './comic';
import {VideoReader} from './video'
export interface PagePresenterProp{
doc:Document,
className?:string
}
interface PagePresenter{
(prop:PagePresenterProp):JSX.Element
}
export const getPresenter = (content:Document):PagePresenter => {
switch (content.content_type) {
case "comic":
return ComicReader;
case "video":
return VideoReader;
}
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,
}){
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={style}></video>)
}
else return (<BackgroundDiv ref={elementRef}>
{loaded && <img src={thumbnailurl}
className={props.className + " thumbnail_img"}
loading="lazy"></img>}
</BackgroundDiv>)
}