feature: perfection tracker for levels with best number of commands

This commit is contained in:
Patolord 2024-11-18 09:42:39 -03:00
parent 4cfaa0ae02
commit 928577b2dc
6 changed files with 53 additions and 16 deletions

View file

@ -23,7 +23,7 @@ describe('this store', function() {
expect(LevelStore.isLevelSolved(firstLevel.id))
.toEqual(false);
LevelActions.setLevelSolved(firstLevel.id);
LevelActions.setLevelSolved(firstLevel.id, false);
expect(LevelStore.isLevelSolved(firstLevel.id))
.toEqual(true);
LevelActions.resetLevelsSolved();
@ -31,4 +31,21 @@ describe('this store', function() {
.toEqual(false);
});
it('can solve a level with best status and then reset', function() {
var sequenceMap = LevelStore.getSequenceToLevels();
var firstLevel = sequenceMap[
Object.keys(sequenceMap)[0]
][0];
expect(LevelStore.isLevelBest(firstLevel.id))
.toEqual(false);
LevelActions.setLevelSolved(firstLevel.id, true);
expect(LevelStore.isLevelBest(firstLevel.id))
.toEqual(true);
LevelActions.resetLevelsSolved();
expect(LevelStore.isLevelBest(firstLevel.id))
.toEqual(false);
});
});

View file

@ -7,10 +7,11 @@ var ActionTypes = AppConstants.ActionTypes;
var LevelActions = {
setLevelSolved: function(levelID) {
setLevelSolved: function(levelID, best) {
AppDispatcher.handleViewAction({
type: ActionTypes.SET_LEVEL_SOLVED,
levelID: levelID
levelID: levelID,
best: best
});
},
@ -29,4 +30,4 @@ var LevelActions = {
};
module.exports = LevelActions;
module.exports = LevelActions;

View file

@ -477,11 +477,15 @@ var Level = Sandbox.extend({
levelSolved: function(defer) {
this.solved = true;
if (!this.isShowingSolution) {
LevelActions.setLevelSolved(this.level.id);
var numCommands = this.gitCommandsIssued.length;
var best = this.getNumSolutionCommands();
var isBest = numCommands <= best;
LevelActions.setLevelSolved(this.level.id, isBest);
log.levelSolved(this.getEnglishName());
}
this.hideGoal();
var nextLevel = LevelStore.getNextLevel(this.level.id);

View file

@ -186,11 +186,17 @@ AppConstants.StoreSubscribePrototype,
},
isLevelSolved: function(levelID) {
if (!_levelMap[levelID]) {
throw new Error('that level doesn\'t exist!');
}
return !!_solvedMap[levelID];
var levelData = _solvedMap[levelID];
return levelData ? levelData.solved === true : false;
},
isLevelBest: function(levelID) {
var levelData = _solvedMap[levelID];
return levelData ? levelData.best === true : false;
},
dispatchToken: AppDispatcher.register(function(payload) {
var action = payload.action;
@ -202,8 +208,8 @@ AppConstants.StoreSubscribePrototype,
_syncToStorage();
shouldInform = true;
break;
case ActionTypes.SET_LEVEL_SOLVED:
_solvedMap[action.levelID] = true;
case ActionTypes.SET_LEVEL_SOLVED:
_solvedMap[action.levelID] = { solved: true, best: action.best || false };
_syncToStorage();
shouldInform = true;
break;

View file

@ -402,12 +402,16 @@ var SeriesView = BaseView.extend({
updateSolvedStatus: function() {
// this is a bit hacky, it really should be some nice model
// property changing but it's the 11th hour...
var toLoop = this.$('a.levelIcon').each(function(index, el) {
var id = $(el).attr('data-id');
$(el).toggleClass('solved', LevelStore.isLevelSolved(id));
this.$('a.levelIcon').each(function() {
var $el = $(this);
var id = $el.attr('data-id');
var isSolved = LevelStore.isLevelSolved(id);
var isBest = LevelStore.isLevelBest(id);
$el.toggleClass('solved', isSolved);
$el.toggleClass('best', isBest);
});
},
getEventID: function(ev) {
var element = ev.target;
return $(element).attr('data-id');

View file

@ -1010,6 +1010,11 @@ a.levelIcon.solved:active {
background: #5edb15;
}
a.levelIcon.best {
border-color: gold;
background: gold;
}
a.levelIcon div.index {
font-weight: 400;
text-shadow: 1px 1px 2px #CCC, 0 2px 0 #C9C9C9;