Commit 0485b793 authored by Jakob Moser's avatar Jakob Moser
Browse files

Rename completed -> solved, Use exerciseIndex where necessary

parent bc867105
Loading
Loading
Loading
Loading
+1 −1
Changes for static/js/snakeoil.mjs: 1 added line, 1 removed line.
Original line number Diff line number Diff line
@@ -18,7 +18,7 @@ export function getHandInToken() {
     * 
     * Congratulations, you've found the security issue :)
     * The token for hand-in is just the Base64 encoded current state
     * (which we will later decode to check all exercises are completed), which
     * (which we will later decode to check all exercises are solved), which
     * is of course easily forged. Even if we signed this somehow, it
     * could still be forged, because everything is done client-side
     * and you have full control over the client.
+19 −19
Changes for static/js/state.mjs: 19 added lines, 19 removed lines.
Original line number Diff line number Diff line
@@ -28,8 +28,8 @@ export const currentState = {
    /**
     * Get the index of the exercise the user is currently working on
     */
    get exercise() {
        const exerciseIndex = localStorage.getItem("exercise")
    get exerciseIndex() {
        const exerciseIndex = localStorage.getItem("exerciseIndex")
        if(exerciseIndex === null) {
            return null
        } else {
@@ -38,10 +38,10 @@ export const currentState = {
    },

    /**
     * Set the number of the exercise the user is currently working on.
     * Set the index of the exercise the user is currently working on.
     * 0 <= index < exercises.length
     */
    set exercise(index) {
    set exerciseIndex(index) {
        if(typeof index !== "number") {
            throw new Error("index must be a number")
        }
@@ -50,40 +50,40 @@ export const currentState = {
            throw new Error(`Exercise index must be >= 0 and < exercises.length (${exercises.length})`)
        }

        localStorage.setItem("exercise", index)
        localStorage.setItem("exerciseIndex", index)
    },

    /**
     * Get a list of indices of all completed exercises
     * Get a list of indices of all solved exercises
     */
    get completedExercises() {
        return JSON.parse(localStorage.getItem("completedExercises")) || []
    get solvedExercises() {
        return JSON.parse(localStorage.getItem("solvedExercises")) || []
    },

    /**
     * Private setter for the list of all completed exercises
     * @param {Array} indices Array of indicies of exercises that are completed
     * Private setter for the list of all solved exercises
     * @param {Array} indices Array of indicies of exercises that are solved
     */
    _setCompletedExercises(indices) {
        localStorage.setItem("completedExercises", JSON.stringify(indices))
    _setSolvedExercises(indices) {
        localStorage.setItem("solvedExercises", JSON.stringify(indices))
    },

    /**
     * Mark the given exercise as completed
     * @param {Number} exerciseIndex The index of the exercise to be marked as complete
     * Mark the given exercise as solved
     * @param {Number} exerciseIndex The index of the exercise to be marked as solved
     */
    complete(exerciseIndex) {
        if(this.completedExercises.includes(exerciseIndex)) {
            throw new Error(`Can't complete the same exercise (${exerciseIndex}) twice`)
    markAsSolved(exerciseIndex) {
        if(this.solvedExercises.includes(exerciseIndex)) {
            throw new Error(`Can't solve the same exercise (${exerciseIndex}) twice`)
        }

        if(exerciseIndex < 0 || exerciseIndex > exercises.length) {
            throw new Error(`Exercise index must be >= 0 and < exercises.length (${exercises.length})`)
        }

        const newIndices = this.completedExercises
        const newIndices = this.solvedExercises
        newIndices.push(exerciseIndex)
        this._setCompletedExercises(newIndices)
        this._setSolvedExercises(newIndices)
    },

    /**
+12 −12
Changes for static/js/yalikejazz.mjs: 12 added lines, 12 removed lines.
Original line number Diff line number Diff line
@@ -3,16 +3,16 @@ import { exercises } from "./exercises.mjs"
import { getHandInToken } from "./snakeoil.mjs"
import { createExerciseCard, displayAsSolved, displayAsNonCurrent, displayAsCurrent } from "./exercises.cards.mjs"

function findNextIncompleteExerciseIndex(currentExerciseIndex) {
    if(currentState.completedExercises.length == exercises.length) {
function findNextUnsolvedExerciseIndex(currentExerciseIndex) {
    if(currentState.solvedExercises.length == exercises.length) {
        return null
    } else {
        let nextIncompleteExerciseIndex = currentExerciseIndex
        while(currentState.completedExercises.includes(nextIncompleteExerciseIndex)) {
            nextIncompleteExerciseIndex = (nextIncompleteExerciseIndex+1) % exercises.length
        let nextUnsolvedExerciseIndex = currentExerciseIndex
        while(currentState.solvedExercises.includes(nextUnsolvedExerciseIndex)) {
            nextUnsolvedExerciseIndex = (nextUnsolvedExerciseIndex+1) % exercises.length
        }

        return nextIncompleteExerciseIndex
        return nextUnsolvedExerciseIndex
    }
}

@@ -24,13 +24,13 @@ function findNextIncompleteExerciseIndex(currentExerciseIndex) {
 */
function createAndInitExerciseCard(exercise, exerciseIndex) {
    const cardEl = createExerciseCard(exercise, exerciseIndex, () => {
        if(!currentState.completedExercises.includes(exerciseIndex) && currentState.exercise !== exerciseIndex) {
        if(!currentState.solvedExercises.includes(exerciseIndex) && currentState.exerciseIndex !== exerciseIndex) {
            // Only skip to exercises that are not solved and aren't itself
            startExercise(exerciseIndex)
        }
    })

    if(currentState.completedExercises.includes(exerciseIndex)) {
    if(currentState.solvedExercises.includes(exerciseIndex)) {
        displayAsSolved(cardEl)
    }

@@ -53,15 +53,15 @@ function startExercise(exerciseIndex) {
    const cardEl = document.querySelector(`.exercise[data-exercise-index='${exerciseIndex}']`)
    const exercise = exercises[exerciseIndex]

    currentState.exercise = exerciseIndex
    currentState.exerciseIndex = exerciseIndex
    exercise.onDescribed(description => cardEl.querySelector(".description").textContent = description)
    exercise.onVerified(
        success => {
            if(success) {
                currentState.complete(exerciseIndex)
                currentState.markAsSolved(exerciseIndex)
                displayAsSolved(cardEl)

                const nextExerciseIndex = findNextIncompleteExerciseIndex(exerciseIndex)
                const nextExerciseIndex = findNextUnsolvedExerciseIndex(exerciseIndex)

                if(nextExerciseIndex === null) {
                    alert("You successfully completed the pool test! You can now hand in :)")
@@ -118,7 +118,7 @@ export function main() {
    initActionLinks()

    // If there is no current exercise, start with the first one.
    startExercise(currentState.exercise || 0)
    startExercise(currentState.exerciseIndex || 0)
}

window.onload = main