From 99bae06198bfaf655ee30bea319cdd191f7d9466 Mon Sep 17 00:00:00 2001 From: Bryan Ashby Date: Sun, 22 Nov 2020 19:46:51 -0700 Subject: [PATCH 01/13] Fix title --- docs/modding/show-art.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/modding/show-art.md b/docs/modding/show-art.md index 5ffce10c..69be395d 100644 --- a/docs/modding/show-art.md +++ b/docs/modding/show-art.md @@ -1,6 +1,6 @@ --- layout: page -title: User List +title: The Show Art Module --- ## The Show Art Module The built in `show_art` module add some advanced ways in which you can configure your system to display art assets beyond what a standard menu entry can provide. For example, based on user selection of a file or message base area. From 6ff8b36836e5337d69690f4adf359f422e2da091 Mon Sep 17 00:00:00 2001 From: Bryan Ashby Date: Sun, 22 Nov 2020 20:59:45 -0700 Subject: [PATCH 02/13] Fix modTimestampFormat --- core/fse.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/core/fse.js b/core/fse.js index 5e018df7..690b9cf8 100644 --- a/core/fse.js +++ b/core/fse.js @@ -853,7 +853,11 @@ exports.FullScreenEditorModule = exports.getModule = class FullScreenEditorModul this.setHeaderText(MciViewIds.header.from, this.message.fromUserName); this.setHeaderText(MciViewIds.header.to, this.message.toUserName); this.setHeaderText(MciViewIds.header.subject, this.message.subject); - this.setHeaderText(MciViewIds.header.modTimestamp, moment(this.message.modTimestamp).format(this.client.currentTheme.helpers.getDateTimeFormat())); + + this.setHeaderText(MciViewIds.header.modTimestamp, moment(this.message.modTimestamp).format( + this.menuConfig.config.modTimestampFormat || this.client.currentTheme.helpers.getDateTimeFormat()) + ); + this.setHeaderText(MciViewIds.header.msgNum, (this.messageIndex + 1).toString()); this.setHeaderText(MciViewIds.header.msgTotal, this.messageTotal.toString()); From 3ea0a14935ba97328bffa2e54510995c131492ed Mon Sep 17 00:00:00 2001 From: Bryan Ashby Date: Sun, 22 Nov 2020 21:05:36 -0700 Subject: [PATCH 03/13] Minor doc fix --- docs/art/mci.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/art/mci.md b/docs/art/mci.md index 3fed8248..9c25bfad 100644 --- a/docs/art/mci.md +++ b/docs/art/mci.md @@ -107,7 +107,7 @@ Some additional special case codes also exist: the time so also check out [core/predefined_mci.js](https://github.com/NuSkooler/enigma-bbs/blob/master/core/mci_view_factory.js) for a full listing. -:note: Many codes attempt to pay homage to Oblivion/2, iNiQUiTY, etc. +:memo: Many codes attempt to pay homage to Oblivion/2, iNiQUiTY, etc. ## Views From 627165bb648d18d1c26bb16068d4f07b05f95ebd Mon Sep 17 00:00:00 2001 From: Bryan Ashby Date: Sun, 22 Nov 2020 21:27:23 -0700 Subject: [PATCH 04/13] More info in Views --- docs/art/mci.md | 49 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 35 insertions(+), 14 deletions(-) diff --git a/docs/art/mci.md b/docs/art/mci.md index 9c25bfad..174643a4 100644 --- a/docs/art/mci.md +++ b/docs/art/mci.md @@ -114,25 +114,46 @@ for a full listing. A **View** is a control placed on a **form** that can display variable data or collect input. One example of a View is a Vertical Menu (`%VM`): Old-school BBSers may recognize this as a lightbar menu. -| Code | Name | Description | -|------|----------------------|------------------| -| `TL` | Text Label | Displays text | -| `ET` | Edit Text | Collect user input | -| `ME` | Masked Edit Text | Collect user input using a *mask* | -| `MT` | Multi Line Text Edit | Multi line edit control | -| `BT` | Button | A button | -| `VM` | Vertical Menu | A vertical menu aka a vertical lightbar | -| `HM` | Horizontal Menu | A horizontal menu aka a horizontal lightbar | -| `SM` | Spinner Menu | A spinner input control | -| `TM` | Toggle Menu | A toggle menu commonly used for Yes/No style input | -| `KE` | Key Entry | A *single* key input control | +| Code | Name | Description | Notes | +|------|----------------------|------------------|-------| +| `TL` | Text Label | Displays text | Static content | +| `ET` | Edit Text | Collect user input | Single line entry | +| `ME` | Masked Edit Text | Collect user input using a *mask* | See **Mask Edits** below | +| `MT` | Multi Line Text Edit | Multi line edit control | Used for FSE, display of FILE_ID.DIZ, etc. | +| `BT` | Button | A button | ...it's a button | +| `VM` | Vertical Menu | A vertical menu | AKA a vertical lightbar; Useful for lists | +| `HM` | Horizontal Menu | A horizontal menu | AKA a horizontal lightbar | +| `SM` | Spinner Menu | A spinner input control | Select *one* from multiple options | +| `TM` | Toggle Menu | A toggle menu | Commonly used for Yes/No style input | +| `KE` | Key Entry | A *single* key input control | Think hotkeys | -:information_source: Peek at [/core/mci_view_factory.js](https://github.com/NuSkooler/enigma-bbs/blob/master/core/mci_view_factory.js) to -see additional information. +:information_source: Peek at [/core/mci_view_factory.js](https://github.com/NuSkooler/enigma-bbs/blob/master/core/mci_view_factory.js) to see additional information. + +### Mask Edits +Mask Edits (`%ME`) use the special `maskPattern` property to control a _mask_. This can be useful for gathering dates, phone numbers, so on. + +`maskPattern`'s can be composed of the following characters: +* `#`: Numeric 0-9 +* `A`: Alpha a-z, A-Z +* `@`: Alphanumeric (combination of the previous patterns) +* `&`: Any "printable" character + +Any other characters are literals. + +An example of a mask for a date may look like this: `##/##/####`. + +Additionally, the following theme stylers can be applied: +* `styleSGR1`: Controls literal character colors for non-focused controls +* `styleSGR2`: Controls literal character colors for focused controls +* `styleSGR3`: Controls fill colors (characters that have not yet received input). + +All of the style properties can take pipe codes such as `|00|08`. ### View Identifiers As mentioned above, MCI codes can (and often should) be explicitly tied to a *View Identifier*. Simply speaking this is a number representing the particular view. These can be useful to reference in code, apply themes, etc. +A view ID is tied to a MCI code by specifying it after the code. For example: `%VM1` or `%SM10`. + ## Properties & Theming Predefined MCI codes and other Views can have properties set via `menu.hjson` and further *themed* via `theme.hjson`. See [Themes](themes.md) for more information on this subject. From 2d9d8782f6ac8cacd4fc2f314d9a646c13e6b987 Mon Sep 17 00:00:00 2001 From: Bryan Ashby Date: Mon, 23 Nov 2020 17:24:40 -0700 Subject: [PATCH 05/13] Move to @breejs/later - maintained later.js --- core/bbs.js | 2 +- core/event_scheduler.js | 2 +- core/scanner_tossers/ftn_bso.js | 2 +- package.json | 2 +- yarn.lock | 10 +++++----- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/core/bbs.js b/core/bbs.js index e3d08ed4..29d4f219 100644 --- a/core/bbs.js +++ b/core/bbs.js @@ -209,7 +209,7 @@ function initialize(cb) { process.on('SIGINT', shutdownSystem); - require('later').date.localTime(); // use local times for later.js/scheduling + require('@breejs/later').date.localTime(); // use local times for later.js/scheduling return callback(null); }, diff --git a/core/event_scheduler.js b/core/event_scheduler.js index 4b7da062..4a464cd8 100644 --- a/core/event_scheduler.js +++ b/core/event_scheduler.js @@ -8,7 +8,7 @@ const Log = require('./logger.js').log; const { Errors } = require('./enig_error.js'); const _ = require('lodash'); -const later = require('later'); +const later = require('@breejs/later'); const path = require('path'); const pty = require('node-pty'); const sane = require('sane'); diff --git a/core/scanner_tossers/ftn_bso.js b/core/scanner_tossers/ftn_bso.js index 2bb2df46..068ff111 100644 --- a/core/scanner_tossers/ftn_bso.js +++ b/core/scanner_tossers/ftn_bso.js @@ -30,7 +30,7 @@ const _ = require('lodash'); const paths = require('path'); const async = require('async'); const fs = require('graceful-fs'); -const later = require('later'); +const later = require('@breejs/later'); const temptmp = require('temptmp').createTrackedSession('ftn_bso'); const assert = require('assert'); const sane = require('sane'); diff --git a/package.json b/package.json index 52fe8641..5f7b0b34 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ "iconv-lite": "^0.6.2", "ini-config-parser": "^1.0.4", "inquirer": "7.3.3", - "later": "1.2.0", + "@breejs/later" : "^4.0.2", "lodash": "4.17.20", "lru-cache": "^5.1.1", "mime-types": "2.1.27", diff --git a/yarn.lock b/yarn.lock index 60f67a5b..ba4ae5b7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -23,6 +23,11 @@ chalk "^2.0.0" js-tokens "^4.0.0" +"@breejs/later@^4.0.2": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@breejs/later/-/later-4.0.2.tgz#38c85cc98b717c7a196f87238090adaea01f8c9e" + integrity sha512-EN0SlbyYouBdtZis1htdsgGlwFePzkXPwdIeqaBaavxkJT1G2/bitc2LSixjv45z2njXslxlJI1mW2O/Gmrb+A== + "@cnakazawa/watch@^1.0.3": version "1.0.3" resolved "https://registry.yarnpkg.com/@cnakazawa/watch/-/watch-1.0.3.tgz#099139eaec7ebf07a27c1786a3ff64f39464d2ef" @@ -1392,11 +1397,6 @@ kind-of@^6.0.0, kind-of@^6.0.2: resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" integrity sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA== -later@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/later/-/later-1.2.0.tgz#f2cf6c4dd7956dd2f520adf0329836e9876bad0f" - integrity sha1-8s9sTdeVbdL1IK3wMpg26YdrrQ8= - levn@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" From 75601a80ec4256bfde6e9ea7eb67f345454d9af8 Mon Sep 17 00:00:00 2001 From: Bryan Ashby Date: Mon, 23 Nov 2020 19:41:08 -0700 Subject: [PATCH 06/13] WIP --- core/fse.js | 90 ++++++++++++++++++++++++++++++++++++++- core/msg_area_view_fse.js | 3 +- 2 files changed, 90 insertions(+), 3 deletions(-) diff --git a/core/fse.js b/core/fse.js index 690b9cf8..15388e1f 100644 --- a/core/fse.js +++ b/core/fse.js @@ -26,12 +26,19 @@ const { getAddressedToInfo } = require('./mail_util.js'); const Events = require('./events.js'); const UserProps = require('./user_property.js'); const SysProps = require('./system_property.js'); +const FileArea = require('./file_base_area.js'); +const FileEntry = require('./file_entry.js'); +const DownloadQueue = require('./download_queue.js'); // deps const async = require('async'); const assert = require('assert'); const _ = require('lodash'); const moment = require('moment'); +const fse = require('fs-extra'); +const fs = require('graceful-fs'); +const paths = require('path'); +const sanatizeFilename = require('sanitize-filename'); exports.moduleInfo = { name : 'Full Screen Editor (FSE)', @@ -255,7 +262,12 @@ exports.FullScreenEditorModule = exports.getModule = class FullScreenEditorModul viewModeMenuHelp : function(formData, extraArgs, cb) { self.viewControllers.footerView.setFocus(false); return self.displayHelp(cb); - } + }, + + addToDownloadQueue : (formData, extraArgs, cb) => { + this.viewControllers.footerView.setFocus(false); + return this.addToDownloadQueue(cb); + }, }; } @@ -905,6 +917,82 @@ exports.FullScreenEditorModule = exports.getModule = class FullScreenEditorModul ); } + addToDownloadQueue(cb) { + this.client.term.rawWrite(ansi.resetScreen()); + + const sysTempDownloadArea = FileArea.getFileAreaByTag(FileArea.WellKnownAreaTags.TempDownloads); + const sysTempDownloadDir = FileArea.getAreaDefaultStorageDirectory(sysTempDownloadArea); + + const msgInfo = this.getHeaderFormatObj(); + + const outputFileName = paths.join( + sysTempDownloadDir, + sanatizeFilename( + `(${msgInfo.messageId}) ${msgInfo.subject}_(${this.message.modTimestamp.format('YYYY-MM-DD')}).txt`) + ); + + async.waterfall( + [ + (callback) => { + const messageBody = this.viewControllers.body + .getView(MciViewIds.body.message) + .getData( { forceLineTerms : true } ); + + fse.mkdirs(sysTempDownloadDir, err => { + return callback(err, messageBody); + }); + }, + (messageBody, callback) => { + return fs.writeFile(outputFileName, messageBody, 'utf8', callback); + }, + (callback) => { + fs.stat(outputFileName, (err, stats) => { + return callback(err, stats.size); + }); + }, + (fileSize, callback) => { + const newEntry = new FileEntry({ + areaTag : sysTempDownloadArea.areaTag, + fileName : paths.basename(outputFileName), + storageTag : sysTempDownloadArea.storageTags[0], + meta : { + upload_by_username : this.client.user.username, + upload_by_user_id : this.client.user.userId, + byte_size : fileSize, + session_temp_dl : 1, // download is valid until session is over + } + }); + + newEntry.desc = `${msgInfo.messageId} - ${msgInfo.subject}`; + + newEntry.persist(err => { + if(!err) { + // queue it! + DownloadQueue.get(this.client).addTemporaryDownload(newEntry); + } + return callback(err); + }); + }, + (callback) => { + theme.displayThemeArt( + { name : this.menuConfig.config.art.dlQueueAdd || 'msg_add_dl_queue', client : this.client }, + () => { + this.client.waitForKeyPress( () => { + this.redrawScreen( () => { + this.viewControllers[this.getFooterName()].setFocus(true); + return callback(null); + }); + }); + } + ); + } + ], + err => { + return cb(err); + } + ); + } + displayQuoteBuilder() { // // Clear body area diff --git a/core/msg_area_view_fse.js b/core/msg_area_view_fse.js index 1ca5617c..ed057438 100644 --- a/core/msg_area_view_fse.js +++ b/core/msg_area_view_fse.js @@ -102,11 +102,10 @@ exports.getModule = class AreaViewFSEModule extends FullScreenEditorModule { self.client.log(extraArgs, 'Missing extraArgs.menu'); return cb(null); - } + }, }); } - loadMessageByUuid(uuid, cb) { const msg = new Message(); msg.load( { uuid : uuid, user : this.client.user }, () => { From 1e2b6ae934f93d34312d1d2d374b2ea274e63e37 Mon Sep 17 00:00:00 2001 From: Bryan Ashby Date: Tue, 24 Nov 2020 13:05:17 -0700 Subject: [PATCH 07/13] Working --- core/fse.js | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/core/fse.js b/core/fse.js index 15388e1f..1a08f133 100644 --- a/core/fse.js +++ b/core/fse.js @@ -21,6 +21,7 @@ const { isAnsi, stripAnsiControlCodes, insert } = require('./string_util.js'); +const { stripMciColorCodes } = require('./color_codes.js'); const Config = require('./config.js').get; const { getAddressedToInfo } = require('./mail_util.js'); const Events = require('./events.js'); @@ -918,8 +919,6 @@ exports.FullScreenEditorModule = exports.getModule = class FullScreenEditorModul } addToDownloadQueue(cb) { - this.client.term.rawWrite(ansi.resetScreen()); - const sysTempDownloadArea = FileArea.getFileAreaByTag(FileArea.WellKnownAreaTags.TempDownloads); const sysTempDownloadDir = FileArea.getAreaDefaultStorageDirectory(sysTempDownloadArea); @@ -934,16 +933,31 @@ exports.FullScreenEditorModule = exports.getModule = class FullScreenEditorModul async.waterfall( [ (callback) => { - const messageBody = this.viewControllers.body + const header = + `+${'-'.repeat(79)} +| To : ${msgInfo.toUserName} +| From : ${msgInfo.fromUserName} +| When : ${moment(this.message.modTimestamp).format('dddd, MMMM Do YYYY, h:mm:ss a (UTCZ)')} +| Subject : ${msgInfo.subject} +| ID : ${this.message.messageUuid} (${msgInfo.messageId}) ++${'-'.repeat(79)} +`; + const body = this.viewControllers.body .getView(MciViewIds.body.message) .getData( { forceLineTerms : true } ); + const cleanBody = stripMciColorCodes( + stripAnsiControlCodes(body, { all : true } ) + ); + + const exportedMessage = `${header}\r\n${cleanBody}`; + fse.mkdirs(sysTempDownloadDir, err => { - return callback(err, messageBody); + return callback(err, exportedMessage); }); }, - (messageBody, callback) => { - return fs.writeFile(outputFileName, messageBody, 'utf8', callback); + (exportedMessage, callback) => { + return fs.writeFile(outputFileName, exportedMessage, 'utf8', callback); }, (callback) => { fs.stat(outputFileName, (err, stats) => { @@ -974,8 +988,11 @@ exports.FullScreenEditorModule = exports.getModule = class FullScreenEditorModul }); }, (callback) => { - theme.displayThemeArt( - { name : this.menuConfig.config.art.dlQueueAdd || 'msg_add_dl_queue', client : this.client }, + const artSpec = this.menuConfig.config.art.dlQueueAdd || + Buffer.from('Exported message added to download queue'); + this.displayAsset( + artSpec, + { clearScreen : true }, () => { this.client.waitForKeyPress( () => { this.redrawScreen( () => { From c944e97699057b79c9dd881a03d82ff27e30cc40 Mon Sep 17 00:00:00 2001 From: Bryan Ashby Date: Tue, 24 Nov 2020 13:15:22 -0700 Subject: [PATCH 08/13] Add to menu --- .../luciano_blocktronics/mb_export_dl_queue.ans | Bin 0 -> 249 bytes core/fse.js | 4 ++-- misc/menu_templates/message_base.in.hjson | 13 +++++++++---- 3 files changed, 11 insertions(+), 6 deletions(-) create mode 100644 art/themes/luciano_blocktronics/mb_export_dl_queue.ans diff --git a/art/themes/luciano_blocktronics/mb_export_dl_queue.ans b/art/themes/luciano_blocktronics/mb_export_dl_queue.ans new file mode 100644 index 0000000000000000000000000000000000000000..c02f2ec71099c7677417e96449bb7612319dd7d2 GIT binary patch literal 249 zcmb1+Hn27^ur@Z&<>Hc#HncW2$W;IW>1YrQ6|l0h0tr|fo8{)F78fU`rz&J57AqvB zrsgT6RutqHm87O9B<7_k6yzi(1DTn53YGb#ML^xT3Mu*Jc{%xsDGG(9simpX(IE4I y=5a{{JBB*D8W?~qqY^MOFfuSSG%~4XU|?Wm3}9de(m){W>Ex>r=I#jL!ASrFj56;4 literal 0 HcmV?d00001 diff --git a/core/fse.js b/core/fse.js index 1a08f133..ba278a01 100644 --- a/core/fse.js +++ b/core/fse.js @@ -988,8 +988,8 @@ exports.FullScreenEditorModule = exports.getModule = class FullScreenEditorModul }); }, (callback) => { - const artSpec = this.menuConfig.config.art.dlQueueAdd || - Buffer.from('Exported message added to download queue'); + const artSpec = this.menuConfig.config.art.expToDlQueue || + Buffer.from('Exported message has been added to your download queue!'); this.displayAsset( artSpec, { clearScreen : true }, diff --git a/misc/menu_templates/message_base.in.hjson b/misc/menu_templates/message_base.in.hjson index 51bf4a19..c302a57b 100644 --- a/misc/menu_templates/message_base.in.hjson +++ b/misc/menu_templates/message_base.in.hjson @@ -477,10 +477,11 @@ module: msg_area_view_fse config: { art: { - header: MSGVHDR - body: MSGBODY + header: MSGVHDR + body: MSGBODY footerView: MSGVFTR - help: MSGVHLP + help: MSGVHLP + expToDlQueue: mb_export_dl_queue }, editorMode: view editorType: area @@ -525,7 +526,7 @@ mci: { HM1: { // :TODO: (#)Jump/(L)Index (msg list)/Last - items: [ "prev", "next", "reply", "quit", "help" ] + items: [ "prev", "next", "reply", "quit", "download", "help" ] focusItemIndex: 1 } } @@ -552,6 +553,10 @@ } { value: { 1: 4 } + action: @method:addToDownloadQueue + } + { + value: { 1: 5 } action: @method:viewModeMenuHelp } ] From b36845f7a1b8f2ad1f61f30dce011546dc633dbd Mon Sep 17 00:00:00 2001 From: Bryan Ashby Date: Tue, 24 Nov 2020 13:22:52 -0700 Subject: [PATCH 09/13] Hotkey + WHATSNEW entry --- WHATSNEW.md | 1 + misc/menu_templates/message_base.in.hjson | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/WHATSNEW.md b/WHATSNEW.md index 8d80ea2b..65e44df0 100644 --- a/WHATSNEW.md +++ b/WHATSNEW.md @@ -8,6 +8,7 @@ This document attempts to track **major** changes and additions in ENiGMA½. For * An explicit prompt file previously specified by `general.promptFile` in `config.hjson` is no longer necessary. Instead, this now simply part of the `prompts` section in `menu.hjson`. The default setup still creates a separate prompt HJSON file, but it is `includes`ed in `menu.hjson`. With the removal of prompts the `PromptsChanged` event will no longer be fired. * New `PV` ACS check for arbitrary user properties. See [ACS](./docs/configuration/acs.md) for details. * The `message` arg used by `msg_list` has been deprecated. Please starting using `messageIndex` for this purpose. Support for `message` will be removed in the future. +* Added ability to export/download messages. This is enabled in the default menu. See `messageAreaViewPost` in [the default message base template](./misc/menu_templates/message_base.in.hjson) and look for the download options for details on adding to your system! ## 0.0.11-beta * Upgraded from `alpha` to `beta` -- The software is far along and mature enough at this point! diff --git a/misc/menu_templates/message_base.in.hjson b/misc/menu_templates/message_base.in.hjson index c302a57b..04ad4c04 100644 --- a/misc/menu_templates/message_base.in.hjson +++ b/misc/menu_templates/message_base.in.hjson @@ -581,6 +581,10 @@ keys: [ "escape", "q", "shift + q" ] action: @systemMethod:prevMenu } + { + keys: [ "d", "shift + d" ] + action: @method:addToDownloadQueue + } { keys: [ "?" ] action: @method:viewModeMenuHelp From 6fb8836d6ec0840af89b9b7133d121b291d10aa2 Mon Sep 17 00:00:00 2001 From: Bryan Ashby Date: Tue, 24 Nov 2020 13:25:33 -0700 Subject: [PATCH 10/13] A bit more info --- WHATSNEW.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WHATSNEW.md b/WHATSNEW.md index 65e44df0..ec186f08 100644 --- a/WHATSNEW.md +++ b/WHATSNEW.md @@ -8,7 +8,7 @@ This document attempts to track **major** changes and additions in ENiGMA½. For * An explicit prompt file previously specified by `general.promptFile` in `config.hjson` is no longer necessary. Instead, this now simply part of the `prompts` section in `menu.hjson`. The default setup still creates a separate prompt HJSON file, but it is `includes`ed in `menu.hjson`. With the removal of prompts the `PromptsChanged` event will no longer be fired. * New `PV` ACS check for arbitrary user properties. See [ACS](./docs/configuration/acs.md) for details. * The `message` arg used by `msg_list` has been deprecated. Please starting using `messageIndex` for this purpose. Support for `message` will be removed in the future. -* Added ability to export/download messages. This is enabled in the default menu. See `messageAreaViewPost` in [the default message base template](./misc/menu_templates/message_base.in.hjson) and look for the download options for details on adding to your system! +* Added ability to export/download messages. This is enabled in the default menu. See `messageAreaViewPost` in [the default message base template](./misc/menu_templates/message_base.in.hjson) and look for the download options (`@method:addToDownloadQueue`, etc.) for details on adding to your system! ## 0.0.11-beta * Upgraded from `alpha` to `beta` -- The software is far along and mature enough at this point! From cc95ef80ddee03879f0ffe8f26cb0a0ebf451755 Mon Sep 17 00:00:00 2001 From: Bryan Ashby Date: Tue, 24 Nov 2020 13:28:37 -0700 Subject: [PATCH 11/13] tabs -> spaces --- misc/menu_templates/message_base.in.hjson | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/misc/menu_templates/message_base.in.hjson b/misc/menu_templates/message_base.in.hjson index 04ad4c04..367e1903 100644 --- a/misc/menu_templates/message_base.in.hjson +++ b/misc/menu_templates/message_base.in.hjson @@ -582,9 +582,9 @@ action: @systemMethod:prevMenu } { - keys: [ "d", "shift + d" ] - action: @method:addToDownloadQueue - } + keys: [ "d", "shift + d" ] + action: @method:addToDownloadQueue + } { keys: [ "?" ] action: @method:viewModeMenuHelp From a7e4f5baef8d89d84119a0e2899a06a68e207859 Mon Sep 17 00:00:00 2001 From: Bryan Ashby Date: Tue, 24 Nov 2020 19:42:02 -0700 Subject: [PATCH 12/13] Use moment.parseZone() * Currently messages are stored with TZ offsets * Imported messages with e.g. TZUTC kludges are adjusted * Due to the above, use parseZone() to preserve when loading a message timestamp --- core/message.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core/message.js b/core/message.js index 73ebe761..c5ad490b 100644 --- a/core/message.js +++ b/core/message.js @@ -634,7 +634,9 @@ module.exports = class Message { self.fromUserName = msgRow.from_user_name; self.subject = msgRow.subject; self.message = msgRow.message; - self.modTimestamp = moment(msgRow.modified_timestamp); + + // We use parseZone() to *preserve* the time zone information + self.modTimestamp = moment.parseZone(msgRow.modified_timestamp); return callback(err); } From 228cd79989dc6114e3233a645cb952eac548be25 Mon Sep 17 00:00:00 2001 From: Bryan Ashby Date: Wed, 25 Nov 2020 13:03:16 -0700 Subject: [PATCH 13/13] Patch around NR v2.00b20 'ansi-256color' ttype --- core/client_term.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/core/client_term.js b/core/client_term.js index e961394e..4cbd603c 100644 --- a/core/client_term.js +++ b/core/client_term.js @@ -132,6 +132,9 @@ ClientTerminal.prototype.isANSI = function() { // // Reports from various terminals // + // NetRunner v2.00beta 20 + // * This version adds 256 colors and reports as "ansi-256color" + // // syncterm: // * SyncTERM // @@ -150,7 +153,7 @@ ClientTerminal.prototype.isANSI = function() { // linux: // * JuiceSSH (note: TERM=linux also) // - return [ 'ansi', 'pcansi', 'pc-ansi', 'ansi-bbs', 'qansi', 'scoansi', 'syncterm' ].includes(this.termType); + return [ 'ansi', 'pcansi', 'pc-ansi', 'ansi-bbs', 'qansi', 'scoansi', 'syncterm', 'ansi-256color' ].includes(this.termType); }; // :TODO: probably need to update these to convert IAC (0xff) -> IACIAC (escape it)