Skip to content

Commit 51c8f0c

Browse files
committed
fix: first section celebration
Fix the first section celebration modal showing logic. On Nutmeg+ it's shown only after the page reload or after going directly to the second section from the course home. Going through the course with the Next/Previous buttons has no effect (which worked on Maple). Notes: - the weekly goal has the same showing logic, but I assume that is correct behavior so no changes are added for it in this commit. - showing a celebration modal for the first section completion when going directly to the first unit of the second section seems to be a bug (reproduces on Maple too)
1 parent 91c5488 commit 51c8f0c

File tree

4 files changed

+45
-8
lines changed

4 files changed

+45
-8
lines changed

src/courseware/course/Course.jsx

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useState } from 'react';
1+
import React, { useEffect, useState } from 'react';
22
import PropTypes from 'prop-types';
33
import { Helmet } from 'react-helmet';
44
import { useDispatch } from 'react-redux';
@@ -46,10 +46,8 @@ function Course({
4646

4747
// Below the tabs, above the breadcrumbs alerts (appearing in the order listed here)
4848
const dispatch = useDispatch();
49-
const celebrateFirstSection = celebrations && celebrations.firstSection;
50-
const [firstSectionCelebrationOpen, setFirstSectionCelebrationOpen] = useState(
51-
shouldCelebrateOnSectionLoad(courseId, sequenceId, celebrateFirstSection, dispatch, celebrations),
52-
);
49+
50+
const [firstSectionCelebrationOpen, setFirstSectionCelebrationOpen] = useState(false);
5351
// If streakLengthToCelebrate is populated, that modal takes precedence. Wait til the next load to display
5452
// the weekly goal celebration modal.
5553
const [weeklyGoalCelebrationOpen, setWeeklyGoalCelebrationOpen] = useState(
@@ -74,6 +72,17 @@ function Course({
7472
/** [MM-P2P] Experiment */
7573
const MMP2P = initCoursewareMMP2P(courseId, sequenceId, unitId);
7674

75+
useEffect(() => {
76+
const celebrateFirstSection = celebrations && celebrations.firstSection;
77+
setFirstSectionCelebrationOpen(shouldCelebrateOnSectionLoad(
78+
courseId,
79+
sequenceId,
80+
celebrateFirstSection,
81+
dispatch,
82+
celebrations,
83+
));
84+
}, [sequenceId]);
85+
7786
return (
7887
<SidebarProvider courseId={courseId} unitId={unitId}>
7988
<Helmet>

src/courseware/course/celebration/CelebrationModal.jsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
useWindowSize,
1010
} from '@edx/paragon';
1111

12+
import { useDispatch } from 'react-redux';
1213
import ClapsMobile from './assets/claps_280x201.gif';
1314
import ClapsTablet from './assets/claps_456x328.gif';
1415
import messages from './messages';
@@ -19,12 +20,13 @@ import { useModel } from '../../../generic/model-store';
1920
function CelebrationModal({
2021
courseId, intl, isOpen, onClose, ...rest
2122
}) {
22-
const { org } = useModel('courseHomeMeta', courseId);
23+
const { org, celebrations } = useModel('courseHomeMeta', courseId);
24+
const dispatch = useDispatch();
2325
const wideScreen = useWindowSize().width >= breakpoints.small.minWidth;
2426

2527
useEffect(() => {
2628
if (isOpen) {
27-
recordFirstSectionCelebration(org, courseId);
29+
recordFirstSectionCelebration(org, courseId, celebrations, dispatch);
2830
}
2931
}, [isOpen]);
3032

src/courseware/course/celebration/utils.jsx

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,20 @@ function handleNextSectionCelebration(sequenceId, nextSequenceId) {
1515
});
1616
}
1717

18-
function recordFirstSectionCelebration(org, courseId) {
18+
function recordFirstSectionCelebration(org, courseId, celebrations, dispatch) {
1919
// Tell the LMS
2020
postCelebrationComplete(courseId, { first_section: false });
21+
// Update our local copy of course data from LMS
22+
dispatch(updateModel({
23+
modelType: 'courseHomeMeta',
24+
model: {
25+
id: courseId,
26+
celebrations: {
27+
...celebrations,
28+
firstSection: false,
29+
},
30+
},
31+
}));
2132

2233
// Tell our analytics
2334
const { administrator } = getAuthenticatedUser();
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { recordFirstSectionCelebration } from './utils';
2+
3+
jest.mock('@edx/frontend-platform/analytics');
4+
jest.mock('./data/api');
5+
jest.mock('@edx/frontend-platform/auth', () => ({
6+
getAuthenticatedUser: jest.fn(() => ({ administrator: 'admin' })),
7+
}));
8+
9+
describe('recordFirstSectionCelebration', () => {
10+
it('updates the local copy of the course data from the LMS', async () => {
11+
const dispatchMock = jest.fn();
12+
recordFirstSectionCelebration('org', 'courseId', 'celebration', dispatchMock);
13+
expect(dispatchMock).toHaveBeenCalled();
14+
});
15+
});

0 commit comments

Comments
 (0)