Several cosmetic fixes for off-by-one in padding and display issues when resetting lists
This commit is contained in:
commit
7a189b238f
Binary file not shown.
|
@ -97,7 +97,7 @@
|
||||||
mci: {
|
mci: {
|
||||||
VM1: {
|
VM1: {
|
||||||
height: 10
|
height: 10
|
||||||
width: 20
|
width: 71
|
||||||
itemFormat: "|00|11{userName:<12}|08: |03{oneliner:<59.59}"
|
itemFormat: "|00|11{userName:<12}|08: |03{oneliner:<59.59}"
|
||||||
}
|
}
|
||||||
TM2: {
|
TM2: {
|
||||||
|
@ -229,6 +229,7 @@
|
||||||
VM1: {
|
VM1: {
|
||||||
height: 10
|
height: 10
|
||||||
itemFormat: "|00|11{userName:<12}|08: |03{oneliner:<59.59}"
|
itemFormat: "|00|11{userName:<12}|08: |03{oneliner:<59.59}"
|
||||||
|
width: 71
|
||||||
}
|
}
|
||||||
TM2: {
|
TM2: {
|
||||||
focusTextStyle: first lower
|
focusTextStyle: first lower
|
||||||
|
@ -486,7 +487,7 @@
|
||||||
|
|
||||||
activityPubFollowingManager: {
|
activityPubFollowingManager: {
|
||||||
config: {
|
config: {
|
||||||
selectedActorInfoFormat: "|00|15{preferredUsername}\n|02{name}\n{plainTextSummary}"
|
selectedActorInfoFormat: "|00|15{preferredUsername} |08(|02{name}|08)\n|07following|08: {statusIndicator}\n\n|06{plainTextSummary}"
|
||||||
statusIndicatorEnabled: "|00|10√"
|
statusIndicatorEnabled: "|00|10√"
|
||||||
staticIndicatorDisabled: "|00|12X"
|
staticIndicatorDisabled: "|00|12X"
|
||||||
}
|
}
|
||||||
|
@ -494,13 +495,13 @@
|
||||||
mci: {
|
mci: {
|
||||||
VM1: {
|
VM1: {
|
||||||
height: 15
|
height: 15
|
||||||
width: 30
|
width: 35
|
||||||
itemFormat: "|00{statusIndicator} |00|03{subject}"
|
itemFormat: "|00{statusIndicator} |00|03{subject}"
|
||||||
focusItemFormat: "|00{statusIndicator} |00|19|15{subject}"
|
focusItemFormat: "|00{statusIndicator} |00|19|15{subject}"
|
||||||
}
|
}
|
||||||
MT2: {
|
MT2: {
|
||||||
height: 15
|
height: 15
|
||||||
width: 38
|
width: 34
|
||||||
}
|
}
|
||||||
TM3: {
|
TM3: {
|
||||||
focusTextStyle: first upper
|
focusTextStyle: first upper
|
||||||
|
|
|
@ -254,12 +254,11 @@ function FullMenuView(options) {
|
||||||
|
|
||||||
if (relativeColumn + renderLength > this.dimens.width) {
|
if (relativeColumn + renderLength > this.dimens.width) {
|
||||||
const overflow = this.hasTextOverflow() ? this.textOverflow : '';
|
const overflow = this.hasTextOverflow() ? this.textOverflow : '';
|
||||||
text =
|
|
||||||
strUtil.renderSubstr(
|
text = strUtil.renderTruncate(text, {
|
||||||
text,
|
length: this.dimens.width - (relativeColumn + overflow.length),
|
||||||
0,
|
omission: overflow,
|
||||||
this.dimens.width - (relativeColumn + overflow.length)
|
});
|
||||||
) + overflow;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let padLength = Math.min(item.fixedLength + 1, this.dimens.width);
|
let padLength = Math.min(item.fixedLength + 1, this.dimens.width);
|
||||||
|
|
|
@ -72,10 +72,12 @@ exports.getModule = class NodeInfo2WebHadnler extends WebHandlerModule {
|
||||||
},
|
},
|
||||||
// :TODO: Only list what's enabled
|
// :TODO: Only list what's enabled
|
||||||
protocols: ['telnet', 'ssh', 'gopher', 'nntp', 'ws', 'activitypub'],
|
protocols: ['telnet', 'ssh', 'gopher', 'nntp', 'ws', 'activitypub'],
|
||||||
services: {
|
|
||||||
inbound: [],
|
// :TODO: what should we really be doing here???
|
||||||
outbound: [''],
|
// services: {
|
||||||
},
|
// inbound: [],
|
||||||
|
// outbound: [],
|
||||||
|
// },
|
||||||
openRegistrations: !config.general.closedSystem,
|
openRegistrations: !config.general.closedSystem,
|
||||||
usage: {
|
usage: {
|
||||||
users: {
|
users: {
|
||||||
|
|
|
@ -19,6 +19,7 @@ exports.debugEscapedString = debugEscapedString;
|
||||||
exports.stringFromNullTermBuffer = stringFromNullTermBuffer;
|
exports.stringFromNullTermBuffer = stringFromNullTermBuffer;
|
||||||
exports.stringToNullTermBuffer = stringToNullTermBuffer;
|
exports.stringToNullTermBuffer = stringToNullTermBuffer;
|
||||||
exports.renderSubstr = renderSubstr;
|
exports.renderSubstr = renderSubstr;
|
||||||
|
exports.renderTruncate = renderTruncate;
|
||||||
exports.renderStringLength = renderStringLength;
|
exports.renderStringLength = renderStringLength;
|
||||||
exports.ansiRenderStringLength = ansiRenderStringLength;
|
exports.ansiRenderStringLength = ansiRenderStringLength;
|
||||||
exports.formatByteSizeAbbr = formatByteSizeAbbr;
|
exports.formatByteSizeAbbr = formatByteSizeAbbr;
|
||||||
|
@ -136,13 +137,12 @@ function stylizeString(s, style) {
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
function pad(s, len, padChar, justify, stringSGR, padSGR, useRenderLen) {
|
function pad(s, len, padChar, justify, stringSGR, padSGR, useRenderLen = true) {
|
||||||
len = len || 0;
|
len = len || 0;
|
||||||
padChar = padChar || ' ';
|
padChar = padChar || ' ';
|
||||||
justify = justify || 'left';
|
justify = justify || 'left';
|
||||||
stringSGR = stringSGR || '';
|
stringSGR = stringSGR || '';
|
||||||
padSGR = padSGR || '';
|
padSGR = padSGR || '';
|
||||||
useRenderLen = _.isUndefined(useRenderLen) ? true : useRenderLen;
|
|
||||||
|
|
||||||
const renderLen = useRenderLen ? renderStringLength(s) : s.length;
|
const renderLen = useRenderLen ? renderStringLength(s) : s.length;
|
||||||
const padLen = len > renderLen ? len - renderLen : 0;
|
const padLen = len > renderLen ? len - renderLen : 0;
|
||||||
|
@ -290,6 +290,29 @@ function renderSubstr(str, start, length) {
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const DefaultTruncateLen = 30;
|
||||||
|
const DefaultTruncateOmission = '...';
|
||||||
|
|
||||||
|
function renderTruncate(str, options) {
|
||||||
|
// shortcut for empty strings
|
||||||
|
if (0 === str.length) {
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
options = options || {};
|
||||||
|
options.length = options.length || DefaultTruncateLen;
|
||||||
|
options.omission = _.isString(options.omission)
|
||||||
|
? options.omission
|
||||||
|
: DefaultTruncateOmission;
|
||||||
|
|
||||||
|
let out = renderSubstr(str, 0, options.length - options.omission.length);
|
||||||
|
if (out.length < str.length) {
|
||||||
|
out += options.omission;
|
||||||
|
}
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Method to return the "rendered" length taking into account Pipe and ANSI color codes.
|
// Method to return the "rendered" length taking into account Pipe and ANSI color codes.
|
||||||
//
|
//
|
||||||
|
@ -464,7 +487,7 @@ function isAnsiLine(line) {
|
||||||
// * Pipe codes
|
// * Pipe codes
|
||||||
// * Extended (CP437) ASCII - https://www.ascii-codes.com/
|
// * Extended (CP437) ASCII - https://www.ascii-codes.com/
|
||||||
// * Tabs
|
// * Tabs
|
||||||
// * Contigous 3+ spaces before the end of the line
|
// * Contiguous 3+ spaces before the end of the line
|
||||||
//
|
//
|
||||||
function isFormattedLine(line) {
|
function isFormattedLine(line) {
|
||||||
if (renderStringLength(line) < line.length) {
|
if (renderStringLength(line) < line.length) {
|
||||||
|
|
|
@ -98,10 +98,10 @@ function VerticalMenuView(options) {
|
||||||
sgr = index === self.focusedItemIndex ? self.getFocusSGR() : self.getSGR();
|
sgr = index === self.focusedItemIndex ? self.getFocusSGR() : self.getSGR();
|
||||||
}
|
}
|
||||||
|
|
||||||
const renderLength = strUtil.renderStringLength(text);
|
text = strUtil.renderTruncate(text, {
|
||||||
if (renderLength > this.dimens.width) {
|
length: this.dimens.width,
|
||||||
text = strUtil.renderSubstr(text, 0, this.dimens.width);
|
omission: this.textOverflow,
|
||||||
}
|
});
|
||||||
|
|
||||||
text = `${sgr}${strUtil.pad(
|
text = `${sgr}${strUtil.pad(
|
||||||
`${text}${this.styleSGR1}`,
|
`${text}${this.styleSGR1}`,
|
||||||
|
@ -109,6 +109,7 @@ function VerticalMenuView(options) {
|
||||||
this.fillChar,
|
this.fillChar,
|
||||||
this.justify
|
this.justify
|
||||||
)}`;
|
)}`;
|
||||||
|
|
||||||
self.client.term.write(`${ansi.goto(item.row, self.position.col)}${text}`);
|
self.client.term.write(`${ansi.goto(item.row, self.position.col)}${text}`);
|
||||||
this.setRenderCacheItem(index, text, item.focused);
|
this.setRenderCacheItem(index, text, item.focused);
|
||||||
};
|
};
|
||||||
|
|
|
@ -50,6 +50,7 @@ function View(options) {
|
||||||
this.textStyle = options.textStyle || 'normal';
|
this.textStyle = options.textStyle || 'normal';
|
||||||
this.focusTextStyle = options.focusTextStyle || this.textStyle;
|
this.focusTextStyle = options.focusTextStyle || this.textStyle;
|
||||||
this.offsetsApplied = false;
|
this.offsetsApplied = false;
|
||||||
|
this.truncateOmission = options.truncateOmission || '';
|
||||||
|
|
||||||
if (options.id) {
|
if (options.id) {
|
||||||
this.setId(options.id);
|
this.setId(options.id);
|
||||||
|
@ -273,6 +274,12 @@ View.prototype.setPropertyValue = function (propName, value) {
|
||||||
this.validate = value;
|
this.validate = value;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'truncateOmission':
|
||||||
|
if (_.isString(value)) {
|
||||||
|
this.truncateOmission = value;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (/styleSGR[0-9]{1,2}/.test(propName)) {
|
if (/styleSGR[0-9]{1,2}/.test(propName)) {
|
||||||
|
|
|
@ -31,6 +31,7 @@ Items can be selected on a menu via the cursor keys, Page Up, Page Down, Home, a
|
||||||
| `fillChar` | Specifies a character to fill extra space in the menu with. Defaults to an empty space |
|
| `fillChar` | Specifies a character to fill extra space in the menu with. Defaults to an empty space |
|
||||||
| `items` | List of items to show in the menu. See **Items** below.
|
| `items` | List of items to show in the menu. See **Items** below.
|
||||||
| `focusItemFormat` | Sets the format for a focused list entry. See **Entry Formatting** in [MCI](../mci.md) |
|
| `focusItemFormat` | Sets the format for a focused list entry. See **Entry Formatting** in [MCI](../mci.md) |
|
||||||
|
| `truncateOmission` | Sets the omission characters for truncated text if used. Defaults to an empty string. Commonly set to "..." |
|
||||||
|
|
||||||
|
|
||||||
### Hot Keys
|
### Hot Keys
|
||||||
|
|
Loading…
Reference in New Issue