Merge pull request #407 from cognitivegears/feature/Remove_position_check
#222 - Removing Cursor Position Report
This commit is contained in:
commit
3d1b97cf3b
|
@ -28,5 +28,8 @@
|
|||
],
|
||||
"comma-dangle": 0,
|
||||
"no-trailing-spaces" :"warn"
|
||||
},
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 2020
|
||||
}
|
||||
}
|
27
UPGRADE.md
27
UPGRADE.md
|
@ -28,6 +28,33 @@ npm install # or simply 'yarn'
|
|||
Report your issue on Xibalba BBS, hop in #enigma-bbs on FreeNode and chat, or
|
||||
[file a issue on GitHub](https://github.com/NuSkooler/enigma-bbs/issues).
|
||||
|
||||
|
||||
# 0.0.12-beta to 0.0.13-beta
|
||||
|
||||
* All features and changes are backwards compatible. There are a few new configuration options in a new `term` section in the configuration. These are all optional, but include the following options in case you use them:
|
||||
|
||||
```hjson
|
||||
{
|
||||
|
||||
term: {
|
||||
// checkUtf8Encoding requires the use of cursor position reports, which are not supported on all terminals.
|
||||
// Using this with a terminal that does not support cursor position reports results in a 2 second delay
|
||||
// during the connect process, but provides better autoconfiguration of utf-8
|
||||
checkUtf8Encoding: true
|
||||
|
||||
|
||||
// Checking the ANSI home position also requires the use of cursor position reports, which are not
|
||||
// supported on all terminals. Using this with a terminal that does not support cursor position reports
|
||||
// results in a 3 second delay during the connect process, but works around positioning problems with
|
||||
// non-standard terminals.
|
||||
checkAnsiHomePosition: true
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
In addition to these, there are also new options for `term.cp437TermList` and `term.utf8TermList`. Under most circumstances these should not need to be changed. If you want to customize these lists, more information is available in `config_default.js`
|
||||
|
||||
# 0.0.11-beta to 0.0.12-beta
|
||||
* Be aware that `master` is now mainline! This means all `git pull`'s will yield the latest version. See [WHATSNEW](WHATSNEW.md) for more information.
|
||||
* **BREAKING CHANGE** There is no longer a `prompt.hjson` file. Prompts are now simply part of the menu set in the `prompts` section. If you have an existing system you will need to add your `prompt.hjson` to your `menu.hjson`'s `includes` section at a minimum. Example:
|
||||
|
|
|
@ -1,6 +1,12 @@
|
|||
# Whats New
|
||||
This document attempts to track **major** changes and additions in ENiGMA½. For details, see GitHub.
|
||||
|
||||
## 0.0.13-beta
|
||||
* Removed terminal `cursor position reports` from most locations in the code. This should greatly increase the number of terminal programs that work with Enigma 1/2. For more information, see [Issue #222](https://github.com/NuSkooler/enigma-bbs/issues/222). This may also resolve other issues, such as [Issue #365](https://github.com/NuSkooler/enigma-bbs/issues/365), and [Issue #320](https://github.com/NuSkooler/enigma-bbs/issues/320). Anyone that previously had terminal incompatibilities please re-check and let us know!
|
||||
* Bumped up the minimum [Node.js](https://nodejs.org/en/) version to V14. This will allow more expressive Javascript programming syntax with ECMAScript 2020 to improve the development experience.
|
||||
* Added new configuration options for `term.checkUtf8Encoding`, `term.checkAnsiHomePostion`, `term.cp437TermList`, and `term.utf8TermList`. More information on these options is available in `UPGRADE.md`
|
||||
* Many additional backward-compatible bug fixes since the first release of 0.0.12-beta. See the [project repository](https://github.com/NuSkooler/enigma-bbs) for more information.
|
||||
|
||||
## 0.0.12-beta
|
||||
* The `master` branch has become mainline. What this means to users is `git pull` will always give you the latest and greatest. Make sure to read [Updating](./docs/admin/updating.md) and keep an eye on `WHATSNEW.md` (this file) and [UPGRADE](UPGRADE.md)! See also [ticket #276](https://github.com/NuSkooler/enigma-bbs/issues/276).
|
||||
* Development now occurs against [Node.js 14 LTS](https://github.com/nodejs/node/blob/master/doc/changelogs/CHANGELOG_V14.md).
|
||||
|
@ -127,4 +133,4 @@ submit: [
|
|||
...LOTS more!
|
||||
|
||||
## Pre 0.0.8-alpha
|
||||
See GitHub
|
||||
See GitHub
|
||||
|
|
|
@ -21,8 +21,6 @@ function ANSIEscapeParser(options) {
|
|||
events.EventEmitter.call(this);
|
||||
|
||||
this.column = 1;
|
||||
this.row = 1;
|
||||
this.scrollBack = 0;
|
||||
this.graphicRendition = {};
|
||||
|
||||
this.parseState = {
|
||||
|
@ -36,11 +34,15 @@ function ANSIEscapeParser(options) {
|
|||
trailingLF : 'default', // default|omit|no|yes, ...
|
||||
});
|
||||
|
||||
|
||||
this.mciReplaceChar = miscUtil.valueWithDefault(options.mciReplaceChar, '');
|
||||
this.termHeight = miscUtil.valueWithDefault(options.termHeight, 25);
|
||||
this.termWidth = miscUtil.valueWithDefault(options.termWidth, 80);
|
||||
this.trailingLF = miscUtil.valueWithDefault(options.trailingLF, 'default');
|
||||
|
||||
|
||||
this.row = Math.min(options?.startRow ?? 1, this.termHeight);
|
||||
|
||||
self.moveCursor = function(cols, rows) {
|
||||
self.column += cols;
|
||||
self.row += rows;
|
||||
|
@ -69,14 +71,11 @@ function ANSIEscapeParser(options) {
|
|||
};
|
||||
|
||||
self.clearScreen = function() {
|
||||
// :TODO: should be doing something with row/column?
|
||||
self.column = 1;
|
||||
self.row = 1;
|
||||
self.emit('clear screen');
|
||||
};
|
||||
|
||||
/*
|
||||
self.rowUpdated = function() {
|
||||
self.emit('row update', self.row + self.scrollBack);
|
||||
};*/
|
||||
|
||||
self.positionUpdated = function() {
|
||||
self.emit('position update', self.row, self.column);
|
||||
|
@ -190,10 +189,11 @@ function ANSIEscapeParser(options) {
|
|||
|
||||
|
||||
self.emit('mci', {
|
||||
mci : mciCode,
|
||||
id : id ? parseInt(id, 10) : null,
|
||||
args : args,
|
||||
SGR : ansi.getSGRFromGraphicRendition(self.graphicRendition, true)
|
||||
position : [self.row, self.column],
|
||||
mci : mciCode,
|
||||
id : id ? parseInt(id, 10) : null,
|
||||
args : args,
|
||||
SGR : ansi.getSGRFromGraphicRendition(self.graphicRendition, true)
|
||||
});
|
||||
|
||||
if(self.mciReplaceChar.length > 0) {
|
||||
|
@ -215,6 +215,9 @@ function ANSIEscapeParser(options) {
|
|||
}
|
||||
|
||||
self.reset = function(input) {
|
||||
self.column = 1;
|
||||
self.row = Math.min(options?.startRow ?? 1, self.termHeight);
|
||||
|
||||
self.parseState = {
|
||||
// ignore anything past EOF marker, if any
|
||||
buffer : input.split(String.fromCharCode(0x1a), 1)[0],
|
||||
|
|
29
core/art.js
29
core/art.js
|
@ -269,19 +269,16 @@ function display(client, art, options, cb) {
|
|||
termHeight : client.term.termHeight,
|
||||
termWidth : client.term.termWidth,
|
||||
trailingLF : options.trailingLF,
|
||||
startRow : options.startRow,
|
||||
});
|
||||
|
||||
let parseComplete = false;
|
||||
let cprListener;
|
||||
let mciMap;
|
||||
const mciCprQueue = [];
|
||||
let artHash;
|
||||
let mciMapFromCache;
|
||||
|
||||
function completed() {
|
||||
if(cprListener) {
|
||||
client.removeListener('cursor position report', cprListener);
|
||||
}
|
||||
|
||||
if(!options.disableMciCache && !mciMapFromCache) {
|
||||
// cache our MCI findings...
|
||||
|
@ -314,18 +311,6 @@ function display(client, art, options, cb) {
|
|||
// no cached MCI info
|
||||
mciMap = {};
|
||||
|
||||
cprListener = function(pos) {
|
||||
if(mciCprQueue.length > 0) {
|
||||
mciMap[mciCprQueue.shift()].position = pos;
|
||||
|
||||
if(parseComplete && 0 === mciCprQueue.length) {
|
||||
return completed();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
client.on('cursor position report', cprListener);
|
||||
|
||||
let generatedId = 100;
|
||||
|
||||
ansiParser.on('mci', mciInfo => {
|
||||
|
@ -339,18 +324,16 @@ function display(client, art, options, cb) {
|
|||
mapEntry.focusArgs = mciInfo.args;
|
||||
} else {
|
||||
mciMap[mapKey] = {
|
||||
args : mciInfo.args,
|
||||
SGR : mciInfo.SGR,
|
||||
code : mciInfo.mci,
|
||||
id : id,
|
||||
position : mciInfo.position,
|
||||
args : mciInfo.args,
|
||||
SGR : mciInfo.SGR,
|
||||
code : mciInfo.mci,
|
||||
id : id,
|
||||
};
|
||||
|
||||
if(!mciInfo.id) {
|
||||
++generatedId;
|
||||
}
|
||||
|
||||
mciCprQueue.push(mapKey);
|
||||
client.term.rawWrite(ansi.queryPos());
|
||||
}
|
||||
|
||||
});
|
||||
|
|
|
@ -4,11 +4,12 @@
|
|||
// ENiGMA½
|
||||
var Log = require('./logger.js').log;
|
||||
var renegadeToAnsi = require('./color_codes.js').renegadeToAnsi;
|
||||
|
||||
const Config = require('./config.js').get;
|
||||
var iconv = require('iconv-lite');
|
||||
var assert = require('assert');
|
||||
var _ = require('lodash');
|
||||
|
||||
|
||||
exports.ClientTerminal = ClientTerminal;
|
||||
|
||||
function ClientTerminal(output) {
|
||||
|
@ -115,7 +116,8 @@ ClientTerminal.prototype.isNixTerm = function() {
|
|||
return true;
|
||||
}
|
||||
|
||||
return [ 'xterm', 'linux', 'screen', 'dumb', 'rxvt', 'konsole', 'gnome', 'x11 terminal emulator' ].includes(this.termType);
|
||||
const utf8TermList = Config().term.utf8TermList;
|
||||
return utf8TermList.includes(this.termType);
|
||||
};
|
||||
|
||||
ClientTerminal.prototype.isANSI = function() {
|
||||
|
@ -153,7 +155,8 @@ ClientTerminal.prototype.isANSI = function() {
|
|||
// linux:
|
||||
// * JuiceSSH (note: TERM=linux also)
|
||||
//
|
||||
return [ 'ansi', 'pcansi', 'pc-ansi', 'ansi-bbs', 'qansi', 'scoansi', 'syncterm', 'ansi-256color', 'ansi-256color-rgb' ].includes(this.termType);
|
||||
const cp437TermList = Config().term.cp437TermList;
|
||||
return cp437TermList.includes(this.termType);
|
||||
};
|
||||
|
||||
// :TODO: probably need to update these to convert IAC (0xff) -> IACIAC (escape it)
|
||||
|
|
|
@ -17,6 +17,24 @@ module.exports = () => {
|
|||
achievementFile : 'achievements.hjson',
|
||||
},
|
||||
|
||||
term : {
|
||||
// checkUtf8Encoding requires the use of cursor position reports, which are not supported on all terminals.
|
||||
// Using this with a terminal that does not support cursor position reports results in a 2 second delay
|
||||
// during the connect process, but provides better autoconfiguration of utf-8
|
||||
checkUtf8Encoding : true,
|
||||
|
||||
// Checking the ANSI home position also requires the use of cursor position reports, which are not
|
||||
// supported on all terminals. Using this with a terminal that does not support cursor position reports
|
||||
// results in a 3 second delay during the connect process, but works around positioning problems with
|
||||
// non-standard terminals.
|
||||
checkAnsiHomePosition: true,
|
||||
|
||||
// List of terms that should be assumed to use cp437 encoding
|
||||
cp437TermList : ['ansi', 'pcansi', 'pc-ansi', 'ansi-bbs', 'qansi', 'scoansi', 'syncterm', 'ansi-256color', 'ansi-256color-rgb'],
|
||||
// List of terms that should be assumed to use utf8 encoding
|
||||
utf8TermList : ['xterm', 'linux', 'screen', 'dumb', 'rxvt', 'konsole', 'gnome', 'x11 terminal emulator'],
|
||||
},
|
||||
|
||||
users : {
|
||||
usernameMin : 2,
|
||||
usernameMax : 16, // Note that FidoNet wants 36 max
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
// ENiGMA½
|
||||
const ansi = require('./ansi_term.js');
|
||||
const Events = require('./events.js');
|
||||
const Config = require('./config.js').get;
|
||||
const { Errors } = require('./enig_error.js');
|
||||
|
||||
// deps
|
||||
|
@ -18,6 +19,13 @@ function ansiDiscoverHomePosition(client, cb) {
|
|||
// think of home as 0,0. If this is the case, we need to offset
|
||||
// our positioning to accommodate for such.
|
||||
//
|
||||
|
||||
|
||||
if( !Config().term.checkAnsiHomePosition ) {
|
||||
// Skip (and assume 1,1) if the home position check is disabled.
|
||||
return cb(null);
|
||||
}
|
||||
|
||||
const done = (err) => {
|
||||
client.removeListener('cursor position report', cprListener);
|
||||
clearTimeout(giveUpTimer);
|
||||
|
@ -68,8 +76,9 @@ function ansiAttemptDetectUTF8(client, cb) {
|
|||
//
|
||||
// We currently only do this if the term hasn't already been ID'd as a
|
||||
// "*nix" terminal -- that is, xterm, etc.
|
||||
//
|
||||
if(!client.term.isNixTerm()) {
|
||||
// Also skip this check if checkUtf8Encoding is disabled in the config
|
||||
|
||||
if(!client.term.isNixTerm() || !Config().term.checkUtf8Encoding) {
|
||||
return cb(null);
|
||||
}
|
||||
|
||||
|
@ -119,6 +128,8 @@ function ansiAttemptDetectUTF8(client, cb) {
|
|||
return giveUp();
|
||||
}, 2000);
|
||||
|
||||
|
||||
|
||||
client.once('cursor position report', cprListener);
|
||||
client.term.rawWrite(ansi.goHome() + ansi.queryPos());
|
||||
}
|
||||
|
@ -216,7 +227,6 @@ function connectEntry(client, nextMenu) {
|
|||
},
|
||||
function discoverHomePosition(callback) {
|
||||
ansiDiscoverHomePosition(client, () => {
|
||||
// :TODO: If CPR for home fully fails, we should bail out on the connection with an error, e.g. ANSI support required
|
||||
return callback(null); // we try to continue anyway
|
||||
});
|
||||
},
|
||||
|
|
90
core/fse.js
90
core/fse.js
|
@ -603,7 +603,7 @@ exports.FullScreenEditorModule = exports.getModule = class FullScreenEditorModul
|
|||
theme.displayThemedAsset(
|
||||
footerArt,
|
||||
self.client,
|
||||
{ font : self.menuConfig.font },
|
||||
{ font : self.menuConfig.font, startRow: self.header.height + self.body.height },
|
||||
function displayed(err, artData) {
|
||||
callback(err, artData);
|
||||
}
|
||||
|
@ -626,19 +626,34 @@ exports.FullScreenEditorModule = exports.getModule = class FullScreenEditorModul
|
|||
async.series(
|
||||
[
|
||||
function displayHeaderAndBody(callback) {
|
||||
async.eachSeries( comps, function dispArt(n, next) {
|
||||
theme.displayThemedAsset(
|
||||
art[n],
|
||||
self.client,
|
||||
{ font : self.menuConfig.font },
|
||||
function displayed(err) {
|
||||
next(err);
|
||||
async.waterfall(
|
||||
[
|
||||
function displayHeader(callback) {
|
||||
theme.displayThemedAsset(
|
||||
art['header'],
|
||||
self.client,
|
||||
{ font : self.menuConfig.font },
|
||||
function displayed(err, artInfo) {
|
||||
return callback(err, artInfo);
|
||||
}
|
||||
);
|
||||
},
|
||||
function displayBody(artInfo, callback) {
|
||||
theme.displayThemedAsset(
|
||||
art['header'],
|
||||
self.client,
|
||||
{ font : self.menuConfig.font, startRow: artInfo.height + 1 },
|
||||
function displayed(err, artInfo) {
|
||||
return callback(err, artInfo);
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
}, function complete(err) {
|
||||
//self.body.height = self.client.term.termHeight - self.header.height - 1;
|
||||
callback(err);
|
||||
});
|
||||
],
|
||||
function complete(err) {
|
||||
//self.body.height = self.client.term.termHeight - self.header.height - 1;
|
||||
callback(err);
|
||||
}
|
||||
);
|
||||
},
|
||||
function displayFooter(callback) {
|
||||
// we have to treat the footer special
|
||||
|
@ -700,31 +715,39 @@ exports.FullScreenEditorModule = exports.getModule = class FullScreenEditorModul
|
|||
|
||||
assert(_.isObject(art));
|
||||
|
||||
async.series(
|
||||
async.waterfall(
|
||||
[
|
||||
function beforeDisplayArt(callback) {
|
||||
self.beforeArt(callback);
|
||||
},
|
||||
function displayHeaderAndBodyArt(callback) {
|
||||
async.eachSeries( [ 'header', 'body' ], function dispArt(n, next) {
|
||||
theme.displayThemedAsset(
|
||||
art[n],
|
||||
self.client,
|
||||
{ font : self.menuConfig.font },
|
||||
function displayed(err, artData) {
|
||||
if(artData) {
|
||||
mciData[n] = artData;
|
||||
self[n] = { height : artData.height };
|
||||
}
|
||||
|
||||
next(err);
|
||||
function displayHeader(callback) {
|
||||
theme.displayThemedAsset(
|
||||
art.header,
|
||||
self.client,
|
||||
{ font : self.menuConfig.font },
|
||||
function displayed(err, artInfo) {
|
||||
if(artInfo) {
|
||||
mciData['header'] = artInfo;
|
||||
self.header = {height: artInfo.height};
|
||||
}
|
||||
);
|
||||
}, function complete(err) {
|
||||
callback(err);
|
||||
});
|
||||
return callback(err, artInfo);
|
||||
}
|
||||
);
|
||||
},
|
||||
function displayFooter(callback) {
|
||||
function displayBody(artInfo, callback) {
|
||||
theme.displayThemedAsset(
|
||||
art.body,
|
||||
self.client,
|
||||
{ font : self.menuConfig.font, startRow: artInfo.height + 1 },
|
||||
function displayed(err, artInfo) {
|
||||
if(artInfo) {
|
||||
mciData['body'] = artInfo;
|
||||
self.body = {height: artInfo.height - self.header.height};
|
||||
}
|
||||
return callback(err, artInfo);
|
||||
});
|
||||
},
|
||||
function displayFooter(artInfo, callback) {
|
||||
self.setInitialFooterMode();
|
||||
|
||||
var footerName = self.getFooterName();
|
||||
|
@ -825,8 +848,7 @@ exports.FullScreenEditorModule = exports.getModule = class FullScreenEditorModul
|
|||
{
|
||||
const fromView = self.viewControllers.header.getView(MciViewIds.header.from);
|
||||
const area = getMessageAreaByTag(self.messageAreaTag);
|
||||
|
||||
if(fromView !== undefined) {
|
||||
if(fromView !== undefined) {
|
||||
if(area && area.realNames) {
|
||||
fromView.setText(self.client.user.properties[UserProps.RealName] || self.client.user.username);
|
||||
} else {
|
||||
|
|
|
@ -56,14 +56,14 @@ exports.MenuModule = class MenuModule extends PluginModule {
|
|||
initSequence() {
|
||||
const self = this;
|
||||
const mciData = {};
|
||||
let pausePosition;
|
||||
let pausePosition = {row: 0, column: 0};
|
||||
|
||||
const hasArt = () => {
|
||||
return _.isString(self.menuConfig.art) ||
|
||||
(Array.isArray(self.menuConfig.art) && _.has(self.menuConfig.art[0], 'acs'));
|
||||
};
|
||||
|
||||
async.series(
|
||||
async.waterfall(
|
||||
[
|
||||
function beforeArtInterrupt(callback) {
|
||||
return self.displayQueuedInterruptions(callback);
|
||||
|
@ -73,7 +73,7 @@ exports.MenuModule = class MenuModule extends PluginModule {
|
|||
},
|
||||
function displayMenuArt(callback) {
|
||||
if(!hasArt()) {
|
||||
return callback(null);
|
||||
return callback(null, null);
|
||||
}
|
||||
|
||||
self.displayAsset(
|
||||
|
@ -86,18 +86,15 @@ exports.MenuModule = class MenuModule extends PluginModule {
|
|||
mciData.menu = artData.mciMap;
|
||||
}
|
||||
|
||||
return callback(null); // any errors are non-fatal
|
||||
if(artData) {
|
||||
pausePosition.row = artData.height + 1;
|
||||
}
|
||||
|
||||
return callback(null, artData); // any errors are non-fatal
|
||||
}
|
||||
);
|
||||
},
|
||||
function moveToPromptLocation(callback) {
|
||||
if(self.menuConfig.prompt) {
|
||||
// :TODO: fetch and move cursor to prompt location, if supplied. See notes/etc. on placements
|
||||
}
|
||||
|
||||
return callback(null);
|
||||
},
|
||||
function displayPromptArt(callback) {
|
||||
function displayPromptArt(artData, callback) {
|
||||
if(!_.isString(self.menuConfig.prompt)) {
|
||||
return callback(null);
|
||||
}
|
||||
|
@ -106,41 +103,41 @@ exports.MenuModule = class MenuModule extends PluginModule {
|
|||
return callback(Errors.MissingConfig('Prompt specified but no "promptConfig" block found'));
|
||||
}
|
||||
|
||||
const options = Object.assign({}, self.menuConfig.config);
|
||||
|
||||
if(_.isNumber(artData?.height)) {
|
||||
options.startRow = artData.height + 1;
|
||||
}
|
||||
|
||||
self.displayAsset(
|
||||
self.menuConfig.promptConfig.art,
|
||||
self.menuConfig.config,
|
||||
options,
|
||||
(err, artData) => {
|
||||
if(artData) {
|
||||
mciData.prompt = artData.mciMap;
|
||||
pausePosition.row = artData.height + 1;
|
||||
}
|
||||
|
||||
return callback(err); // pass err here; prompts *must* have art
|
||||
}
|
||||
);
|
||||
},
|
||||
function recordCursorPosition(callback) {
|
||||
if(!self.shouldPause()) {
|
||||
return callback(null); // cursor position not needed
|
||||
}
|
||||
|
||||
self.client.once('cursor position report', pos => {
|
||||
pausePosition = { row : pos[0], col : 1 };
|
||||
self.client.log.trace('After art position recorded', pausePosition );
|
||||
return callback(null);
|
||||
});
|
||||
|
||||
self.client.term.rawWrite(ansi.queryPos());
|
||||
},
|
||||
function afterArtDisplayed(callback) {
|
||||
return self.mciReady(mciData, callback);
|
||||
},
|
||||
function displayPauseIfRequested(callback) {
|
||||
if(!self.shouldPause()) {
|
||||
return callback(null);
|
||||
return callback(null, null);
|
||||
}
|
||||
|
||||
if(self.client.term.termHeight > 0 && pausePosition.row > self.client.termHeight) {
|
||||
// If this scrolled, the prompt will go to the bottom of the screen
|
||||
pausePosition.row = self.client.termHeight;
|
||||
}
|
||||
|
||||
return self.pausePrompt(pausePosition, callback);
|
||||
},
|
||||
function finishAndNext(callback) {
|
||||
function finishAndNext(artInfo, callback) {
|
||||
self.finishedLoading();
|
||||
self.realTimeInterrupt = 'allowed';
|
||||
return self.autoNextMenu(callback);
|
||||
|
@ -512,7 +509,7 @@ exports.MenuModule = class MenuModule extends PluginModule {
|
|||
|
||||
this.optionalMoveToPosition(position);
|
||||
|
||||
return theme.displayThemedPause(this.client, cb);
|
||||
return theme.displayThemedPause(this.client, {position}, cb);
|
||||
}
|
||||
|
||||
promptForInput( { formName, formId, promptName, prevFormName, position } = {}, options, cb) {
|
||||
|
|
|
@ -171,22 +171,15 @@ exports.getModule = class ShowArtModule extends MenuModule {
|
|||
return callback(err);
|
||||
}
|
||||
const mciData = { menu : artData.mciMap };
|
||||
return callback(null, mciData);
|
||||
if(self.client.term.termHeight > 0 && artData.height > self.client.term.termHeight) {
|
||||
// We must have scrolled, adjust the positioning for pause
|
||||
artData.height = self.client.term.termHeight;
|
||||
}
|
||||
const pausePosition = { row: artData.height + 1, col: 1};
|
||||
return callback(null, mciData, pausePosition);
|
||||
}
|
||||
);
|
||||
},
|
||||
function recordCursorPosition(mciData, callback) {
|
||||
if(!options.pause) {
|
||||
return callback(null, mciData, null); // cursor position not needed
|
||||
}
|
||||
|
||||
self.client.once('cursor position report', pos => {
|
||||
const pausePosition = { row : pos[0], col : 1 };
|
||||
return callback(null, mciData, pausePosition);
|
||||
});
|
||||
|
||||
self.client.term.rawWrite(ANSI.queryPos());
|
||||
},
|
||||
function afterArtDisplayed(mciData, pausePosition, callback) {
|
||||
self.mciReady(mciData, err => {
|
||||
return callback(err, pausePosition);
|
||||
|
|
|
@ -495,6 +495,7 @@ function displayPreparedArt(options, artInfo, cb) {
|
|||
sauce : artInfo.sauce,
|
||||
font : options.font,
|
||||
trailingLF : options.trailingLF,
|
||||
startRow : options.startRow,
|
||||
};
|
||||
art.display(options.client, artInfo.data, displayOpts, (err, mciMap, extraInfo) => {
|
||||
return cb(err, { mciMap : mciMap, artInfo : artInfo, extraInfo : extraInfo } );
|
||||
|
@ -551,6 +552,7 @@ function displayThemedPrompt(name, client, options, cb) {
|
|||
|
||||
if(options.clearScreen) {
|
||||
client.term.rawWrite(ansi.resetScreen());
|
||||
options.position = {row: 1, column: 1};
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -583,12 +585,15 @@ function displayThemedPrompt(name, client, options, cb) {
|
|||
return callback(null, promptConfig, artInfo);
|
||||
}
|
||||
|
||||
client.once('cursor position report', pos => {
|
||||
artInfo.startRow = pos[0] - artInfo.height;
|
||||
return callback(null, promptConfig, artInfo);
|
||||
});
|
||||
if(_.isNumber(options?.position?.row)) {
|
||||
artInfo.startRow = options.position.row;
|
||||
if(client.term.termHeight > 0 && artInfo.startRow + artInfo.height > client.term.termHeight) {
|
||||
// in this case, we will have scrolled
|
||||
artInfo.startRow = client.term.termHeight - artInfo.height;
|
||||
}
|
||||
}
|
||||
|
||||
client.term.rawWrite(ansi.queryPos());
|
||||
return callback(null, promptConfig, artInfo);
|
||||
},
|
||||
function createMCIViews(promptConfig, artInfo, callback) {
|
||||
const assocViewController = usingTempViewController ? new ViewController( { client : client } ) : options.viewController;
|
||||
|
@ -614,7 +619,9 @@ function displayThemedPrompt(name, client, options, cb) {
|
|||
});
|
||||
},
|
||||
function clearPauseArt(artInfo, assocViewController, callback) {
|
||||
if(options.clearPrompt) {
|
||||
// Only clear with height if clearPrompt is true and if we were able
|
||||
// to determine the row
|
||||
if(options.clearPrompt && artInfo.startRow) {
|
||||
if(artInfo.startRow && artInfo.height) {
|
||||
client.term.rawWrite(ansi.goto(artInfo.startRow, 1));
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ For Linux environments it's recommended you run the [install script](install-scr
|
|||
do things manually, read on...
|
||||
|
||||
## Prerequisites
|
||||
* [Node.js](https://nodejs.org/) version **v12.x LTS or higher** (Other versions may work but are not supported).
|
||||
* [Node.js](https://nodejs.org/) version **v14.x LTS or higher**. Versions under v14 are known not to work due to language level changes.
|
||||
* :bulb: It is **highly** recommended to use [Node Version Manager (NVM)](https://github.com/creationix/nvm) to manage your Node.js installation if you're on a Linux/Unix environment.
|
||||
|
||||
* [Python](https://www.python.org/downloads/) for compiling Node.js packages with native extensions via `node-gyp`.
|
||||
|
|
|
@ -67,6 +67,21 @@
|
|||
description : 'Yet another awesome ENiGMA½ BBS'
|
||||
}
|
||||
|
||||
term: {
|
||||
// checkUtf8Encoding requires the use of cursor position reports, which are not supported on all terminals.
|
||||
// Using this with a terminal that does not support cursor position reports results in a 2 second delay
|
||||
// during the connect process, but provides better autoconfiguration of utf-8
|
||||
checkUtf8Encoding : true
|
||||
|
||||
// Checking the ANSI home position also requires the use of cursor position reports, which are not
|
||||
// supported on all terminals. Using this with a terminal that does not support cursor position reports
|
||||
// results in a 3 second delay during the connect process, but works around positioning problems with
|
||||
// non-standard terminals.
|
||||
checkAnsiHomePosition: true
|
||||
|
||||
// other options here include cp437TermList and utf8TermList, see config_default.js for more information
|
||||
}
|
||||
|
||||
paths: {
|
||||
//
|
||||
// Other paths can also be configured as well,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "enigma-bbs",
|
||||
"version": "0.0.12-beta",
|
||||
"version": "0.0.13-beta",
|
||||
"description": "ENiGMA½ Bulletin Board System",
|
||||
"author": "Bryan Ashby <bryan@l33t.codes>",
|
||||
"license": "BSD-2-Clause",
|
||||
|
@ -62,9 +62,9 @@
|
|||
"yazl": "^2.5.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint": "7.19.0"
|
||||
"eslint": "8.12.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
"node": ">=14"
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue