Newer
Older
this.sMsgInfoFormatHighlightStr = "";
this.MSGNUM_LEN = (typeof(pMsgNumLen) == "number" ? pMsgNumLen : this.NumMessages(null, true).toString().length);
if (this.MSGNUM_LEN < 4)
this.MSGNUM_LEN = 4;
this.DATE_LEN = 10; // i.e., YYYY-MM-DD
this.TIME_LEN = 8; // i.e., HH:MM:SS
// Variable field widths: From, to, and subject
this.FROM_LEN = (console.screen_columns * (15/console.screen_columns)).toFixed(0);
this.TO_LEN = (console.screen_columns * (15/console.screen_columns)).toFixed(0);

Eric Oulashin
committed
//var colsLeftForSubject = console.screen_columns-this.MSGNUM_LEN-this.DATE_LEN-this.TIME_LEN-this.FROM_LEN-this.TO_LEN-6; // 6 to account for the spaces
//this.SUBJ_LEN = (console.screen_columns * (colsLeftForSubject/console.screen_columns)).toFixed(0);
this.SUBJ_LEN = console.screen_columns-this.MSGNUM_LEN-this.DATE_LEN-this.TIME_LEN-this.FROM_LEN-this.TO_LEN-6; // 6 to account for the spaces
15015
15016
15017
15018
15019
15020
15021
15022
15023
15024
15025
15026
15027
15028
15029
15030
15031
15032
15033
15034
15035
15036
15037
15038
15039
15040
15041
15042
15043
15044
15045
15046
15047
15048
15049
15050
15051
15052
15053
15054
15055
15056
15057
15058
15059
15060
15061
15062
15063
15064
15065
15066
15067
15068
15069
15070
15071
15072
15073
15074
15075
15076
15077
15078
15079
15080
15081
15082
15083
15084
15085
15086
15087
15088
15089
15090
15091
15092
15093
15094
15095
15096
15097
15098
15099
15100
15101
if (this.showScoresInMsgList)
{
this.SUBJ_LEN -= (this.SCORE_LEN + 1);
this.sMsgListHdrFormatStr = "%" + this.MSGNUM_LEN + "s %-" + this.FROM_LEN + "s %-"
+ this.TO_LEN + "s %-" + this.SUBJ_LEN + "s %"
+ this.SCORE_LEN + "s %-" + this.DATE_LEN + "s %-"
+ this.TIME_LEN + "s";
this.sMsgInfoFormatStr = this.colors.msgListMsgNumColor + "%" + this.MSGNUM_LEN + "d%s"
+ this.colors.msgListFromColor + "%-" + this.FROM_LEN + "s "
+ this.colors.msgListToColor + "%-" + this.TO_LEN + "s "
+ this.colors.msgListSubjectColor + "%-" + this.SUBJ_LEN + "s "
+ this.colors.msgListScoreColor + "%" + this.SCORE_LEN + "d "
+ this.colors.msgListDateColor + "%-" + this.DATE_LEN + "s "
+ this.colors.msgListTimeColor + "%-" + this.TIME_LEN + "s";
// Message information format string with colors to use when the message is
// written to the user.
this.sMsgInfoToUserFormatStr = this.colors.msgListToUserMsgNumColor + "%" + this.MSGNUM_LEN + "d%s"
+ this.colors.msgListToUserFromColor
+ "%-" + this.FROM_LEN + "s " + this.colors.msgListToUserToColor + "%-"
+ this.TO_LEN + "s " + this.colors.msgListToUserSubjectColor + "%-"
+ this.SUBJ_LEN + "s " + this.colors.msgListToUserScoreColor + "%"
+ this.SCORE_LEN + "d " + this.colors.msgListToUserDateColor
+ "%-" + this.DATE_LEN + "s " + this.colors.msgListToUserTimeColor
+ "%-" + this.TIME_LEN + "s";
// Message information format string with colors to use when the message is
// from the user.
this.sMsgInfoFromUserFormatStr = this.colors.msgListFromUserMsgNumColor + "%" + this.MSGNUM_LEN + "d%s"
+ this.colors.msgListFromUserFromColor
+ "%-" + this.FROM_LEN + "s " + this.colors.msgListFromUserToColor + "%-"
+ this.TO_LEN + "s " + this.colors.msgListFromUserSubjectColor + "%-"
+ this.SUBJ_LEN + "s " + this.colors.msgListFromUserScoreColor + "%"
+ this.SCORE_LEN + "d " + this.colors.msgListFromUserDateColor
+ "%-" + this.DATE_LEN + "s " + this.colors.msgListFromUserTimeColor
+ "%-" + this.TIME_LEN + "s";
// Highlighted message information line for the message list (used for the
// lightbar interface)
this.sMsgInfoFormatHighlightStr = this.colors.msgListMsgNumHighlightColor
+ "%" + this.MSGNUM_LEN + "d%s"
+ this.colors.msgListFromHighlightColor + "%-" + this.FROM_LEN
+ "s " + this.colors.msgListToHighlightColor + "%-" + this.TO_LEN + "s "
+ this.colors.msgListSubjHighlightColor + "%-" + this.SUBJ_LEN + "s "
+ this.colors.msgListScoreHighlightColor + "%" + this.SCORE_LEN + "d "
+ this.colors.msgListDateHighlightColor + "%-" + this.DATE_LEN + "s "
+ this.colors.msgListTimeHighlightColor + "%-" + this.TIME_LEN + "s";
}
else
{
this.sMsgListHdrFormatStr = "%" + this.MSGNUM_LEN + "s %-" + this.FROM_LEN + "s %-"
+ this.TO_LEN + "s %-" + this.SUBJ_LEN + "s %-"
+ this.DATE_LEN + "s %-" + this.TIME_LEN + "s";
this.sMsgInfoFormatStr = this.colors.msgListMsgNumColor + "%" + this.MSGNUM_LEN + "d%s"
+ this.colors.msgListFromColor + "%-" + this.FROM_LEN + "s "
+ this.colors.msgListToColor + "%-" + this.TO_LEN + "s "
+ this.colors.msgListSubjectColor + "%-" + this.SUBJ_LEN + "s "
+ this.colors.msgListDateColor + "%-" + this.DATE_LEN + "s "
+ this.colors.msgListTimeColor + "%-" + this.TIME_LEN + "s";
// Message information format string with colors to use when the message is
// written to the user.
this.sMsgInfoToUserFormatStr = this.colors.msgListToUserMsgNumColor + "%" + this.MSGNUM_LEN + "d%s"
+ this.colors.msgListToUserFromColor
+ "%-" + this.FROM_LEN + "s " + this.colors.msgListToUserToColor + "%-"
+ this.TO_LEN + "s " + this.colors.msgListToUserSubjectColor + "%-"
+ this.SUBJ_LEN + "s " + this.colors.msgListToUserDateColor
+ "%-" + this.DATE_LEN + "s " + this.colors.msgListToUserTimeColor
+ "%-" + this.TIME_LEN + "s";
// Message information format string with colors to use when the message is
// from the user.
this.sMsgInfoFromUserFormatStr = this.colors.msgListFromUserMsgNumColor + "%" + this.MSGNUM_LEN + "d%s"
+ this.colors.msgListFromUserFromColor
+ "%-" + this.FROM_LEN + "s " + this.colors.msgListFromUserToColor + "%-"
+ this.TO_LEN + "s " + this.colors.msgListFromUserSubjectColor + "%-"
+ this.SUBJ_LEN + "s " + this.colors.msgListFromUserDateColor
+ "%-" + this.DATE_LEN + "s " + this.colors.msgListFromUserTimeColor
+ "%-" + this.TIME_LEN + "s";
// Highlighted message information line for the message list (used for the
// lightbar interface)
this.sMsgInfoFormatHighlightStr = this.colors.msgListMsgNumHighlightColor
+ "%" + this.MSGNUM_LEN + "d%s"
+ this.colors.msgListFromHighlightColor + "%-" + this.FROM_LEN
+ "s " + this.colors.msgListToHighlightColor + "%-" + this.TO_LEN + "s "
+ this.colors.msgListSubjHighlightColor + "%-" + this.SUBJ_LEN + "s "
+ this.colors.msgListDateHighlightColor + "%-" + this.DATE_LEN + "s "
+ this.colors.msgListTimeHighlightColor + "%-" + this.TIME_LEN + "s";
}
// If the user's terminal doesn't support ANSI, then append a newline to
// the end of the header format string (we won't be able to move the cursor).
if (!canDoHighASCIIAndANSI())
this.sMsgListHdrFormatStr += "\r\n";
}
// For the DigDistMessageReader class: Writes a temporary error message at the key help line
// for lightbar mode.
//
// Parameters:
// pErrorMsg: The error message to write
// pHelpLineRefreshDef: Optional - Specifies which help line to refresh on the screen
// (i.e., REFRESH_MSG_AREA_CHG_LIGHTBAR_HELP_LINE)
function DigDistMsgReader_WriteLightbarKeyHelpErrorMsg(pErrorMsg, pLineRefreshDef)
{
console.gotoxy(1, console.screen_rows);
console.cleartoeol("\x01n");
console.gotoxy(1, console.screen_rows);
console.print("\x01y\x01h" + pErrorMsg + "\x01n");
mswait(ERROR_WAIT_MS);
var helpLineRefreshDef = (typeof(pHelpLineRefreshDef) == "number" ? pHelpLineRefreshDef : -1);
if (helpLineRefreshDef == REFRESH_MSG_AREA_CHG_LIGHTBAR_HELP_LINE)
this.WriteChgMsgAreaKeysHelpLine();
}

