From 5b80c5bec8eb39ea2eefb9e24bce5b98662cda57 Mon Sep 17 00:00:00 2001 From: Farhaan Bukhsh Date: Tue, 30 Jul 2024 00:57:46 +0530 Subject: [PATCH 1/2] fix: Fixes the auto_advance feature for video XBlock The commit adds eventlistener which picks up the autoAdvance message and triggers the next sequence. This has the same effect of clicking the next button. Signed-off-by: Farhaan Bukhsh --- .../course/sequence/Unit/constants.js | 1 + .../sequence/Unit/hooks/useIFrameBehavior.js | 18 +++++++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) 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..3f9d22cb7f 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'; @@ -30,6 +34,12 @@ const useIFrameBehavior = ({ useLoadBearingHook(id); const dispatch = useDispatch(); + const navigate = useNavigate(); + const activeSequenceId = useSelector(getSequenceId); + const activeSequence = useModel('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 +81,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, From 73296d38ee4c4b30ebf2f01e83226dd2e3fb6305 Mon Sep 17 00:00:00 2001 From: Farhaan Bukhsh Date: Thu, 1 Aug 2024 14:53:30 +0530 Subject: [PATCH 2/2] fix: Fixes tests for the functions Signed-off-by: Farhaan Bukhsh --- .../course/sequence/Unit/hooks/useIFrameBehavior.js | 5 +++-- .../course/sequence/Unit/hooks/useIFrameBehavior.test.js | 7 +++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/courseware/course/sequence/Unit/hooks/useIFrameBehavior.js b/src/courseware/course/sequence/Unit/hooks/useIFrameBehavior.js index 3f9d22cb7f..89fea4d717 100644 --- a/src/courseware/course/sequence/Unit/hooks/useIFrameBehavior.js +++ b/src/courseware/course/sequence/Unit/hooks/useIFrameBehavior.js @@ -22,6 +22,7 @@ export const stateKeys = StrictDict({ hasLoaded: 'hasLoaded', showError: 'showError', windowTopOffset: 'windowTopOffset', + sequences: 'sequences', }); const useIFrameBehavior = ({ @@ -34,9 +35,9 @@ const useIFrameBehavior = ({ useLoadBearingHook(id); const dispatch = useDispatch(); - const navigate = useNavigate(); const activeSequenceId = useSelector(getSequenceId); - const activeSequence = useModel('sequences', activeSequenceId); + 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); 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);