diff --git a/src/courseware/course/sequence/Unit/constants.js b/src/courseware/course/sequence/Unit/constants.js index 43b64c2503..f8eb23e1c2 100644 --- a/src/courseware/course/sequence/Unit/constants.js +++ b/src/courseware/course/sequence/Unit/constants.js @@ -16,6 +16,7 @@ export const messageTypes = StrictDict({ modal: 'plugin.modal', resize: 'plugin.resize', videoFullScreen: 'plugin.videoFullScreen', + autoAdvance: 'plugin.autoAdvance', }); export default StrictDict({ diff --git a/src/courseware/course/sequence/Unit/hooks/useIFrameBehavior.js b/src/courseware/course/sequence/Unit/hooks/useIFrameBehavior.js index 71282a7b31..89fea4d717 100644 --- a/src/courseware/course/sequence/Unit/hooks/useIFrameBehavior.js +++ b/src/courseware/course/sequence/Unit/hooks/useIFrameBehavior.js @@ -1,7 +1,8 @@ import { getConfig } from '@edx/frontend-platform'; import { sendTrackEvent } from '@edx/frontend-platform/analytics'; import React from 'react'; -import { useDispatch } from 'react-redux'; +import { useDispatch, useSelector } from 'react-redux'; +import { useNavigate } from 'react-router-dom'; import { StrictDict, useKeyedState } from '@edx/react-unit-test-utils'; import { logError } from '@edx/frontend-platform/logging'; @@ -9,6 +10,9 @@ import { logError } from '@edx/frontend-platform/logging'; import { fetchCourse } from '@src/courseware/data'; import { processEvent } from '@src/course-home/data/thunks'; import { useEventListener } from '@src/generic/hooks'; +import { getSequenceId } from '@src/courseware/data/selectors'; +import { useModel } from '@src/generic/model-store'; +import { useSequenceNavigationMetadata } from '@src/courseware/course/sequence/sequence-navigation/hooks'; import { messageTypes } from '../constants'; import useLoadBearingHook from './useLoadBearingHook'; @@ -18,6 +22,7 @@ export const stateKeys = StrictDict({ hasLoaded: 'hasLoaded', showError: 'showError', windowTopOffset: 'windowTopOffset', + sequences: 'sequences', }); const useIFrameBehavior = ({ @@ -30,6 +35,12 @@ const useIFrameBehavior = ({ useLoadBearingHook(id); const dispatch = useDispatch(); + const activeSequenceId = useSelector(getSequenceId); + const navigate = useNavigate(); + const activeSequence = useModel(stateKeys.sequences, activeSequenceId); + const activeUnitId = activeSequence.unitIds.length > 0 + ? activeSequence.unitIds[activeSequence.activeUnitIndex] : null; + const { isLastUnit, nextLink } = useSequenceNavigationMetadata(activeSequenceId, activeUnitId); const [iframeHeight, setIframeHeight] = useKeyedState(stateKeys.iframeHeight, 0); const [hasLoaded, setHasLoaded] = useKeyedState(stateKeys.hasLoaded, false); @@ -71,6 +82,12 @@ const useIFrameBehavior = ({ // We listen for this message from LMS to know when the page needs to // be scrolled to another location on the page. window.scrollTo(0, data.offset + document.getElementById('unit-iframe').offsetTop); + } else if (type === messageTypes.autoAdvance) { + // We are listening to autoAdvance message to move to next sequence automatically. + // In case it is the last unit we need not do anything. + if (!isLastUnit) { + navigate(nextLink); + } } }, [ id, diff --git a/src/courseware/course/sequence/Unit/hooks/useIFrameBehavior.test.js b/src/courseware/course/sequence/Unit/hooks/useIFrameBehavior.test.js index 28b23faadf..71c1478259 100644 --- a/src/courseware/course/sequence/Unit/hooks/useIFrameBehavior.test.js +++ b/src/courseware/course/sequence/Unit/hooks/useIFrameBehavior.test.js @@ -28,6 +28,7 @@ jest.mock('react', () => ({ jest.mock('react-redux', () => ({ useDispatch: jest.fn(), + useSelector: jest.fn(), })); jest.mock('./useLoadBearingHook', () => jest.fn()); @@ -45,6 +46,12 @@ jest.mock('@src/course-home/data/thunks', () => ({ jest.mock('@src/generic/hooks', () => ({ useEventListener: jest.fn(), })); +jest.mock('@src/generic/model-store', () => ({ + useModel: () => ({ unitIds: ['unit1', 'unit2'] }), +})); +jest.mock('react-router-dom', () => ({ + useNavigate: jest.fn(), +})); const state = mockUseKeyedState(stateKeys);