Skip to content

Commit

Permalink
fix: save scroll position on exit from video xblock fullscreen mode
Browse files Browse the repository at this point in the history
  • Loading branch information
ihor-romaniuk authored and xitij2000 committed Mar 22, 2024
1 parent 5d8e17f commit 3d7311d
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 1 deletion.
14 changes: 13 additions & 1 deletion src/courseware/course/sequence/Unit.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ const Unit = ({
const [showError, setShowError] = useState(false);
const [modalOptions, setModalOptions] = useState({ open: false });
const [shouldDisplayHonorCode, setShouldDisplayHonorCode] = useState(false);
const [windowTopOffset, setWindowTopOffset] = useState(null);

const unit = useModel('units', id);
const course = useModel('coursewareMeta', courseId);
Expand Down Expand Up @@ -120,6 +121,13 @@ const Unit = ({
} = data;
if (type === 'plugin.resize') {
setIframeHeight(payload.height);

// We observe exit from the video xblock full screen mode
// and do page scroll to the previously saved scroll position
if (windowTopOffset !== null) {
window.scrollTo(0, Number(windowTopOffset));
}

if (!hasLoaded && iframeHeight === 0 && payload.height > 0) {
setHasLoaded(true);
if (onLoaded) {
Expand All @@ -129,12 +137,16 @@ const Unit = ({
} else if (type === 'plugin.modal') {
payload.open = true;
setModalOptions(payload);
} else if (type === 'plugin.videoFullScreen') {
// We listen for this message from LMS to know when we need to
// save or reset scroll position on toggle video xblock full screen mode.
setWindowTopOffset(payload.open ? window.scrollY : null);
} else if (data.offset) {
// 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);
}
}, [id, setIframeHeight, hasLoaded, iframeHeight, setHasLoaded, onLoaded]);
}, [id, setIframeHeight, hasLoaded, iframeHeight, setHasLoaded, onLoaded, setWindowTopOffset, windowTopOffset]);
useEventListener('message', receiveMessage);
useEffect(() => {
sendUrlHashToFrame(document.getElementById('unit-iframe'));
Expand Down
15 changes: 15 additions & 0 deletions src/courseware/course/sequence/Unit.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,21 @@ describe('Unit', () => {
expect(window.scrollY === testMessageWithOffset.offset);
});

it('scrolls page on MessagaeEvent when receiving videoFullScreen state', async () => {
// Set message to constain video full screen data.
const defaultTopOffset = 800;
const testMessageWithOtherHeight = { ...messageEvent, payload: { height: 500 } };
const testMessageWithFullscreenState = (isOpen) => ({ type: 'plugin.videoFullScreen', payload: { open: isOpen } });
render(<Unit {...mockData} />);
Object.defineProperty(window, 'scrollY', { value: defaultTopOffset, writable: true });
window.postMessage(testMessageWithFullscreenState(true), '*');
window.postMessage(testMessageWithFullscreenState(false), '*');
window.postMessage(testMessageWithOtherHeight, '*');

await expect(waitFor(() => expect(window.scrollTo()).toHaveBeenCalledTimes(1)));
expect(window.scrollY === defaultTopOffset);
});

it('ignores MessageEvent with unhandled type', async () => {
// Clone message and set different type.
const testMessageWithUnhandledType = { ...messageEvent, type: 'wrong type' };
Expand Down

0 comments on commit 3d7311d

Please sign in to comment.