From dfe1c297b5ea8ddace2aecc1f2b659ef34ecedec Mon Sep 17 00:00:00 2001 From: Bryan Ashby Date: Sun, 5 Aug 2018 14:06:30 -0600 Subject: [PATCH] Menu "options" block is now deprecated. Move members to "config"! * Deprecate & allow conversion behind the scenes for now + add warning in log * Add some initial docs * Clean up prompt.hjson and menu.hjson --- config/menu.hjson | 78 +++++++++++++------------------- config/prompt.hjson | 2 +- core/menu_module.js | 20 ++++---- core/menu_stack.js | 21 +++++++-- core/menu_util.js | 8 ++-- core/show_art.js | 2 +- core/theme.js | 2 +- docs/configuration/menu-hjson.md | 45 +++++++++++------- 8 files changed, 95 insertions(+), 83 deletions(-) diff --git a/config/menu.hjson b/config/menu.hjson index 39149416..3d651412 100644 --- a/config/menu.hjson +++ b/config/menu.hjson @@ -32,7 +32,7 @@ telnetConnected: { art: CONNECT next: matrix - options: { nextTimeout: 1500 } + config: { nextTimeout: 1500 } } // @@ -42,7 +42,7 @@ sshConnected: { art: CONNECT next: fullLoginSequenceLoginArt - options: { nextTimeout: 1500 } + config: { nextTimeout: 1500 } } // @@ -53,7 +53,7 @@ sshConnectedNewUser: { art: CONNECT next: newUserApplicationPreSsh - options: { nextTimeout: 1500 } + config: { nextTimeout: 1500 } } // Ye ol' standard matrix @@ -158,7 +158,7 @@ loginAttemptTooNode: { art: TOONODE - options: { + config: { cls: true nextTimeout: 2000 } @@ -179,7 +179,7 @@ forgotPasswordSubmitted: { desc: Forgot password art: FORGOTPWSENT - options: { + config: { cls: true pause: true } @@ -206,7 +206,7 @@ art: PRELOGAD desc: Logging Off next: fullLogoffSequenceRandomBoardAd - options: { + config: { cls: true nextTimeout: 1500 } @@ -216,7 +216,7 @@ art: OTHRBBS desc: Logging Off next: logoff - options: { + config: { baudRate: 57600 pause: true cls: true @@ -234,7 +234,7 @@ art: NEWUSER1 next: newUserApplication desc: Applying - options: { + config: { pause: true cls: true menuFlags: [ "noHistory" ] @@ -349,7 +349,7 @@ art: NEWUSER1 next: newUserApplicationSsh desc: Applying - options: { + config: { pause: true cls: true menuFlags: [ "noHistory" ] @@ -456,7 +456,7 @@ newUserFeedbackToSysOpPreamble: { art: LETTER - options: { pause: true } + config: { pause: true } next: newUserFeedbackToSysOp } @@ -583,14 +583,14 @@ newUserInactiveDone: { desc: Finished with NUA art: DONE - options: { pause: true } + config: { pause: true } next: @menu:logoff } fullLoginSequenceLoginArt: { desc: Logging In art: WELCOME - options: { pause: true } + config: { pause: true } next: fullLoginSequenceLastCallers } @@ -598,7 +598,7 @@ desc: Last Callers module: last_callers art: LASTCALL - options: { + config: { pause: true font: cp437 } @@ -608,7 +608,7 @@ desc: Who's Online module: whos_online art: WHOSON - options: { pause: true } + config: { pause: true } next: fullLoginSequenceOnelinerz } @@ -626,10 +626,8 @@ next: fullLoginSequenceUserStats } ] - options: { - cls: true - } config: { + cls: true art: { view: ONELINER add: ONEADD @@ -737,13 +735,13 @@ fullLoginSequenceSysStats: { desc: System Stats art: SYSSTAT - options: { pause: true } + config: { pause: true } next: fullLoginSequenceUserStats } fullLoginSequenceUserStats: { desc: User Stats art: STATUS - options: { pause: true } + config: { pause: true } next: mainMenu } @@ -937,7 +935,7 @@ art: MMENU desc: Main Menu prompt: menuCommand - options: { + config: { font: cp437 } submit: [ @@ -1016,26 +1014,26 @@ desc: Last Callers module: last_callers art: LASTCALL - options: { pause: true } + config: { pause: true } } mainMenuWhosOnline: { desc: Who's Online module: whos_online art: WHOSON - options: { pause: true } + config: { pause: true } } mainMenuUserStats: { desc: User Stats art: STATUS - options: { pause: true } + config: { pause: true } } mainMenuSystemStats: { desc: System Stats art: SYSSTAT - options: { pause: true } + config: { pause: true } } mainMenuUserList: { @@ -1282,10 +1280,8 @@ mainMenuOnelinerz: { desc: Viewing Onelinerz module: onelinerz - options: { - cls: true - } config: { + cls: true art: { view: ONELINER add: ONEADD @@ -1368,10 +1364,8 @@ mainMenuRumorz: { desc: Rumorz module: rumorz - options: { - cls: true - } config: { + cls: true art: { entries: RUMORS add: RUMORADD @@ -1454,10 +1448,8 @@ bbsList: { desc: Viewing BBS List module: bbs_list - options: { - cls: true - } config: { + cls: true art: { entries: BBSLIST add: BBSADD @@ -1831,7 +1823,7 @@ messageSearchNoResults: { desc: Message Search art: MSRCNORES - options: { + config: { pause: true } } @@ -1912,8 +1904,6 @@ config: { method: messageConf key: confTag - } - options: { pause: true cls: true menuFlags: [ "popParent", "noHistory" ] @@ -1956,8 +1946,6 @@ config: { method: messageArea key: areaTag - } - options: { pause: true cls: true menuFlags: [ "popParent", "noHistory" ] @@ -2732,10 +2720,8 @@ fileBaseExportList: { module: file_base_user_list_export art: FBLISTEXP - options: { - pause: true - } config: { + pause: true templates: { entry: file_list_entry.asc } @@ -2753,7 +2739,7 @@ fileBaseExportListNoResults: { desc: Browsing Files art: FBNORES - options: { + config: { pause: true menuFlags: [ "noHistory", "popParent" ] } @@ -2975,7 +2961,7 @@ fileBaseGetRatingForSelectedEntry: { desc: Rating a File prompt: fileBaseRateEntryPrompt - options: { + config: { cls: true } submit: [ @@ -2991,7 +2977,7 @@ fileBaseListEntriesNoResults: { desc: Browsing Files art: FBNORES - options: { + config: { pause: true menuFlags: [ "noHistory", "popParent" ] } @@ -3282,7 +3268,7 @@ fileBaseDownloadManagerEmptyQueue: { desc: Empty Download Queue art: FEMPTYQ - options: { + config: { pause: true menuFlags: [ "noHistory", "popParent" ] } @@ -3446,7 +3432,7 @@ fileBaseNoUploadAreasAvail: { desc: File Base art: ULNOAREA - options: { + config: { pause: true menuFlags: [ "noHistory", "popParent" ] } diff --git a/config/prompt.hjson b/config/prompt.hjson index b165fbd5..e5a50630 100644 --- a/config/prompt.hjson +++ b/config/prompt.hjson @@ -233,7 +233,7 @@ // Any menu 'pause' will use this prompt // art: pause - options: { + config: { trailingLF: no } /* diff --git a/core/menu_module.js b/core/menu_module.js index 992c17fb..ee1502cb 100644 --- a/core/menu_module.js +++ b/core/menu_module.js @@ -25,11 +25,13 @@ exports.MenuModule = class MenuModule extends PluginModule { this.menuName = options.menuName; this.menuConfig = options.menuConfig; this.client = options.client; - this.menuConfig.options = options.menuConfig.options || {}; + //this.menuConfig.options = options.menuConfig.options || {}; this.menuMethods = {}; // methods called from @method's this.menuConfig.config = this.menuConfig.config || {}; - this.cls = _.isBoolean(this.menuConfig.options.cls) ? this.menuConfig.options.cls : Config().menus.cls; + this.cls = _.get(this.menuConfig.config, 'cls', Config().menus.cls); + + //this.cls = _.isBoolean(this.menuConfig.options.cls) ? this.menuConfig.options.cls : Config().menus.cls; this.viewControllers = {}; } @@ -59,7 +61,7 @@ exports.MenuModule = class MenuModule extends PluginModule { self.displayAsset( self.menuConfig.art, - self.menuConfig.options, + self.menuConfig.config, (err, artData) => { if(err) { self.client.log.trace('Could not display art', { art : self.menuConfig.art, reason : err.message } ); @@ -89,7 +91,7 @@ exports.MenuModule = class MenuModule extends PluginModule { self.displayAsset( self.menuConfig.promptConfig.art, - self.menuConfig.options, + self.menuConfig.config, (err, artData) => { if(artData) { mciData.prompt = artData.mciMap; @@ -137,9 +139,9 @@ exports.MenuModule = class MenuModule extends PluginModule { } beforeArt(cb) { - if(_.isNumber(this.menuConfig.options.baudRate)) { + if(_.isNumber(this.menuConfig.config.baudRate)) { // :TODO: some terminals not supporting cterm style emulated baud rate end up displaying a broken ESC sequence or a single "r" here - this.client.term.rawWrite(ansi.setEmulatedBaudRate(this.menuConfig.options.baudRate)); + this.client.term.rawWrite(ansi.setEmulatedBaudRate(this.menuConfig.config.baudRate)); } if(this.cls) { @@ -220,11 +222,11 @@ exports.MenuModule = class MenuModule extends PluginModule { } shouldPause() { - return ('end' === this.menuConfig.options.pause || true === this.menuConfig.options.pause); + return ('end' === this.menuConfig.config.pause || true === this.menuConfig.config.pause); } hasNextTimeout() { - return _.isNumber(this.menuConfig.options.nextTimeout); + return _.isNumber(this.menuConfig.config.nextTimeout); } haveNext() { @@ -246,7 +248,7 @@ exports.MenuModule = class MenuModule extends PluginModule { if(this.hasNextTimeout()) { setTimeout( () => { return gotoNextMenu(); - }, this.menuConfig.options.nextTimeout); + }, this.menuConfig.config.nextTimeout); } else { return gotoNextMenu(); } diff --git a/core/menu_stack.js b/core/menu_stack.js index 06b53d76..3e9c455b 100644 --- a/core/menu_stack.js +++ b/core/menu_stack.js @@ -134,15 +134,28 @@ module.exports = class MenuStack { return; } + // + // Handle deprecated 'options' block by merging to config and warning user. + // :TODO: Remove in 0.0.10+ + // + if(modInst.menuConfig.options) { + self.client.log.warn( + { options : modInst.menuConfig.options }, + 'Use of "options" is deprecated. Move relevant members to "config" block! Support will be fully removed in future versions' + ); + Object.assign(modInst.menuConfig.config || {}, modInst.menuConfig.options); + delete modInst.menuConfig.options; + } + // // If menuFlags were supplied in menu.hjson, they should win over // anything supplied in code. // let menuFlags; - if(0 === modInst.menuConfig.options.menuFlags.length) { + if(0 === modInst.menuConfig.config.menuFlags.length) { menuFlags = Array.isArray(options.menuFlags) ? options.menuFlags : []; } else { - menuFlags = modInst.menuConfig.options.menuFlags; + menuFlags = modInst.menuConfig.config.menuFlags; // in code we can ask to merge in if(Array.isArray(options.menuFlags) && options.menuFlags.includes('mergeFlags')) { @@ -179,8 +192,8 @@ module.exports = class MenuStack { const stackEntries = self.stack.map(stackEntry => { let name = stackEntry.name; - if(stackEntry.instance.menuConfig.options.menuFlags.length > 0) { - name += ` (${stackEntry.instance.menuConfig.options.menuFlags.join(', ')})`; + if(stackEntry.instance.menuConfig.config.menuFlags.length > 0) { + name += ` (${stackEntry.instance.menuConfig.config.menuFlags.join(', ')})`; } return name; }); diff --git a/core/menu_util.js b/core/menu_util.js index 7eca129d..c05f90d9 100644 --- a/core/menu_util.js +++ b/core/menu_util.js @@ -61,10 +61,10 @@ function loadMenu(options, cb) { }, function loadMenuModule(menuConfig, callback) { - menuConfig.options = menuConfig.options || {}; - menuConfig.options.menuFlags = menuConfig.options.menuFlags || []; - if(!Array.isArray(menuConfig.options.menuFlags)) { - menuConfig.options.menuFlags = [ menuConfig.options.menuFlags ]; + menuConfig.config = menuConfig.config || {}; + menuConfig.config.menuFlags = menuConfig.config.menuFlags || []; + if(!Array.isArray(menuConfig.config.menuFlags)) { + menuConfig.config.menuFlags = [ menuConfig.config.menuFlags ]; } const modAsset = asset.getModuleAsset(menuConfig.module); diff --git a/core/show_art.js b/core/show_art.js index bcd15d7b..30b6e56e 100644 --- a/core/show_art.js +++ b/core/show_art.js @@ -156,7 +156,7 @@ exports.getModule = class ShowArtModule extends MenuModule { // :TODO: we really need a way to supply an explicit path to look in, e.g. general/area_art/ self.displayAsset( artSpec, - self.menuConfig.options, + self.menuConfig.config, (err, artData) => { if(err) { return callback(err); diff --git a/core/theme.js b/core/theme.js index c7a2b06d..bdba70bc 100644 --- a/core/theme.js +++ b/core/theme.js @@ -571,7 +571,7 @@ function displayThemedPrompt(name, client, options, cb) { // doing so messes things up -- most terminals that support font // changing can only display a single font at at time. // - const dispOptions = Object.assign( {}, options, promptConfig.options ); + const dispOptions = Object.assign( {}, options, promptConfig.config ); // :TODO: We can use term detection to do nifty things like avoid this kind of kludge: if(!options.clearScreen) { dispOptions.font = 'not_really_a_font!'; // kludge :) diff --git a/docs/configuration/menu-hjson.md b/docs/configuration/menu-hjson.md index 58a06d5a..7d1bbed4 100644 --- a/docs/configuration/menu-hjson.md +++ b/docs/configuration/menu-hjson.md @@ -2,12 +2,11 @@ layout: page title: menu.hjson --- -:warning: ***IMPORTANT!*** Before making any customisations, create your own copy of `/config/menu.hjson`, and specify it in the -`general` section of `config.hjson`: +:warning: ***IMPORTANT!*** Before making any customisations, create your own copy of `/config/menu.hjson`, and specify it in the `general` section of `config.hjson`: ````hjson general: { - menuFile: my-menu.hjson + menuFile: yourboardname.hjson } ```` This document and others will refer to `menu.hjson`. This should be seen as an alias to `yourboardname.hjson` @@ -15,16 +14,33 @@ This document and others will refer to `menu.hjson`. This should be seen as an a ## The Basics Like all configuration within ENiGMA½, menu configuration is done in [HJSON](https://hjson.org/) format. -Entries in `menu.hjson` are objects defining a menu. A menu in this sense is something the user can see -or visit. Examples include but are not limited to: +Entries in `menu.hjson` are objects or _sections_ defining a menu. A menu in this sense is something the user can see or visit. Examples include but are not limited to: * Classical Main, Messages, and File menus * Art file display -* Module driven menus such as door launchers +* Module driven menus such as door launchers and other custom mods +Menu entries live under the `menus` section of `menu.hjson`. The *key* for a menu is it's name that can be referenced by other menus and areas of the system. -Each entry in `menu.hjson` defines an object that represents a menu. These objects live within the `menus` -parent object. Each object's *key* is a menu name you can reference within other menus in the system. +## Common Menu Entry Members +* `desc`: A friendly description that can be found in places such as "Who's Online" or the `%MD` MCI code. +* `art`: An art file specification. +* `next`: Specifies the next menu to go to next. Can be explicit or an array of possibilites dependent on ACS. See **Flow Control** in the **ACS Checks** section below. +* `prompt`: Specifies a prompt, by name, to use along with this menu. +* `form`: Defines one or more forms available on this menu. +* `submit`: Defines a submit handler when using `prompt`. +* `config`: May contain any of the following standard configuration members in addition to per-module defined types (see appropriate module for more information): + * `cls`: If `true` the screen will be cleared before showing this menu. + * `pause`: If `true` a pause will occur after showing this menu. Useful for simple menus such as displaying art or status screens. + * `nextTimeout`: Sets the number of **milliseconds** before the system will automatically advanced to the `next` menu. + * `baudRate`: Sets the SyncTERM style emulated baud rate. May be `300`, `600`, `1200`, `2400`, `4800`, `9600`, `19200`, `38400`, `57600`, `76800`, or `115200`. A value of `ulimited`, `off`, or `0` resets (disables) the rate. See [this specification](https://github.com/protomouse/synchronet/blob/master/src/conio/cterm.txt) for more information. + * `font`: Sets the SyncTERM style font. May be one of the following: `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`. See [this specification](https://github.com/protomouse/synchronet/blob/master/src/conio/cterm.txt) for more information. + +## Forms +TODO + +## Submit Handlers +TODO ## Example Let's look a couple basic menu entries: @@ -37,18 +53,13 @@ telnetConnected: { } ``` -The above entry `telnetConnected` is set as the Telnet server's first menu entry (set by `firstMenu` in -the Telnet server's config). +The above entry `telnetConnected` is set as the Telnet server's first menu entry (set by `firstMenu` in the Telnet server's config). -An art pattern of `CONNECT` is set telling the system to look for `CONNECT.*` where `` represents -a optional integer in art files to cause randomness, e.g. `CONNECT1.ANS`, `CONNECT2.ANS`, and so on. If -desired, you can also be explicit by supplying a full filename with an extention such as `CONNECT.ANS`. +An art pattern of `CONNECT` is set telling the system to look for `CONNECT.*` where `` represents a optional integer in art files to cause randomness, e.g. `CONNECT1.ANS`, `CONNECT2.ANS`, and so on. If desired, you can also be explicit by supplying a full filename with an extention such as `CONNECT.ANS`. -The entry `next` sets up the next menu, by name, in the stack (`matrix`) that we'll go to after -`telnetConnected`. +The entry `next` sets up the next menu, by name, in the stack (`matrix`) that we'll go to after `telnetConnected`. -Finally, an `options` object may contain various common options for menus. In this case, `nextTimeout` -tells the system to proceed to the `next` entry automatically after 1500ms. +Finally, an `options` object may contain various common options for menus. In this case, `nextTimeout` tells the system to proceed to the `next` entry automatically after 1500ms. Now let's look at `matrix`, the `next` entry from `telnetConnected`: