diff --git a/app/data/dataFileNames.json b/app/data/dataFileNames.json index 467fdd0..96ecfbf 100644 --- a/app/data/dataFileNames.json +++ b/app/data/dataFileNames.json @@ -1 +1 @@ -{"main":"firstModule.json","others":["RfEsZpNK.791f2cda554d18a95fc3734bbe65f88b.json","sArkxak3.bda40d280ffd6baa48d38117905bd5ab.json","2qVqSwId.6c0be3e0610de0d44ac1b294da16d4fd.json","vQrgRbIS.80594ce9bebcfa2809538046c647dde3.json","U77gcZNf.8857dc7179e0813487e12b85611b3b9b.json","RqGMsFtz.aeed2715e184fe51657af9db9ba6f965.json"]} \ No newline at end of file +{"main":"firstModule.json","others":["RfEsZpNK.791f2cda554d18a95fc3734bbe65f88b.json","sArkxak3.bda40d280ffd6baa48d38117905bd5ab.json","2qVqSwId.b86995173d611d4e9c0524bce3ecf6e5.json","vQrgRbIS.80594ce9bebcfa2809538046c647dde3.json","U77gcZNf.8857dc7179e0813487e12b85611b3b9b.json","RqGMsFtz.aeed2715e184fe51657af9db9ba6f965.json"]} \ No newline at end of file diff --git a/app/data/store.js b/app/data/store.js index 8996ae7..6718bf9 100644 --- a/app/data/store.js +++ b/app/data/store.js @@ -27,6 +27,7 @@ import { ANALYTICS_STRINGS, EVENTS, SCORES, + INHERITING_KEYS, } from '../utils/constants'; import logTiming from '../utils/logTiming'; @@ -99,6 +100,14 @@ const store = { }); }, + computeInheritRule(newScoreKey, oldScoreKey) { + if (INHERITING_KEYS.includes(newScoreKey)) { + return [(item) => true, newScoreKey]; + } else if (INHERITING_KEYS.includes(oldScoreKey)) { + return [(item) => item.scoreKey === oldScoreKey, SCORES.LEVEL_0.key]; + } + }, + getItem(idOrItem) { if (typeof idOrItem === `string`) { return this.itemCache[idOrItem]; @@ -221,11 +230,32 @@ const store = { if (!item) return; const updateDom = (typeof options.updateDom !== `undefined`) ? options.updateDom : true; + const oldScoreKey = item.scoreKey; + // caution: update the score summary before updating the item - const updatedItems = this.updateScoreSummary(item, scoreKey, item.scoreKey); + const updatedItems = this.updateScoreSummary(item, scoreKey, oldScoreKey); this.updateItem(item, { scoreKey }, options); + const updateChildren = (parent, inheritRule) => { + const children = this.getChildrenOf(parent.id); + if (!children) return; + + children.forEach((child) => { + if (inheritRule[0](child)) { + this.updateItem(child, { scoreKey: inheritRule[1] }, options); + } + + updateChildren(child, inheritRule); + }); + }; + + const inheritRule = this.computeInheritRule(scoreKey, oldScoreKey); + + if (inheritRule) { + updateChildren(item, inheritRule); + } + if (updateDom) { updatedItems.forEach((updatedItem) => { this.triggerListener(`PIE-${updatedItem.id}`); @@ -241,23 +271,56 @@ const store = { oldScoreKey = oldScoreKey || SCORES.LEVEL_0.key; const updatedItems = []; - const updateParentScore = (child) => { - const parent = this.getParent(child); - if (!parent) return; // we're at the top + const updateSummary = (parent, inheritRule) => { + const children = this.getChildrenOf(parent.id); + if (!children) return; // we're at the bottom updatedItems.push(parent); this.scoreSummary[parent.id] = this.scoreSummary[parent.id] || {}; - this.scoreSummary[parent.id][newScoreKey] = this.scoreSummary[parent.id][newScoreKey] || 0; - this.scoreSummary[parent.id][newScoreKey] += 1; + Object.keys(SCORES).forEach((scoreKey) => { + this.scoreSummary[parent.id][scoreKey] = children + .map((child) => { + this.scoreSummary[child.id] = this.scoreSummary[child.id] || {}; + const scoreSummary = this.scoreSummary[child.id][scoreKey] || 0; + let newValue = child.scoreKey || SCORES.LEVEL_0.key; + + if (child === item) { + newValue = newScoreKey; + } else if (inheritRule) { + if (inheritRule[0](child)) { + newValue = inheritRule[1]; + } + } + + return newValue === scoreKey ? scoreSummary + 1 : scoreSummary; + }) + .reduce((a, b) => a + b, 0); + }); + }; + const updateChildrenScore = (parent, inheritRule) => { + const children = this.getChildrenOf(parent.id); + if (!children) return; // we're at the bottom - if (!newItem) { - this.scoreSummary[parent.id][oldScoreKey] -= 1; - } + children.forEach((child) => { + updateChildrenScore(child, inheritRule); + }); + updateSummary(parent, inheritRule); + }; + const updateParentScore = (child) => { + const parent = this.getParent(child); + if (!parent) return; // we're at the top + + updateSummary(parent); updateParentScore(parent); }; - // we don't update the item directly, only its ancestors + const inheritRule = this.computeInheritRule(newScoreKey, oldScoreKey); + + if (inheritRule) { + updateChildrenScore(item, inheritRule); + } + updateParentScore(item); return updatedItems; diff --git a/app/utils/constants.js b/app/utils/constants.js index 593753b..ff9817d 100644 --- a/app/utils/constants.js +++ b/app/utils/constants.js @@ -131,6 +131,8 @@ export const SCORES = { }, }; +export const INHERITING_KEYS = [SCORES.LEVEL_1.key, SCORES.LEVEL_4.key]; + export const KEYS = { DOWN: 40, ENTER: 13,