* Tons of work with menu/prompts refactoring -- more to come soon
* More work with menu/prompt accets
This commit is contained in:
parent
5faa11664b
commit
bac2f63c1a
|
@ -205,53 +205,6 @@ var FONT_MAP = {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
var SYNC_TERM_FONTS = [
|
|
||||||
'cp437',
|
|
||||||
'cp1251',
|
|
||||||
'koi8_r',
|
|
||||||
'iso8859_2',
|
|
||||||
'iso8859_4',
|
|
||||||
'cp866',
|
|
||||||
'iso8859_9',
|
|
||||||
'haik8',
|
|
||||||
'iso8859_8',
|
|
||||||
'koi8_u',
|
|
||||||
'iso8859_15',
|
|
||||||
'iso8859_4',
|
|
||||||
'koi8_r_b',
|
|
||||||
'iso8859_4',
|
|
||||||
'iso8859_5',
|
|
||||||
'ARMSCII_8',
|
|
||||||
'iso8859_15',
|
|
||||||
'cp850',
|
|
||||||
'cp850',
|
|
||||||
'cp885',
|
|
||||||
'cp1251',
|
|
||||||
'iso8859_7',
|
|
||||||
'koi8-r_c',
|
|
||||||
'iso8859_4',
|
|
||||||
'iso8859_1',
|
|
||||||
'cp866',
|
|
||||||
'cp437',
|
|
||||||
'cp866',
|
|
||||||
'cp885',
|
|
||||||
'cp866_u',
|
|
||||||
'iso8859_1',
|
|
||||||
'cp1131',
|
|
||||||
'c64_upper',
|
|
||||||
'c64_lower',
|
|
||||||
'c128_upper',
|
|
||||||
'c128_lower',
|
|
||||||
'atari',
|
|
||||||
'pot_noodle',
|
|
||||||
'mo_soul',
|
|
||||||
'microknight_plus',
|
|
||||||
'topaz_plus',
|
|
||||||
'microknight',
|
|
||||||
'topaz',
|
|
||||||
];
|
|
||||||
|
|
||||||
// Create methods such as up(), nextLine(),...
|
// Create methods such as up(), nextLine(),...
|
||||||
Object.keys(CONTROL).forEach(function onControlName(name) {
|
Object.keys(CONTROL).forEach(function onControlName(name) {
|
||||||
var code = CONTROL[name];
|
var code = CONTROL[name];
|
||||||
|
@ -338,21 +291,6 @@ function disableVT100LineWrapping() {
|
||||||
//
|
//
|
||||||
// See http://cvs.synchro.net/cgi-bin/viewcvs.cgi/*checkout*/src/conio/cterm.txt
|
// See http://cvs.synchro.net/cgi-bin/viewcvs.cgi/*checkout*/src/conio/cterm.txt
|
||||||
//
|
//
|
||||||
// :TODO: allow full spec here.
|
|
||||||
/*
|
|
||||||
function setFont(name, fontPage) {
|
|
||||||
fontPage = miscUtil.valueWithDefault(fontPage, 0);
|
|
||||||
|
|
||||||
assert(fontPage === 0 || fontPage === 1); // see spec
|
|
||||||
|
|
||||||
var i = SYNC_TERM_FONTS.indexOf(name);
|
|
||||||
if(-1 != i) {
|
|
||||||
return ESC_CSI + fontPage + ';' + i + ' D';
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
function setFont(name, fontPage) {
|
function setFont(name, fontPage) {
|
||||||
name = name.toLowerCase().replace(/ /g, '_'); // conform to map
|
name = name.toLowerCase().replace(/ /g, '_'); // conform to map
|
||||||
|
|
||||||
|
|
17
core/art.js
17
core/art.js
|
@ -13,6 +13,8 @@ var util = require('util');
|
||||||
var ansi = require('./ansi_term.js');
|
var ansi = require('./ansi_term.js');
|
||||||
var aep = require('./ansi_escape_parser.js');
|
var aep = require('./ansi_escape_parser.js');
|
||||||
|
|
||||||
|
var _ = require('lodash');
|
||||||
|
|
||||||
exports.getArt = getArt;
|
exports.getArt = getArt;
|
||||||
exports.getArtFromPath = getArtFromPath;
|
exports.getArtFromPath = getArtFromPath;
|
||||||
exports.display = display;
|
exports.display = display;
|
||||||
|
@ -395,7 +397,19 @@ function display(options, cb) {
|
||||||
var pauseKeys = miscUtil.valueWithDefault(options.pauseKeys, []);
|
var pauseKeys = miscUtil.valueWithDefault(options.pauseKeys, []);
|
||||||
var pauseAtTermHeight = miscUtil.valueWithDefault(options.pauseAtTermHeight, false);
|
var pauseAtTermHeight = miscUtil.valueWithDefault(options.pauseAtTermHeight, false);
|
||||||
var mciReplaceChar = miscUtil.valueWithDefault(options.mciReplaceChar, ' ');
|
var mciReplaceChar = miscUtil.valueWithDefault(options.mciReplaceChar, ' ');
|
||||||
var iceColors = miscUtil.valueWithDefault(options.iceColors, false);
|
|
||||||
|
var iceColors = options.iceColors;
|
||||||
|
if(_.isUndefined(options.iceColors)) {
|
||||||
|
// detect from SAUCE, if present
|
||||||
|
iceColors = false;
|
||||||
|
if(_.isObject(options.sauce) && _.isNumber(options.sauce.ansiFlags)) {
|
||||||
|
if(options.sauce.ansiFlags & (1 << 0)) {
|
||||||
|
iceColors = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//var iceColors = miscUtil.valueWithDefault(options.iceColors, false);
|
||||||
|
|
||||||
// :TODO: support pause/cancel & pause @ termHeight
|
// :TODO: support pause/cancel & pause @ termHeight
|
||||||
var canceled = false;
|
var canceled = false;
|
||||||
|
@ -437,6 +451,7 @@ function display(options, cb) {
|
||||||
options.client.on('cursor position report', onCPR);
|
options.client.on('cursor position report', onCPR);
|
||||||
|
|
||||||
parser.on('mci', function onMCI(mciCode, id, args) {
|
parser.on('mci', function onMCI(mciCode, id, args) {
|
||||||
|
// :TODO: ensure generatedId's do not conflict with any |id|
|
||||||
id = id || generatedId++;
|
id = id || generatedId++;
|
||||||
var mapItem = mciCode + id;
|
var mapItem = mciCode + id;
|
||||||
// :TODO: Avoid mutiple [] lookups here
|
// :TODO: Avoid mutiple [] lookups here
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
/* jslint node: true */
|
/* jslint node: true */
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
var _ = require('lodash');
|
||||||
|
var assert = require('assert');
|
||||||
|
|
||||||
exports.parseAsset = parseAsset;
|
exports.parseAsset = parseAsset;
|
||||||
|
exports.getArtAsset = getArtAsset;
|
||||||
|
|
||||||
var ALL_ASSETS = [
|
var ALL_ASSETS = [
|
||||||
'art',
|
'art',
|
||||||
|
@ -10,8 +14,7 @@ var ALL_ASSETS = [
|
||||||
'prompt',
|
'prompt',
|
||||||
];
|
];
|
||||||
|
|
||||||
// \@(art|menu|method)\:([\w\.]*)(?:\/?([\w\d\_]+))*
|
var ASSET_RE = new RegExp('\\@(' + ALL_ASSETS.join('|') + ')\\:([\\w\\d\\.]*)(?:\\/([\\w\\d\\_]+))*');
|
||||||
var ASSET_RE = new RegExp('\\@(' + ALL_ASSETS.join('|') + ')\\:([\\w\\.]*)(?:\\?/([\\w\\d\\_]+))*');
|
|
||||||
|
|
||||||
function parseAsset(s) {
|
function parseAsset(s) {
|
||||||
var m = ASSET_RE.exec(s);
|
var m = ASSET_RE.exec(s);
|
||||||
|
@ -29,3 +32,21 @@ function parseAsset(s) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getArtAsset(art, cb) {
|
||||||
|
if(!_.isString(art)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if('@' === art[0]) {
|
||||||
|
var artAsset = parseAsset(art);
|
||||||
|
assert('art' === artAsset.type || 'method' === artAsset.type);
|
||||||
|
|
||||||
|
return artAsset;
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
type : 'art',
|
||||||
|
asset : art,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
63
core/bbs.js
63
core/bbs.js
|
@ -12,10 +12,70 @@ var iconv = require('iconv-lite');
|
||||||
var paths = require('path');
|
var paths = require('path');
|
||||||
var async = require('async');
|
var async = require('async');
|
||||||
var util = require('util');
|
var util = require('util');
|
||||||
var async = require('async');
|
var _ = require('lodash');
|
||||||
|
|
||||||
exports.bbsMain = bbsMain;
|
exports.bbsMain = bbsMain;
|
||||||
|
|
||||||
|
function bbsMain() {
|
||||||
|
async.waterfall(
|
||||||
|
[
|
||||||
|
function processArgs(callback) {
|
||||||
|
var args = parseArgs();
|
||||||
|
|
||||||
|
var configPath;
|
||||||
|
|
||||||
|
if(args.indexOf('--help') > 0) {
|
||||||
|
// :TODO: display help
|
||||||
|
} else {
|
||||||
|
var argCount = args.length;
|
||||||
|
for(var i = 0; i < argCount; ++i) {
|
||||||
|
var arg = args[i];
|
||||||
|
if('--config' == arg) {
|
||||||
|
configPath = args[i + 1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var configPathSupplied = _.isString(configPath);
|
||||||
|
callback(null, configPath || conf.getDefaultPath(), configPathSupplied);
|
||||||
|
},
|
||||||
|
function initConfig(configPath, configPathSupplied, callback) {
|
||||||
|
conf.init(configPath, function configInit(err) {
|
||||||
|
|
||||||
|
//
|
||||||
|
// If the user supplied a path and we can't read/parse it
|
||||||
|
// then it's a fatal error
|
||||||
|
//
|
||||||
|
if(configPathSupplied && err) {
|
||||||
|
if('ENOENT' === err.code) {
|
||||||
|
console.error('Configuration file does not existing: ' + configPath);
|
||||||
|
} else {
|
||||||
|
console.error('Failed parsing configuration: ' + configPath);
|
||||||
|
}
|
||||||
|
callback(err);
|
||||||
|
} else {
|
||||||
|
callback(null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
function initSystem(callback) {
|
||||||
|
initialize(function init(err) {
|
||||||
|
if(err) {
|
||||||
|
console.error('Error initializing: ' + util.inspect(err));
|
||||||
|
}
|
||||||
|
callback(err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
],
|
||||||
|
function complete(err) {
|
||||||
|
if(!err) {
|
||||||
|
startListening();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
function bbsMain() {
|
function bbsMain() {
|
||||||
var mainArgs = parseArgs();
|
var mainArgs = parseArgs();
|
||||||
|
|
||||||
|
@ -62,6 +122,7 @@ function bbsMain() {
|
||||||
startListening();
|
startListening();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
function parseArgs() {
|
function parseArgs() {
|
||||||
var args = [];
|
var args = [];
|
||||||
|
|
|
@ -216,7 +216,7 @@ Client.prototype.gotoMenuModule = function(options, cb) {
|
||||||
if(err) {
|
if(err) {
|
||||||
cb(err);
|
cb(err);
|
||||||
} else {
|
} else {
|
||||||
Log.debug({ name : options.name }, 'Goto menu module');
|
Log.debug( { menuName : options.name }, 'Goto menu module');
|
||||||
|
|
||||||
modInst.enter(self);
|
modInst.enter(self);
|
||||||
|
|
||||||
|
|
|
@ -1,45 +1,95 @@
|
||||||
/* jslint node: true */
|
/* jslint node: true */
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var fs = require('fs');
|
|
||||||
var paths = require('path');
|
|
||||||
var miscUtil = require('./misc_util.js');
|
var miscUtil = require('./misc_util.js');
|
||||||
|
|
||||||
// :TODO: it would be nice to allow for defaults here & .json file only overrides -- e.g. merge the two
|
var fs = require('fs');
|
||||||
|
var paths = require('path');
|
||||||
|
var stripJsonComments = require('strip-json-comments');
|
||||||
|
var async = require('async');
|
||||||
|
var _ = require('lodash');
|
||||||
|
|
||||||
module.exports = {
|
exports.init = init;
|
||||||
defaultPath : function() {
|
exports.getDefaultPath = getDefaultPath;
|
||||||
|
|
||||||
|
function init(configPath, cb) {
|
||||||
|
|
||||||
|
// Probably many better ways of doing this:
|
||||||
|
// :TODO: See http://jsfiddle.net/jlowery2663/z8at6knn/4/
|
||||||
|
var recursiveMerge = function(target, source) {
|
||||||
|
for(var p in source) {
|
||||||
|
try {
|
||||||
|
if(_.isObject(source)) {
|
||||||
|
target[p] = recursiveMerge(target[p], source[p]);
|
||||||
|
} else {
|
||||||
|
target[p] = source[p];
|
||||||
|
}
|
||||||
|
} catch(e) {
|
||||||
|
target[p] = source[p];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return target;
|
||||||
|
};
|
||||||
|
|
||||||
|
async.waterfall(
|
||||||
|
[
|
||||||
|
function loadUserConfig(callback) {
|
||||||
|
|
||||||
|
fs.readFile(configPath, { encoding : 'utf8' }, function configData(err, data) {
|
||||||
|
if(err) {
|
||||||
|
callback(null, { } );
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
var configJson = JSON.parse(stripJsonComments(data));
|
||||||
|
callback(null, configJson);
|
||||||
|
} catch(e) {
|
||||||
|
callback(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
function mergeWithDefaultConfig(menuConfig, callback) {
|
||||||
|
var mergedConfig = recursiveMerge(menuConfig, getDefaultConfig());
|
||||||
|
callback(null, mergedConfig);
|
||||||
|
}
|
||||||
|
],
|
||||||
|
function complete(err, mergedConfig) {
|
||||||
|
exports.config = mergedConfig;
|
||||||
|
cb(err);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getDefaultPath() {
|
||||||
var base = miscUtil.resolvePath('~/');
|
var base = miscUtil.resolvePath('~/');
|
||||||
if(base) {
|
if(base) {
|
||||||
return paths.join(base, '.enigmabbs', 'config.json');
|
return paths.join(base, '.enigmabbs', 'config.json');
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getDefaultConfig() {
|
||||||
|
return {
|
||||||
|
general : {
|
||||||
|
boardName : 'Another Fine ENiGMA½ BBS',
|
||||||
},
|
},
|
||||||
|
|
||||||
initFromFile : function(path, cb) {
|
firstMenu : 'connected',
|
||||||
var data = fs.readFileSync(path, 'utf8');
|
|
||||||
// :TODO: strip comments
|
|
||||||
this.config = JSON.parse(data);
|
|
||||||
},
|
|
||||||
|
|
||||||
createDefault : function() {
|
|
||||||
this.config = {
|
|
||||||
bbsName : 'Another Fine ENiGMA½ BBS',
|
|
||||||
|
|
||||||
// :TODO: probably replace this with 'firstMenu' or somthing once that's available
|
|
||||||
entryMod : 'matrix',
|
|
||||||
|
|
||||||
preLoginTheme : '*',
|
preLoginTheme : '*',
|
||||||
|
|
||||||
users : {
|
users : {
|
||||||
usernameMin : 2,
|
usernameMin : 2,
|
||||||
usernameMax : 22,
|
usernameMax : 22,
|
||||||
|
usernamePattern : '^[A-Za-z0-9~!@#$%^&*()\\-\\_+]+$',
|
||||||
passwordMin : 6,
|
passwordMin : 6,
|
||||||
|
passwordMax : 256,
|
||||||
requireActivation : true, // require SysOp activation?
|
requireActivation : true, // require SysOp activation?
|
||||||
|
invalidUsernames : [],
|
||||||
},
|
},
|
||||||
|
|
||||||
defaults : {
|
defaults : {
|
||||||
theme : 'NU-MAYA',
|
theme : 'NU-MAYA', // :TODO: allow "*" here
|
||||||
passwordChar : '*',
|
passwordChar : '*', // TODO: move to user ?
|
||||||
},
|
},
|
||||||
|
|
||||||
paths : {
|
paths : {
|
||||||
|
@ -65,4 +115,3 @@ module.exports = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
|
|
@ -70,42 +70,14 @@ function connectEntry(client) {
|
||||||
ansiQueryTermSizeIfNeeded(client);
|
ansiQueryTermSizeIfNeeded(client);
|
||||||
|
|
||||||
prepareTerminal(term);
|
prepareTerminal(term);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Always show a ENiGMA½ banner
|
||||||
|
//
|
||||||
displayBanner(term);
|
displayBanner(term);
|
||||||
|
|
||||||
setTimeout(function onTimeout() {
|
setTimeout(function onTimeout() {
|
||||||
term.write(ansi.clearScreen());
|
client.gotoMenuModule( { name : Config.firstMenu });
|
||||||
|
|
||||||
|
|
||||||
var dispOptions = {
|
|
||||||
name : 'CONNECT',
|
|
||||||
client : client,
|
|
||||||
};
|
|
||||||
|
|
||||||
// :TODO: if connect.js were a MenuModule, MCI/etc. would function here!
|
|
||||||
// ... could also avoid some of the boilerplate code
|
|
||||||
theme.displayThemeArt(dispOptions, function artDisplayed(err) {
|
|
||||||
var timeout = err ? 0 : 2000;
|
|
||||||
|
|
||||||
setTimeout(function timeout() {
|
|
||||||
client.gotoMenuModule( { name : Config.entryMod } );
|
|
||||||
}, timeout);
|
|
||||||
});
|
|
||||||
|
|
||||||
/*artwork.getArt('CONNECT', { random : true, readSauce : true }, function onArt(err, art) {
|
|
||||||
var timeout = 0;
|
|
||||||
|
|
||||||
if(!err) {
|
|
||||||
term.write(art.data);
|
|
||||||
timeout = 1000;
|
|
||||||
}
|
|
||||||
|
|
||||||
setTimeout(function onTimeout() {
|
|
||||||
term.write(ansi.clearScreen());
|
|
||||||
|
|
||||||
client.gotoMenuModule({ name : Config.entryMod } );
|
|
||||||
}, timeout);
|
|
||||||
});
|
|
||||||
*/
|
|
||||||
}, 500);
|
}, 500);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ var miscUtil = require('./misc_util.js');
|
||||||
var strUtil = require('./string_util.js');
|
var strUtil = require('./string_util.js');
|
||||||
var util = require('util');
|
var util = require('util');
|
||||||
var assert = require('assert');
|
var assert = require('assert');
|
||||||
|
var _ = require('lodash');
|
||||||
|
|
||||||
exports.EditTextView = EditTextView;
|
exports.EditTextView = EditTextView;
|
||||||
|
|
||||||
|
@ -32,8 +33,7 @@ EditTextView.prototype.onKeyPress = function(key, isSpecial) {
|
||||||
assert(1 === key.length);
|
assert(1 === key.length);
|
||||||
|
|
||||||
// :TODO: how to handle justify left/center?
|
// :TODO: how to handle justify left/center?
|
||||||
|
if(!_.isNumber(this.maxLength) || this.text.length < this.maxLength) {
|
||||||
if(this.text.length < this.maxLength) {
|
|
||||||
key = strUtil.stylizeString(key, this.textStyle);
|
key = strUtil.stylizeString(key, this.textStyle);
|
||||||
|
|
||||||
this.text += key;
|
this.text += key;
|
||||||
|
|
|
@ -23,7 +23,7 @@ MCIViewFactory.prototype.getPredefinedViewLabel = function(code) {
|
||||||
var label;
|
var label;
|
||||||
switch(code) {
|
switch(code) {
|
||||||
// :TODO: Fix conflict with ButtonView (BN); chagne to BT
|
// :TODO: Fix conflict with ButtonView (BN); chagne to BT
|
||||||
case 'BN' : label = Config.bbsName; break;
|
case 'BN' : label = Config.general.boardName; break;
|
||||||
case 'VL' : label = 'ENiGMA½ v' + packageJson.version; break;
|
case 'VL' : label = 'ENiGMA½ v' + packageJson.version; break;
|
||||||
case 'VN' : label = packageJson.version; break;
|
case 'VN' : label = packageJson.version; break;
|
||||||
|
|
||||||
|
@ -93,7 +93,7 @@ MCIViewFactory.prototype.createFromMCI = function(mci) {
|
||||||
// Edit Text
|
// Edit Text
|
||||||
case 'ET' :
|
case 'ET' :
|
||||||
if(setOption(0, 'maxLength')) {
|
if(setOption(0, 'maxLength')) {
|
||||||
options.maxLength = parseInt(options.maxLength, 10);
|
options.maxLength = parseInt(options.maxLength, 10); // ensure number
|
||||||
options.dimens = { width : options.maxLength };
|
options.dimens = { width : options.maxLength };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,11 +3,16 @@
|
||||||
|
|
||||||
var PluginModule = require('./plugin_module.js').PluginModule;
|
var PluginModule = require('./plugin_module.js').PluginModule;
|
||||||
var theme = require('./theme.js');
|
var theme = require('./theme.js');
|
||||||
|
var art = require('./art.js');
|
||||||
var Log = require('./logger.js').log;
|
var Log = require('./logger.js').log;
|
||||||
var ansi = require('./ansi_term.js');
|
var ansi = require('./ansi_term.js');
|
||||||
|
var asset = require('./asset.js');
|
||||||
|
//var promptUtil = require('./prompt_util.js');
|
||||||
|
var ViewController = require('./view_controller.js').ViewController;
|
||||||
|
|
||||||
var async = require('async');
|
var async = require('async');
|
||||||
var assert = require('assert');
|
var assert = require('assert');
|
||||||
|
var _ = require('lodash');
|
||||||
|
|
||||||
exports.MenuModule = MenuModule;
|
exports.MenuModule = MenuModule;
|
||||||
|
|
||||||
|
@ -17,30 +22,129 @@ function MenuModule(options) {
|
||||||
var self = this;
|
var self = this;
|
||||||
this.menuConfig = options.menuConfig;
|
this.menuConfig = options.menuConfig;
|
||||||
this.menuConfig.options = options.menuConfig.options || {};
|
this.menuConfig.options = options.menuConfig.options || {};
|
||||||
this.menuMethods = {};
|
this.menuMethods = {}; // methods called from @method's
|
||||||
this.viewControllers = [];
|
this.viewControllers = {}; // name->vc
|
||||||
|
|
||||||
|
this.displayArtAsset = function(assetSpec, cb) {
|
||||||
|
var artAsset = asset.getArtAsset(assetSpec);
|
||||||
|
|
||||||
|
if(!artAsset) {
|
||||||
|
cb(new Error('Asset not found: ' + assetSpec));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var dispOptions = {
|
||||||
|
name : artAsset.asset,
|
||||||
|
client : self.client,
|
||||||
|
font : self.menuConfig.font,
|
||||||
|
};
|
||||||
|
|
||||||
|
switch(artAsset.type) {
|
||||||
|
case 'art' :
|
||||||
|
theme.displayThemeArt(dispOptions, function displayed(err, mciMap) {
|
||||||
|
cb(err, mciMap);
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'method' :
|
||||||
|
// :TODO: fetch and render via method/generator
|
||||||
|
break;
|
||||||
|
|
||||||
|
default :
|
||||||
|
cb(new Error('Unsupported art asset type'));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
this.initSequence = function() {
|
this.initSequence = function() {
|
||||||
|
var mciData = { };
|
||||||
|
|
||||||
async.waterfall(
|
async.waterfall(
|
||||||
[
|
[
|
||||||
function beforeDisplayArt(callback) {
|
function beforeDisplayArt(callback) {
|
||||||
self.beforeArt();
|
self.beforeArt();
|
||||||
callback(null);
|
callback(null);
|
||||||
},
|
},
|
||||||
function displayArt(callback) {
|
function displayMenuArt(callback) {
|
||||||
|
if(_.isString(self.menuConfig.art)) {
|
||||||
|
self.displayArtAsset(self.menuConfig.art, function displayed(err, mciMap) {
|
||||||
|
mciData.menu = mciMap;
|
||||||
|
callback(err);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
callback(null);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
function moveToPromptLocation(callback) {
|
||||||
|
if(self.menuConfig.prompt) {
|
||||||
|
// :TODO: fetch and move cursor to prompt location, if supplied. See notes/etc. on placements
|
||||||
|
}
|
||||||
|
|
||||||
|
callback(null);
|
||||||
|
},
|
||||||
|
function displayPromptArt(callback) {
|
||||||
|
if(_.isString(self.menuConfig.prompt)) {
|
||||||
|
// If a prompt is specified, we need the configuration
|
||||||
|
if(!_.isObject(self.menuConfig.promptConfig)) {
|
||||||
|
callback(new Error('Prompt specified but configuraiton not found!'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prompts *must* have art. If it's missing it's an error
|
||||||
|
// :TODO: allow inline prompts in the future, e.g. @inline:memberName -> "memberName" : { ... }
|
||||||
|
var promptConfig = self.menuConfig.promptConfig;
|
||||||
|
self.displayArtAsset(promptConfig.art, function displayed(err, mciMap) {
|
||||||
|
mciData.prompt = mciMap;
|
||||||
|
callback(err);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
callback(null);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
function afterArtDisplayed(callback) {
|
||||||
|
self.mciReady(mciData);
|
||||||
|
callback(null);
|
||||||
|
}
|
||||||
|
],
|
||||||
|
function complete(err) {
|
||||||
|
if(err) {
|
||||||
|
// :TODO: what to do exactly?????
|
||||||
|
}
|
||||||
|
|
||||||
|
self.finishedLoading();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
/*
|
||||||
|
this.initSequence2 = function() {
|
||||||
|
async.waterfall(
|
||||||
|
[
|
||||||
|
function beforeDisplayArt(callback) {
|
||||||
|
self.beforeArt();
|
||||||
|
callback(null);
|
||||||
|
},
|
||||||
|
function displayArtAsset(callback) {
|
||||||
|
var artAsset = asset.getArtAsset(self.menuConfig.art);
|
||||||
|
|
||||||
|
if(!artAsset) {
|
||||||
|
// no art to display
|
||||||
|
callback(null, null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var dispOptions = {
|
var dispOptions = {
|
||||||
name : self.menuConfig.art,
|
name : artAsset.asset,
|
||||||
font : self.menuConfig.font,
|
|
||||||
client : self.client,
|
client : self.client,
|
||||||
|
font : self.menuConfig.font,
|
||||||
};
|
};
|
||||||
|
|
||||||
theme.displayThemeArt(dispOptions, function onArt(err, mciMap) {
|
if('art' === artAsset.type) {
|
||||||
// :TODO: If the art simply is not found, or failed to load... we need to continue
|
theme.displayThemeArt(dispOptions, function displayedArt(err, mciMap) {
|
||||||
if(err) {
|
|
||||||
console.log('TODO: log this error properly... maybe handle slightly diff.');
|
|
||||||
}
|
|
||||||
callback(null, mciMap);
|
callback(null, mciMap);
|
||||||
});
|
});
|
||||||
|
} else if('method' === artAsset.type) {
|
||||||
|
// :TODO: support fetching the asset (e.g. rendering into buffer) -> display it.
|
||||||
|
}
|
||||||
},
|
},
|
||||||
function afterArtDisplayed(mciMap, callback) {
|
function afterArtDisplayed(mciMap, callback) {
|
||||||
if(mciMap) {
|
if(mciMap) {
|
||||||
|
@ -48,6 +152,42 @@ function MenuModule(options) {
|
||||||
}
|
}
|
||||||
|
|
||||||
callback(null);
|
callback(null);
|
||||||
|
},
|
||||||
|
function loadPrompt(callback) {
|
||||||
|
if(!_.isString(self.menuConfig.prompt)) {
|
||||||
|
// no prompt supplied
|
||||||
|
callback(null, null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var loadPromptOpts = {
|
||||||
|
name : self.menuConfig.prompt,
|
||||||
|
client : self.client,
|
||||||
|
};
|
||||||
|
|
||||||
|
promptUtil.loadPrompt(loadPromptOpts, function promptLoaded(err, prompt) {
|
||||||
|
callback(err, prompt);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
function displayPrompt(prompt, callback) {
|
||||||
|
if(!prompt) {
|
||||||
|
callback(null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// :TODO: go to proper prompt location before displaying
|
||||||
|
|
||||||
|
var dispOptions = {
|
||||||
|
art : prompt.artInfo.data,
|
||||||
|
sauce : prompt.artInfo.sauce,
|
||||||
|
client : self.client,
|
||||||
|
font : prompt.config.font,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
art.display(dispOptions, function displayed(err, mciMap) {
|
||||||
|
|
||||||
|
});
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
function complete(err) {
|
function complete(err) {
|
||||||
|
@ -60,26 +200,28 @@ function MenuModule(options) {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
require('util').inherits(MenuModule, PluginModule);
|
require('util').inherits(MenuModule, PluginModule);
|
||||||
|
|
||||||
MenuModule.prototype.enter = function(client) {
|
MenuModule.prototype.enter = function(client) {
|
||||||
this.client = client;
|
this.client = client;
|
||||||
assert(typeof client !== 'undefined');
|
assert(_.isObject(client));
|
||||||
|
|
||||||
this.initSequence();
|
this.initSequence();
|
||||||
};
|
};
|
||||||
|
|
||||||
MenuModule.prototype.leave = function() {
|
MenuModule.prototype.leave = function() {
|
||||||
var count = this.viewControllers.length;
|
var self = this;
|
||||||
for(var i = 0; i < count; ++i) {
|
Object.keys(this.viewControllers).forEach(function entry(name) {
|
||||||
this.viewControllers[i].detachClientEvents();
|
self.viewControllers[name].detachClientEvents();
|
||||||
}
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
MenuModule.prototype.addViewController = function(vc) {
|
MenuModule.prototype.addViewController = function(name, vc) {
|
||||||
this.viewControllers.push(vc);
|
assert(!this.viewControllers[name]);
|
||||||
|
this.viewControllers[name] = vc;
|
||||||
return vc;
|
return vc;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -87,11 +229,20 @@ MenuModule.prototype.beforeArt = function() {
|
||||||
if(this.menuConfig.options.clearScreen) {
|
if(this.menuConfig.options.clearScreen) {
|
||||||
this.client.term.write(ansi.resetScreen());
|
this.client.term.write(ansi.resetScreen());
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
MenuModule.prototype.mciReady = function(mciMap) {
|
MenuModule.prototype.mciReady = function(mciData) {
|
||||||
};
|
};
|
||||||
|
|
||||||
MenuModule.prototype.finishedLoading = function() {
|
MenuModule.prototype.finishedLoading = function() {
|
||||||
|
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
if(_.isNumber(this.menuConfig.options.nextTimeout) &&
|
||||||
|
_.isString(this.menuConfig.next))
|
||||||
|
{
|
||||||
|
setTimeout(function nextTimeout() {
|
||||||
|
self.client.gotoMenuModule( { name : self.menuConfig.next } );
|
||||||
|
}, this.menuConfig.options.nextTimeout);
|
||||||
|
}
|
||||||
};
|
};
|
|
@ -4,7 +4,10 @@
|
||||||
// ENiGMA½
|
// ENiGMA½
|
||||||
var moduleUtil = require('./module_util.js');
|
var moduleUtil = require('./module_util.js');
|
||||||
var Log = require('./logger.js').log;
|
var Log = require('./logger.js').log;
|
||||||
var conf = require('./config.js');
|
var conf = require('./config.js'); // :TODO: remove me!
|
||||||
|
var Config = require('./config.js').config;
|
||||||
|
var asset = require('./asset.js');
|
||||||
|
var theme = require('./theme.js');
|
||||||
|
|
||||||
var fs = require('fs');
|
var fs = require('fs');
|
||||||
var paths = require('path');
|
var paths = require('path');
|
||||||
|
@ -17,7 +20,111 @@ var stripJsonComments = require('strip-json-comments');
|
||||||
exports.loadMenu = loadMenu;
|
exports.loadMenu = loadMenu;
|
||||||
exports.getFormConfig = getFormConfig;
|
exports.getFormConfig = getFormConfig;
|
||||||
|
|
||||||
|
|
||||||
|
function loadModJSON(fileName, cb) {
|
||||||
|
// :TODO: really need to cache menu.json and prompt.json only reloading if they change - see chokidar & gaze npms
|
||||||
|
var filePath = paths.join(Config.paths.mods, fileName);
|
||||||
|
|
||||||
|
fs.readFile(filePath, { encoding : 'utf8' }, function jsonData(err, data) {
|
||||||
|
try {
|
||||||
|
var json = JSON.parse(stripJsonComments(data));
|
||||||
|
cb(null, json);
|
||||||
|
} catch(e) {
|
||||||
|
cb(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function getMenuConfig(name, cb) {
|
||||||
|
var menuConfig;
|
||||||
|
|
||||||
|
async.waterfall(
|
||||||
|
[
|
||||||
|
function loadMenuJSON(callback) {
|
||||||
|
loadModJSON('menu.json', function loaded(err, menuJson) {
|
||||||
|
callback(err, menuJson);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
function locateMenuConfig(menuJson, callback) {
|
||||||
|
if(_.isObject(menuJson[name])) {
|
||||||
|
menuConfig = menuJson[name];
|
||||||
|
callback(null);
|
||||||
|
} else {
|
||||||
|
callback(new Error('No menu entry for \'' + name + '\''));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
function loadPromptJSON(callback) {
|
||||||
|
if(_.isString(menuConfig.prompt)) {
|
||||||
|
loadModJSON('prompt.json', function loaded(err, promptJson) {
|
||||||
|
callback(err, promptJson);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
callback(null, null);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
function locatePromptConfig(promptJson, callback) {
|
||||||
|
if(promptJson) {
|
||||||
|
if(_.isObject(promptJson[menuConfig.prompt])) {
|
||||||
|
menuConfig.promptConfig = promptJson[menuConfig.prompt];
|
||||||
|
} else {
|
||||||
|
callback(new Error('No prompt entry for \'' + menuConfig.prompt + '\''));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
callback(null);
|
||||||
|
}
|
||||||
|
],
|
||||||
|
function complete(err) {
|
||||||
|
cb(err, menuConfig);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
function loadMenu(options, cb) {
|
function loadMenu(options, cb) {
|
||||||
|
assert(_.isObject(options));
|
||||||
|
assert(_.isString(options.name));
|
||||||
|
assert(_.isObject(options.client));
|
||||||
|
|
||||||
|
async.waterfall(
|
||||||
|
[
|
||||||
|
function getMenuConfiguration(callback) {
|
||||||
|
getMenuConfig(options.name, function menuConfigLoaded(err, menuConfig) {
|
||||||
|
callback(err, menuConfig);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
function loadMenuModule(menuConfig, callback) {
|
||||||
|
var moduleName = menuConfig.module || 'standard_menu';
|
||||||
|
|
||||||
|
moduleUtil.loadModule(moduleName, 'mods', function moduleLoaded(err, mod) {
|
||||||
|
var modData = {
|
||||||
|
name : moduleName,
|
||||||
|
config : menuConfig,
|
||||||
|
mod : mod,
|
||||||
|
};
|
||||||
|
|
||||||
|
callback(err, modData);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
function createModuleInstance(modData, callback) {
|
||||||
|
Log.debug(
|
||||||
|
{ moduleName : modData.name, args : options.args, config : modData.config, info : modData.mod.modInfo },
|
||||||
|
'Creating menu module instance');
|
||||||
|
|
||||||
|
try {
|
||||||
|
var moduleInstance = new modData.mod.getModule( { menuConfig : modData.config, args : options.args } );
|
||||||
|
callback(null, moduleInstance);
|
||||||
|
} catch(e) {
|
||||||
|
callback(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
function complete(err, modInst) {
|
||||||
|
cb(err, modInst);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadMenu2(options, cb) {
|
||||||
|
|
||||||
assert(options);
|
assert(options);
|
||||||
assert(options.name);
|
assert(options.name);
|
||||||
|
@ -33,6 +140,7 @@ function loadMenu(options, cb) {
|
||||||
|
|
||||||
async.waterfall(
|
async.waterfall(
|
||||||
[
|
[
|
||||||
|
// :TODO: Need a good way to cache this information & only (re)load if modified
|
||||||
function loadMenuConfig(callback) {
|
function loadMenuConfig(callback) {
|
||||||
var configJsonPath = paths.join(conf.config.paths.mods, 'menu.json');
|
var configJsonPath = paths.join(conf.config.paths.mods, 'menu.json');
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,7 @@ function loadModule(name, category, cb) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// :TODO: what was the point of this? Remove it
|
||||||
mod.runtime = {
|
mod.runtime = {
|
||||||
config : config
|
config : config
|
||||||
};
|
};
|
||||||
|
|
|
@ -112,7 +112,7 @@ function getThemeArt(name, themeID, options, cb) {
|
||||||
|
|
||||||
// set/override some options
|
// set/override some options
|
||||||
options.asAnsi = true;
|
options.asAnsi = true;
|
||||||
options.readSauce = true; // can help with encoding
|
options.readSauce = true; // encoding/fonts/etc.
|
||||||
options.random = miscUtil.valueWithDefault(options.random, true);
|
options.random = miscUtil.valueWithDefault(options.random, true);
|
||||||
options.basePath = paths.join(Config.paths.themes, themeID);
|
options.basePath = paths.join(Config.paths.themes, themeID);
|
||||||
|
|
||||||
|
@ -138,28 +138,19 @@ function displayThemeArt(options, cb) {
|
||||||
assert(_.isObject(options.client));
|
assert(_.isObject(options.client));
|
||||||
assert(_.isString(options.name));
|
assert(_.isString(options.name));
|
||||||
|
|
||||||
getThemeArt(options.name, options.client.user.properties.art_theme_id, function onArt(err, artInfo) {
|
getThemeArt(options.name, options.client.user.properties.art_theme_id, function themeArt(err, artInfo) {
|
||||||
if(err) {
|
if(err) {
|
||||||
cb(err);
|
cb(err);
|
||||||
} else {
|
} else {
|
||||||
var iceColors = false;
|
|
||||||
if(artInfo.sauce && artInfo.sauce.ansiFlags) {
|
|
||||||
if(artInfo.sauce.ansiFlags & (1 << 0)) {
|
|
||||||
iceColors = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var dispOptions = {
|
var dispOptions = {
|
||||||
art : artInfo.data,
|
art : artInfo.data,
|
||||||
sauce : artInfo.sauce,
|
sauce : artInfo.sauce,
|
||||||
client : options.client,
|
client : options.client,
|
||||||
iceColors : iceColors,
|
|
||||||
font : options.font,
|
font : options.font,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
art.display(dispOptions, function displayed(err, mciMap) {
|
||||||
art.display(dispOptions, function onDisplayed(err, mci) {
|
cb(err, mciMap, artInfo);
|
||||||
cb(err, mci, artInfo);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -183,7 +183,7 @@ View.prototype.onSpecialKeyPress = function(keyName) {
|
||||||
if(this.isSpecialKeyMapped('accept', keyName)) {
|
if(this.isSpecialKeyMapped('accept', keyName)) {
|
||||||
this.emit('action', 'accept');
|
this.emit('action', 'accept');
|
||||||
} else if(this.isSpecialKeyMapped('next', keyName)) {
|
} else if(this.isSpecialKeyMapped('next', keyName)) {
|
||||||
this.emit('action', 'next');
|
console.log('next')
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
var MCIViewFactory = require('./mci_view_factory.js').MCIViewFactory;
|
var MCIViewFactory = require('./mci_view_factory.js').MCIViewFactory;
|
||||||
var menuUtil = require('./menu_util.js');
|
var menuUtil = require('./menu_util.js');
|
||||||
var Log = require('./logger.js').log;
|
var Log = require('./logger.js').log;
|
||||||
|
var Config = require('./config.js').config;
|
||||||
var asset = require('./asset.js');
|
var asset = require('./asset.js');
|
||||||
|
|
||||||
var events = require('events');
|
var events = require('events');
|
||||||
|
@ -12,9 +13,12 @@ var util = require('util');
|
||||||
var assert = require('assert');
|
var assert = require('assert');
|
||||||
var async = require('async');
|
var async = require('async');
|
||||||
var _ = require('lodash');
|
var _ = require('lodash');
|
||||||
|
var paths = require('path');
|
||||||
|
|
||||||
exports.ViewController = ViewController;
|
exports.ViewController = ViewController;
|
||||||
|
|
||||||
|
var MCI_REGEXP = /([A-Z]{2})([0-9]{1,2})/;
|
||||||
|
|
||||||
function ViewController(options) {
|
function ViewController(options) {
|
||||||
assert(_.isObject(options));
|
assert(_.isObject(options));
|
||||||
assert(_.isObject(options.client));
|
assert(_.isObject(options.client));
|
||||||
|
@ -44,7 +48,7 @@ function ViewController(options) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.onViewAction = function(action) {
|
this.viewActionListener = function(action) {
|
||||||
switch(action) {
|
switch(action) {
|
||||||
case 'next' :
|
case 'next' :
|
||||||
self.emit('action', { view : this, action : action });
|
self.emit('action', { view : this, action : action });
|
||||||
|
@ -84,12 +88,18 @@ function ViewController(options) {
|
||||||
};
|
};
|
||||||
|
|
||||||
var viewData;
|
var viewData;
|
||||||
|
var view;
|
||||||
for(var id in self.views) {
|
for(var id in self.views) {
|
||||||
try {
|
try {
|
||||||
viewData = self.views[id].getData();
|
view = self.views[id];
|
||||||
if(typeof viewData !== 'undefined') {
|
viewData = view.getData();
|
||||||
|
if(!_.isUndefined(viewData)) {
|
||||||
|
if(_.isString(view.submitArgName)) {
|
||||||
|
formData.value[view.submitArgName] = viewData;
|
||||||
|
} else {
|
||||||
formData.value[id] = viewData;
|
formData.value[id] = viewData;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
Log.error(e); // :TODO: Log better ;)
|
Log.error(e); // :TODO: Log better ;)
|
||||||
}
|
}
|
||||||
|
@ -108,6 +118,42 @@ function ViewController(options) {
|
||||||
self.emitSwitchFocus = false;
|
self.emitSwitchFocus = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.handleSubmitAction = function(callingMenu, formData, conf) {
|
||||||
|
assert(_.isObject(conf));
|
||||||
|
assert(_.isString(conf.action));
|
||||||
|
|
||||||
|
var actionAsset = asset.parseAsset(conf.action);
|
||||||
|
assert(_.isObject(actionAsset));
|
||||||
|
|
||||||
|
var extraArgs;
|
||||||
|
if(conf.extraArgs) {
|
||||||
|
extraArgs = self.formatMenuArgs(conf.extraArgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(actionAsset.type) {
|
||||||
|
case 'method' :
|
||||||
|
if(_.isString(actionAsset.location)) {
|
||||||
|
// :TODO: allow omition of '.js'
|
||||||
|
var methodMod = require(paths.join(Config.paths.mods, actionAsset.location));
|
||||||
|
if(_.isFunction(methodMod[actionAsset.asset])) {
|
||||||
|
methodMod[actionAsset.asset](callingMenu, formData, extraArgs);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// local to current module
|
||||||
|
var currentModule = self.client.currentMenuModule;
|
||||||
|
if(_.isFunction(currentModule.menuMethods[actionAsset.asset])) {
|
||||||
|
currentModule.menuMethods[actionAsset.asset](formData, extraArgs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'menu' :
|
||||||
|
// :TODO: update everythign to handle this format
|
||||||
|
self.client.gotoMenuModule( { name : actionAsset.asset, submitData : formData, extraArgs : extraArgs } );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
this.attachClientEvents();
|
this.attachClientEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -218,13 +264,206 @@ ViewController.prototype.loadFromMCIMap = function(mciMap) {
|
||||||
var view = factory.createFromMCI(mci);
|
var view = factory.createFromMCI(mci);
|
||||||
|
|
||||||
if(view) {
|
if(view) {
|
||||||
view.on('action', self.onViewAction);
|
view.on('action', self.viewActionListener);
|
||||||
self.addView(view);
|
self.addView(view);
|
||||||
view.redraw(); // :TODO: This can result in double redraw() if we set focus on this item after
|
view.redraw(); // :TODO: This can result in double redraw() if we set focus on this item after
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function setViewPropertiesFromMCIConf(view, conf) {
|
||||||
|
view.submit = conf.submit || false;
|
||||||
|
|
||||||
|
if(_.isArray(conf.items)) {
|
||||||
|
view.setItems(conf.items);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(_.isString(conf.text)) {
|
||||||
|
view.setText(conf.text);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(_.isString(conf.argName)) {
|
||||||
|
view.submitArgName = conf.argName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ViewController.prototype.loadFromPrompt = function(options, cb) {
|
||||||
|
assert(_.isObject(options));
|
||||||
|
//assert(_.isObject(options.promptConfig));
|
||||||
|
assert(_.isObject(options.callingMenu));
|
||||||
|
assert(_.isObject(options.callingMenu.menuConfig));
|
||||||
|
assert(_.isObject(options.callingMenu.menuConfig.promptConfig));
|
||||||
|
assert(_.isObject(options.mciMap));
|
||||||
|
|
||||||
|
var promptConfig = options.callingMenu.menuConfig.promptConfig;
|
||||||
|
var self = this;
|
||||||
|
var factory = new MCIViewFactory(this.client);
|
||||||
|
var initialFocusId = 1; // default to first
|
||||||
|
|
||||||
|
// :TODO: if 'submit' is not present anywhere default to last ID
|
||||||
|
|
||||||
|
async.waterfall(
|
||||||
|
[
|
||||||
|
function createViewsFromMCI(callback) {
|
||||||
|
async.each(Object.keys(options.mciMap), function entry(name, nextItem) {
|
||||||
|
var mci = options.mciMap[name];
|
||||||
|
var view = factory.createFromMCI(mci);
|
||||||
|
|
||||||
|
if(view) {
|
||||||
|
view.on('action', self.viewActionListener);
|
||||||
|
|
||||||
|
self.addView(view);
|
||||||
|
|
||||||
|
view.redraw(); // :TODO: fix double-redraw if this is the item we set focus to!
|
||||||
|
}
|
||||||
|
|
||||||
|
nextItem(null);
|
||||||
|
},
|
||||||
|
function complete(err) {
|
||||||
|
self.setViewOrder();
|
||||||
|
callback(err);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
function applyPromptConfig(callback) {
|
||||||
|
var highestId = 1;
|
||||||
|
var submitId;
|
||||||
|
|
||||||
|
async.each(Object.keys(promptConfig.mci), function entry(mci, nextItem) {
|
||||||
|
var mciMatch = mci.match(MCI_REGEXP); // :TODO: what about auto-generated IDs? Do they simply not apply to menu configs?
|
||||||
|
|
||||||
|
var viewId = parseInt(mciMatch[2]);
|
||||||
|
assert(!isNaN(viewId));
|
||||||
|
|
||||||
|
var view = self.getView(viewId);
|
||||||
|
var mciConf = promptConfig.mci[mci];
|
||||||
|
|
||||||
|
setViewPropertiesFromMCIConf(view, mciConf);
|
||||||
|
|
||||||
|
if(mciConf.focus) {
|
||||||
|
initialFocusId = viewId;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(view.submit) {
|
||||||
|
submitId = viewId;
|
||||||
|
}
|
||||||
|
|
||||||
|
nextItem(null);
|
||||||
|
},
|
||||||
|
function complete(err) {
|
||||||
|
|
||||||
|
// default to highest ID if no 'submit' entry present
|
||||||
|
if(!submitId) {
|
||||||
|
self.getView(highestId).submit = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
callback(err);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
function setupSubmit(callback) {
|
||||||
|
|
||||||
|
self.on('submit', function promptSubmit(formData) {
|
||||||
|
// :TODO: Need to come up with a way to log without dumping sensitive form data here, e.g. remove password, etc.
|
||||||
|
Log.trace( { formData : formData }, 'Prompt submit');
|
||||||
|
|
||||||
|
var actionAsset = asset.parseAsset(promptConfig.action);
|
||||||
|
assert(_.isObject(actionAsset));
|
||||||
|
|
||||||
|
var extraArgs;
|
||||||
|
if(promptConfig.extraArgs) {
|
||||||
|
extraArgs = self.formatMenuArgs(promptConfig.extraArgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
self.handleSubmitAction(options.callingMenu, formData, promptConfig);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*var formattedArgs;
|
||||||
|
if(conf.args) {
|
||||||
|
formattedArgs = self.formatMenuArgs(conf.args);
|
||||||
|
}
|
||||||
|
|
||||||
|
var actionAsset = asset.parseAsset(conf.action);
|
||||||
|
assert(_.isObject(actionAsset));
|
||||||
|
|
||||||
|
if('method' === actionAsset.type) {
|
||||||
|
if(actionAsset.location) {
|
||||||
|
// :TODO: call with (client, args, ...) at least.
|
||||||
|
} else {
|
||||||
|
// local to current module
|
||||||
|
var currentMod = self.client.currentMenuModule;
|
||||||
|
if(currentMod.menuMethods[actionAsset.asset]) {
|
||||||
|
currentMod.menuMethods[actionAsset.asset](formattedArgs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if('menu' === actionAsset.type) {
|
||||||
|
self.client.gotoMenuModule( { name : actionAsset.asset, args : formattedArgs } );
|
||||||
|
}*/
|
||||||
|
});
|
||||||
|
|
||||||
|
callback(null);
|
||||||
|
},
|
||||||
|
function setInitialFocus(callback) {
|
||||||
|
if(initialFocusId) {
|
||||||
|
self.switchFocus(initialFocusId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
function complete(err) {
|
||||||
|
console.log(err)
|
||||||
|
cb(err);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
ViewController.prototype.loadFromPrompt = function(options, cb) {
|
||||||
|
assert(_.isObject(options));
|
||||||
|
assert(_.isObject(options.prompt));
|
||||||
|
assert(_.isObject(options.prompt.artInfo));
|
||||||
|
assert(_.isObject(options.prompt.artInfo.mciMap));
|
||||||
|
assert(_.isObject(options.prompt.config));
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Prompts are like simplified forms:
|
||||||
|
// * They do not contain submit information themselves; this must
|
||||||
|
// the owning menu: options.prompt.config
|
||||||
|
// * There is only one form in a prompt (e.g. form 0, but this is not explicit)
|
||||||
|
// * Only one MCI mapping: options.prompt.artInfo.mciMap
|
||||||
|
//
|
||||||
|
var self = this;
|
||||||
|
var factory = new MCIViewFactory(this.client);
|
||||||
|
var mciMap = options.prompt.artInfo.mciMap;
|
||||||
|
|
||||||
|
async.waterfall(
|
||||||
|
[
|
||||||
|
function createViewsFromMCI(callback) {
|
||||||
|
async.each(Object.keys(mciMap), function mciEntry(name, nextItem) {
|
||||||
|
var mci = mciMap[name];
|
||||||
|
var view = factory.createFromMCI(mci);
|
||||||
|
|
||||||
|
if(view) {
|
||||||
|
self.addView(view);
|
||||||
|
view.redraw(); // :TODO: fix double-redraw if this is the item we set focus to!
|
||||||
|
}
|
||||||
|
|
||||||
|
nextItem(null);
|
||||||
|
},
|
||||||
|
function mciComplete(err) {
|
||||||
|
callback(err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
],
|
||||||
|
function compelte(err) {
|
||||||
|
cb(err);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
};
|
||||||
|
*/
|
||||||
|
|
||||||
ViewController.prototype.loadFromMCIMapAndConfig = function(options, cb) {
|
ViewController.prototype.loadFromMCIMapAndConfig = function(options, cb) {
|
||||||
assert(options.mciMap);
|
assert(options.mciMap);
|
||||||
|
|
||||||
|
@ -247,7 +486,7 @@ ViewController.prototype.loadFromMCIMapAndConfig = function(options, cb) {
|
||||||
|
|
||||||
if(err) {
|
if(err) {
|
||||||
// :TODO: fix logging of err here:
|
// :TODO: fix logging of err here:
|
||||||
Log.warn(
|
Log.trace(
|
||||||
{ err : err.toString(), mci : Object.keys(options.mciMap), formIdKey : formIdKey } ,
|
{ err : err.toString(), mci : Object.keys(options.mciMap), formIdKey : formIdKey } ,
|
||||||
'Unable to load menu configuration');
|
'Unable to load menu configuration');
|
||||||
}
|
}
|
||||||
|
@ -255,13 +494,13 @@ ViewController.prototype.loadFromMCIMapAndConfig = function(options, cb) {
|
||||||
callback(null);
|
callback(null);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
function createViewsFromMCIMap(callback) {
|
function createViewsFromMCI(callback) {
|
||||||
async.each(Object.keys(options.mciMap), function onMciEntry(name, eachCb) {
|
async.each(Object.keys(options.mciMap), function onMciEntry(name, eachCb) {
|
||||||
var mci = options.mciMap[name];
|
var mci = options.mciMap[name];
|
||||||
var view = factory.createFromMCI(mci);
|
var view = factory.createFromMCI(mci);
|
||||||
|
|
||||||
if(view) {
|
if(view) {
|
||||||
view.on('action', self.onViewAction);
|
view.on('action', self.viewActionListener);
|
||||||
self.addView(view);
|
self.addView(view);
|
||||||
view.redraw(); // :TODO: This can result in double redraw() if we set focus on this item after
|
view.redraw(); // :TODO: This can result in double redraw() if we set focus on this item after
|
||||||
}
|
}
|
||||||
|
@ -269,7 +508,6 @@ ViewController.prototype.loadFromMCIMapAndConfig = function(options, cb) {
|
||||||
},
|
},
|
||||||
function eachMciComplete(err) {
|
function eachMciComplete(err) {
|
||||||
self.setViewOrder();
|
self.setViewOrder();
|
||||||
|
|
||||||
callback(err);
|
callback(err);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
|
@ -92,6 +92,12 @@ function ApplyModule(menuConfig) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var re = new RegExp(Config.users.usernamePattern);
|
||||||
|
if(!re.test(args.username)) {
|
||||||
|
cb('Handle contains invalid characters!', [ 1 ] );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if(args.pw.length < Config.users.passwordMin) {
|
if(args.pw.length < Config.users.passwordMin) {
|
||||||
cb('Password too short!', [ 9, 10 ]);
|
cb('Password too short!', [ 9, 10 ]);
|
||||||
return;
|
return;
|
||||||
|
@ -123,13 +129,13 @@ ApplyModule.prototype.beforeArt = function() {
|
||||||
ApplyModule.super_.prototype.beforeArt.call(this);
|
ApplyModule.super_.prototype.beforeArt.call(this);
|
||||||
};
|
};
|
||||||
|
|
||||||
ApplyModule.prototype.mciReady = function(mciMap) {
|
ApplyModule.prototype.mciReady = function(mciMaps) {
|
||||||
ApplyModule.super_.prototype.mciReady.call(this, mciMap);
|
ApplyModule.super_.prototype.mciReady.call(this, mciMaps);
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
self.viewController = self.addViewController(new ViewController({ client : self.client } ));
|
self.viewController = self.addViewController(new ViewController({ client : self.client } ));
|
||||||
self.viewController.loadFromMCIMapAndConfig( { mciMap : mciMap, menuConfig : self.menuConfig }, function onViewReady(err) {
|
self.viewController.loadFromMCIMapAndConfig( { mciMap : mciMaps.menu, menuConfig : self.menuConfig }, function onViewReady(err) {
|
||||||
|
|
||||||
});
|
});
|
||||||
};
|
};
|
|
@ -21,6 +21,37 @@ exports.moduleInfo = {
|
||||||
|
|
||||||
exports.getModule = LoginModule;
|
exports.getModule = LoginModule;
|
||||||
|
|
||||||
|
exports.attemptLogin = attemptLogin;
|
||||||
|
|
||||||
|
function attemptLogin(callingMenu, formData, extraArgs) {
|
||||||
|
var client = callingMenu.client;
|
||||||
|
|
||||||
|
client.user.authenticate(formData.value.username, formData.value.password, function authenticated(err) {
|
||||||
|
if(err) {
|
||||||
|
Log.info( { username : formData.value.username }, 'Failed login attempt %s', err);
|
||||||
|
|
||||||
|
client.gotoMenuModule( { name : callingMenu.menuConfig.fallback } );
|
||||||
|
} else {
|
||||||
|
// use client.user so we can get correct case
|
||||||
|
Log.info( { username : callingMenu.client.user.username }, 'Successful login');
|
||||||
|
|
||||||
|
async.parallel(
|
||||||
|
[
|
||||||
|
function loadThemeConfig(callback) {
|
||||||
|
theme.getThemeInfo(client.user.properties.art_theme_id, function themeInfo(err, info) {
|
||||||
|
client.currentThemeInfo = info;
|
||||||
|
callback(null);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
],
|
||||||
|
function complete(err, results) {
|
||||||
|
client.gotoMenuModule( { name : callingMenu.menuConfig.next } );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function LoginModule(menuConfig) {
|
function LoginModule(menuConfig) {
|
||||||
MenuModule.call(this, menuConfig);
|
MenuModule.call(this, menuConfig);
|
||||||
|
@ -91,12 +122,12 @@ LoginModule.prototype.beforeArt = function() {
|
||||||
//this.client.term.write(ansi.resetScreen());
|
//this.client.term.write(ansi.resetScreen());
|
||||||
};
|
};
|
||||||
|
|
||||||
LoginModule.prototype.mciReady = function(mciMap) {
|
LoginModule.prototype.mciReady = function(mciData) {
|
||||||
LoginModule.super_.prototype.mciReady.call(this, mciMap);
|
LoginModule.super_.prototype.mciReady.call(this, mciData);
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
self.viewController = self.addViewController(new ViewController( { client : self.client } ));
|
self.viewController = self.addViewController(new ViewController( { client : self.client } ));
|
||||||
self.viewController.loadFromMCIMapAndConfig( { mciMap : mciMap, menuConfig : self.menuConfig }, function onViewReady(err) {
|
self.viewController.loadFromMCIMapAndConfig( { mciMap : mciData.menu, menuConfig : self.menuConfig }, function onViewReady(err) {
|
||||||
});
|
});
|
||||||
};
|
};
|
|
@ -28,8 +28,8 @@ LogOffModule.prototype.beforeArt = function() {
|
||||||
this.client.term.write(ansi.resetScreen());
|
this.client.term.write(ansi.resetScreen());
|
||||||
};
|
};
|
||||||
|
|
||||||
LogOffModule.prototype.mciReady = function(mciMap) {
|
LogOffModule.prototype.mciReady = function(mciData) {
|
||||||
LogOffModule.super_.prototype.mciReady.call(this, mciMap);
|
LogOffModule.super_.prototype.mciReady.call(this, mciData);
|
||||||
};
|
};
|
||||||
|
|
||||||
LogOffModule.prototype.finishedLoading = function() {
|
LogOffModule.prototype.finishedLoading = function() {
|
||||||
|
|
|
@ -38,8 +38,6 @@ MatrixModule.prototype.enter = function(client) {
|
||||||
|
|
||||||
MatrixModule.prototype.beforeArt = function() {
|
MatrixModule.prototype.beforeArt = function() {
|
||||||
MatrixModule.super_.prototype.beforeArt.call(this);
|
MatrixModule.super_.prototype.beforeArt.call(this);
|
||||||
|
|
||||||
this.client.term.write(ansi.resetScreen());
|
|
||||||
};
|
};
|
||||||
|
|
||||||
MatrixModule.prototype.mciReady = function(mciMap) {
|
MatrixModule.prototype.mciReady = function(mciMap) {
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
// @method:scriptName[.js]/methodName (foreign .js)
|
// @method:scriptName[.js]/methodName (foreign .js)
|
||||||
// @art:artName
|
// @art:artName
|
||||||
// @method:/methodName (local to module.js)
|
// @method:/methodName (local to module.js)
|
||||||
|
// ... pass isFocused/etc. into draw method
|
||||||
"draw" : {
|
"draw" : {
|
||||||
"normal" : ...,
|
"normal" : ...,
|
||||||
"focus" : ...
|
"focus" : ...
|
||||||
|
@ -20,10 +21,18 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
"connected" : {
|
||||||
|
"art" : "connect",
|
||||||
|
"next" : "matrix",
|
||||||
|
"options" : {
|
||||||
|
"clearScreen" : true,
|
||||||
|
"nextTimeout" : 1500
|
||||||
|
}
|
||||||
|
},
|
||||||
"matrix" : {
|
"matrix" : {
|
||||||
"art" : "matrix",
|
"art" : "matrix",
|
||||||
"form" : {
|
"form" : {
|
||||||
"0" : {
|
"0" : { // :TODO: Make form "0" the default if missing (e.g. optional)
|
||||||
"VM1" : {
|
"VM1" : {
|
||||||
"mci" : {
|
"mci" : {
|
||||||
"VM1" : {
|
"VM1" : {
|
||||||
|
@ -57,12 +66,18 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"login" : {
|
"login" : {
|
||||||
"art" : "login", // TODO: rename to login_form
|
//"art" : "login", // TODO: rename to login_form
|
||||||
"module" : "login",
|
"prompt" : "userCredentials",
|
||||||
|
"fallback" : "matrix",
|
||||||
|
"next" : "newUserActive",
|
||||||
|
//"module" : "login",
|
||||||
|
/*
|
||||||
"form" : {
|
"form" : {
|
||||||
"0" : {
|
"0" : {
|
||||||
"BT3BT4ET1ET2TL5" :{
|
"BT3BT4ET1ET2TL5" :{
|
||||||
"mci" :{
|
"mci" :{
|
||||||
|
// :TODO: LIke prompts, assign "argName" values here, e.g.:
|
||||||
|
// "argName" : "username", ...
|
||||||
"ET1" : {
|
"ET1" : {
|
||||||
"focus" : true
|
"focus" : true
|
||||||
},
|
},
|
||||||
|
@ -80,25 +95,30 @@
|
||||||
{
|
{
|
||||||
"value" : { "3" : null },
|
"value" : { "3" : null },
|
||||||
"action" : "@method:attemptLogin",
|
"action" : "@method:attemptLogin",
|
||||||
|
// :TODO: see above about argName;
|
||||||
|
// any other args should be "extraArgs"
|
||||||
"args" : {
|
"args" : {
|
||||||
"next" : {
|
"next" : {
|
||||||
|
// :TODO: just use menu.next
|
||||||
"success" : "newUserActive"
|
"success" : "newUserActive"
|
||||||
},
|
},
|
||||||
"username" : "{1}",
|
"username" : "{1}",
|
||||||
"password" : "{2}"
|
"password" : "{2}"
|
||||||
} // :TODO: rename to actionArgs ?
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"4" : [ // Cancel
|
"4" : [ // Cancel
|
||||||
{
|
{
|
||||||
"value" : { "4" : null },
|
"value" : { "4" : null },
|
||||||
"action" : "@menu:matrix"
|
"action" : "@menu:matrix"
|
||||||
|
// :TODO: Just use menu.fallback, e.g. @fallback
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
*/
|
||||||
"options" : {
|
"options" : {
|
||||||
"clearScreen" : true
|
"clearScreen" : true
|
||||||
}
|
}
|
||||||
|
@ -165,19 +185,10 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"newUserActive" : {
|
"newUserActive" : {
|
||||||
"art" : "NEWACT",
|
"art" : "STATS",
|
||||||
"options" : {
|
"options" : {
|
||||||
// :TODO: implement MCI codes for this
|
// :TODO: implement MCI codes for this
|
||||||
"clearScreen" : true
|
"clearScreen" : true
|
||||||
},
|
|
||||||
"form" : {
|
|
||||||
"0" : {
|
|
||||||
"UN1UR2" : {
|
|
||||||
"mci" : {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -29,19 +29,61 @@ StandardMenuModule.prototype.beforeArt = function() {
|
||||||
StandardMenuModule.super_.prototype.beforeArt.call(this);
|
StandardMenuModule.super_.prototype.beforeArt.call(this);
|
||||||
};
|
};
|
||||||
|
|
||||||
StandardMenuModule.prototype.mciReady = function(mciMap) {
|
StandardMenuModule.prototype.mciReady = function(mciData) {
|
||||||
StandardMenuModule.super_.prototype.mciReady.call(this, mciMap);
|
StandardMenuModule.super_.prototype.mciReady.call(this, mciData);
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
|
//
|
||||||
|
// 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)
|
||||||
|
//
|
||||||
|
self.viewControllers = {};
|
||||||
|
|
||||||
|
var vcOpts = { client : self.client };
|
||||||
|
|
||||||
|
if(mciData.menu) {
|
||||||
|
self.viewControllers.menu = new ViewController(vcOpts);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(mciData.prompt) {
|
||||||
|
self.viewControllers.prompt = new ViewController(vcOpts);
|
||||||
|
}
|
||||||
|
|
||||||
|
var viewsReady = function(err) {
|
||||||
|
// :TODO: Hrm.....
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
if(self.viewControllers.menu) {
|
||||||
|
var menuLoadOpts = {
|
||||||
|
mciMap : mciData.menu,
|
||||||
|
menuConfig : self.menuConfig,
|
||||||
|
withForm : !mciData.prompt,
|
||||||
|
};
|
||||||
|
|
||||||
|
self.viewControllers.menu.loadFromMCIMapAndConfig(menuLoadOpts, viewsReady);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(self.viewControllers.prompt) {
|
||||||
|
var promptLoadOpts = {
|
||||||
|
callingMenu : self,
|
||||||
|
mciMap : mciData.prompt,
|
||||||
|
//promptConfig : self.menuConfig.promptConfig,
|
||||||
|
};
|
||||||
|
|
||||||
|
self.viewControllers.prompt.loadFromPrompt(promptLoadOpts, viewsReady);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
var vc = self.addViewController(new ViewController({ client : self.client } ));
|
var vc = self.addViewController(new ViewController({ client : self.client } ));
|
||||||
vc.loadFromMCIMapAndConfig( { mciMap : mciMap, menuConfig : self.menuConfig }, function onViewReady(err) {
|
vc.loadFromMCIMapAndConfig( { mciMap : mciData.menu, menuConfig : self.menuConfig }, function onViewReady(err) {
|
||||||
if(err) {
|
if(err) {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
} else {
|
} else {
|
||||||
/* vc.on('submit', function onFormSubmit(formData) {
|
|
||||||
console.log(formData);
|
|
||||||
});*/
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
*/
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue