import {useState, useEffect, useReducer} from 'preact/hooks'; const {connect} = KalturaPlayer.ui.redux; import {PageReducer} from './page-reducer'; import {PageAction} from './page-action'; import {ArrowLeft, ArrowLeftDisabled, ArrowRight, ArrowRightDisabled} from 'components/pagination-arrow/pagination-arrow'; import * as styles from './related-grid.scss'; import {Sources} from 'types/sources'; import {getEntryDimensions, getSizeClass, getNextEntry, getPageSize, getExpandedEntryDimensions, getGridEntry} from './grid-utils'; import {EntryDimensions} from 'types/entry-dimensions'; const mapStateToProps = (state: any) => { const {shell} = state; return { sizeBreakpoint: shell.playerSize }; }; interface RelatedGridProps { data: Sources[]; countdown: number; sizeBreakpoint: string; } /** * Displays related entries in grid form with pagination. * The grid view changes according to player size. * * @param {object} props Component props. * @param {object} props.data Related entries data. * @param {number} props.countdown Next entry auto continue countdown time. * @param {string} props.sizeBreakpoint Player size breakpoint. */ const RelatedGrid = connect(mapStateToProps)(({data, countdown, sizeBreakpoint}: RelatedGridProps) => { if (!data.length) return <>; const onAnimationEnd = () => { if (pageAction !== PageAction.NOTHING) { dispatch(pageAction); setPageAnimation(''); setPageAction(PageAction.NOTHING); } }; const [pageState, dispatch] = useReducer(PageReducer, { prevPage: -1, currPage: 0, nextPage: 1 }); const {prevPage, currPage, nextPage} = pageState; const [pageAction, setPageAction] = useState(PageAction.NOTHING); const [pageAnimation, setPageAnimation] = useState(''); useEffect(() => { if (pageAction !== PageAction.NOTHING) { setPageAnimation(pageAction === PageAction.NEXT ? styles.slideLeft : styles.slideRight); } }, [pageAction]); const entriesPerPage = getPageSize(sizeBreakpoint); const getEntriesByPage = (page: number) => { const firstPageSize = entriesPerPage - 1; if (page < 0) { return []; } else if (page === 0) { return data.slice(0, firstPageSize); } return data.slice(firstPageSize + (page - 1) * entriesPerPage, firstPageSize + page * entriesPerPage); }; const arrowLeft = (
{currPage === 0 ? : setPageAction(PageAction.PREV)} />}
); const arrowRight = (
{currPage > 0 && data.length <= nextPage * entriesPerPage ? ( ) : ( setPageAction(PageAction.NEXT)} /> )}
); const firstPageEntryDimensions = getEntryDimensions(sizeBreakpoint); const entryDimensions = getExpandedEntryDimensions(sizeBreakpoint); return (
{data.length > entriesPerPage - 1 ? arrowLeft : <>}
{data.length > entriesPerPage - 1 ? arrowRight : <>}
); }); const GridPage = ({ isFirstPage = false, isActive = false, entryDimensions, sizeBreakpoint, data, countdown }: { isFirstPage?: boolean; isActive?: boolean; entryDimensions: EntryDimensions; sizeBreakpoint: string; countdown: number; data: Sources[]; }) => { if (!data.length) { return
; } let nextEntry; if (isFirstPage) { nextEntry = getNextEntry(sizeBreakpoint, countdown, data[0]); data = data.slice(1); } const entries = []; for (let i = 0; i < data.length; ++i) { const row = i % 2; const col = (i - row) / 2; const entryData = data[i]; entries.push(
{entryData ? getGridEntry(sizeBreakpoint, entryData, entryDimensions) : <>}
); } return (
{nextEntry}
{entries}
); }; export {RelatedGrid};