Eric Oulashin
committed
// For the scrollable reader interface: Refreshes a rectangular region on the screen
// by printing part of the message text.
//
// pTxtLines: The array of text lines of the message being displayed
// pTopLineIdx: The index of the text line currently at the top row in the reader area
// pTopLeftX: The upper-left corner column of the rectangle to be refreshed (1-based) - Absolute screen coordinate
// pTopLeftY: The upper-left corner row of the rectangle to be refreshed (1-based) - Absolute screen coordinate
// pWidth: The width of the rectangle to be refreshed
// pHeight: The height of the rectangle to be refreshed
function DigDistMsgReader_RefreshMsgAreaRectangle(pTxtLines, pTopLineIdx, pTopLeftX, pTopLeftY, pWidth, pHeight)
{

Eric Oulashin
committed
15138
15139
15140
15141
15142
15143
15144
15145
15146
15147
15148
15149
15150
15151
15152
15153
15154
15155
15156
15157
15158
15159
15160
15161
15162
15163
15164
15165
15166
15167
15168
15169
15170
15171
15172
15173
15174
15175
15176
15177
15178
15179
15180
15181
15182
15183
15184
15185
15186
15187
15188
15189
15190
15191
15192
15193
15194
15195
15196
15197
15198
15199
15200
15201
15202
15203
15204
15205
15206
15207
15208
15209
15210
15211
15212
15213
15214
15215
15216
15217
15218
15219
15220
15221
15222
15223
15224
15225
15226
15227
15228
15229
15230
15231
if (typeof(pTxtLines) !== "object")
return;
if (typeof(pTopLineIdx) !== "number" || pTopLineIdx < 0 || pTopLineIdx >= pTxtLines.length)
return;
if (typeof(pTopLeftX) !== "number" || pTopLeftX < 1 || pTopLeftX > console.screen_columns)
return;
if (typeof(pTopLeftY) !== "number" || pTopLeftY < 1 || pTopLeftY > console.screen_rows)
return;
if (typeof(pWidth) !== "number" || pWidth <= 0 || typeof(pHeight) !== "number" || pHeight <= 0)
return;
var firstTxtLineIdx = pTopLeftY - pTopLineIdx - 1;
if (firstTxtLineIdx < 0) firstTxtLineIdx = 0; // Shouldn't happen, but just in case
//this.msgAreaLeft = 1;
//this.msgAreaRight = console.screen_columns - 1;
//this.msgAreaWidth = this.msgAreaRight - this.msgAreaLeft + 1;
//this.msgAreaHeight = this.msgAreaBottom - this.msgAreaTop + 1;
// Sanity checking
if (pTopLeftY < this.msgAreaTop)
{
var diff = this.msgAreaTop - pTopLeftY;
pTopLeftY = this.msgAreaTop;
pTopLineIdx += diff;
}
var lastScreenRow = pTopLeftY + pHeight - 1; // Inclusive, for loop
if (lastScreenRow > this.msgAreaBottom)
lastScreenRow = this.msgAreaBottom;
if (pTopLeftX + pWidth > this.msgAreaRight)
pWidth = this.msgAreaRight - pTopLeftX + 1;
// Print the parts of the text lines that make up the rectangle
var txtLineIdx = pTopLineIdx + (pTopLeftY-this.msgAreaTop);
if (txtLineIdx < 0) txtLineIdx = 0; // Just in case, but shouldn't happen
var txtLineStartIdx = pTopLeftX - this.msgAreaLeft; // Within each text line (it seemed right to subtract 1 but it wasn't)
if (txtLineStartIdx < 0) txtLineStartIdx = 0; // Just in case, but shouldn't happen
var emptyFormatStr = "\x01n%" + pWidth + "s"; // For printing empty strings after printing all text lines
console.print("\x01n");
for (var screenRow = pTopLeftY; screenRow <= lastScreenRow; ++screenRow)
{
console.gotoxy(pTopLeftX, screenRow);
// If the current text line index is within the array of text lines, then output the section of the
// text line. Otherwise, output an empty string.
if (txtLineIdx < pTxtLines.length)
{
// Get the text attributes up to the current point and output them
console.print(getAllEditLineAttrsUntilLineIdx(pTxtLines, txtLineIdx, true, txtLineStartIdx));
// Get the section of line (and make sure it can fill the needed width), and print it
// Note: substrWithAttrCodes(pStr, pStartIdx, pLen) is defined in dd_lightbar_menu.js
var lineText = substrWithAttrCodes(pTxtLines[txtLineIdx], txtLineStartIdx, pWidth);
var printableTxtLen = console.strlen(lineText);
if (printableTxtLen < pWidth)
{
var lenDiff = pWidth - printableTxtLen;
lineText += format("\x01n%" + lenDiff + "s", "");
}
console.print(lineText);
}
else // We've printed all the remaining text lines, so now print an empty string.
printf(emptyFormatStr, "");
++txtLineIdx;
}
}
// For the scrollable reader interface: Returns whether a 'from' or 'to' name in a message header
// is in the user's personal twitlist.
//
// Parameters:
// pMsgHdr: A message header to check
//
// Return value: Boolean - Whether or not the header 'from' or 'to' name is in the user's personal twitlist
function DigDistMsgReader_MsgHdrFromOrToInUserTwitlist(pMsgHdr)
{
if (pMsgHdr == null || typeof(pMsgHdr) !== "object")
return false;
if (!pMsgHdr.hasOwnProperty("from") && !pMsgHdr.hasOwnProperty("to"))
return false;
// The names in the user's twitlist have been converted to lowercase for case-insensitive matching.
var fromLower = pMsgHdr.from.toLowerCase();
var toLower = pMsgHdr.to.toLowerCase();
var hdrNamesInTwitlist = false;
for (var i = 0; i < this.userSettings.twitList.length && !hdrNamesInTwitlist; ++i)
hdrNamesInTwitlist = (this.userSettings.twitList[i] == fromLower || this.userSettings.twitList[i] == toLower);
return hdrNamesInTwitlist;
}
///////////////////////////////////////////////////////////////////////////////////
// Helper functions
// Displays the program information.
function DisplayProgramInfo()
{
displayTextWithLineBelow("Digital Distortion Message Reader", true, "\x01n\x01c\x01h", "\x01k\x01h")
console.center("\x01n\x01cVersion \x01g" + READER_VERSION + " \x01w\x01h(\x01b" + READER_DATE + "\x01w)");
console.crlf();
}
// This function returns an array of default colors used in the
// DigDistMessageReader class.
function getDefaultColors()
{
return {
// Colors for the message header displayed above messages in the scrollable reader mode
msgHdrMsgNumColor: "\x01n\x01b\x01h", // Message #
msgHdrFromColor: "\x01n\x01b\x01h", // From username
msgHdrToColor: "\x01n\x01b\x01h", // To username
msgHdrToUserColor: "\x01n\x01g\x01h", // To username when it's to the current user
msgHdrSubjColor: "\x01n\x01b\x01h", // Message subject
msgHdrDateColor: "\x01n\x01b\x01h", // Message date
// Message list header line: "Current msg group:"
msgListHeaderMsgGroupTextColor: "\x01n\x01" + "4\x01c", // Normal cyan on blue background
// msgListHeaderMsgGroupTextColor: "\x01n\x01" + "4\x01w", // Normal white on blue background
// Message list header line: Message group name
msgListHeaderMsgGroupNameColor: "\x01h\x01c", // High cyan
// msgListHeaderMsgGroupNameColor: "\x01h\x01w", // High white
// Message list header line: "Current sub-board:"
msgListHeaderSubBoardTextColor: "\x01n\x01" + "4\x01c", // Normal cyan on blue background
// msgListHeaderSubBoardTextColor: "\x01n\x01" + "4\x01w", // Normal white on blue background
// Message list header line: Message sub-board name
msgListHeaderMsgSubBoardName: "\x01h\x01c", // High cyan
// msgListHeaderMsgSubBoardName: "\x01h\x01w", // High white
// Line with column headers
// msgListColHeader: "\x01h\x01w", // High white (keep blue background)
msgListColHeader: "\x01n\x01h\x01w", // High white on black background
// msgListColHeader: "\x01h\x01c", // High cyan (keep blue background)
// msgListColHeader: "\x01" + "4\x01h\x01y", // High yellow (keep blue background)
// Message list information
msgListMsgNumColor: "\x01n\x01h\x01y",
msgListFromColor: "\x01n\x01c",
msgListToColor: "\x01n\x01c",
msgListSubjectColor: "\x01n\x01c",
msgListScoreColor: "\x01n\x01c",
msgListDateColor: "\x01h\x01b",
msgListTimeColor: "\x01h\x01b",
// Message information for messages written to the user
msgListToUserMsgNumColor: "\x01n\x01h\x01y",
msgListToUserFromColor: "\x01h\x01g",
msgListToUserToColor: "\x01h\x01g",
msgListToUserSubjectColor: "\x01h\x01g",
msgListToUserScoreColor: "\x01h\x01g",
msgListToUserDateColor: "\x01h\x01b",
msgListToUserTimeColor: "\x01h\x01b",
// Message information for messages from the user
msgListFromUserMsgNumColor: "\x01n\x01h\x01y",
msgListFromUserFromColor: "\x01n\x01c",
msgListFromUserToColor: "\x01n\x01c",
msgListFromUserSubjectColor: "\x01n\x01c",
msgListFromUserScoreColor: "\x01n\x01c",
msgListFromUserDateColor: "\x01h\x01b",
msgListFromUserTimeColor: "\x01h\x01b",
// Message list highlight colors
msgListHighlightBkgColor: "\x01" + "4", // Background
msgListMsgNumHighlightColor: "\x01h\x01y",
msgListFromHighlightColor: "\x01h\x01c",
msgListToHighlightColor: "\x01h\x01c",
msgListSubjHighlightColor: "\x01h\x01c",
msgListScoreHighlightColor: "\x01h\x01c",
msgListDateHighlightColor: "\x01h\x01w",
msgListTimeHighlightColor: "\x01h\x01w",
// Lightbar message list help line colors
lightbarMsgListHelpLineBkgColor: "\x01" + "7", // Background
lightbarMsgListHelpLineGeneralColor: "\x01b",
lightbarMsgListHelpLineHotkeyColor: "\x01r",
lightbarMsgListHelpLineParenColor: "\x01m",
// Continue prompt colors
tradInterfaceContPromptMainColor: "\x01n\x01g", // Main text color
tradInterfaceContPromptHotkeyColor: "\x01h\x01c", // Hotkey color
tradInterfaceContPromptUserInputColor: "\x01h\x01g", // User input color
// Message body color
msgBodyColor: "\x01n\x01w",
// Read message confirmation colors
readMsgConfirmColor: "\x01n\x01c",
readMsgConfirmNumberColor: "\x01h\x01c",
// Prompt for continuing to list messages after reading a message
afterReadMsg_ListMorePromptColor: "\x01n\x01c",
// Help screen text color
tradInterfaceHelpScreenColor: "\x01n\x01h\x01w",
// Colors for choosing a message group & sub-board
areaChooserMsgAreaNumColor: "\x01n\x01w\x01h",
areaChooserMsgAreaDescColor: "\x01n\x01c",
areaChooserMsgAreaNumItemsColor: "\x01b\x01h",
areaChooserMsgAreaHeaderColor: "\x01n\x01y\x01h",
areaChooserSubBoardHeaderColor: "\x01n\x01g",
areaChooserMsgAreaMarkColor: "\x01g\x01h",
areaChooserMsgAreaLatestDateColor: "\x01n\x01g",
areaChooserMsgAreaLatestTimeColor: "\x01n\x01m",
// Highlighted colors (for lightbar mode)
areaChooserMsgAreaBkgHighlightColor: "\x01" + "4", // Blue background
areaChooserMsgAreaNumHighlightColor: "\x01w\x01h",
areaChooserMsgAreaDescHighlightColor: "\x01c",
areaChooserMsgAreaDateHighlightColor: "\x01w\x01h",
areaChooserMsgAreaTimeHighlightColor: "\x01w\x01h",
areaChooserMsgAreaNumItemsHighlightColor: "\x01w\x01h",
// Lightbar area chooser help line
lightbarAreaChooserHelpLineBkgColor: "\x01" + "7", // Background
lightbarAreaChooserHelpLineGeneralColor: "\x01b",
lightbarAreaChooserHelpLineHotkeyColor: "\x01r",
lightbarAreaChooserHelpLineParenColor: "\x01m",
// Scrollbar background and scroll block colors (for the enhanced
// message reader interface)
scrollbarBGColor: "\x01n\x01h\x01k",
scrollbarScrollBlockColor: "\x01n\x01h\x01w",
// Color for the line drawn in the 2nd to last line of the message
// area in the enhanced reader mode before a prompt
enhReaderPromptSepLineColor: "\x01n\x01h\x01g",
// Colors for the enhanced reader help line
enhReaderHelpLineBkgColor: "\x01" + "7",
enhReaderHelpLineGeneralColor: "\x01b",
enhReaderHelpLineHotkeyColor: "\x01r",
enhReaderHelpLineParenColor: "\x01m",
// Message header line colors
hdrLineLabelColor: "\x01n\x01c",
hdrLineValueColor: "\x01n\x01b\x01h",
// Selected message marker color
selectedMsgMarkColor: "\x01n\x01w\x01h"
};
15370
15371
15372
15373
15374
15375
15376
15377
15378
15379
15380
15381
15382
15383
15384
15385
15386
15387
15388
15389
15390
15391
15392
15393
15394
15395
15396
15397
15398
15399
15400
15401
15402
15403
15404
15405
15406
15407
15408
15409
15410
15411
15412
15413
15414
15415
15416
15417
15418
15419
15420
15421
15422
15423
15424
15425
15426
15427
15428
15429
15430
15431
15432
15433
15434
15435
15436
15437
15438
15439
15440
15441
15442
15443
15444
15445
15446
15447
15448
15449
15450
15451
15452
15453
15454
15455
15456
15457
15458
}
// This function returns the month number (1-based) from a capitalized
// month name.
//
// Parameters:
// pMonthName: The name of the month
//
// Return value: The number of the month (1-12).
function getMonthNum(pMonthName)
{
var monthNum = 1;
if (pMonthName.substr(0, 3) == "Jan")
monthNum = 1;
else if (pMonthName.substr(0, 3) == "Feb")
monthNum = 2;
else if (pMonthName.substr(0, 3) == "Mar")
monthNum = 3;
else if (pMonthName.substr(0, 3) == "Apr")
monthNum = 4;
else if (pMonthName.substr(0, 3) == "May")
monthNum = 5;
else if (pMonthName.substr(0, 3) == "Jun")
monthNum = 6;
else if (pMonthName.substr(0, 3) == "Jul")
monthNum = 7;
else if (pMonthName.substr(0, 3) == "Aug")
monthNum = 8;
else if (pMonthName.substr(0, 3) == "Sep")
monthNum = 9;
else if (pMonthName.substr(0, 3) == "Oct")
monthNum = 10;
else if (pMonthName.substr(0, 3) == "Nov")
monthNum = 11;
else if (pMonthName.substr(0, 3) == "Dec")
monthNum = 12;
return monthNum;
}
// Clears each line from a given line to the end of the screen.
//
// Parameters:
// pStartLineNum: The line number to start at (1-based)
function clearToEOS(pStartLineNum)
{
if (typeof(pStartLineNum) == "undefined")
return;
if (pStartLineNum == null)
return;
for (var lineNum = pStartLineNum; lineNum <= console.screen_rows; ++lineNum)
{
console.gotoxy(1, lineNum);
console.clearline();
}
}
// Returns the number of messages in a sub-board.
//
// Parameters:
// pSubBoardCode: The sub-board code (i.e., from bbs.cursub_code)
//
// Return value: The number of messages in the sub-board, or 0
// if the sub-board could not be opened.
function numMessages(pSubBoardCode)
{
var messageCount = 0;
var myMsgbase = new MsgBase(pSubBoardCode);
if (myMsgbase.open())
messageCount = myMsgbase.total_msgs;
myMsgbase.close();
myMsgbase = null;
return messageCount;
}
// Removes multiple, leading, and/or trailing spaces
// The search & replace regular expressions used in this
// function came from the following URL:
// http://qodo.co.uk/blog/javascript-trim-leading-and-trailing-spaces
//
// Parameters:
// pString: The string to trim
// pLeading: Whether or not to trim leading spaces (optional, defaults to true)
// pMultiple: Whether or not to trim multiple spaces (optional, defaults to true)
// pTrailing: Whether or not to trim trailing spaces (optional, defaults to true)

