diff --git a/core/menu_module.js b/core/menu_module.js index 02e91dca..ef08bafb 100644 --- a/core/menu_module.js +++ b/core/menu_module.js @@ -97,8 +97,19 @@ function MenuModule(options) { } }, function afterArtDisplayed(callback) { - self.mciReady(mciData); - callback(null); + self.mciReady(mciData, callback); + }, + function displayPauseIfRequested(callback) { + if(self.shouldPause()) { + self.client.term.write(ansi.goto(self.afterArtPos[0], 1)); + + // :TODO: really need a client.term.pause() that uses the correct art/etc. + theme.displayThemedPause( { client : self.client }, function keyPressed() { + callback(null); + }); + } else { + callback(null); + } } ], function complete(err) { @@ -108,30 +119,18 @@ function MenuModule(options) { } self.finishedLoading(); + self.nextAction(); } ); }; this.shouldPause = function() { - return 'end' === self.menuConfig.pause || true === self.menuConfig.pause; - }; - - this.allViewsReady = function() { - if(self.shouldPause()) { - self.client.term.write(ansi.goto(self.afterArtPos[0], 1)); - - // :TODO: really need a client.term.pause() that uses the correct art/etc. - theme.displayThemedPause( { client : self.client }, function keyPressed() { - self.nextAction(); - }); - } else { - self.nextAction(); - } + return 'end' === self.menuConfig.options.pause || true === self.menuConfig.options.pause; }; this.nextAction = function() { if(!_.isObject(self.menuConfig.form) && !_.isString(self.menuConfig.prompt) && - _.isString(self.menuConfig.action)) + _.isString(self.menuConfig.action)) { menuUtil.handleAction(self.client, null, self.menuConfig); } @@ -170,58 +169,63 @@ MenuModule.prototype.beforeArt = function() { } }; -MenuModule.prototype.mciReady = function(mciData) { +MenuModule.prototype.mciReady = function(mciData, cb) { + // Reserved for sub classes + cb(null); }; -MenuModule.prototype.standardMCIReadyHandler = function(mciData) { +MenuModule.prototype.standardMCIReadyHandler = function(mciData, cb) { // // A quick rundown: // * We may have mciData.menu, mciData.prompt, or both. // * Prompt form is favored over menu form if both are present. // * Standard/prefdefined MCI entries must load both (e.g. %BN is expected to resolve) // - var self = this; - var vcCount = 0; - var vcReady = 0; + var self = this; - _.forEach(mciData, function entry(mciMap, name) { - assert('menu' === name || 'prompt' === name); - ++vcCount; - self.addViewController(name, new ViewController( { client : self.client } )); - }); + async.series( + [ + function addViewControllers(callback) { + _.forEach(mciData, function entry(mciMap, name) { + assert('menu' === name || 'prompt' === name); + self.addViewController(name, new ViewController( { client : self.client } )); + }); + callback(null); + }, + function createMenu(callback) { + if(self.viewControllers.menu) { + var menuLoadOpts = { + mciMap : mciData.menu, + callingMenu : self, + withoutForm : _.isObject(mciData.prompt), + }; - var viewsReady = function(err) { - // :TODO: what should really happen here? - if(err) { - self.client.log.warn(err); + self.viewControllers.menu.loadFromMenuConfig(menuLoadOpts, function menuLoaded(err) { + callback(err); + }); + } else { + callback(null); + } + }, + function createPrompt(callback) { + if(self.viewControllers.prompt) { + var promptLoadOpts = { + callingMenu : self, + mciMap : mciData.prompt, + }; + + self.viewControllers.prompt.loadFromPromptConfig(promptLoadOpts, function promptLoaded(err) { + callback(err); + }); + } else { + callback(null); + } + } + ], + function complete(err) { + cb(err); } - - ++vcReady; - if(vcReady === vcCount) { - self.allViewsReady(); - } - - }; - - - if(self.viewControllers.menu) { - var menuLoadOpts = { - mciMap : mciData.menu, - callingMenu : self, - withoutForm : _.isObject(mciData.prompt), - }; - - self.viewControllers.menu.loadFromMenuConfig(menuLoadOpts, viewsReady); - } - - if(self.viewControllers.prompt) { - var promptLoadOpts = { - callingMenu : self, - mciMap : mciData.prompt, - }; - - self.viewControllers.prompt.loadFromPromptConfig(promptLoadOpts, viewsReady); - } + ); }; MenuModule.prototype.finishedLoading = function() { @@ -234,26 +238,5 @@ MenuModule.prototype.finishedLoading = function() { setTimeout(function nextTimeout() { self.client.gotoMenuModule( { name : self.menuConfig.next } ); }, this.menuConfig.options.nextTimeout); - } else { - /* - var nextAction = function() { - if(!_.isObject(self.menuConfig.form) && !_.isString(self.menuConfig.prompt) && - _.isString(self.menuConfig.action)) - { - menuUtil.handleAction(self.client, null, self.menuConfig); - } - }; - - if(self.shouldPause()) { - self.client.term.write(ansi.goto(self.afterArtPos[0], 1)); - - // :TODO: really need a client.term.pause() that uses the correct art/etc. - theme.displayThemedPause( { client : self.client }, function keyPressed() { - nextAction(); - }); - } else { - nextAction(); - } - */ } }; \ No newline at end of file diff --git a/core/standard_menu.js b/core/standard_menu.js index 5c61368f..d38a84f7 100644 --- a/core/standard_menu.js +++ b/core/standard_menu.js @@ -26,9 +26,15 @@ StandardMenuModule.prototype.beforeArt = function() { StandardMenuModule.super_.prototype.beforeArt.call(this); }; -StandardMenuModule.prototype.mciReady = function(mciData) { - StandardMenuModule.super_.prototype.mciReady.call(this, mciData); - - // we do this so other modules can be both customized and still perform standard tasks - StandardMenuModule.super_.prototype.standardMCIReadyHandler.call(this, mciData); +StandardMenuModule.prototype.mciReady = function(mciData, cb) { + var self = this; + + StandardMenuModule.super_.prototype.mciReady.call(this, mciData, function mciReadyComplete(err) { + if(err) { + cb(err); + } else { + // we do this so other modules can be both customized and still perform standard tasks + StandardMenuModule.super_.prototype.standardMCIReadyHandler.call(self, mciData, cb); + } + }); }; diff --git a/mods/last_callers.js b/mods/last_callers.js index 8587e6a9..57696f8d 100644 --- a/mods/last_callers.js +++ b/mods/last_callers.js @@ -55,15 +55,18 @@ LastCallersModule.prototype.enter = function(client) { } }; -LastCallersModule.prototype.mciReady = function(mciData) { - LastCallersModule.super_.prototype.mciReady.call(this, mciData); - +LastCallersModule.prototype.mciReady = function(mciData, cb) { var self = this; var vc = self.viewControllers.lastCallers = new ViewController( { client : self.client } ); var loginHistory; async.series( [ + function callParentMciReady(callback) { + LastCallersModule.super_.prototype.mciReady.call(this, mciData, function parentMciReady(err) { + callback(err); + }); + }, function loadFromConfig(callback) { var loadOpts = { callingMenu : self, @@ -155,10 +158,15 @@ LastCallersModule.prototype.mciReady = function(mciData) { row++; }); + + callback(null); } ], function complete(err) { - self.client.log.error(err); + if(err) { + self.client.log.error(err); + } + cb(err); } ); }; diff --git a/mods/menu.json b/mods/menu.json index ffb5aca1..966122ba 100644 --- a/mods/menu.json +++ b/mods/menu.json @@ -34,8 +34,8 @@ } */ "menus" : { - "art" : "CONNECT", "connected" : { + "art" : "CONNECT", "next" : "matrix", "options" : { "cls" : true, @@ -191,24 +191,18 @@ }, "newUserActive" : { "art" : "SO-CC1.ANS", - "options" : { "cls" : true }, - "action" : "@menu:currentUserStats", - "pause" : "end" + "options" : { "cls" : true, "pause" : true }, + "action" : "@menu:currentUserStats" }, "currentUserStats" : { "art" : "userstats", - //"prompt" : "pause", - "options" : { - // :TODO: implement MCI codes for this - "cls" : true - }, - "pause" : true, + "options" : { "cls" : true, "pause" : true }, "action" : "@menu:lastCallers" }, "lastCallers" :{ "module" : "last_callers", "art" : "LASTCALL.ANS", - "options" : { "cls" : true }, + "options" : { "cls" : true, "pause" : true }, "config" : { "dateTimeFormat" : "ddd MMM Do H:mm a" },