Compare commits
3 Commits
open-relea
...
open-relea
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fbaa41a8ae | ||
|
|
5dab08761c | ||
|
|
e499280e49 |
@@ -1,4 +1,4 @@
|
||||
import React, { useState } from 'react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Helmet } from 'react-helmet';
|
||||
import { useDispatch } from 'react-redux';
|
||||
@@ -46,10 +46,8 @@ function Course({
|
||||
|
||||
// Below the tabs, above the breadcrumbs alerts (appearing in the order listed here)
|
||||
const dispatch = useDispatch();
|
||||
const celebrateFirstSection = celebrations && celebrations.firstSection;
|
||||
const [firstSectionCelebrationOpen, setFirstSectionCelebrationOpen] = useState(shouldCelebrateOnSectionLoad(
|
||||
courseId, sequenceId, celebrateFirstSection, dispatch, celebrations,
|
||||
));
|
||||
|
||||
const [firstSectionCelebrationOpen, setFirstSectionCelebrationOpen] = useState(false);
|
||||
// If streakLengthToCelebrate is populated, that modal takes precedence. Wait til the next load to display
|
||||
// the weekly goal celebration modal.
|
||||
const [weeklyGoalCelebrationOpen, setWeeklyGoalCelebrationOpen] = useState(
|
||||
@@ -74,6 +72,17 @@ function Course({
|
||||
/** [MM-P2P] Experiment */
|
||||
const MMP2P = initCoursewareMMP2P(courseId, sequenceId, unitId);
|
||||
|
||||
useEffect(() => {
|
||||
const celebrateFirstSection = celebrations && celebrations.firstSection;
|
||||
setFirstSectionCelebrationOpen(shouldCelebrateOnSectionLoad(
|
||||
courseId,
|
||||
sequenceId,
|
||||
celebrateFirstSection,
|
||||
dispatch,
|
||||
celebrations,
|
||||
));
|
||||
}, [sequenceId]);
|
||||
|
||||
return (
|
||||
<SidebarProvider courseId={courseId} unitId={unitId}>
|
||||
<Helmet>
|
||||
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
useWindowSize,
|
||||
} from '@edx/paragon';
|
||||
|
||||
import { useDispatch } from 'react-redux';
|
||||
import ClapsMobile from './assets/claps_280x201.gif';
|
||||
import ClapsTablet from './assets/claps_456x328.gif';
|
||||
import messages from './messages';
|
||||
@@ -19,12 +20,13 @@ import { useModel } from '../../../generic/model-store';
|
||||
function CelebrationModal({
|
||||
courseId, intl, isOpen, onClose, ...rest
|
||||
}) {
|
||||
const { org } = useModel('courseHomeMeta', courseId);
|
||||
const { org, celebrations } = useModel('courseHomeMeta', courseId);
|
||||
const dispatch = useDispatch();
|
||||
const wideScreen = useWindowSize().width >= breakpoints.small.minWidth;
|
||||
|
||||
useEffect(() => {
|
||||
if (isOpen) {
|
||||
recordFirstSectionCelebration(org, courseId);
|
||||
recordFirstSectionCelebration(org, courseId, celebrations, dispatch);
|
||||
}
|
||||
}, [isOpen]);
|
||||
|
||||
|
||||
@@ -15,9 +15,20 @@ function handleNextSectionCelebration(sequenceId, nextSequenceId) {
|
||||
});
|
||||
}
|
||||
|
||||
function recordFirstSectionCelebration(org, courseId) {
|
||||
function recordFirstSectionCelebration(org, courseId, celebrations, dispatch) {
|
||||
// Tell the LMS
|
||||
postCelebrationComplete(courseId, { first_section: false });
|
||||
// Update our local copy of course data from LMS
|
||||
dispatch(updateModel({
|
||||
modelType: 'courseHomeMeta',
|
||||
model: {
|
||||
id: courseId,
|
||||
celebrations: {
|
||||
...celebrations,
|
||||
firstSection: false,
|
||||
},
|
||||
},
|
||||
}));
|
||||
|
||||
// Tell our analytics
|
||||
const { administrator } = getAuthenticatedUser();
|
||||
|
||||
15
src/courseware/course/celebration/utils.test.jsx
Normal file
15
src/courseware/course/celebration/utils.test.jsx
Normal file
@@ -0,0 +1,15 @@
|
||||
import { recordFirstSectionCelebration } from './utils';
|
||||
|
||||
jest.mock('@edx/frontend-platform/analytics');
|
||||
jest.mock('./data/api');
|
||||
jest.mock('@edx/frontend-platform/auth', () => ({
|
||||
getAuthenticatedUser: jest.fn(() => ({ administrator: 'admin' })),
|
||||
}));
|
||||
|
||||
describe('recordFirstSectionCelebration', () => {
|
||||
it('updates the local copy of the course data from the LMS', async () => {
|
||||
const dispatchMock = jest.fn();
|
||||
recordFirstSectionCelebration('org', 'courseId', 'celebration', dispatchMock);
|
||||
expect(dispatchMock).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
@@ -57,7 +57,7 @@ subscribe(APP_READY, () => {
|
||||
</TabContainer>
|
||||
</PageRoute>
|
||||
<PageRoute path="/course/:courseId/live">
|
||||
<TabContainer tab="live" fetch={fetchLiveTab} slice="courseHome">
|
||||
<TabContainer tab="lti_live" fetch={fetchLiveTab} slice="courseHome">
|
||||
<LiveTab />
|
||||
</TabContainer>
|
||||
</PageRoute>
|
||||
|
||||
@@ -160,8 +160,8 @@ function StreakModal({
|
||||
</ModalDialog.Title>
|
||||
</ModalDialog.Header>
|
||||
<ModalDialog.Body className="modal-body">
|
||||
<p>{intl.formatMessage(messages.streakBody)}</p>
|
||||
<p className="modal-image">
|
||||
<p className="text-center">{intl.formatMessage(messages.streakBody)}</p>
|
||||
<p className="modal-image text-center">
|
||||
{!wideScreen && <img src={StreakMobileImage} alt="" className="img-fluid" />}
|
||||
{wideScreen && <img src={StreakDesktopImage} alt="" className="img-fluid" />}
|
||||
</p>
|
||||
|
||||
@@ -26,6 +26,10 @@
|
||||
.modal-body {
|
||||
padding-top: .5rem;
|
||||
font-size: 1.2rem;
|
||||
|
||||
.pgn__modal-body-content {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.modal-footer {
|
||||
|
||||
Reference in New Issue
Block a user