nightfox
committed
//
// Return value: The string with whitespace trimmed
15461
15462
15463
15464
15465
15466
15467
15468
15469
15470
15471
15472
15473
15474
15475
15476
15477
15478
15479
15480
15481
15482
15483
15484
15485
15486
15487
15488
15489
15490
15491
15492
15493
15494
15495
15496
15497
15498
15499
15500
15501
15502
15503
15504
15505
15506
15507
15508
15509
15510
function trimSpaces(pString, pLeading, pMultiple, pTrailing)
{
var leading = true;
var multiple = true;
var trailing = true;
if(typeof(pLeading) != "undefined")
leading = pLeading;
if(typeof(pMultiple) != "undefined")
multiple = pMultiple;
if(typeof(pTrailing) != "undefined")
trailing = pTrailing;
// To remove both leading & trailing spaces:
//pString = pString.replace(/(^\s*)|(\s*$)/gi,"");
if (leading)
pString = pString.replace(/(^\s*)/gi,"");
if (multiple)
pString = pString.replace(/[ ]{2,}/gi," ");
if (trailing)
pString = pString.replace(/(\s*$)/gi,"");
return pString;
}
// Returns whether an internal sub-board code is valid.
//
// Parameters:
// pSubBoardCode: The internal sub-board code to test
//
// Return value: Boolean - Whether or not the given internal code is a valid
// sub-board code
function subBoardCodeIsValid(pSubBoardCode)
{
return ((pSubBoardCode == "mail") || (typeof(msg_area.sub[pSubBoardCode]) == "object"))
}
// Displays some text with a solid horizontal line on the next line.
//
// Parameters:
// pText: The text to display
// pCenter: Whether or not to center the text. Optional; defaults
// to false.
// pTextColor: The color to use for the text. Optional; by default,
// normal white will be used.
// pLineColor: The color to use for the line underneath the text.
// Optional; by default, bright black will be used.
function displayTextWithLineBelow(pText, pCenter, pTextColor, pLineColor)
{
var centerText = (typeof(pCenter) == "boolean" ? pCenter : false);
var textColor = (typeof(pTextColor) == "string" ? pTextColor : "\x01n\x01w");
var lineColor = (typeof(pLineColor) == "string" ? pLineColor : "\x01n\x01k\x01h");
// Output the text and a solid line on the next line.
if (centerText)
{
console.center(textColor + pText);
var solidLine = "";
var textLength = console.strlen(pText);
for (var i = 0; i < textLength; ++i)
solidLine += HORIZONTAL_SINGLE;
console.center(lineColor + solidLine);
}
else
{
console.print(textColor + pText);
console.crlf();
console.print(lineColor);
var textLength = console.strlen(pText);
for (var i = 0; i < textLength; ++i)
console.print(HORIZONTAL_SINGLE);
console.crlf();
}
15534
15535
15536
15537
15538
15539
15540
15541
15542
15543
15544
15545
15546
15547
15548
15549
15550
15551
15552
15553
15554
15555
15556
15557
15558
15559
15560
15561
15562
15563
15564
15565
15566
15567
15568
15569
15570
15571
15572
15573
15574
15575
15576
15577
15578
15579
15580
15581
15582
15583
15584
15585
15586
15587
15588
15589
15590
15591
15592
15593
15594
15595
15596
15597
15598
15599
15600
15601
15602
15603
15604
15605
15606
15607
15608
15609
15610
15611
15612
15613
15614
15615
15616
15617
}
// Removes multiple, leading, and/or trailing spaces.
// The search & replace regular expressions used in this
// function came from the following URL:
// http://qodo.co.uk/blog/javascript-trim-leading-and-trailing-spaces
//
// Parameters:
// pString: The string to trim
// pLeading: Whether or not to trim leading spaces (optional, defaults to true)
// pMultiple: Whether or not to trim multiple spaces (optional, defaults to true)
// pTrailing: Whether or not to trim trailing spaces (optional, defaults to true)
function trimSpaces(pString, pLeading, pMultiple, pTrailing)
{
var leading = true;
var multiple = true;
var trailing = true;
if(typeof(pLeading) != "undefined")
leading = pLeading;
if(typeof(pMultiple) != "undefined")
multiple = pMultiple;
if(typeof(pTrailing) != "undefined")
trailing = pTrailing;
// To remove both leading & trailing spaces:
//pString = pString.replace(/(^\s*)|(\s*$)/gi,"");
if (leading)
pString = pString.replace(/(^\s*)/gi,"");
if (multiple)
pString = pString.replace(/[ ]{2,}/gi," ");
if (trailing)
pString = pString.replace(/(\s*$)/gi,"");
return pString;
}
// Calculates & returns a page number.
//
// Parameters:
// pTopIndex: The index (0-based) of the topmost item on the page
// pNumPerPage: The number of items per page
//
// Return value: The page number
function calcPageNum(pTopIndex, pNumPerPage)
{
return ((pTopIndex / pNumPerPage) + 1);
}
// Returns the greatest number of messages of all sub-boards within
// a message group.
//
// Parameters:
// pGrpIndex: The index of the message group
//
// Returns: The greatest number of messages of all sub-boards within
// the message group
function getGreatestNumMsgs(pGrpIndex)
{
// Sanity checking
if (typeof(pGrpIndex) != "number")
return 0;
if (typeof(msg_area.grp_list[pGrpIndex]) == "undefined")
return 0;
var greatestNumMsgs = 0;
var msgBase = null;
for (var subIndex = 0; subIndex < msg_area.grp_list[pGrpIndex].sub_list.length; ++subIndex)
{
msgBase = new MsgBase(msg_area.grp_list[pGrpIndex].sub_list[subIndex].code);
if (msgBase == null) continue;
if (msgBase.open())
{
if (msgBase.total_msgs > greatestNumMsgs)
greatestNumMsgs = msgBase.total_msgs;
msgBase.close();
}
}
return greatestNumMsgs;
}
// Inputs a keypress from the user and handles some ESC-based
// characters such as PageUp, PageDown, and ESC. If PageUp
// or PageDown are pressed, this function will return the
// string defined by KEY_PAGE_UP or KEY_PAGE_DOWN,
// respectively. Also, F1-F5 will be returned as "\x01F1"
// through "\x01F5", respectively.
// Thanks goes to Psi-Jack for the original impementation
// of this function.
//
// Parameters:
// pGetKeyMode: Optional - The mode bits for console.getkey().
// If not specified, K_NONE will be used.
//
// Return value: The user's keypress
function getKeyWithESCChars(pGetKeyMode)
{
15631
15632
15633
15634
15635
15636
15637
15638
15639
15640
15641
15642
15643
15644
15645
15646
15647
15648
15649
15650
var getKeyMode = K_NONE;
if (typeof(pGetKeyMode) == "number")
getKeyMode = pGetKeyMode;
var userInput = console.getkey(getKeyMode);
if (userInput == KEY_ESC) {
switch (console.inkey(K_NOECHO|K_NOSPIN, 2)) {
case '[':
switch (console.inkey(K_NOECHO|K_NOSPIN, 2)) {
case 'V':
userInput = KEY_PAGE_UP;
break;
case 'U':
userInput = KEY_PAGE_DOWN;
break;
}
break;
case 'O':
switch (console.inkey(K_NOECHO|K_NOSPIN, 2)) {
case 'P':
userInput = "\x01F1";
break;
case 'Q':
userInput = "\x01F2";
break;
case 'R':
userInput = "\x01F3";
break;
case 'S':
userInput = "\x01F4";
break;
case 't':
userInput = "\x01F5";
break;
}
default:
break;
}
}
return userInput;
15672
15673
15674
15675
15676
15677
15678
15679
15680
15681
15682
15683
15684
15685
15686
15687
15688
15689
15690
15691
15692
15693
15694
15695
}
// Finds the next or previous non-empty message sub-board. Returns an
// object containing the message group & sub-board indexes. If all of
// the next/previous sub-boards are empty, then the given current indexes
// will be returned.
//
// Parameters:
// pStartGrpIdx: The index of the message group to start from
// pStartSubIdx: The index of the sub-board in the message group to start from
// pForward: Boolean - Whether or not to search forward (true) or backward (false).
// Optional; defaults to true, to search forward.
//
// Return value: An object with the following properties:
// foundSubBoard: Boolean - Whether or not a different sub-board was found
// grpIdx: The message group index of the found sub-board
// subIdx: The sub-board index in the group of the found sub-board
// subCode: The internal code of the sub-board
// subChanged: Boolean - Whether or not the found sub-board is
// different from the one that was passed in
// paramsValid: Boolean - Whether or not all the passed-in parameters
// were valid.
function findNextOrPrevNonEmptySubBoard(pStartGrpIdx, pStartSubIdx, pForward)
{
var retObj = {
grpIdx: pStartGrpIdx,
subIdx: pStartSubIdx,
subCode: msg_area.grp_list[pStartGrpIdx].sub_list[pStartSubIdx].code,
foundSubBoard: false
};
15702
15703
15704
15705
15706
15707
15708
15709
15710
15711
15712
15713
15714
15715
15716
15717
15718
15719
15720
15721
15722
15723
15724
15725
15726
15727
15728
15729
15730
15731
15732
15733
15734
15735
15736
15737
15738
15739
15740
15741
15742
15743
15744
15745
15746
15747
15748
15749
15750
15751
15752
15753
15754
15755
15756
15757
15758
15759
15760
15761
15762
15763
15764
15765
15766
15767
15768
15769
15770
15771
15772
15773
15774
15775
15776
15777
15778
15779
15780
15781
15782
15783
15784
15785
15786
15787
15788
15789
15790
15791
15792
15793
15794
15795
15796
15797
15798
15799
15800
15801
15802
15803
15804
15805
15806
15807
15808
15809
15810
15811
15812
15813
15814
15815
15816
15817
15818
15819
15820
15821
15822
15823
15824
15825
15826
15827
15828
15829
15830
15831
15832
15833
15834
15835
15836
15837
15838
15839
15840
15841
15842
15843
15844
15845
15846
15847
15848
15849
15850
15851
15852
15853
15854
15855
15856
15857
15858
15859
15860
15861
15862
15863
// Sanity checking
retObj.paramsValid = ((pStartGrpIdx >= 0) && (pStartGrpIdx < msg_area.grp_list.length) &&
(pStartSubIdx >= 0) &&
(pStartSubIdx < msg_area.grp_list[pStartGrpIdx].sub_list.length));
if (!retObj.paramsValid)
return retObj;
var grpIdx = pStartGrpIdx;
var subIdx = pStartSubIdx;
var searchForward = (typeof(pForward) == "boolean" ? pForward : true);
if (searchForward)
{
// Advance the sub-board (and group) index, and determine whether or not
// to do the search (i.e., we might not want to if the starting sub-board
// is the last sub-board in the last group).
var searchForSubBoard = true;
if (subIdx < msg_area.grp_list[grpIdx].sub_list.length - 1)
++subIdx;
else
{
if ((grpIdx < msg_area.grp_list.length - 1) && (msg_area.grp_list[grpIdx+1].sub_list.length > 0))
{
subIdx = 0;
++grpIdx;
}
else
searchForSubBoard = false;
}
// If we can search, then do it.
if (searchForSubBoard)
{
while (numMsgsInSubBoard(msg_area.grp_list[grpIdx].sub_list[subIdx].code) == 0)
{
if (subIdx < msg_area.grp_list[grpIdx].sub_list.length - 1)
++subIdx;
else
{
if ((grpIdx < msg_area.grp_list.length - 1) && (msg_area.grp_list[grpIdx+1].sub_list.length > 0))
{
subIdx = 0;
++grpIdx;
}
else
break; // Stop searching
}
}
}
}
else
{
// Search the sub-boards in reverse
// Decrement the sub-board (and group) index, and determine whether or not
// to do the search (i.e., we might not want to if the starting sub-board
// is the first sub-board in the first group).
var searchForSubBoard = true;
if (subIdx > 0)
--subIdx;
else
{
if ((grpIdx > 0) && (msg_area.grp_list[grpIdx-1].sub_list.length > 0))
{
--grpIdx;
subIdx = msg_area.grp_list[grpIdx].sub_list.length - 1;
}
else
searchForSubBoard = false;
}
// If we can search, then do it.
if (searchForSubBoard)
{
while (numMsgsInSubBoard(msg_area.grp_list[grpIdx].sub_list[subIdx].code) == 0)
{
if (subIdx > 0)
--subIdx;
else
{
if ((grpIdx > 0) && (msg_area.grp_list[grpIdx-1].sub_list.length > 0))
{
--grpIdx;
subIdx = msg_area.grp_list[grpIdx].sub_list.length - 1;
}
else
break; // Stop searching
}
}
}
}
// If we found a sub-board with messages in it, then set the variables
// in the return object
if (numMsgsInSubBoard(msg_area.grp_list[grpIdx].sub_list[subIdx].code) > 0)
{
retObj.grpIdx = grpIdx;
retObj.subIdx = subIdx;
retObj.subCode = msg_area.grp_list[grpIdx].sub_list[subIdx].code;
retObj.foundSubBoard = true;
retObj.subChanged = ((grpIdx != pStartGrpIdx) || (subIdx != pStartSubIdx));
}
return retObj;
}
// Returns the number of messages in a sub-board.
//
// Parameters:
// pSubBoardCode: The internal code of the sub-board to check
// pIncludeDeleted: Optional boolean - Whether or not to include deleted
// messages in the count. Defaults to false.
//
// Return value: The number of messages in the sub-board
function numMsgsInSubBoard(pSubBoardCode, pIncludeDeleted)
{
var numMessages = 0;
var msgbase = new MsgBase(pSubBoardCode);
if (msgbase.open())
{
var includeDeleted = (typeof(pIncludeDeleted) == "boolean" ? pIncludeDeleted : false);
if (includeDeleted)
numMessages = msgbase.total_msgs;
else
{
// Don't include deleted messages. Go through each message
// in the sub-board and count the ones that aren't marked
// as deleted.
for (var msgIdx = 0; msgIdx < msgbase.total_msgs; ++msgIdx)
{
var msgHdr = msgbase.get_msg_header(true, msgIdx, false);
if ((msgHdr != null) && ((msgHdr.attr & MSG_DELETE) == 0))
++numMessages;
}
}
msgbase.close();
}
return numMessages;
}
// Replaces @-codes in a string and returns the new string.
//
// Parameters:
// pStr: A string in which to replace @-codes
//
// Return value: A version of the string with @-codes interpreted
function replaceAtCodesInStr(pStr)
{
if (typeof(pStr) != "string")
return "";
// This code was originally written by Deuce. I updated it to check whether
// the string returned by bbs.atcode() is null, and if so, just return
// the original string.
return pStr.replace(/@([^@]+)@/g, function(m, code) {
var decoded = bbs.atcode(code);
return (decoded != null ? decoded : "@" + code + "@");
});
}
// Shortens a string, accounting for control/attribute codes. Returns a new
// (shortened) copy of the string.
//
// Parameters:
// pStr: The string to shorten
// pNewLength: The new (shorter) length of the string

