images_viewer/src/components/BookComponent.tsx

140 lines
3.9 KiB
TypeScript

import React, {createContext} from 'react'
import OnePageView from './OnePageView'
import TwoPagesView from './TwoPagesView'
import BookComponentsController from './BookComponentsController'
import './index.css'
export const BookContext = createContext({})
export interface IBookPage {
src: string
alt?: string
thumbnail?: string
}
export const getBookViewModes = (currIndex = 0, srcLength = 0)=>[
{
text: 'One Page',
value: 'one page',
icon: '',
pagesToTurn: 1,
nextDisable: currIndex >= srcLength - 1,
prevDisable: currIndex === 0,
},
{
text: 'Two Pages',
value: 'two pages',
icon: '',
pagesToTurn: 2,
nextDisable: currIndex >= srcLength - 2,
prevDisable: currIndex <= 1,
}
]
export enum BookViewMode {
onePage = 'one page',
twoPages = 'two pages'
}
export interface IBookContext {
currIndex?: number,
src?: IBookPage[],
flagToReverse?: boolean,
mode?: BookViewMode,
readonly setBookContextState: (newState: any)=> undefined
}
const getPagesCountToTurn = (mode: string)=>{
let pagesToTurn = getBookViewModes().find(item=> item.value === mode)?.pagesToTurn
return pagesToTurn || 0
}
class BookComponent extends React.Component<any, any>{
constructor(props: any){
super(props)
this.state = {
currIndex: 0,
src: [],
flagToReverse: false,
mode: "one page",
setBookContextState: (newState: IBookContext)=>{
this.setState((oldState: any)=> ({
...oldState,
...newState
}))
},
changePage: this.changePage,
pagesToTurn: 1,
}
}
changePage = (goToPrevious: boolean, indexToGo?: number)=>{
const {mode, currIndex} = this.state
const pagesCountToTurn = indexToGo || getPagesCountToTurn(mode)
const prefixPageCount = goToPrevious? -1 : 1
this.setState({
currIndex: (pagesCountToTurn * prefixPageCount) + currIndex,
flagToReverse: goToPrevious
})
}
componentDidMount(){
fetch('https://picsum.photos/v2/list')
.then(response=>{
return response.json()
}).then(data=>{
data = data.map((item: any)=>{
return {
src: item.download_url,
alt: item.author
}
})
this.setState({
src: data
})
})
}
getControlsDisable = ()=>{
const {mode, currIndex, src} = this.state
const {nextDisable, prevDisable} = getBookViewModes(currIndex, src.length).find(item=> item.value === mode) || {
nextDisable: true,
prevDisable: true
}
return {
nextDisable,
prevDisable
}
}
render(){
const {mode} = this.state
return <BookContext.Provider value={{...this.state}}>
<BookContext.Consumer>
{state=>(
<>
{mode === "one page" && <OnePageView {...state}/>}
{mode === "two pages" && <TwoPagesView {...state}/>}
<BookComponentsController
onPrevClick={()=>{
this.changePage(true)
}}
onNextClick={()=>{
this.changePage(false)
}}
{...this.getControlsDisable()}
{...this.state}
/>
</>
)}
</BookContext.Consumer>
</BookContext.Provider>
}
}
export default BookComponent