mirror of
https://github.com/pcottle/learnGitBranching.git
synced 2025-07-10 06:34:26 +02:00
pretty legit level dropdown
This commit is contained in:
parent
0012c3de54
commit
378fcc0377
10 changed files with 542 additions and 28 deletions
312
build/bundle.js
312
build/bundle.js
|
@ -10026,6 +10026,7 @@ var CanvasTerminalHolder = BaseView.extend({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
exports.BaseView = BaseView;
|
||||||
exports.ModalView = ModalView;
|
exports.ModalView = ModalView;
|
||||||
exports.ModalTerminal = ModalTerminal;
|
exports.ModalTerminal = ModalTerminal;
|
||||||
exports.ModalAlert = ModalAlert;
|
exports.ModalAlert = ModalAlert;
|
||||||
|
@ -15392,15 +15393,21 @@ var sequenceInfo = require('../levels').sequenceInfo;
|
||||||
function LevelArbiter() {
|
function LevelArbiter() {
|
||||||
this.levelMap = {};
|
this.levelMap = {};
|
||||||
this.init();
|
this.init();
|
||||||
|
// TODO -- local storage sync
|
||||||
|
this.solvedMap = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
LevelArbiter.prototype.init = function() {
|
LevelArbiter.prototype.init = function() {
|
||||||
var previousLevelID;
|
var previousLevelID;
|
||||||
_.each(levelSequences, function(levels, levelSequenceName) {
|
_.each(levelSequences, function(levels, levelSequenceName) {
|
||||||
// for this particular sequence...
|
// for this particular sequence...
|
||||||
_.each(levels, function(level) {
|
_.each(levels, function(level, index) {
|
||||||
this.validateLevel(level);
|
this.validateLevel(level);
|
||||||
this.levelMap[level.id] = level;
|
this.levelMap[level.id] = _.extend(
|
||||||
|
{},
|
||||||
|
{ index: index },
|
||||||
|
level
|
||||||
|
);
|
||||||
|
|
||||||
// build up the chaining between levels
|
// build up the chaining between levels
|
||||||
if (previousLevelID) {
|
if (previousLevelID) {
|
||||||
|
@ -15411,6 +15418,18 @@ LevelArbiter.prototype.init = function() {
|
||||||
}, this);
|
}, this);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
LevelArbiter.prototype.getSolvedMap = function() {
|
||||||
|
return this.solvedMap;
|
||||||
|
};
|
||||||
|
|
||||||
|
LevelArbiter.prototype.isLevelSolved = function(id) {
|
||||||
|
if (!this.levelMap[id]) {
|
||||||
|
throw new Error('that level doesnt exist!');
|
||||||
|
}
|
||||||
|
console.log('is it solved', id);
|
||||||
|
return Boolean(this.solvedMap[id]);
|
||||||
|
};
|
||||||
|
|
||||||
LevelArbiter.prototype.validateLevel = function(level) {
|
LevelArbiter.prototype.validateLevel = function(level) {
|
||||||
level = level || {};
|
level = level || {};
|
||||||
var requiredFields = [
|
var requiredFields = [
|
||||||
|
@ -15484,11 +15503,11 @@ exports.levelSequences = {
|
||||||
// there are also cute names and such for sequences
|
// there are also cute names and such for sequences
|
||||||
exports.sequenceInfo = {
|
exports.sequenceInfo = {
|
||||||
intro: {
|
intro: {
|
||||||
name: 'Introduction Sequence',
|
displayName: 'Introduction Sequence',
|
||||||
about: 'A nicely paced introduction to the majority of git commands'
|
about: 'A nicely paced introduction to the majority of git commands'
|
||||||
},
|
},
|
||||||
rebase: {
|
rebase: {
|
||||||
name: 'Master the Rebase Luke!',
|
displayName: 'Master the Rebase Luke!',
|
||||||
about: 'What is this whole rebase hotness everyone is talking about? Find out!'
|
about: 'What is this whole rebase hotness everyone is talking about? Find out!'
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -15800,10 +15819,6 @@ var CommandPromptView = Backbone.View.extend({
|
||||||
((value.length && this.index !== -1 &&
|
((value.length && this.index !== -1 &&
|
||||||
this.commands.toArray()[this.index].get('text') !== value));
|
this.commands.toArray()[this.index].get('text') !== value));
|
||||||
|
|
||||||
if (this.index !== -1) {
|
|
||||||
console.log(this.commands.toArray()[this.index]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!shouldAdd) {
|
if (!shouldAdd) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -16068,6 +16083,129 @@ HeadlessGit.prototype.sendCommand = function(value) {
|
||||||
exports.HeadlessGit = HeadlessGit;
|
exports.HeadlessGit = HeadlessGit;
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
require.define("/src/js/views/levelDropdownView.js",function(require,module,exports,__dirname,__filename,process,global){var _ = require('underscore');
|
||||||
|
var Q = require('q');
|
||||||
|
// horrible hack to get localStorage Backbone plugin
|
||||||
|
var Backbone = (!require('../util').isBrowser()) ? require('backbone') : window.Backbone;
|
||||||
|
|
||||||
|
var util = require('../util');
|
||||||
|
var KeyboardListener = require('../util/keyboard').KeyboardListener;
|
||||||
|
var Main = require('../app');
|
||||||
|
|
||||||
|
var ModalTerminal = require('../views').ModalTerminal;
|
||||||
|
var ContainedBase = require('../views').ContainedBase;
|
||||||
|
var BaseView = require('../views').BaseView;
|
||||||
|
|
||||||
|
var LevelDropdownView = ContainedBase.extend({
|
||||||
|
tagName: 'div',
|
||||||
|
className: 'levelDropdownView box vertical',
|
||||||
|
template: _.template($('#level-dropdown-view').html()),
|
||||||
|
|
||||||
|
initialize: function(options) {
|
||||||
|
options = options || {};
|
||||||
|
this.JSON = {};
|
||||||
|
|
||||||
|
this.navEvents = _.clone(Backbone.Events);
|
||||||
|
this.navEvents.on('clickedID', _.debounce(
|
||||||
|
_.bind(this.loadLevelID, this),
|
||||||
|
300,
|
||||||
|
true
|
||||||
|
));
|
||||||
|
|
||||||
|
this.sequences = Main.getLevelArbiter().getSequences();
|
||||||
|
this.container = new ModalTerminal({
|
||||||
|
title: 'Select a Level'
|
||||||
|
});
|
||||||
|
this.render();
|
||||||
|
this.buildSequences();
|
||||||
|
|
||||||
|
if (!options.wait) {
|
||||||
|
this.show();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
loadLevelID: function(id) {
|
||||||
|
Main.getEventBaton().trigger(
|
||||||
|
'commandSubmitted',
|
||||||
|
'level ' + id
|
||||||
|
);
|
||||||
|
this.hide();
|
||||||
|
},
|
||||||
|
|
||||||
|
updateSolvedStatus: function() {
|
||||||
|
_.each(this.seriesViews, function(view) {
|
||||||
|
view.updateSolvedStatus();
|
||||||
|
}, this);
|
||||||
|
},
|
||||||
|
|
||||||
|
buildSequences: function() {
|
||||||
|
this.seriesViews = [];
|
||||||
|
_.each(this.sequences, function(sequenceName) {
|
||||||
|
this.seriesViews.push(new SeriesView({
|
||||||
|
destination: this.$el,
|
||||||
|
name: sequenceName,
|
||||||
|
navEvents: this.navEvents
|
||||||
|
}));
|
||||||
|
}, this);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var SeriesView = BaseView.extend({
|
||||||
|
tagName: 'div',
|
||||||
|
className: 'seriesView box flex1 vertical',
|
||||||
|
template: _.template($('#series-view').html()),
|
||||||
|
events: {
|
||||||
|
'click div.levelIcon': 'click'
|
||||||
|
},
|
||||||
|
|
||||||
|
initialize: function(options) {
|
||||||
|
this.name = options.name || 'intro';
|
||||||
|
this.navEvents = options.navEvents;
|
||||||
|
this.info = Main.getLevelArbiter().getSequenceInfo(this.name);
|
||||||
|
this.levels = Main.getLevelArbiter().getLevelsInSequence(this.name);
|
||||||
|
|
||||||
|
this.levelIDs = [];
|
||||||
|
_.each(this.levels, function(level) {
|
||||||
|
this.levelIDs.push(level.id);
|
||||||
|
}, this);
|
||||||
|
|
||||||
|
this.destination = options.destination;
|
||||||
|
this.JSON = {
|
||||||
|
displayName: this.info.displayName,
|
||||||
|
about: this.info.about,
|
||||||
|
ids: this.levelIDs
|
||||||
|
};
|
||||||
|
|
||||||
|
this.render();
|
||||||
|
this.updateSolvedStatus();
|
||||||
|
},
|
||||||
|
|
||||||
|
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.$('div.levelIcon').each(function(index, el) {
|
||||||
|
var id = el.id;
|
||||||
|
$(el).toggleClass('solved', Main.getLevelArbiter().isLevelSolved(id));
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
click: function(ev) {
|
||||||
|
console.log(ev.srcElement);
|
||||||
|
console.log(ev.srcElement.id);
|
||||||
|
if (!ev || !ev.srcElement || !ev.srcElement.id) {
|
||||||
|
console.warn('wut, no id'); return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var id = ev.srcElement.id;
|
||||||
|
this.navEvents.trigger('clickedID', id);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
exports.LevelDropdownView = LevelDropdownView;
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
require.define("/src/js/app/index.js",function(require,module,exports,__dirname,__filename,process,global){var _ = require('underscore');
|
require.define("/src/js/app/index.js",function(require,module,exports,__dirname,__filename,process,global){var _ = require('underscore');
|
||||||
|
@ -18434,15 +18572,21 @@ var sequenceInfo = require('../levels').sequenceInfo;
|
||||||
function LevelArbiter() {
|
function LevelArbiter() {
|
||||||
this.levelMap = {};
|
this.levelMap = {};
|
||||||
this.init();
|
this.init();
|
||||||
|
// TODO -- local storage sync
|
||||||
|
this.solvedMap = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
LevelArbiter.prototype.init = function() {
|
LevelArbiter.prototype.init = function() {
|
||||||
var previousLevelID;
|
var previousLevelID;
|
||||||
_.each(levelSequences, function(levels, levelSequenceName) {
|
_.each(levelSequences, function(levels, levelSequenceName) {
|
||||||
// for this particular sequence...
|
// for this particular sequence...
|
||||||
_.each(levels, function(level) {
|
_.each(levels, function(level, index) {
|
||||||
this.validateLevel(level);
|
this.validateLevel(level);
|
||||||
this.levelMap[level.id] = level;
|
this.levelMap[level.id] = _.extend(
|
||||||
|
{},
|
||||||
|
{ index: index },
|
||||||
|
level
|
||||||
|
);
|
||||||
|
|
||||||
// build up the chaining between levels
|
// build up the chaining between levels
|
||||||
if (previousLevelID) {
|
if (previousLevelID) {
|
||||||
|
@ -18453,6 +18597,18 @@ LevelArbiter.prototype.init = function() {
|
||||||
}, this);
|
}, this);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
LevelArbiter.prototype.getSolvedMap = function() {
|
||||||
|
return this.solvedMap;
|
||||||
|
};
|
||||||
|
|
||||||
|
LevelArbiter.prototype.isLevelSolved = function(id) {
|
||||||
|
if (!this.levelMap[id]) {
|
||||||
|
throw new Error('that level doesnt exist!');
|
||||||
|
}
|
||||||
|
console.log('is it solved', id);
|
||||||
|
return Boolean(this.solvedMap[id]);
|
||||||
|
};
|
||||||
|
|
||||||
LevelArbiter.prototype.validateLevel = function(level) {
|
LevelArbiter.prototype.validateLevel = function(level) {
|
||||||
level = level || {};
|
level = level || {};
|
||||||
var requiredFields = [
|
var requiredFields = [
|
||||||
|
@ -19740,7 +19896,8 @@ var toGlobalize = {
|
||||||
Level: require('../level'),
|
Level: require('../level'),
|
||||||
Sandbox: require('../level/sandbox'),
|
Sandbox: require('../level/sandbox'),
|
||||||
GitDemonstrationView: require('../views/gitDemonstrationView'),
|
GitDemonstrationView: require('../views/gitDemonstrationView'),
|
||||||
Markdown: require('markdown')
|
Markdown: require('markdown'),
|
||||||
|
LevelDropdownView: require('../views/levelDropdownView')
|
||||||
};
|
};
|
||||||
|
|
||||||
_.each(toGlobalize, function(module) {
|
_.each(toGlobalize, function(module) {
|
||||||
|
@ -20306,10 +20463,6 @@ var CommandPromptView = Backbone.View.extend({
|
||||||
((value.length && this.index !== -1 &&
|
((value.length && this.index !== -1 &&
|
||||||
this.commands.toArray()[this.index].get('text') !== value));
|
this.commands.toArray()[this.index].get('text') !== value));
|
||||||
|
|
||||||
if (this.index !== -1) {
|
|
||||||
console.log(this.commands.toArray()[this.index]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!shouldAdd) {
|
if (!shouldAdd) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -21210,6 +21363,7 @@ var CanvasTerminalHolder = BaseView.extend({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
exports.BaseView = BaseView;
|
||||||
exports.ModalView = ModalView;
|
exports.ModalView = ModalView;
|
||||||
exports.ModalTerminal = ModalTerminal;
|
exports.ModalTerminal = ModalTerminal;
|
||||||
exports.ModalAlert = ModalAlert;
|
exports.ModalAlert = ModalAlert;
|
||||||
|
@ -21227,9 +21381,129 @@ exports.NextLevelConfirm = NextLevelConfirm;
|
||||||
});
|
});
|
||||||
require("/src/js/views/index.js");
|
require("/src/js/views/index.js");
|
||||||
|
|
||||||
require.define("/src/js/views/levelDropdown.js",function(require,module,exports,__dirname,__filename,process,global){
|
require.define("/src/js/views/levelDropdownView.js",function(require,module,exports,__dirname,__filename,process,global){var _ = require('underscore');
|
||||||
|
var Q = require('q');
|
||||||
|
// horrible hack to get localStorage Backbone plugin
|
||||||
|
var Backbone = (!require('../util').isBrowser()) ? require('backbone') : window.Backbone;
|
||||||
|
|
||||||
|
var util = require('../util');
|
||||||
|
var KeyboardListener = require('../util/keyboard').KeyboardListener;
|
||||||
|
var Main = require('../app');
|
||||||
|
|
||||||
|
var ModalTerminal = require('../views').ModalTerminal;
|
||||||
|
var ContainedBase = require('../views').ContainedBase;
|
||||||
|
var BaseView = require('../views').BaseView;
|
||||||
|
|
||||||
|
var LevelDropdownView = ContainedBase.extend({
|
||||||
|
tagName: 'div',
|
||||||
|
className: 'levelDropdownView box vertical',
|
||||||
|
template: _.template($('#level-dropdown-view').html()),
|
||||||
|
|
||||||
|
initialize: function(options) {
|
||||||
|
options = options || {};
|
||||||
|
this.JSON = {};
|
||||||
|
|
||||||
|
this.navEvents = _.clone(Backbone.Events);
|
||||||
|
this.navEvents.on('clickedID', _.debounce(
|
||||||
|
_.bind(this.loadLevelID, this),
|
||||||
|
300,
|
||||||
|
true
|
||||||
|
));
|
||||||
|
|
||||||
|
this.sequences = Main.getLevelArbiter().getSequences();
|
||||||
|
this.container = new ModalTerminal({
|
||||||
|
title: 'Select a Level'
|
||||||
|
});
|
||||||
|
this.render();
|
||||||
|
this.buildSequences();
|
||||||
|
|
||||||
|
if (!options.wait) {
|
||||||
|
this.show();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
loadLevelID: function(id) {
|
||||||
|
Main.getEventBaton().trigger(
|
||||||
|
'commandSubmitted',
|
||||||
|
'level ' + id
|
||||||
|
);
|
||||||
|
this.hide();
|
||||||
|
},
|
||||||
|
|
||||||
|
updateSolvedStatus: function() {
|
||||||
|
_.each(this.seriesViews, function(view) {
|
||||||
|
view.updateSolvedStatus();
|
||||||
|
}, this);
|
||||||
|
},
|
||||||
|
|
||||||
|
buildSequences: function() {
|
||||||
|
this.seriesViews = [];
|
||||||
|
_.each(this.sequences, function(sequenceName) {
|
||||||
|
this.seriesViews.push(new SeriesView({
|
||||||
|
destination: this.$el,
|
||||||
|
name: sequenceName,
|
||||||
|
navEvents: this.navEvents
|
||||||
|
}));
|
||||||
|
}, this);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
require("/src/js/views/levelDropdown.js");
|
|
||||||
|
var SeriesView = BaseView.extend({
|
||||||
|
tagName: 'div',
|
||||||
|
className: 'seriesView box flex1 vertical',
|
||||||
|
template: _.template($('#series-view').html()),
|
||||||
|
events: {
|
||||||
|
'click div.levelIcon': 'click'
|
||||||
|
},
|
||||||
|
|
||||||
|
initialize: function(options) {
|
||||||
|
this.name = options.name || 'intro';
|
||||||
|
this.navEvents = options.navEvents;
|
||||||
|
this.info = Main.getLevelArbiter().getSequenceInfo(this.name);
|
||||||
|
this.levels = Main.getLevelArbiter().getLevelsInSequence(this.name);
|
||||||
|
|
||||||
|
this.levelIDs = [];
|
||||||
|
_.each(this.levels, function(level) {
|
||||||
|
this.levelIDs.push(level.id);
|
||||||
|
}, this);
|
||||||
|
|
||||||
|
this.destination = options.destination;
|
||||||
|
this.JSON = {
|
||||||
|
displayName: this.info.displayName,
|
||||||
|
about: this.info.about,
|
||||||
|
ids: this.levelIDs
|
||||||
|
};
|
||||||
|
|
||||||
|
this.render();
|
||||||
|
this.updateSolvedStatus();
|
||||||
|
},
|
||||||
|
|
||||||
|
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.$('div.levelIcon').each(function(index, el) {
|
||||||
|
var id = el.id;
|
||||||
|
$(el).toggleClass('solved', Main.getLevelArbiter().isLevelSolved(id));
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
click: function(ev) {
|
||||||
|
console.log(ev.srcElement);
|
||||||
|
console.log(ev.srcElement.id);
|
||||||
|
if (!ev || !ev.srcElement || !ev.srcElement.id) {
|
||||||
|
console.warn('wut, no id'); return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var id = ev.srcElement.id;
|
||||||
|
this.navEvents.trigger('clickedID', id);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
exports.LevelDropdownView = LevelDropdownView;
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
require("/src/js/views/levelDropdownView.js");
|
||||||
|
|
||||||
require.define("/src/js/views/multiView.js",function(require,module,exports,__dirname,__filename,process,global){var _ = require('underscore');
|
require.define("/src/js/views/multiView.js",function(require,module,exports,__dirname,__filename,process,global){var _ = require('underscore');
|
||||||
var Q = require('q');
|
var Q = require('q');
|
||||||
|
@ -24046,11 +24320,11 @@ exports.levelSequences = {
|
||||||
// there are also cute names and such for sequences
|
// there are also cute names and such for sequences
|
||||||
exports.sequenceInfo = {
|
exports.sequenceInfo = {
|
||||||
intro: {
|
intro: {
|
||||||
name: 'Introduction Sequence',
|
displayName: 'Introduction Sequence',
|
||||||
about: 'A nicely paced introduction to the majority of git commands'
|
about: 'A nicely paced introduction to the majority of git commands'
|
||||||
},
|
},
|
||||||
rebase: {
|
rebase: {
|
||||||
name: 'Master the Rebase Luke!',
|
displayName: 'Master the Rebase Luke!',
|
||||||
about: 'What is this whole rebase hotness everyone is talking about? Find out!'
|
about: 'What is this whole rebase hotness everyone is talking about? Find out!'
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -179,6 +179,30 @@
|
||||||
</div>
|
</div>
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<script type="text/html" id="level-dropdown-view">
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script type="text/html" id="series-view">
|
||||||
|
<div class="displayName">
|
||||||
|
<h3> <%= displayName %> </h3>
|
||||||
|
</div>
|
||||||
|
<p class="about">
|
||||||
|
<%= about %>
|
||||||
|
</p>
|
||||||
|
<div class="iconHolder box horizontal">
|
||||||
|
<% for (var i = 0; i < ids.length; i++) { %>
|
||||||
|
<div class="levelIcon box center centerAlign vertical" id="<%=ids[i]%>">
|
||||||
|
<div class="index box" id="<%=ids[i]%>">
|
||||||
|
<i class="icon-ok-circle"></i>
|
||||||
|
<div class="indexNum">
|
||||||
|
<%= i %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% } %>
|
||||||
|
</div>
|
||||||
|
</script>
|
||||||
|
|
||||||
<script type="text/html" id="git-demonstration-view">
|
<script type="text/html" id="git-demonstration-view">
|
||||||
<div class="demonstrationText box vertical">
|
<div class="demonstrationText box vertical">
|
||||||
<div class="beforeText box flex1 vertical center">
|
<div class="beforeText box flex1 vertical center">
|
||||||
|
|
|
@ -9,15 +9,21 @@ var sequenceInfo = require('../levels').sequenceInfo;
|
||||||
function LevelArbiter() {
|
function LevelArbiter() {
|
||||||
this.levelMap = {};
|
this.levelMap = {};
|
||||||
this.init();
|
this.init();
|
||||||
|
// TODO -- local storage sync
|
||||||
|
this.solvedMap = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
LevelArbiter.prototype.init = function() {
|
LevelArbiter.prototype.init = function() {
|
||||||
var previousLevelID;
|
var previousLevelID;
|
||||||
_.each(levelSequences, function(levels, levelSequenceName) {
|
_.each(levelSequences, function(levels, levelSequenceName) {
|
||||||
// for this particular sequence...
|
// for this particular sequence...
|
||||||
_.each(levels, function(level) {
|
_.each(levels, function(level, index) {
|
||||||
this.validateLevel(level);
|
this.validateLevel(level);
|
||||||
this.levelMap[level.id] = level;
|
this.levelMap[level.id] = _.extend(
|
||||||
|
{},
|
||||||
|
{ index: index },
|
||||||
|
level
|
||||||
|
);
|
||||||
|
|
||||||
// build up the chaining between levels
|
// build up the chaining between levels
|
||||||
if (previousLevelID) {
|
if (previousLevelID) {
|
||||||
|
@ -28,6 +34,18 @@ LevelArbiter.prototype.init = function() {
|
||||||
}, this);
|
}, this);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
LevelArbiter.prototype.getSolvedMap = function() {
|
||||||
|
return this.solvedMap;
|
||||||
|
};
|
||||||
|
|
||||||
|
LevelArbiter.prototype.isLevelSolved = function(id) {
|
||||||
|
if (!this.levelMap[id]) {
|
||||||
|
throw new Error('that level doesnt exist!');
|
||||||
|
}
|
||||||
|
console.log('is it solved', id);
|
||||||
|
return Boolean(this.solvedMap[id]);
|
||||||
|
};
|
||||||
|
|
||||||
LevelArbiter.prototype.validateLevel = function(level) {
|
LevelArbiter.prototype.validateLevel = function(level) {
|
||||||
level = level || {};
|
level = level || {};
|
||||||
var requiredFields = [
|
var requiredFields = [
|
||||||
|
|
|
@ -21,7 +21,8 @@ var toGlobalize = {
|
||||||
Level: require('../level'),
|
Level: require('../level'),
|
||||||
Sandbox: require('../level/sandbox'),
|
Sandbox: require('../level/sandbox'),
|
||||||
GitDemonstrationView: require('../views/gitDemonstrationView'),
|
GitDemonstrationView: require('../views/gitDemonstrationView'),
|
||||||
Markdown: require('markdown')
|
Markdown: require('markdown'),
|
||||||
|
LevelDropdownView: require('../views/levelDropdownView')
|
||||||
};
|
};
|
||||||
|
|
||||||
_.each(toGlobalize, function(module) {
|
_.each(toGlobalize, function(module) {
|
||||||
|
|
|
@ -206,10 +206,6 @@ var CommandPromptView = Backbone.View.extend({
|
||||||
((value.length && this.index !== -1 &&
|
((value.length && this.index !== -1 &&
|
||||||
this.commands.toArray()[this.index].get('text') !== value));
|
this.commands.toArray()[this.index].get('text') !== value));
|
||||||
|
|
||||||
if (this.index !== -1) {
|
|
||||||
console.log(this.commands.toArray()[this.index]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!shouldAdd) {
|
if (!shouldAdd) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -523,6 +523,7 @@ var CanvasTerminalHolder = BaseView.extend({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
exports.BaseView = BaseView;
|
||||||
exports.ModalView = ModalView;
|
exports.ModalView = ModalView;
|
||||||
exports.ModalTerminal = ModalTerminal;
|
exports.ModalTerminal = ModalTerminal;
|
||||||
exports.ModalAlert = ModalAlert;
|
exports.ModalAlert = ModalAlert;
|
||||||
|
|
120
src/js/views/levelDropdownView.js
Normal file
120
src/js/views/levelDropdownView.js
Normal file
|
@ -0,0 +1,120 @@
|
||||||
|
var _ = require('underscore');
|
||||||
|
var Q = require('q');
|
||||||
|
// horrible hack to get localStorage Backbone plugin
|
||||||
|
var Backbone = (!require('../util').isBrowser()) ? require('backbone') : window.Backbone;
|
||||||
|
|
||||||
|
var util = require('../util');
|
||||||
|
var KeyboardListener = require('../util/keyboard').KeyboardListener;
|
||||||
|
var Main = require('../app');
|
||||||
|
|
||||||
|
var ModalTerminal = require('../views').ModalTerminal;
|
||||||
|
var ContainedBase = require('../views').ContainedBase;
|
||||||
|
var BaseView = require('../views').BaseView;
|
||||||
|
|
||||||
|
var LevelDropdownView = ContainedBase.extend({
|
||||||
|
tagName: 'div',
|
||||||
|
className: 'levelDropdownView box vertical',
|
||||||
|
template: _.template($('#level-dropdown-view').html()),
|
||||||
|
|
||||||
|
initialize: function(options) {
|
||||||
|
options = options || {};
|
||||||
|
this.JSON = {};
|
||||||
|
|
||||||
|
this.navEvents = _.clone(Backbone.Events);
|
||||||
|
this.navEvents.on('clickedID', _.debounce(
|
||||||
|
_.bind(this.loadLevelID, this),
|
||||||
|
300,
|
||||||
|
true
|
||||||
|
));
|
||||||
|
|
||||||
|
this.sequences = Main.getLevelArbiter().getSequences();
|
||||||
|
this.container = new ModalTerminal({
|
||||||
|
title: 'Select a Level'
|
||||||
|
});
|
||||||
|
this.render();
|
||||||
|
this.buildSequences();
|
||||||
|
|
||||||
|
if (!options.wait) {
|
||||||
|
this.show();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
loadLevelID: function(id) {
|
||||||
|
Main.getEventBaton().trigger(
|
||||||
|
'commandSubmitted',
|
||||||
|
'level ' + id
|
||||||
|
);
|
||||||
|
this.hide();
|
||||||
|
},
|
||||||
|
|
||||||
|
updateSolvedStatus: function() {
|
||||||
|
_.each(this.seriesViews, function(view) {
|
||||||
|
view.updateSolvedStatus();
|
||||||
|
}, this);
|
||||||
|
},
|
||||||
|
|
||||||
|
buildSequences: function() {
|
||||||
|
this.seriesViews = [];
|
||||||
|
_.each(this.sequences, function(sequenceName) {
|
||||||
|
this.seriesViews.push(new SeriesView({
|
||||||
|
destination: this.$el,
|
||||||
|
name: sequenceName,
|
||||||
|
navEvents: this.navEvents
|
||||||
|
}));
|
||||||
|
}, this);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var SeriesView = BaseView.extend({
|
||||||
|
tagName: 'div',
|
||||||
|
className: 'seriesView box flex1 vertical',
|
||||||
|
template: _.template($('#series-view').html()),
|
||||||
|
events: {
|
||||||
|
'click div.levelIcon': 'click'
|
||||||
|
},
|
||||||
|
|
||||||
|
initialize: function(options) {
|
||||||
|
this.name = options.name || 'intro';
|
||||||
|
this.navEvents = options.navEvents;
|
||||||
|
this.info = Main.getLevelArbiter().getSequenceInfo(this.name);
|
||||||
|
this.levels = Main.getLevelArbiter().getLevelsInSequence(this.name);
|
||||||
|
|
||||||
|
this.levelIDs = [];
|
||||||
|
_.each(this.levels, function(level) {
|
||||||
|
this.levelIDs.push(level.id);
|
||||||
|
}, this);
|
||||||
|
|
||||||
|
this.destination = options.destination;
|
||||||
|
this.JSON = {
|
||||||
|
displayName: this.info.displayName,
|
||||||
|
about: this.info.about,
|
||||||
|
ids: this.levelIDs
|
||||||
|
};
|
||||||
|
|
||||||
|
this.render();
|
||||||
|
this.updateSolvedStatus();
|
||||||
|
},
|
||||||
|
|
||||||
|
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.$('div.levelIcon').each(function(index, el) {
|
||||||
|
var id = el.id;
|
||||||
|
$(el).toggleClass('solved', Main.getLevelArbiter().isLevelSolved(id));
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
click: function(ev) {
|
||||||
|
console.log(ev.srcElement);
|
||||||
|
console.log(ev.srcElement.id);
|
||||||
|
if (!ev || !ev.srcElement || !ev.srcElement.id) {
|
||||||
|
console.warn('wut, no id'); return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var id = ev.srcElement.id;
|
||||||
|
this.navEvents.trigger('clickedID', id);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
exports.LevelDropdownView = LevelDropdownView;
|
||||||
|
|
|
@ -14,11 +14,11 @@ exports.levelSequences = {
|
||||||
// there are also cute names and such for sequences
|
// there are also cute names and such for sequences
|
||||||
exports.sequenceInfo = {
|
exports.sequenceInfo = {
|
||||||
intro: {
|
intro: {
|
||||||
name: 'Introduction Sequence',
|
displayName: 'Introduction Sequence',
|
||||||
about: 'A nicely paced introduction to the majority of git commands'
|
about: 'A nicely paced introduction to the majority of git commands'
|
||||||
},
|
},
|
||||||
rebase: {
|
rebase: {
|
||||||
name: 'Master the Rebase Luke!',
|
displayName: 'Master the Rebase Luke!',
|
||||||
about: 'What is this whole rebase hotness everyone is talking about? Find out!'
|
about: 'What is this whole rebase hotness everyone is talking about? Find out!'
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -556,6 +556,86 @@ li.rebaseEntry.notPicked {
|
||||||
-webkit-transform: translate3d(0,0,0);
|
-webkit-transform: translate3d(0,0,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Level dropdown view */
|
||||||
|
.levelDropdownView {
|
||||||
|
}
|
||||||
|
|
||||||
|
div.displayName {
|
||||||
|
border-bottom: 1px dashed grey;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.displayName h3 {
|
||||||
|
margin: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.iconHolder {
|
||||||
|
}
|
||||||
|
|
||||||
|
div.seriesView p.about {
|
||||||
|
margin: 0px;
|
||||||
|
padding: 4px;
|
||||||
|
font-size: 10px;
|
||||||
|
color: #CCC;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.levelIcon {
|
||||||
|
height: 40px;
|
||||||
|
width: 40px;
|
||||||
|
border-radius: 5px;
|
||||||
|
margin: 10px 20px;
|
||||||
|
box-shadow: 2px 2px 10px rgba(0,0,0,0.7);
|
||||||
|
background-image: -webkit-linear-gradient(top, white, #AAB1AA);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.levelIcon:hover {
|
||||||
|
background-image: -webkit-linear-gradient(top, #DADADA, #888686);
|
||||||
|
}
|
||||||
|
|
||||||
|
div.levelIcon:active {
|
||||||
|
background-image: -webkit-linear-gradient(top, #888686, #7A7A7A)
|
||||||
|
}
|
||||||
|
|
||||||
|
div.levelIcon.solved {
|
||||||
|
background: -webkit-gradient(linear, left top, left bottom, from(#F3F86B), to(#35A30F));
|
||||||
|
border-top: 1px solid #f4ffa1;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.levelIcon.solved:hover {
|
||||||
|
border-top-color: #30f03d;
|
||||||
|
background: #30f03d;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.levelIcon.solved:active {
|
||||||
|
border-top-color: #5edb15;
|
||||||
|
background: #5edb15;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.levelIcon div.index {
|
||||||
|
font-weight: 400;
|
||||||
|
text-shadow: 1px 1px 2px #CCC, 0 2px 0 #C9C9C9;
|
||||||
|
font-size: 20px;
|
||||||
|
color: #333;
|
||||||
|
-webkit-text-stroke: 1px #111;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.levelIcon div.index i {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.levelIcon.solved div.index i {
|
||||||
|
display: block;
|
||||||
|
color: white;
|
||||||
|
-webkit-text-stroke: 0;
|
||||||
|
text-shadow: none;
|
||||||
|
font-size: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.levelIcon.solved div.index div.indexNum {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
/* Git demonstration view */
|
/* Git demonstration view */
|
||||||
|
|
||||||
.gitDemonstrationView > div.demonstrationText {
|
.gitDemonstrationView > div.demonstrationText {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue