This commit is contained in:
David Joy
2020-01-10 16:39:52 -05:00
3 changed files with 59 additions and 5 deletions

View File

@@ -3,8 +3,11 @@ import React, { useContext } from 'react';
import SubSectionNavigation from './SubSectionNavigation';
import CourseStructureContext from '../CourseStructureContext';
import Unit from './Unit';
import { useSubSectionMetadata, useExamRedirect } from './data/hooks';
import {
useSubSectionMetadata,
useExamRedirect,
usePersistentUnitPosition
} from './data/hooks';
export default function SubSection() {
const {
@@ -14,7 +17,7 @@ export default function SubSection() {
blocks,
} = useContext(CourseStructureContext);
const { metadata } = useSubSectionMetadata(courseId, subSectionId);
usePersistentUnitPosition(courseId, subSectionId, unitId, metadata);
useExamRedirect(metadata, blocks);
const ready = blocks !== null && metadata !== null;

View File

@@ -3,9 +3,31 @@ import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
/* eslint-disable import/prefer-default-export */
const getSubSectionXModuleHandlerUrl = (courseId, subSectionId) =>
`${getConfig().LMS_BASE_URL}/courses/${courseId}/xblock/${subSectionId}/handler/xmodule_handler`;
export async function getSubSectionMetadata(courseId, subSectionId) {
const { data } = await getAuthenticatedHttpClient()
.get(`${getConfig().LMS_BASE_URL}/courses/${courseId}/xblock/${subSectionId}/handler/xmodule_handler/metadata`, {});
.get(`${getSubSectionXModuleHandlerUrl(courseId, subSectionId)}/metadata`, {});
return data;
}
export async function saveSubSectionPosition(courseId, subSectionId, position) {
// Post data sent to this endpoint must be url encoded
// TODO: Remove the need for this to be the case.
// TODO: Ensure this usage of URLSearchParams is working in Internet Explorer
const urlEncoded = new URLSearchParams();
urlEncoded.append('position', position);
const requestConfig = {
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
};
const { data } = await getAuthenticatedHttpClient().post(
`${getSubSectionXModuleHandlerUrl(courseId, subSectionId)}/goto_position`,
urlEncoded.toString(),
requestConfig,
);
return data;
}

View File

@@ -1,6 +1,6 @@
import { useState, useEffect } from 'react';
import { getSubSectionMetadata } from './api';
import { getSubSectionMetadata, saveSubSectionPosition } from './api';
export function useSubSectionMetadata(courseId, subSectionId) {
const [metadata, setMetadata] = useState(null);
@@ -29,3 +29,32 @@ export function useExamRedirect(metadata, blocks) {
}
}, [metadata, blocks]);
}
/**
* Save the position of current unit the subsection
*/
export function usePersistentUnitPosition(courseId, subSectionId, unitId, subSectionMetadata) {
useEffect(() => {
// All values must be defined to function
const hasNeededData = courseId && subSectionId && unitId && subSectionMetadata;
if (!hasNeededData) {
return;
}
const { items, save_position: savePosition } = subSectionMetadata;
// A sub-section can individually specify whether positions should be saved
if (!savePosition) {
return;
}
const unitIndex = items.findIndex(({ id }) => unitId === id);
// "position" is a 1-indexed value due to legacy compatibility concerns.
// TODO: Make this value 0-indexed
const newPosition = unitIndex + 1;
// TODO: update the local understanding of the position and
// don't make requests to update the position if they still match?
saveSubSectionPosition(courseId, subSectionId, newPosition);
}, [courseId, subSectionId, unitId, subSectionMetadata]);
}