+ Start work on MenuView & friends
* connect.js no longer a module. Part of initial connection always * Cleaner & expandable BBS init * Better theme handling
This commit is contained in:
parent
14a321de2f
commit
c3aa4c44e2
32
core/bbs.js
32
core/bbs.js
|
@ -11,6 +11,7 @@ var database = require('./database.js');
|
||||||
var iconv = require('iconv-lite');
|
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');
|
||||||
|
|
||||||
exports.bbsMain = bbsMain;
|
exports.bbsMain = bbsMain;
|
||||||
|
|
||||||
|
@ -51,22 +52,15 @@ function bbsMain() {
|
||||||
conf.createDefault();
|
conf.createDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.init();
|
initialize(function onInit(err) {
|
||||||
|
if(err) {
|
||||||
|
console.error('Error initializing: ' + util.inspect(err));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
process.on('SIGINT', function onSigInt() {
|
startListening();
|
||||||
// :TODO: for any client in |clientConnections|, if 'ready', send a "Server Disconnecting" + semi-gracefull hangup
|
|
||||||
// e.g. client.disconnectNow()
|
|
||||||
|
|
||||||
logger.log.info('Process interrupted, shutting down');
|
|
||||||
process.exit();
|
|
||||||
});
|
});
|
||||||
|
}
|
||||||
database.initializeDatabases();
|
|
||||||
|
|
||||||
preServingInit();
|
|
||||||
|
|
||||||
startListening();
|
|
||||||
};
|
|
||||||
|
|
||||||
function parseArgs() {
|
function parseArgs() {
|
||||||
var args = [];
|
var args = [];
|
||||||
|
@ -91,6 +85,8 @@ function initialize(cb) {
|
||||||
process.exit();
|
process.exit();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
iconv.extendNodeEncodings();
|
||||||
|
|
||||||
callback(null);
|
callback(null);
|
||||||
},
|
},
|
||||||
function initDatabases(callback) {
|
function initDatabases(callback) {
|
||||||
|
@ -112,10 +108,6 @@ function initialize(cb) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function preServingInit() {
|
|
||||||
iconv.extendNodeEncodings();
|
|
||||||
}
|
|
||||||
|
|
||||||
var clientConnections = [];
|
var clientConnections = [];
|
||||||
|
|
||||||
function startListening() {
|
function startListening() {
|
||||||
|
@ -151,14 +143,13 @@ function startListening() {
|
||||||
}
|
}
|
||||||
|
|
||||||
addNewClient(client);
|
addNewClient(client);
|
||||||
//client.runtime.id = clientConnections.push(client) - 1;
|
|
||||||
|
|
||||||
//logger.log.info({ clientId : client.runtime.id, from : client.address(), server : module.moduleInfo.name }, 'Client connected');
|
//logger.log.info({ clientId : client.runtime.id, from : client.address(), server : module.moduleInfo.name }, 'Client connected');
|
||||||
|
|
||||||
client.on('ready', function onClientReady() {
|
client.on('ready', function onClientReady() {
|
||||||
// Go to module -- use default error handler
|
// Go to module -- use default error handler
|
||||||
prepareClient(client, function onPrepared() {
|
prepareClient(client, function onPrepared() {
|
||||||
modules.goto(conf.config.entryMod, client);
|
require('./connect.js').connectEntry(client);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -199,6 +190,7 @@ function removeClient(client) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function prepareClient(client, cb) {
|
function prepareClient(client, cb) {
|
||||||
|
// :TODO: it feels like this should go somewhere else... and be a bit more elegant.
|
||||||
if('*' === conf.config.preLoginTheme) {
|
if('*' === conf.config.preLoginTheme) {
|
||||||
var theme = require('./theme.js');
|
var theme = require('./theme.js');
|
||||||
theme.getRandomTheme(function onRandTheme(err, themeId) {
|
theme.getRandomTheme(function onRandTheme(err, themeId) {
|
||||||
|
|
|
@ -7,7 +7,7 @@ var miscUtil = require('./misc_util.js');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
// :TODO: remove this ... anti-pattern!
|
// :TODO: remove this ... anti-pattern!
|
||||||
config : undefined,
|
//config : undefined,
|
||||||
|
|
||||||
defaultPath : function() {
|
defaultPath : function() {
|
||||||
var base = miscUtil.resolvePath('~/');
|
var base = miscUtil.resolvePath('~/');
|
||||||
|
@ -26,7 +26,7 @@ module.exports = {
|
||||||
bbsName : 'Another Fine ENiGMA½ BBS',
|
bbsName : 'Another Fine ENiGMA½ BBS',
|
||||||
|
|
||||||
// :TODO: probably replace this with 'firstMenu' or somthing once that's available
|
// :TODO: probably replace this with 'firstMenu' or somthing once that's available
|
||||||
entryMod : 'connect',
|
entryMod : 'matrix',
|
||||||
|
|
||||||
preLoginTheme : '*',
|
preLoginTheme : '*',
|
||||||
|
|
||||||
|
|
|
@ -1,21 +1,17 @@
|
||||||
/* jslint node: true */
|
/* jslint node: true */
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var ansi = require('../core/ansi_term.js');
|
var ansi = require('./ansi_term.js');
|
||||||
var artwork = require('../core/art.js');
|
var artwork = require('./art.js');
|
||||||
var modules = require('../core/modules.js');
|
var modules = require('./modules.js');
|
||||||
var Log = require('../core/logger.js').log;
|
var Log = require('./logger.js').log;
|
||||||
|
var Config = require('./config.js').config;
|
||||||
var packageJson = require('../package.json');
|
var packageJson = require('../package.json');
|
||||||
|
|
||||||
|
var assert = require('assert');
|
||||||
var util = require('util');
|
var util = require('util');
|
||||||
|
|
||||||
exports.moduleInfo = {
|
exports.connectEntry = connectEntry;
|
||||||
name : 'Connect',
|
|
||||||
desc : 'First module upon connection',
|
|
||||||
author : 'NuSkooler',
|
|
||||||
};
|
|
||||||
|
|
||||||
exports.entryPoint = entryPoint;
|
|
||||||
|
|
||||||
function ansiQueryTermSizeIfNeeded(client) {
|
function ansiQueryTermSizeIfNeeded(client) {
|
||||||
if(client.term.termHeight > 0 || client.term.termWidth > 0) {
|
if(client.term.termHeight > 0 || client.term.termWidth > 0) {
|
||||||
|
@ -30,10 +26,13 @@ function ansiQueryTermSizeIfNeeded(client) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert(2 === pos.length);
|
||||||
client.term.termHeight = pos[0];
|
client.term.termHeight = pos[0];
|
||||||
client.term.termWidth = pos[1];
|
client.term.termWidth = pos[1];
|
||||||
|
|
||||||
Log.debug({ termWidth : client.term.termWidth, termHeight : client.term.termHeight, updateSource : 'ANSI CPR' }, 'Window size updated');
|
Log.debug(
|
||||||
|
{ termWidth : client.term.termWidth, termHeight : client.term.termHeight, updateSource : 'ANSI CPR' },
|
||||||
|
'Window size updated');
|
||||||
};
|
};
|
||||||
|
|
||||||
client.once('cursor position report', onCPR);
|
client.once('cursor position report', onCPR);
|
||||||
|
@ -46,7 +45,21 @@ function ansiQueryTermSizeIfNeeded(client) {
|
||||||
client.term.write(ansi.queryScreenSize());
|
client.term.write(ansi.queryScreenSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
function entryPoint(client) {
|
function prepareTerminal(term) {
|
||||||
|
term.write(ansi.normal());
|
||||||
|
term.write(ansi.disableVT100LineWrapping());
|
||||||
|
// :TODO: set xterm stuff -- see x84/others
|
||||||
|
}
|
||||||
|
|
||||||
|
function displayBanner(term) {
|
||||||
|
// :TODO: add URL to banner
|
||||||
|
term.write(ansi.fromPipeCode(util.format('' +
|
||||||
|
'|33Conected to |32EN|33|01i|32|22GMA|32|01½|00 |33BBS version|31|01 %s\n' +
|
||||||
|
'|00|33Copyright (c) 2014 Bryan Ashby\n' +
|
||||||
|
'|00', packageJson.version)));
|
||||||
|
}
|
||||||
|
|
||||||
|
function connectEntry(client) {
|
||||||
var term = client.term;
|
var term = client.term;
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -55,24 +68,8 @@ function entryPoint(client) {
|
||||||
//
|
//
|
||||||
ansiQueryTermSizeIfNeeded(client);
|
ansiQueryTermSizeIfNeeded(client);
|
||||||
|
|
||||||
term.write(ansi.normal());
|
prepareTerminal(term);
|
||||||
|
displayBanner(term);
|
||||||
term.write(ansi.disableVT100LineWrapping());
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// If we don't yet know the client term width/height, try
|
|
||||||
// a nonstandard ANSI query
|
|
||||||
//
|
|
||||||
|
|
||||||
// :TODO: set xterm stuff -- see x84/others
|
|
||||||
|
|
||||||
// :TODO: add URL to banner
|
|
||||||
term.write(ansi.fromPipeCode(util.format('' +
|
|
||||||
'|33Conected to |32EN|33|01i|32|22GMA|32|01½|00 |33BBS version|31|01 %s\n' +
|
|
||||||
'|00|33Copyright (c) 2014 Bryan Ashby\n' +
|
|
||||||
'|00', packageJson.version)));
|
|
||||||
|
|
||||||
setTimeout(function onTimeout() {
|
setTimeout(function onTimeout() {
|
||||||
term.write(ansi.clearScreen());
|
term.write(ansi.clearScreen());
|
||||||
|
@ -87,7 +84,7 @@ function entryPoint(client) {
|
||||||
|
|
||||||
setTimeout(function onTimeout() {
|
setTimeout(function onTimeout() {
|
||||||
term.write(ansi.clearScreen());
|
term.write(ansi.clearScreen());
|
||||||
modules.goto('matrix', client);
|
modules.goto(Config.entryMod, client);
|
||||||
}, timeout);
|
}, timeout);
|
||||||
});
|
});
|
||||||
}, 500);
|
}, 500);
|
|
@ -0,0 +1,31 @@
|
||||||
|
/* jslint node: true */
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var View = require('./view.js').View;
|
||||||
|
var ansi = require('./ansi_term.js');
|
||||||
|
var util = require('util');
|
||||||
|
var assert = require('assert');
|
||||||
|
|
||||||
|
exports.MenuView = MenuView;
|
||||||
|
|
||||||
|
function MenuView(client, options) {
|
||||||
|
View.call(this, client, options);
|
||||||
|
|
||||||
|
this.items = [];
|
||||||
|
if(this.options.items) {
|
||||||
|
this.options.items.forEach(function onItem(itemText) {
|
||||||
|
this.items.push({
|
||||||
|
text : itemText,
|
||||||
|
focused : false,
|
||||||
|
selected : false,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
this.itemSpacing = this.options.itemSpacing || 1;
|
||||||
|
this.focusPrefix = this.options.focusPrefix || '';
|
||||||
|
this.focusSuffix = this.options.focusSuffix || '';
|
||||||
|
}
|
||||||
|
|
||||||
|
util.inherits(MenuView, View);
|
||||||
|
|
|
@ -13,8 +13,6 @@ exports.TextView = TextView;
|
||||||
function TextView(client, options) {
|
function TextView(client, options) {
|
||||||
View.call(this, client, options);
|
View.call(this, client, options);
|
||||||
|
|
||||||
var self = this;
|
|
||||||
|
|
||||||
if(this.options.maxLength) {
|
if(this.options.maxLength) {
|
||||||
this.maxLength = this.options.maxLength;
|
this.maxLength = this.options.maxLength;
|
||||||
}
|
}
|
||||||
|
@ -31,7 +29,7 @@ function TextView(client, options) {
|
||||||
|
|
||||||
this.setText(this.options.text || '');
|
this.setText(this.options.text || '');
|
||||||
|
|
||||||
this.isPasswordTextStyle = 'P' === self.textStyle || 'password' === self.textStyle;
|
this.isPasswordTextStyle = 'P' === this.textStyle || 'password' === this.textStyle;
|
||||||
|
|
||||||
if(this.isPasswordTextStyle) {
|
if(this.isPasswordTextStyle) {
|
||||||
this.textMaskChar = miscUtil.valueWithDefault(this.options.textMaskChar, '*').substr(0, 1);
|
this.textMaskChar = miscUtil.valueWithDefault(this.options.textMaskChar, '*').substr(0, 1);
|
||||||
|
|
|
@ -33,7 +33,6 @@ function getThemeInfo(themeID, cb) {
|
||||||
var availableThemes = {};
|
var availableThemes = {};
|
||||||
|
|
||||||
function initAvailableThemes(cb) {
|
function initAvailableThemes(cb) {
|
||||||
// lazy init
|
|
||||||
async.waterfall(
|
async.waterfall(
|
||||||
[
|
[
|
||||||
function getDir(callback) {
|
function getDir(callback) {
|
||||||
|
@ -56,9 +55,9 @@ function initAvailableThemes(cb) {
|
||||||
}
|
}
|
||||||
availableThemes[themeId] = info;
|
availableThemes[themeId] = info;
|
||||||
}
|
}
|
||||||
callback(null);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
callback(null);
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
function onComplete(err) {
|
function onComplete(err) {
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
/* jslint node: true */
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var MenuView = require('./menu_view.js').MenuView;
|
||||||
|
var ansi = require('./ansi_term.js');
|
||||||
|
var util = require('util');
|
||||||
|
var assert = require('assert');
|
||||||
|
|
||||||
|
function VerticalMenuView(client, options) {
|
||||||
|
MenuView.call(this, client, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
util.inherits(VerticalMenuView, MenuView);
|
||||||
|
|
||||||
|
VerticalMenuView.prototype.redraw = function() {
|
||||||
|
VerticalMenuView.super_.prototype.redraw.call(this);
|
||||||
|
};
|
|
@ -40,8 +40,6 @@ function entryPoint(client) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(mci);
|
|
||||||
|
|
||||||
user.authenticate('NuSkooler', 'password', client, function onAuth(isValid) {
|
user.authenticate('NuSkooler', 'password', client, function onAuth(isValid) {
|
||||||
console.log(isValid);
|
console.log(isValid);
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue