diff --git a/src/scripts/components/story-pagination/story-pagination.tsx b/src/scripts/components/story-pagination/story-pagination.tsx index 7e20f923a..8bd255f6a 100644 --- a/src/scripts/components/story-pagination/story-pagination.tsx +++ b/src/scripts/components/story-pagination/story-pagination.tsx @@ -7,7 +7,6 @@ import {PreviousIcon} from '../icons/previous-icon'; import {NextIcon} from '../icons/next-icon'; import {PlayIcon} from '../icons/play-icon'; import {RemoveIcon} from '../icons/remove-icon'; -import {useStoryNavigation} from '../../libs/get-navigation-links'; import {Slide} from '../../types/story'; import {StoryMode} from '../../types/story-mode'; @@ -19,26 +18,29 @@ interface Props { storyId: string; mode: StoryMode; slides: Slide[]; + previousLink?: string; + showPrevious?: boolean; + nextLink?: string; + showNext?: boolean; } const StoryPagination: FunctionComponent = ({ currentPage, mode, - slides + slides, + previousLink, + showPrevious, + nextLink, + showNext }) => { const intl = useIntl(); const isPresenterMode = mode === StoryMode.Present; const classes = cx(styles.pagination, isPresenterMode && styles.present); - const {previousLink, showPrevious, nextLink, showNext} = useStoryNavigation( - slides, - currentPage - ); - return (
- {showPrevious ? ( + {showPrevious && previousLink ? ( @@ -50,7 +52,7 @@ const StoryPagination: FunctionComponent = ({ {currentPage + 1}/{slides.length} - {showNext ? ( + {showNext && nextLink ? ( diff --git a/src/scripts/components/story/story.tsx b/src/scripts/components/story/story.tsx index fd92877a0..9fda97e11 100644 --- a/src/scripts/components/story/story.tsx +++ b/src/scripts/components/story/story.tsx @@ -1,6 +1,6 @@ import React, {FunctionComponent, useEffect} from 'react'; import {useDispatch, useSelector} from 'react-redux'; -import {useParams, Redirect} from 'react-router-dom'; +import {useParams, Redirect, useLocation, useHistory} from 'react-router-dom'; import StoryPagination from '../story-pagination/story-pagination'; import fetchStory from '../../actions/fetch-story'; @@ -11,6 +11,8 @@ import Slide from '../slide/slide'; import {State} from '../../reducers'; import config from '../../config/main'; import StoryHeader from '../story-header/story-header'; +import {useInterval} from '../../hooks/use-interval'; +import {getStoryNavigation} from '../../libs/get-story-navigation'; import {StoryMode} from '../../types/story-mode'; @@ -39,6 +41,8 @@ const getStoryId = (params: Params, mode: StoryMode) => { const Story: FunctionComponent = ({mode}) => { const params = useParams(); + const {pathname} = useLocation(); + const history = useHistory(); const storyId = getStoryId(params, mode); const story = useSelector((state: State) => selectedStorySelector(state, storyId) @@ -71,6 +75,23 @@ const Story: FunctionComponent = ({mode}) => { [dispatch] ); + const navigationData = getStoryNavigation({ + pathname, + pageNumber, + slides: story?.slides + }); + + const showNext = navigationData?.showNext; + const showPrevious = navigationData?.showPrevious; + const nextLink = navigationData?.nextLink; + const previousLink = navigationData?.previousLink; + + useInterval(() => { + if (mode === StoryMode.Showcase) { + showNext && history.replace(`${nextLink}`); + } + }, 5000); + // redirect to first slide when current slide does not exist if (story && !slide) { return ; @@ -101,6 +122,10 @@ const Story: FunctionComponent = ({mode}) => { storyId={story.id} mode={mode} slides={story.slides} + previousLink={previousLink} + showPrevious={showPrevious} + nextLink={nextLink} + showNext={showNext} /> )}
diff --git a/src/scripts/hooks/use-interval.ts b/src/scripts/hooks/use-interval.ts new file mode 100644 index 000000000..73c294746 --- /dev/null +++ b/src/scripts/hooks/use-interval.ts @@ -0,0 +1,22 @@ +import {useEffect, useRef} from 'react'; + +export const useInterval = (callback: () => void, delay: number) => { + const savedCallback = useRef<() => void | undefined>(); + + // Remember the latest callback. + useEffect(() => { + savedCallback.current = callback; + }, [callback]); + + // Set up the interval. + useEffect(() => { + function tick() { + savedCallback.current && savedCallback.current(); + } + + if (delay !== null) { + const id = setInterval(tick, delay); + return () => clearInterval(id); + } + }, [delay]); +}; diff --git a/src/scripts/libs/get-navigation-links.ts b/src/scripts/libs/get-story-navigation.ts similarity index 59% rename from src/scripts/libs/get-navigation-links.ts rename to src/scripts/libs/get-story-navigation.ts index c2dcfc33f..704a8470c 100644 --- a/src/scripts/libs/get-navigation-links.ts +++ b/src/scripts/libs/get-story-navigation.ts @@ -1,14 +1,22 @@ import {Slide} from '../types/story'; -import {useLocation} from 'react-router-dom'; -export const useStoryNavigation = (slides: Slide[], currentPage: number) => { - const location = useLocation(); - const nextPageNumber = currentPage + 1; - const previousPageNumber = currentPage - 1; +interface Params { + pathname: string; + pageNumber: number; + slides?: Slide[]; +} + +export const getStoryNavigation = ({pathname, pageNumber, slides}: Params) => { + if (!slides) { + return null; + } + + const nextPageNumber = pageNumber + 1; + const previousPageNumber = pageNumber - 1; const showNextButton = nextPageNumber < slides.length; const showPreviousButton = previousPageNumber >= 0; - const pathParts = location.pathname.split('/'); + const pathParts = pathname.split('/'); pathParts.pop(); const nextPath = pathParts.concat(nextPageNumber.toString()).join('/'); const previousPath = pathParts