diff --git a/core/bbs.js b/core/bbs.js index 8cf9a921..9214d147 100644 --- a/core/bbs.js +++ b/core/bbs.js @@ -211,8 +211,8 @@ function prepareClient(client, cb) { client.user.properties.theme_id = theme.getRandomTheme() || ''; - theme.getThemeInfo(client.user.properties.theme_id, function themeInfo(err, info) { - client.currentThemeInfo = info; + theme.loadTheme(client.user.properties.theme_id, function themeLoaded(err, theme) { + client.currentTheme = theme; cb(null); }); } else { diff --git a/core/config.js b/core/config.js index 29ba1927..ce7bc945 100644 --- a/core/config.js +++ b/core/config.js @@ -77,7 +77,6 @@ function getDefaultConfig() { preLoginTheme : '*', - // :TODO: change to nua users : { usernameMin : 2, usernameMax : 22, diff --git a/core/system_menu_method.js b/core/system_menu_method.js index c41db392..25cf577a 100644 --- a/core/system_menu_method.js +++ b/core/system_menu_method.js @@ -25,9 +25,9 @@ function login(callingMenu, formData, extraArgs) { async.parallel( [ function loadThemeConfig(callback) { - theme.getThemeInfo(client.user.properties.theme_id, function themeInfo(err, info) { - client.currentThemeInfo = info; - callback(null); + theme.loadTheme(client.user.properties.theme_id, function themeLoaded(err, theme) { + client.currentTheme = theme; + callback(null); // always non-fatal }); } ], diff --git a/core/theme.js b/core/theme.js index 5d82ac51..d08032c1 100644 --- a/core/theme.js +++ b/core/theme.js @@ -1,50 +1,60 @@ /* jslint node: true */ 'use strict'; -var Config = require('./config.js').config; -var art = require('./art.js'); -var miscUtil = require('./misc_util.js'); -var Log = require('./logger.js').log; +var Config = require('./config.js').config; +var art = require('./art.js'); +var miscUtil = require('./misc_util.js'); +var Log = require('./logger.js').log; -var fs = require('fs'); -var paths = require('path'); -var async = require('async'); -var _ = require('lodash'); -var assert = require('assert'); +var fs = require('fs'); +var paths = require('path'); +var async = require('async'); +var _ = require('lodash'); +var assert = require('assert'); +var stripJsonComments = require('strip-json-comments'); -exports.getThemeInfo = getThemeInfo; +exports.loadTheme = loadTheme; exports.getThemeArt = getThemeArt; exports.getRandomTheme = getRandomTheme; exports.initAvailableThemes = initAvailableThemes; exports.displayThemeArt = displayThemeArt; -function getThemeInfo(themeID, cb) { - var path = paths.join(Config.paths.themes, themeID, 'theme_info.json'); +function loadTheme(themeID, cb) { + var path = paths.join(Config.paths.themes, themeID, 'theme.json'); - fs.readFile(path, function onData(err, data) { + fs.readFile(path, { encoding : 'utf8' }, function onData(err, data) { if(err) { cb(err); } else { try { - // :TODO: strip comments/etc. ala menu.json - var info = JSON.parse(data); + var theme = JSON.parse(stripJsonComments(data)); + + if(!_.isObject(theme.info)) { + cb(new Error('Invalid theme JSON')); + return; + } + + assert(!_.isObject(theme.helpers)); // we create this on the fly! // // Create some handy helpers // - info.getPasswordChar = function() { - var pwChar = Config.defaults.passwordChar; - if(_.isObject(info.config)) { - if(_.isString(info.config.passwordChar)) { - pwChar = info.config.passwordChar.substr(0, 1); - } else if(_.isNumber(info.config.passwordChar)) { - pwChar = String.fromCharCode(info.config.passwordChar); + theme.helpers = { + getPasswordChar : function() { + var pwChar = Config.defaults.passwordChar; + if(_.isObject(theme.defaults) && _.isObject(theme.defaults.general)) { + var themePasswordChar = theme.defaults.general.passwordChar; + if(_.isString(themePasswordChar)) { + pwChar = themePasswordChar.substr(0, 1); + } else if(_.isNumber(themePasswordChar)) { + pwChar = String.fromCharCode(themePasswordChar); + } } + return pwChar; } - return pwChar; - }; + } - cb(null, info); + cb(null, theme); } catch(e) { cb(err); } @@ -70,15 +80,13 @@ function initAvailableThemes(cb) { }, function populateAvailable(filtered, callback) { filtered.forEach(function onTheme(themeId) { - getThemeInfo(themeId, function onThemeInfo(err, info) { + loadTheme(themeId, function themeLoaded(err, theme) { if(!err) { - if(!availableThemes) { - availableThemes = {}; - } - availableThemes[themeId] = info; - Log.debug( { info : info }, 'Theme loaded'); + availableThemes[themeId] = theme; + Log.debug( { info : theme.info }, 'Theme loaded'); } }); + }); callback(null); } @@ -101,17 +109,6 @@ function getRandomTheme() { } } -/* -function getRandomTheme(cb) { - if(Object.getOwnPropertyNames(availableThemes).length > 0) { - var themeIds = Object.keys(availableThemes); - cb(null, themeIds[Math.floor(Math.random() * themeIds.length)]); - } else { - cb(new Error('No themes available')); - } -} -*/ - function getThemeArt(name, themeID, options, cb) { // allow options to be optional if(_.isUndefined(cb)) { diff --git a/core/user.js b/core/user.js index cc42602d..2826a88b 100644 --- a/core/user.js +++ b/core/user.js @@ -22,7 +22,7 @@ function User() { this.groups = {}; // id:name this.isValid = function() { - if(self.userId <= 0 || self.username.length < 2) { + if(self.userId <= 0 || self.username.length < Config.users.usernameMin) { return false; } diff --git a/core/view_controller.js b/core/view_controller.js index bc60b85e..749ec37b 100644 --- a/core/view_controller.js +++ b/core/view_controller.js @@ -196,9 +196,9 @@ function ViewController(options) { ['styleSGR1', 'styleSGR2'].forEach(function styleSgr(style) { setViewProp(style, function(v) { if(_.isObject(v)) { - view.styleSGR1 = ansi.getSGRFromGraphicRendition(v, true); + view[style] = ansi.getSGRFromGraphicRendition(v, true); } else if(_.isString(v)) { - view.styleSGR1 = v; + view[style] = ansi.fromPipeCode(v); } }); }); @@ -213,7 +213,7 @@ function ViewController(options) { setViewProp('password', function(v) { if(true === v) { - view.textMaskChar = self.client.currentThemeInfo.getPasswordChar(); + view.textMaskChar = self.client.currentTheme.helpers.getPasswordChar(); } }); diff --git a/mods/art/themes/NU-MAYA/theme.json b/mods/art/themes/NU-MAYA/theme.json new file mode 100644 index 00000000..242be889 --- /dev/null +++ b/mods/art/themes/NU-MAYA/theme.json @@ -0,0 +1,18 @@ +{ + "info" : { + "name" : "Nu Mayan", + "author" : "NuSkooler" + }, + "defaults" : { + "general" : { + "passwordChar" : "φ" + } + }, + "menus" : { + "matrix" : { + "VM1" : { + "itemSpacing" : 0 + } + } + } +} \ No newline at end of file diff --git a/mods/art/themes/NU-MAYA/theme_info.json b/mods/art/themes/NU-MAYA/theme_info.json deleted file mode 100644 index 0760612a..00000000 --- a/mods/art/themes/NU-MAYA/theme_info.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name" : "Nu Mayan", - "author" : "NuSkooler", - "config" : { - "passwordChar" : "φ" - } -} \ No newline at end of file diff --git a/mods/login.js b/mods/login.js index 90cb25bc..bffa67b8 100644 --- a/mods/login.js +++ b/mods/login.js @@ -24,7 +24,7 @@ function login(callingMenu, formData, extraArgs) { [ function loadThemeConfig(callback) { theme.getThemeInfo(client.user.properties.theme_id, function themeInfo(err, info) { - client.currentThemeInfo = info; + client.currentTheme = info; callback(null); }); } diff --git a/mods/menu.json b/mods/menu.json index e71031c7..5e1c3e62 100644 --- a/mods/menu.json +++ b/mods/menu.json @@ -320,7 +320,7 @@ }, "TM3" : { "items" : [ "Yarly", "Nowaii" ], - "styleSGR1" : { "fg" : 30, "intensity" : 1 }, + "styleSGR1" : "|00|30|01", "hotkeys" : { "Y" : 0, "N" : 1 } }, "BT8" : {