140 lines
3.9 KiB
TypeScript
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 |