nightfox
committed
// pFromLeft: Optional boolean - Whether to start from the left (default) or
// from the right. Defaults to true.
//
// Return value: The shortened version of the string

nightfox
committed
function shortenStrWithAttrCodes(pStr, pNewLength, pFromLeft)
{

nightfox
committed
15870
15871
15872
15873
15874
15875
15876
15877
15878
15879
15880
15881
15882
15883
15884
15885
15886
15887
15888
15889
15890
15891
15892
15893
15894
15895
15896
15897
15898
15899
15900
15901
15902
15903
15904
15905
if (typeof(pStr) != "string")
return "";
if (typeof(pNewLength) != "number")
return pStr;
if (pNewLength >= console.strlen(pStr))
return pStr;
var fromLeft = (typeof(pFromLeft) == "boolean" ? pFromLeft : true);
var strCopy = "";
var tmpStr = "";
var strIdx = 0;
var lengthGood = true;
if (fromLeft)
{
while (lengthGood && (strIdx < pStr.length))
{
tmpStr = strCopy + pStr.charAt(strIdx++);
if (console.strlen(tmpStr) <= pNewLength)
strCopy = tmpStr;
else
lengthGood = false;
}
}
else
{
strIdx = pStr.length - 1;
while (lengthGood && (strIdx >= 0))
{
tmpStr = pStr.charAt(strIdx--) + strCopy;
if (console.strlen(tmpStr) <= pNewLength)
strCopy = tmpStr;
else
lengthGood = false;
}
}
return strCopy;
}
// Returns whether a given name matches the logged-in user's handle, alias, or
// name.
//
// Parameters:
// pName: A name to match against the logged-in user
//
// Return value: Boolean - Whether or not the given name matches the logged-in
// user's handle, alias, or name
function userHandleAliasNameMatch(pName)
{
if (typeof(pName) != "string")
return false;
var userMatch = false;
var nameUpper = pName.toUpperCase();
if (user.handle.length > 0)
userMatch = (nameUpper.indexOf(user.handle.toUpperCase()) > -1);
if (!userMatch && (user.alias.length > 0))
userMatch = (nameUpper.indexOf(user.alias.toUpperCase()) > -1);
if (!userMatch && (user.name.length > 0))
userMatch = (nameUpper.indexOf(user.name.toUpperCase()) > -1);
return userMatch;
15930
15931
15932
15933
15934
15935
15936
15937
15938
15939
15940
15941
15942
15943
15944
15945
15946
15947
15948
15949
15950
15951
15952
15953
15954
15955
15956
15957
15958
15959
15960
15961
15962
}
// Displays a range of text lines on the screen and allows scrolling through them
// with the up & down arrow keys, PageUp, PageDown, HOME, and END. It is assumed
// that the array of text lines are already truncated to fit in the width of the
// text area, as a speed optimization.
//
// Parameters:
// pTxtLines: The array of text lines to allow scrolling for
// pTopLineIdx: The index of the text line to display at the top
// pTxtAttrib: The attribute(s) to apply to the text lines
// pWriteTxtLines: Boolean - Whether or not to write the text lines (in addition
// to doing the message loop). If false, this will only do the
// the message loop. This parameter is intended as a screen
// refresh optimization.
// pTopLeftX: The upper-left corner column for the text area
// pTopLeftY: The upper-left corner row for the text area
// pWidth: The width of the text area
// pHeight: The height of the text area
// pPostWriteCurX: The X location for the cursor after writing the message
// lines
// pPostWriteCurY: The Y location for the cursor after writing the message
// lines
// pScrollUpdateFn: A function that the caller can provide for updating the
// scroll position. This function has one parameter:
// - fractionToLastPage: The fraction of the top index divided
// by the top index for the last page (basically, the progress
// to the last page).
//
// Return value: An object with the following properties:
// lastKeypress: The last key pressed by the user (a string)
// topLineIdx: The new top line index of the text lines, in case of scrolling
function scrollTextLines(pTxtLines, pTopLineIdx, pTxtAttrib, pWriteTxtLines, pTopLeftX, pTopLeftY,
pWidth, pHeight, pPostWriteCurX, pPostWriteCurY, pScrollUpdateFn,

Eric Oulashin
committed
pScrollbarInfo)
{
// Variables for the top line index for the last page, scrolling, etc.
var topLineIdxForLastPage = pTxtLines.length - pHeight;
if (topLineIdxForLastPage < 0)
topLineIdxForLastPage = 0;
var msgFractionShown = pHeight / pTxtLines.length;
if (msgFractionShown > 1)
msgFractionShown = 1.0;
var fractionToLastPage = 0;
var lastTxtRow = pTopLeftY + pHeight - 1;
var txtLineFormatStr = "%-" + pWidth + "s";
var retObj = {
lastKeypress: "",

Eric Oulashin
committed
topLineIdx: pTopLineIdx
};
// Create an array of color/attribute codes for each line of
// text, in case there are any such codes in the text lines,
// so that the colors in the message are displayed properly.
// First, get the last color/attribute codes from first text
// line and apply them to the next line, and so on.
var attrCodes = getAttrsBeforeStrIdx(pTxtLines[0], pTxtLines[0].length-1);
for (var lineIdx = 1; lineIdx < pTxtLines.length; ++lineIdx)
{
pTxtLines[lineIdx] = attrCodes + pTxtLines[lineIdx];
attrCodes = getAttrsBeforeStrIdx(pTxtLines[lineIdx], pTxtLines[lineIdx].length-1);
}
var writeTxtLines = pWriteTxtLines;
var continueOn = true;
var mouseInputOnly_continue = false;
while (continueOn)
{
mouseInputOnly_continue = false;