mirror of
https://github.com/pcottle/learnGitBranching.git
synced 2025-06-27 00:18:56 +02:00
199 lines
5 KiB
JavaScript
199 lines
5 KiB
JavaScript
var _ = require('underscore');
|
|
var Q = require('q');
|
|
// horrible hack to get localStorage Backbone plugin
|
|
var Backbone = (!require('../util').isBrowser()) ? require('backbone') : window.Backbone;
|
|
|
|
var ModalTerminal = require('../views').ModalTerminal;
|
|
var ContainedBase = require('../views').ContainedBase;
|
|
var ConfirmCancelView = require('../views').ConfirmCancelView;
|
|
var LeftRightView = require('../views').LeftRightView;
|
|
var ModalAlert = require('../views').ModalAlert;
|
|
var GitDemonstrationView = require('../views/gitDemonstrationView').GitDemonstrationView;
|
|
|
|
var BuilderViews = require('../views/builderViews');
|
|
var MarkdownPresenter = BuilderViews.MarkdownPresenter;
|
|
|
|
var KeyboardListener = require('../util/keyboard').KeyboardListener;
|
|
var GitError = require('../util/errors').GitError;
|
|
|
|
var MultiView = Backbone.View.extend({
|
|
tagName: 'div',
|
|
className: 'multiView',
|
|
// ms to debounce the nav functions
|
|
navEventDebounce: 550,
|
|
deathTime: 700,
|
|
|
|
// a simple mapping of what childViews we support
|
|
typeToConstructor: {
|
|
ModalAlert: ModalAlert,
|
|
GitDemonstrationView: GitDemonstrationView,
|
|
MarkdownPresenter: MarkdownPresenter
|
|
},
|
|
|
|
initialize: function(options) {
|
|
options = options || {};
|
|
this.childViewJSONs = options.childViews || [{
|
|
type: 'ModalAlert',
|
|
options: {
|
|
markdown: 'Woah wtf!!'
|
|
}
|
|
}, {
|
|
type: 'GitDemonstrationView',
|
|
options: {
|
|
command: 'git checkout -b side; git commit; git commit'
|
|
}
|
|
}, {
|
|
type: 'ModalAlert',
|
|
options: {
|
|
markdown: 'Im second'
|
|
}
|
|
}];
|
|
this.deferred = options.deferred || Q.defer();
|
|
|
|
this.childViews = [];
|
|
this.currentIndex = 0;
|
|
|
|
this.navEvents = _.clone(Backbone.Events);
|
|
this.navEvents.on('negative', this.getNegFunc(), this);
|
|
this.navEvents.on('positive', this.getPosFunc(), this);
|
|
this.navEvents.on('quit', this.finish, this);
|
|
|
|
this.keyboardListener = new KeyboardListener({
|
|
events: this.navEvents,
|
|
aliasMap: {
|
|
left: 'negative',
|
|
right: 'positive',
|
|
enter: 'positive',
|
|
esc: 'quit'
|
|
}
|
|
});
|
|
|
|
this.render();
|
|
if (!options.wait) {
|
|
this.start();
|
|
}
|
|
},
|
|
|
|
onWindowFocus: function() {
|
|
// nothing here for now...
|
|
// TODO -- add a cool glow effect?
|
|
},
|
|
|
|
getAnimationTime: function() {
|
|
return 700;
|
|
},
|
|
|
|
getPromise: function() {
|
|
return this.deferred.promise;
|
|
},
|
|
|
|
getPosFunc: function() {
|
|
return _.debounce(_.bind(function() {
|
|
this.navForward();
|
|
}, this), this.navEventDebounce, true);
|
|
},
|
|
|
|
getNegFunc: function() {
|
|
return _.debounce(_.bind(function() {
|
|
this.navBackward();
|
|
}, this), this.navEventDebounce, true);
|
|
},
|
|
|
|
lock: function() {
|
|
this.locked = true;
|
|
},
|
|
|
|
unlock: function() {
|
|
this.locked = false;
|
|
},
|
|
|
|
navForward: function() {
|
|
// we need to prevent nav changes when a git demonstration view hasnt finished
|
|
if (this.locked) { return; }
|
|
if (this.currentIndex === this.childViews.length - 1) {
|
|
this.hideViewIndex(this.currentIndex);
|
|
this.finish();
|
|
return;
|
|
}
|
|
|
|
this.navIndexChange(1);
|
|
},
|
|
|
|
navBackward: function() {
|
|
if (this.currentIndex === 0) {
|
|
return;
|
|
}
|
|
|
|
this.navIndexChange(-1);
|
|
},
|
|
|
|
navIndexChange: function(delta) {
|
|
this.hideViewIndex(this.currentIndex);
|
|
this.currentIndex += delta;
|
|
this.showViewIndex(this.currentIndex);
|
|
},
|
|
|
|
hideViewIndex: function(index) {
|
|
this.childViews[index].hide();
|
|
},
|
|
|
|
showViewIndex: function(index) {
|
|
this.childViews[index].show();
|
|
},
|
|
|
|
finish: function() {
|
|
// first we stop listening to keyboard and give that back to UI, which
|
|
// other views will take if they need to
|
|
this.keyboardListener.mute();
|
|
|
|
_.each(this.childViews, function(childView) {
|
|
childView.die();
|
|
});
|
|
|
|
this.deferred.resolve();
|
|
},
|
|
|
|
start: function() {
|
|
// steal the window focus baton
|
|
this.showViewIndex(this.currentIndex);
|
|
},
|
|
|
|
createChildView: function(viewJSON) {
|
|
var type = viewJSON.type;
|
|
if (!this.typeToConstructor[type]) {
|
|
throw new Error('no constructor for type "' + type + '"');
|
|
}
|
|
var view = new this.typeToConstructor[type](_.extend(
|
|
{},
|
|
viewJSON.options,
|
|
{ wait: true }
|
|
));
|
|
return view;
|
|
},
|
|
|
|
addNavToView: function(view, index) {
|
|
var leftRight = new LeftRightView({
|
|
events: this.navEvents,
|
|
// we want the arrows to be on the same level as the content (not
|
|
// beneath), so we go one level up with getDestination()
|
|
destination: view.getDestination(),
|
|
showLeft: (index !== 0),
|
|
lastNav: (index === this.childViewJSONs.length - 1)
|
|
});
|
|
if (view.receiveMetaNav) {
|
|
view.receiveMetaNav(leftRight, this);
|
|
}
|
|
},
|
|
|
|
render: function() {
|
|
// go through each and render... show the first
|
|
_.each(this.childViewJSONs, function(childViewJSON, index) {
|
|
var childView = this.createChildView(childViewJSON);
|
|
this.childViews.push(childView);
|
|
this.addNavToView(childView, index);
|
|
}, this);
|
|
}
|
|
});
|
|
|
|
exports.MultiView = MultiView;
|
|
|