Skip to content

Commit cd430eb

Browse files
dyudyunovleangseu-edx
authored andcommitted
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 630d44a commit cd430eb

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';
@@ -43,10 +43,8 @@ const Course = ({
4343

4444
// Below the tabs, above the breadcrumbs alerts (appearing in the order listed here)
4545
const dispatch = useDispatch();
46-
const celebrateFirstSection = celebrations && celebrations.firstSection;
47-
const [firstSectionCelebrationOpen, setFirstSectionCelebrationOpen] = useState(
48-
shouldCelebrateOnSectionLoad(courseId, sequenceId, celebrateFirstSection, dispatch, celebrations),
49-
);
46+
47+
const [firstSectionCelebrationOpen, setFirstSectionCelebrationOpen] = useState(false);
5048
// If streakLengthToCelebrate is populated, that modal takes precedence. Wait til the next load to display
5149
// the weekly goal celebration modal.
5250
const [weeklyGoalCelebrationOpen, setWeeklyGoalCelebrationOpen] = useState(
@@ -68,6 +66,17 @@ const Course = ({
6866
}
6967
}
7068

69+
useEffect(() => {
70+
const celebrateFirstSection = celebrations && celebrations.firstSection;
71+
setFirstSectionCelebrationOpen(shouldCelebrateOnSectionLoad(
72+
courseId,
73+
sequenceId,
74+
celebrateFirstSection,
75+
dispatch,
76+
celebrations,
77+
));
78+
}, [sequenceId]);
79+
7180
return (
7281
<SidebarProvider courseId={courseId} unitId={unitId}>
7382
<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
const 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
// eslint-disable-next-line react-hooks/exhaustive-deps
3032
}, [isOpen]);

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)