3
3
class PassedState {
4
4
5
5
_key = 'passedState' ;
6
- state = null ;
6
+ _state = null ;
7
7
8
8
constructor ( initialState = { } ) {
9
9
const currentState = localStorage . getItem ( this . _key ) ;
@@ -16,9 +16,9 @@ class PassedState {
16
16
const rawState = this . _prepareState ( initialState ) ;
17
17
18
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 ) ;
19
+ const state = this . _checkAndMerge ( currentState , rawState ) ;
20
20
this . _save ( state ) ;
21
- this . state = state ;
21
+ this . _state = state ;
22
22
return
23
23
}
24
24
@@ -48,7 +48,7 @@ class PassedState {
48
48
}
49
49
50
50
get ( ) {
51
- return this . state ;
51
+ return this . _state ;
52
52
}
53
53
54
54
_save ( state ) {
@@ -62,15 +62,15 @@ class PassedState {
62
62
* @returns void
63
63
*/
64
64
setPassed ( level , challengeName ) {
65
- const challenges = this . state [ level ] ;
65
+ const challenges = this . _state [ level ] ;
66
66
for ( const challenge of challenges ) {
67
67
if ( challenge . name === challengeName ) {
68
68
challenge . passed = true ;
69
69
break ;
70
70
}
71
71
}
72
72
73
- this . _save ( this . state ) ;
73
+ this . _save ( this . _state ) ;
74
74
}
75
75
76
76
/**
@@ -79,14 +79,41 @@ class PassedState {
79
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
80
* @param {object } newState
81
81
*/
82
- _checkAndMerge ( newState , oldState ) {
82
+ _checkAndMerge ( oldState , newState ) {
83
83
if ( ! newState && ! oldState ) {
84
84
throw new Error ( 'one of the new state and the old state is required.' ) ;
85
85
}
86
86
87
87
if ( ! newState ) {
88
88
return oldState ;
89
89
}
90
- // TODO: compare the new state with the old state and merge the new state to the old state.
90
+
91
+ let mergedState = { } ;
92
+ const levels = [ 'basic' , 'intermediate' , 'advanced' , 'expert' ] ;
93
+
94
+ for ( const level of levels ) {
95
+ // Initialize an empty array for merged challenges
96
+ let mergedChallenges = [ ] ;
97
+
98
+ // Create a map for quick lookup of challenges by name
99
+ const oldChallengesMap = new Map ( oldState [ level ] . map ( challenge => [ challenge . name , challenge ] ) ) ;
100
+ const newChallengesMap = new Map ( newState [ level ] . map ( challenge => [ challenge . name , challenge ] ) ) ;
101
+
102
+ // Add or update challenges from the newState
103
+ for ( const [ name , newChallenge ] of newChallengesMap . entries ( ) ) {
104
+ mergedChallenges . push ( { ...newChallenge , passed : oldChallengesMap . get ( name ) ?. passed } ) ;
105
+ oldChallengesMap . delete ( name ) ; // Remove the challenge from oldChallengesMap since it's updated
106
+ }
107
+
108
+ // Add remaining challenges from the oldState that are not updated (not present in newState)
109
+ for ( const oldChallenge of oldChallengesMap . values ( ) ) {
110
+ mergedChallenges . push ( oldChallenge ) ;
111
+ }
112
+
113
+ // Set the merged challenges for the current level in the mergedState
114
+ mergedState [ level ] = mergedChallenges ;
115
+ }
116
+
117
+ return mergedState ;
91
118
}
92
119
}
0 commit comments