Skip to content

Commit 24162fa

Browse files
committed
Add basic method for passedState
1 parent e2328ad commit 24162fa

File tree

1 file changed

+62
-13
lines changed

1 file changed

+62
-13
lines changed

static/js/passedState.js

Lines changed: 62 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,25 @@
11

22

33
class PassedState {
4+
5+
_key = 'passedState';
6+
state = null;
7+
48
constructor(initialState = {}) {
5-
const currentState = localStorage.getItem('passedState');
9+
const currentState = localStorage.getItem(this._key);
610
// initialize the state when there is no state in the local storage.
7-
if (!currentState) {
8-
if (!initialState) {
9-
throw new Error('initial state is required when there is no state in the local storage.');
10-
}
11-
12-
const state = this._prepareState(initialState);
13-
localStorage.setItem('passedState', JSON.stringify(state));
14-
this.state = state;
15-
return;
11+
if (!currentState && !initialState) {
12+
throw new Error('initial state is required when there is no state in the local storage.');
1613
}
1714

18-
if (currentState) {
19-
this.state = JSON.parse(currentState);
20-
}
15+
// add passed property to the challenges in the initial state.
16+
const rawState = this._prepareState(initialState);
17+
18+
// check new state and old state whether is undefined or not. and merge the new state to the old state.
19+
const state = this._checkAndMerge(rawState, currentState);
20+
this._save(state);
21+
this.state = state;
22+
return
2123
}
2224

2325
/**
@@ -26,6 +28,10 @@ class PassedState {
2628
* @returns state - the state contains the challenge name and whether the challenge is passed.
2729
*/
2830
_prepareState(rawState) {
31+
if (!rawState) {
32+
return {};
33+
}
34+
2935
const state = {};
3036
for (const level in rawState) {
3137
const challenges = [];
@@ -40,4 +46,47 @@ class PassedState {
4046

4147
return state;
4248
}
49+
50+
get() {
51+
return this.state;
52+
}
53+
54+
_save(state) {
55+
localStorage.setItem(this._key, JSON.stringify(state));
56+
}
57+
58+
/**
59+
* Set the challenge as passed in the state.
60+
* @param {'basic' | 'intermediate' | 'advanced' | 'extreme'} level - the level of the challenge.
61+
* @param {string} challengeName - the name of the challenge.
62+
* @returns void
63+
*/
64+
setPassed(level, challengeName) {
65+
const challenges = this.state[level];
66+
for (const challenge of challenges) {
67+
if (challenge.name === challengeName) {
68+
challenge.passed = true;
69+
break;
70+
}
71+
}
72+
73+
this._save(this.state);
74+
}
75+
76+
/**
77+
* Merge the new state to the current state. this function will compare the new state with the current state and finally overwrite the current state based on the new state:
78+
* - If the old key in the current state is not in the new state, the old key will be removed from the current state.
79+
* - If the new key in the new state is not in the current state, the new key will be added to the current state.
80+
* @param {object} newState
81+
*/
82+
_checkAndMerge(newState, oldState) {
83+
if (!newState && !oldState) {
84+
throw new Error('one of the new state and the old state is required.');
85+
}
86+
87+
if (!newState) {
88+
return oldState;
89+
}
90+
// TODO: compare the new state with the old state and merge the new state to the old state.
91+
}
4392
}

0 commit comments

Comments
 (0)