diff --git a/build/bundle.js b/build/bundle.js index 88ff7a3a..f2fb5096 100644 --- a/build/bundle.js +++ b/build/bundle.js @@ -15518,6 +15518,10 @@ LevelArbiter.prototype.validateLevel = function(level) { } }; +LevelArbiter.prototype.getSequenceToLevels = function() { + return levelSequences; +}; + LevelArbiter.prototype.getSequences = function() { return _.keys(levelSequences); }; @@ -15563,7 +15567,8 @@ exports.levelSequences = { ], rebase: [ require('../../levels/rebase/1').level, - require('../../levels/rebase/2').level + require('../../levels/rebase/2').level, + require('../../levels/rebase/3').level ] }; @@ -15637,6 +15642,17 @@ require.define("/src/levels/rebase/2.js",function(require,module,exports,__dirna }; +}); + +require.define("/src/levels/rebase/3.js",function(require,module,exports,__dirname,__filename,process,global){exports.level = { + id: 'rebase3', + name: 'Introduction #1', + goalTreeString: '{"branches":{"master":{"target":"C1","id":"master"},"win":{"target":"C2","id":"win"}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"}},"HEAD":{"target":"win","id":"HEAD"}}', + solutionCommand: 'git checkout -b win; git commit', + hint: 'Try checking out a branch named after Charlie Sheen' +}; + + }); require.define("/src/js/views/levelDropdownView.js",function(require,module,exports,__dirname,__filename,process,global){var _ = require('underscore'); @@ -15670,15 +15686,24 @@ var LevelDropdownView = ContainedBase.extend({ true )); this.navEvents.on('negative', this.negative, this); + this.navEvents.on('positive', this.positive, this); + this.navEvents.on('left', this.left, this); + this.navEvents.on('right', this.right, this); + this.navEvents.on('up', this.up, this); + this.navEvents.on('down', this.down, this); + this.keyboardListener = new KeyboardListener({ events: this.navEvents, aliasMap: { - esc: 'negative' + esc: 'negative', + enter: 'positive' }, wait: true }); this.sequences = Main.getLevelArbiter().getSequences(); + this.sequenceToLevels = Main.getLevelArbiter().getSequenceToLevels(); + this.container = new ModalTerminal({ title: 'Select a Level' }); @@ -15690,6 +15715,148 @@ var LevelDropdownView = ContainedBase.extend({ } }, + positive: function() { + if (!this.selectedID) { + return; + } + this.loadLevelID(this.selectedID); + }, + + left: function() { + if (this.turnOnKeyboardSelection()) { + return; + } + this.leftOrRight(-1); + }, + + leftOrRight: function(delta) { + this.deselectIconByID(this.selectedID); + this.selectedIndex = this.wrapIndex(this.selectedIndex + delta, this.getCurrentSequence()); + this.selectedID = this.getSelectedID(); + this.selectIconByID(this.selectedID); + }, + + right: function() { + if (this.turnOnKeyboardSelection()) { + return; + } + this.leftOrRight(1); + }, + + up: function() { + if (this.turnOnKeyboardSelection()) { + return; + } + this.selectedSequence = this.getPreviousSequence(); + this.downOrUp(); + }, + + down: function() { + if (this.turnOnKeyboardSelection()) { + return; + } + this.selectedSequence = this.getNextSequence(); + this.downOrUp(); + }, + + downOrUp: function() { + this.selectedIndex = this.boundIndex(this.selectedIndex, this.getCurrentSequence()); + this.deselectIconByID(this.selectedID); + this.selectedID = this.getSelectedID(); + this.selectIconByID(this.selectedID); + }, + + turnOnKeyboardSelection: function() { + if (!this.selectedID) { + this.selectFirst(); + return true; + } + return false; + }, + + turnOffKeyboardSelection: function() { + if (!this.selectedID) { return; } + this.deselectIconByID(this.selectedID); + this.selectedID = undefined; + this.selectedIndex = undefined; + this.selectedSequence = undefined; + }, + + wrapIndex: function(index, arr) { + index = (index >= arr.length) ? 0 : index; + index = (index < 0) ? arr.length - 1 : index; + return index; + }, + + boundIndex: function(index, arr) { + index = (index >= arr.length) ? arr.length - 1 : index; + index = (index < 0) ? 0 : index; + return index; + }, + + getNextSequence: function() { + var current = this.getSequenceIndex(this.selectedSequence); + var desired = this.wrapIndex(current + 1, this.sequences); + return this.sequences[desired]; + }, + + getPreviousSequence: function() { + var current = this.getSequenceIndex(this.selectedSequence); + var desired = this.wrapIndex(current - 1, this.sequences); + return this.sequences[desired]; + }, + + getSequenceIndex: function(name) { + var index; + _.each(this.sequences, function(_name, _index) { + if (_name == name) { + index = _index; + } + }); + if (index === undefined) { throw new Error('didnt find'); } + return index; + }, + + getIndexForID: function(id) { + var index; + var levels = this.sequenceToLevels[this.selectedSequence]; + _.each(levels, function(level, _index) { + if (level.id == id) { + index = _index; + } + }); + return index; + }, + + selectFirst: function() { + var firstID = this.sequenceToLevels[this.sequences[0]][0].id; + this.selectIconByID(firstID); + this.selectedIndex = 0; + this.selectedSequence = this.sequences[0]; + }, + + getCurrentSequence: function() { + return this.sequenceToLevels[this.selectedSequence]; + }, + + getSelectedID: function() { + return this.sequenceToLevels[this.selectedSequence][this.selectedIndex].id; + }, + + selectIconByID: function(id) { + this.toggleIconSelect(id, true); + }, + + deselectIconByID: function(id) { + this.toggleIconSelect(id, false); + }, + + toggleIconSelect: function(id, value) { + this.selectedID = id; + var selector = '#levelIcon-' + id; + $(selector).toggleClass('selected', value); + }, + negative: function() { this.hide(); }, @@ -15706,6 +15873,7 @@ var LevelDropdownView = ContainedBase.extend({ } this.showDeferred = undefined; this.keyboardListener.mute(); + this.turnOffKeyboardSelection(); LevelDropdownView.__super__.hide.apply(this); }, @@ -18768,6 +18936,10 @@ LevelArbiter.prototype.validateLevel = function(level) { } }; +LevelArbiter.prototype.getSequenceToLevels = function() { + return levelSequences; +}; + LevelArbiter.prototype.getSequences = function() { return _.keys(levelSequences); }; @@ -21586,15 +21758,24 @@ var LevelDropdownView = ContainedBase.extend({ true )); this.navEvents.on('negative', this.negative, this); + this.navEvents.on('positive', this.positive, this); + this.navEvents.on('left', this.left, this); + this.navEvents.on('right', this.right, this); + this.navEvents.on('up', this.up, this); + this.navEvents.on('down', this.down, this); + this.keyboardListener = new KeyboardListener({ events: this.navEvents, aliasMap: { - esc: 'negative' + esc: 'negative', + enter: 'positive' }, wait: true }); this.sequences = Main.getLevelArbiter().getSequences(); + this.sequenceToLevels = Main.getLevelArbiter().getSequenceToLevels(); + this.container = new ModalTerminal({ title: 'Select a Level' }); @@ -21606,6 +21787,148 @@ var LevelDropdownView = ContainedBase.extend({ } }, + positive: function() { + if (!this.selectedID) { + return; + } + this.loadLevelID(this.selectedID); + }, + + left: function() { + if (this.turnOnKeyboardSelection()) { + return; + } + this.leftOrRight(-1); + }, + + leftOrRight: function(delta) { + this.deselectIconByID(this.selectedID); + this.selectedIndex = this.wrapIndex(this.selectedIndex + delta, this.getCurrentSequence()); + this.selectedID = this.getSelectedID(); + this.selectIconByID(this.selectedID); + }, + + right: function() { + if (this.turnOnKeyboardSelection()) { + return; + } + this.leftOrRight(1); + }, + + up: function() { + if (this.turnOnKeyboardSelection()) { + return; + } + this.selectedSequence = this.getPreviousSequence(); + this.downOrUp(); + }, + + down: function() { + if (this.turnOnKeyboardSelection()) { + return; + } + this.selectedSequence = this.getNextSequence(); + this.downOrUp(); + }, + + downOrUp: function() { + this.selectedIndex = this.boundIndex(this.selectedIndex, this.getCurrentSequence()); + this.deselectIconByID(this.selectedID); + this.selectedID = this.getSelectedID(); + this.selectIconByID(this.selectedID); + }, + + turnOnKeyboardSelection: function() { + if (!this.selectedID) { + this.selectFirst(); + return true; + } + return false; + }, + + turnOffKeyboardSelection: function() { + if (!this.selectedID) { return; } + this.deselectIconByID(this.selectedID); + this.selectedID = undefined; + this.selectedIndex = undefined; + this.selectedSequence = undefined; + }, + + wrapIndex: function(index, arr) { + index = (index >= arr.length) ? 0 : index; + index = (index < 0) ? arr.length - 1 : index; + return index; + }, + + boundIndex: function(index, arr) { + index = (index >= arr.length) ? arr.length - 1 : index; + index = (index < 0) ? 0 : index; + return index; + }, + + getNextSequence: function() { + var current = this.getSequenceIndex(this.selectedSequence); + var desired = this.wrapIndex(current + 1, this.sequences); + return this.sequences[desired]; + }, + + getPreviousSequence: function() { + var current = this.getSequenceIndex(this.selectedSequence); + var desired = this.wrapIndex(current - 1, this.sequences); + return this.sequences[desired]; + }, + + getSequenceIndex: function(name) { + var index; + _.each(this.sequences, function(_name, _index) { + if (_name == name) { + index = _index; + } + }); + if (index === undefined) { throw new Error('didnt find'); } + return index; + }, + + getIndexForID: function(id) { + var index; + var levels = this.sequenceToLevels[this.selectedSequence]; + _.each(levels, function(level, _index) { + if (level.id == id) { + index = _index; + } + }); + return index; + }, + + selectFirst: function() { + var firstID = this.sequenceToLevels[this.sequences[0]][0].id; + this.selectIconByID(firstID); + this.selectedIndex = 0; + this.selectedSequence = this.sequences[0]; + }, + + getCurrentSequence: function() { + return this.sequenceToLevels[this.selectedSequence]; + }, + + getSelectedID: function() { + return this.sequenceToLevels[this.selectedSequence][this.selectedIndex].id; + }, + + selectIconByID: function(id) { + this.toggleIconSelect(id, true); + }, + + deselectIconByID: function(id) { + this.toggleIconSelect(id, false); + }, + + toggleIconSelect: function(id, value) { + this.selectedID = id; + var selector = '#levelIcon-' + id; + $(selector).toggleClass('selected', value); + }, + negative: function() { this.hide(); }, @@ -21622,6 +21945,7 @@ var LevelDropdownView = ContainedBase.extend({ } this.showDeferred = undefined; this.keyboardListener.mute(); + this.turnOffKeyboardSelection(); LevelDropdownView.__super__.hide.apply(this); }, @@ -24515,7 +24839,8 @@ exports.levelSequences = { ], rebase: [ require('../../levels/rebase/1').level, - require('../../levels/rebase/2').level + require('../../levels/rebase/2').level, + require('../../levels/rebase/3').level ] }; @@ -24596,4 +24921,16 @@ require.define("/src/levels/rebase/2.js",function(require,module,exports,__dirna }); require("/src/levels/rebase/2.js"); +require.define("/src/levels/rebase/3.js",function(require,module,exports,__dirname,__filename,process,global){exports.level = { + id: 'rebase3', + name: 'Introduction #1', + goalTreeString: '{"branches":{"master":{"target":"C1","id":"master"},"win":{"target":"C2","id":"win"}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"}},"HEAD":{"target":"win","id":"HEAD"}}', + solutionCommand: 'git checkout -b win; git commit', + hint: 'Try checking out a branch named after Charlie Sheen' +}; + + +}); +require("/src/levels/rebase/3.js"); + })(); diff --git a/src/index.html b/src/index.html index 4249d31a..c91cd51d 100644 --- a/src/index.html +++ b/src/index.html @@ -191,7 +191,7 @@

<% for (var i = 0; i < ids.length; i++) { %> -
+
diff --git a/src/js/level/arbiter.js b/src/js/level/arbiter.js index 232a6f45..9aba919a 100644 --- a/src/js/level/arbiter.js +++ b/src/js/level/arbiter.js @@ -89,6 +89,10 @@ LevelArbiter.prototype.validateLevel = function(level) { } }; +LevelArbiter.prototype.getSequenceToLevels = function() { + return levelSequences; +}; + LevelArbiter.prototype.getSequences = function() { return _.keys(levelSequences); }; diff --git a/src/js/views/levelDropdownView.js b/src/js/views/levelDropdownView.js index 59b3a9e3..050ba59e 100644 --- a/src/js/views/levelDropdownView.js +++ b/src/js/views/levelDropdownView.js @@ -29,15 +29,24 @@ var LevelDropdownView = ContainedBase.extend({ true )); this.navEvents.on('negative', this.negative, this); + this.navEvents.on('positive', this.positive, this); + this.navEvents.on('left', this.left, this); + this.navEvents.on('right', this.right, this); + this.navEvents.on('up', this.up, this); + this.navEvents.on('down', this.down, this); + this.keyboardListener = new KeyboardListener({ events: this.navEvents, aliasMap: { - esc: 'negative' + esc: 'negative', + enter: 'positive' }, wait: true }); this.sequences = Main.getLevelArbiter().getSequences(); + this.sequenceToLevels = Main.getLevelArbiter().getSequenceToLevels(); + this.container = new ModalTerminal({ title: 'Select a Level' }); @@ -49,6 +58,148 @@ var LevelDropdownView = ContainedBase.extend({ } }, + positive: function() { + if (!this.selectedID) { + return; + } + this.loadLevelID(this.selectedID); + }, + + left: function() { + if (this.turnOnKeyboardSelection()) { + return; + } + this.leftOrRight(-1); + }, + + leftOrRight: function(delta) { + this.deselectIconByID(this.selectedID); + this.selectedIndex = this.wrapIndex(this.selectedIndex + delta, this.getCurrentSequence()); + this.selectedID = this.getSelectedID(); + this.selectIconByID(this.selectedID); + }, + + right: function() { + if (this.turnOnKeyboardSelection()) { + return; + } + this.leftOrRight(1); + }, + + up: function() { + if (this.turnOnKeyboardSelection()) { + return; + } + this.selectedSequence = this.getPreviousSequence(); + this.downOrUp(); + }, + + down: function() { + if (this.turnOnKeyboardSelection()) { + return; + } + this.selectedSequence = this.getNextSequence(); + this.downOrUp(); + }, + + downOrUp: function() { + this.selectedIndex = this.boundIndex(this.selectedIndex, this.getCurrentSequence()); + this.deselectIconByID(this.selectedID); + this.selectedID = this.getSelectedID(); + this.selectIconByID(this.selectedID); + }, + + turnOnKeyboardSelection: function() { + if (!this.selectedID) { + this.selectFirst(); + return true; + } + return false; + }, + + turnOffKeyboardSelection: function() { + if (!this.selectedID) { return; } + this.deselectIconByID(this.selectedID); + this.selectedID = undefined; + this.selectedIndex = undefined; + this.selectedSequence = undefined; + }, + + wrapIndex: function(index, arr) { + index = (index >= arr.length) ? 0 : index; + index = (index < 0) ? arr.length - 1 : index; + return index; + }, + + boundIndex: function(index, arr) { + index = (index >= arr.length) ? arr.length - 1 : index; + index = (index < 0) ? 0 : index; + return index; + }, + + getNextSequence: function() { + var current = this.getSequenceIndex(this.selectedSequence); + var desired = this.wrapIndex(current + 1, this.sequences); + return this.sequences[desired]; + }, + + getPreviousSequence: function() { + var current = this.getSequenceIndex(this.selectedSequence); + var desired = this.wrapIndex(current - 1, this.sequences); + return this.sequences[desired]; + }, + + getSequenceIndex: function(name) { + var index; + _.each(this.sequences, function(_name, _index) { + if (_name == name) { + index = _index; + } + }); + if (index === undefined) { throw new Error('didnt find'); } + return index; + }, + + getIndexForID: function(id) { + var index; + var levels = this.sequenceToLevels[this.selectedSequence]; + _.each(levels, function(level, _index) { + if (level.id == id) { + index = _index; + } + }); + return index; + }, + + selectFirst: function() { + var firstID = this.sequenceToLevels[this.sequences[0]][0].id; + this.selectIconByID(firstID); + this.selectedIndex = 0; + this.selectedSequence = this.sequences[0]; + }, + + getCurrentSequence: function() { + return this.sequenceToLevels[this.selectedSequence]; + }, + + getSelectedID: function() { + return this.sequenceToLevels[this.selectedSequence][this.selectedIndex].id; + }, + + selectIconByID: function(id) { + this.toggleIconSelect(id, true); + }, + + deselectIconByID: function(id) { + this.toggleIconSelect(id, false); + }, + + toggleIconSelect: function(id, value) { + this.selectedID = id; + var selector = '#levelIcon-' + id; + $(selector).toggleClass('selected', value); + }, + negative: function() { this.hide(); }, @@ -65,6 +216,7 @@ var LevelDropdownView = ContainedBase.extend({ } this.showDeferred = undefined; this.keyboardListener.mute(); + this.turnOffKeyboardSelection(); LevelDropdownView.__super__.hide.apply(this); }, diff --git a/src/levels/index.js b/src/levels/index.js index 257a5dd0..025d123b 100644 --- a/src/levels/index.js +++ b/src/levels/index.js @@ -7,7 +7,8 @@ exports.levelSequences = { ], rebase: [ require('../../levels/rebase/1').level, - require('../../levels/rebase/2').level + require('../../levels/rebase/2').level, + require('../../levels/rebase/3').level ] }; diff --git a/src/style/main.css b/src/style/main.css index 25861965..23f08553 100644 --- a/src/style/main.css +++ b/src/style/main.css @@ -597,6 +597,10 @@ div.levelIcon:active { background-image: -webkit-linear-gradient(top, #888686, #7A7A7A) } +div.levelIcon.selected { + box-shadow: 0 0 15px #25F6FF; +} + div.levelIcon.solved { background: -webkit-gradient(linear, left top, left bottom, from(#F3F86B), to(#35A30F)); border-top: 1px solid #f4ffa1; diff --git a/todo.txt b/todo.txt index 690571c7..2288412c 100644 --- a/todo.txt +++ b/todo.txt @@ -13,7 +13,6 @@ Cases to handle / things to edit Small things to implement: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -[x] optional multiview on start Minor Bugs to fix: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -22,16 +21,21 @@ Big Bugs to fix: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [ ] rebase bug... ugh +Ideas for cleaning +~~~~~~~~~~~~~ +- CSS... a ton. Switch to less + /************************************* ** Publish Things ** ************************************/ - cross browser support... firefox only LULZ. should be just css right? - fix terminal input field in general -- maybe have keyboard navigation for level selection? Done things: (I only started this on Dec 17th 2012 to get a better sense of what was done) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +[x] keyboard navigation for level selector +[x] optional multiview on start [x] local storage for solved map [x] what if they just type "levels" ? [x] hookup for when solving happens