Newer
Older
// and it's not the same message number that was passed in.
if ((msgNumInput > 0) && (msgNumInput-1 != pOffset))
{
// If the message is marked as deleted, then output an error
if (this.MessageIsDeleted(msgNumInput-1))
{
writeWithPause(this.msgAreaLeft, console.screen_rows-1,
"\1n" + this.text.msgHasBeenDeletedText.replace("%d", msgNumInput) + "\1n",
ERROR_PAUSE_WAIT_MS, "\1n", true);
}
else
{
// Confirm with the user whether to read the message
var readMsg = true;
if (this.promptToReadMessage)
{
var sReadMsgConfirmText = this.colors["readMsgConfirmColor"]
+ "Read message "
+ this.colors["readMsgConfirmNumberColor"]
+ msgNumInput + this.colors["readMsgConfirmColor"]
+ ": Are you sure";
console.gotoxy(promptPos);
console.print("\1n");
readMsg = console.yesno(sReadMsgConfirmText);
}
if (readMsg)
{
continueOn = false;
retObj.newMsgOffset = msgNumInput - 1;
retObj.nextAction = ACTION_GO_SPECIFIC_MSG;
}
else
writeMessage = false; // Don't re-write the current message again
}
}
else // Message number invalid or the same as what was passed in
writeMessage = false; // Don't re-write the current message again
// If the user chose to continue reading messages, then refresh
// the last 2 message lines in the last part of the message area
// and then put the cursor back to its original position.
if (continueOn)
{
this.DisplayEnhReaderError("", msgInfo.messageLines, topMsgLineIdx, msgLineFormatStr);
// Move the cursor back to its original position
console.gotoxy(originalCurpos);
}
break;
case this.enhReaderKeys.prevMsgByTitle: // Previous message by title
case this.enhReaderKeys.prevMsgByAuthor: // Previous message by author
case this.enhReaderKeys.prevMsgByToUser: // Previous message by 'to user'
case this.enhReaderKeys.prevMsgByThreadID: // Previous message by thread ID
// Only allow this if we aren't doing a message search.
if (!this.SearchingAndResultObjsDefinedForCurSub())
{
var threadPrevMsgOffset = this.FindThreadPrevOffset(msgHeader,
keypressToThreadType(retObj.lastKeypress, this.enhReaderKeys),
true);
if (threadPrevMsgOffset > -1)
{
retObj.newMsgOffset = threadPrevMsgOffset;
retObj.nextAction = ACTION_GO_SPECIFIC_MSG;
continueOn = false;
}
else
{
// Refresh the help line at the bottom of the screen
//this.DisplayEnhancedMsgReadHelpLine(console.screen_rows, allowChgMsgArea);
writeMessage = false; // Don't re-write the current message again
}
// Make sure the help line on the bottom of the screen is
// drawn.
this.DisplayEnhancedMsgReadHelpLine(console.screen_rows, allowChgMsgArea);
}
else
writeMessage = false; // Don't re-write the current message again
break;
case this.enhReaderKeys.nextMsgByTitle: // Next message by title (subject)
case this.enhReaderKeys.nextMsgByAuthor: // Next message by author
case this.enhReaderKeys.nextMsgByToUser: // Next message by 'to user'
case this.enhReaderKeys.nextMsgByThreadID: // Next message by thread ID
// Only allow this if we aren't doing a message search.
if (!this.SearchingAndResultObjsDefinedForCurSub())
{
var threadPrevMsgOffset = this.FindThreadNextOffset(msgHeader,
keypressToThreadType(retObj.lastKeypress, this.enhReaderKeys),
true);
if (threadPrevMsgOffset > -1)
{
retObj.newMsgOffset = threadPrevMsgOffset;
retObj.nextAction = ACTION_GO_SPECIFIC_MSG;
continueOn = false;
}
else
writeMessage = false; // Don't re-write the current message again
// Make sure the help line on the bottom of the screen is
// drawn.
this.DisplayEnhancedMsgReadHelpLine(console.screen_rows, allowChgMsgArea);
}
else
writeMessage = false; // Don't re-write the current message again
break;

nightfox
committed
case this.enhReaderKeys.previousMsg: // Previous message
// Look for a prior message that isn't marked for deletion. Even
// if we don't find one, we'll still want to return from this
// function (with message index -1) so that this script can go
// onto the previous message sub-board/group.
retObj.newMsgOffset = this.FindNextNonDeletedMsgIdx(pOffset, false);
// As a screen redraw optimization: Only return if there is a valid new
// message offset or the user is allowed to change to a different sub-board.
// Otherwise, don't return, and don't refresh the message on the screen.
var goToPrevMessage = false;
if ((retObj.newMsgOffset > -1) || allowChgMsgArea)
{
if (retObj.newMsgOffset == -1 && !curMsgSubBoardIsLast())
{
goToPrevMessage = this.EnhReaderPromptYesNo(this.text.goToPrevMsgAreaPromptText,
msgInfo.messageLines, topMsgLineIdx,
msgLineFormatStr, solidBlockStartRow,
numSolidScrollBlocks);
}
else
{
// We're not at the beginning of the sub-board, so it's okay to exit this
// method and go to the previous message.
goToPrevMessage = true;
}
}
if (goToPrevMessage)
{
continueOn = false;
retObj.nextAction = ACTION_GO_PREVIOUS_MSG;
}
else
writeMessage = false; // No need to refresh the message
break;

nightfox
committed
case this.enhReaderKeys.nextMsg: // Next message
case KEY_ENTER:
// Look for a later message that isn't marked for deletion. Even
// if we don't find one, we'll still want to return from this
// function (with message index -1) so that this script can go
// onto the next message sub-board/group.
retObj.newMsgOffset = this.FindNextNonDeletedMsgIdx(pOffset, true);
// Note: Unlike the left arrow key, we want to exit this method when
// navigating to the next message, regardless of whether or not the
// user is allowed to change to a different sub-board, so that processes
// that require continuation (such as new message scan) can continue.
// Still, if there are no more readable messages in the current sub-board
// (and thus the user would go onto the next message area), prompt the
// user whether they want to continue onto the next message area.
if (retObj.newMsgOffset == -1 && !curMsgSubBoardIsLast())
{
// For personal mail, don't do anything, and don't refresh the
// message. In a sub-board, ask the user if they want to go
// to the next one.
if (this.readingPersonalEmail)
writeMessage = false;
else
{
// If configured to allow the user to post in the sub-board
// instead of going to the next message area and we're not
// scanning, then do so.
if (this.readingPostOnSubBoardInsteadOfGoToNext && !this.doingMsgScan)
{
console.print("\1n");
console.crlf();
// Ask the user if they want to post on the sub-board.
// If they say yes, then do so before exiting.
if (!console.noyes(format(this.text.postOnSubBoard, this.msgbase.cfg.grp_name, this.msgbase.cfg.description)))
bbs.post_msg(this.subBoardCode);
continueOn = false;
retObj.nextAction = ACTION_QUIT;
}
else
{
// Prompt the user whether they want to go to the next message area
if (this.EnhReaderPromptYesNo(this.text.goToNextMsgAreaPromptText, msgInfo.messageLines, topMsgLineIdx, msgLineFormatStr, solidBlockStartRow, numSolidScrollBlocks))
{
// Let this method exit and let the caller go to the next sub-board
continueOn = false;
retObj.nextAction = ACTION_GO_NEXT_MSG;
}
else
writeMessage = false; // No need to refresh the message
}
}
}
else
{
// We're not at the end of the sub-board, so it's okay to exit this
// method and go to the next message.
continueOn = false;
retObj.nextAction = ACTION_GO_NEXT_MSG;
}
break;
// First & last message: Quit out of this input loop and let the
// calling function, this.ReadMessages(), handle the action.

nightfox
committed
case this.enhReaderKeys.firstMsg: // First message
// Only leave this function if we aren't already on the first message.
if (pOffset > 0)
{
continueOn = false;
retObj.nextAction = ACTION_GO_FIRST_MSG;
}
else
writeMessage = false; // Don't re-write the current message again
break;

nightfox
committed
case this.enhReaderKeys.lastMsg: // Last message
// Only leave this function if we aren't already on the last message.
if (pOffset < this.NumMessages() - 1)
{
continueOn = false;
retObj.nextAction = ACTION_GO_LAST_MSG;
}
else
writeMessage = false; // Don't re-write the current message again
break;
case this.enhReaderKeys.prevSubBoard: // Go to the previous message area
if (allowChgMsgArea)
{
continueOn = false;
retObj.nextAction = ACTION_GO_PREV_MSG_AREA;
}
else
writeMessage = false; // Don't re-write the current message again
break;
case this.enhReaderKeys.nextSubBoard: // Go to the next message area
if (allowChgMsgArea || this.doingMultiSubBoardScan)
{
continueOn = false;
retObj.nextAction = ACTION_GO_NEXT_MSG_AREA;
}
else
writeMessage = false; // Don't re-write the current message again
break;
// H and K: Display the extended message header info/kludge lines
// (for the sysop)

nightfox
committed
case this.enhReaderKeys.showHdrInfo:
case this.enhReaderKeys.showKludgeLines:
if (gIsSysop)
{
// Save the original cursor position
var originalCurPos = console.getxy();
// Get an array of the extended header info/kludge lines and then
// allow the user to scroll through them.

nightfox
committed
var extdHdrInfoLines = this.GetExtdMsgHdrInfo(msgHeader, (retObj.lastKeypress == this.enhReaderKeys.showKludgeLines));
if (extdHdrInfoLines.length > 0)
{
// Calculate information for the scrollbar for the kludge lines
var infoFractionShown = this.msgAreaHeight / extdHdrInfoLines.length;
if (infoFractionShown > 1)
infoFractionShown = 1.0;
var numInfoSolidScrollBlocks = Math.floor(this.msgAreaHeight * infoFractionShown);
if (numInfoSolidScrollBlocks == 0)
numInfoSolidScrollBlocks = 1;
var numNonSolidInfoScrollBlocks = this.msgAreaHeight - numInfoSolidScrollBlocks;
var lastInfoSolidBlockStartRow = this.msgAreaTop;
// Define a scrollbar update function for the header info/kludge lines
function msgInfoScrollbarUpdateFn(pFractionToLastPage)
{
var infoSolidBlockStartRow = msgReaderObj.msgAreaTop + Math.floor(numNonSolidInfoScrollBlocks * pFractionToLastPage);
if (infoSolidBlockStartRow != lastInfoSolidBlockStartRow)
msgReaderObj.UpdateEnhancedReaderScollbar(infoSolidBlockStartRow, lastInfoSolidBlockStartRow, numInfoSolidScrollBlocks);
lastInfoSolidBlockStartRow = infoSolidBlockStartRow;
console.gotoxy(1, console.screen_rows);
}
// Display the kludge lines and let the user scroll through them
this.DisplayEnhancedReaderWholeScrollbar(this.msgAreaTop, numInfoSolidScrollBlocks);
scrollTextLines(extdHdrInfoLines, 0, this.colors["msgBodyColor"], true,
this.msgAreaLeft, this.msgAreaTop, this.msgAreaWidth,
msgAreaHeight, 1, console.screen_rows,
msgInfoScrollbarUpdateFn);
// Display the scrollbar for the message to refresh it on the screen
solidBlockStartRow = this.msgAreaTop + Math.floor(numNonSolidScrollBlocks * fractionToLastPage);
this.DisplayEnhancedReaderWholeScrollbar(solidBlockStartRow, numSolidScrollBlocks);
writeMessage = true; // We want to refresh the message on the screen
}
else
{
// There are no kludge lines for this message
this.DisplayEnhReaderError(this.text.noKludgeLinesForThisMsgText, msgInfo.messageLines, topMsgLineIdx, msgLineFormatStr);
console.gotoxy(originalCurPos);
writeMessage = false;
}
}
else // The user is not a sysop
writeMessage = false;
break;
// Message list, change message area: Quit out of this input loop
// and let the calling function, this.ReadMessages(), handle the
// action.

nightfox
committed
case this.enhReaderKeys.showMsgList: // Message list
retObj.nextAction = ACTION_DISPLAY_MSG_LIST;
continueOn = false;
break;

nightfox
committed
case this.enhReaderKeys.chgMsgArea: // Change message area, if allowed
if (allowChgMsgArea)
{
retObj.nextAction = ACTION_CHG_MSG_AREA;
continueOn = false;
}
else
writeMessage = false; // No need to refresh the message
break;
case this.enhReaderKeys.downloadAttachments: // Download attachments
5307
5308
5309
5310
5311
5312
5313
5314
5315
5316
5317
5318
5319
5320
5321
5322
5323
5324
5325
5326
5327
5328
if (msgInfo.attachments.length > 0)
{
console.print("\1n");
console.gotoxy(1, console.screen_rows);
console.crlf();
console.print("\1c- Download Attached Files -\1n");
// Note: sendAttachedFiles() will output a CRLF at the beginning.
sendAttachedFiles(msgInfo.attachments);
// Refresh things on the screen
console.clear("\1n");
// Display the message header and key help line again
this.DisplayEnhancedMsgHdr(msgHeader, pOffset+1, 1);
this.DisplayEnhancedMsgReadHelpLine(console.screen_rows, allowChgMsgArea);
// Display the scrollbar again to refresh it on the screen
solidBlockStartRow = this.msgAreaTop + Math.floor(numNonSolidScrollBlocks * fractionToLastPage);
this.DisplayEnhancedReaderWholeScrollbar(solidBlockStartRow, numSolidScrollBlocks);
writeMessage = true; // We want to refresh the message on the screen
}
else
writeMessage = false;
break;
case this.enhReaderKeys.saveToBBSMachine:
// Save the message to the BBS machine - Only allow this
// if the user is a sysop.
if (gIsSysop)
{
// Prompt the user for a filename to save the message to the
// BBS machine
var promptPos = this.EnhReaderPrepLast2LinesForPrompt();
console.print("\1n\1cFilename:\1h");
var inputLen = console.screen_columns - 10; // 10 = "Filename:" length + 1
var filename = console.getstr(inputLen, K_NOCRLF);
console.print("\1n");
if (filename.length > 0)
{
//var saveMsgRetObj = this.SaveMsgToFile(msgHeader, filename, true, msgInfo.messageLines);
var saveMsgRetObj = this.SaveMsgToFile(msgHeader, filename, true);
console.gotoxy(promptPos);
console.cleartoeol("\1n");
console.gotoxy(promptPos);
if (saveMsgRetObj.succeeded)
console.print("\1n\1cThe message has been saved.\1n");
else
console.print("\1n\1y\1hFailed: " + saveMsgRetObj.errorMsg + "\1n");
mswait(ERROR_PAUSE_WAIT_MS);
}
else
{
console.gotoxy(promptPos);
console.print("\1n\1y\1hMessage not exported\1n");
mswait(ERROR_PAUSE_WAIT_MS);
}
// Refresh the last 2 lines of the message on the screen to overwrite
// the file save prompt
this.DisplayEnhReaderError("", msgInfo.messageLines, topMsgLineIdx, msgLineFormatStr);
writeMessage = false; // Don't write the whole message again
}
else
writeMessage = false;
break;

nightfox
committed
case this.enhReaderKeys.userEdit: // Edit the user who wrote the message
if (gIsSysop)
{
console.print("\1n");
console.crlf();
console.print("- Edit user " + msgHeader.from);
console.crlf();
var editObj = editUser(msgHeader.from);
if (editObj.errorMsg.length != 0)
{
console.print("\1n");
console.crlf();
console.print("\1y\1h" + editObj.errorMsg + "\1n");
console.crlf();
console.pause();
}
// Refresh things on the screen
console.clear("\1n");
// Display the message header and key help line again
this.DisplayEnhancedMsgHdr(msgHeader, pOffset+1, 1);
this.DisplayEnhancedMsgReadHelpLine(console.screen_rows, allowChgMsgArea);
// Display the scrollbar again to refresh it on the screen
solidBlockStartRow = this.msgAreaTop + Math.floor(numNonSolidScrollBlocks * fractionToLastPage);
this.DisplayEnhancedReaderWholeScrollbar(solidBlockStartRow, numSolidScrollBlocks);
writeMessage = true; // We want to refresh the message on the screen
}
else // The user is not a sysop
writeMessage = false;
break;

nightfox
committed
5398
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408
5409
5410
5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
5421
case this.enhReaderKeys.forwardMsg: // Forward the message
console.print("\1n");
console.crlf();
console.print("\1c- Forward message\1n");
console.crlf();
var retStr = this.ForwardMessage(msgHeader, messageText);
if (retStr.length > 0)
{
console.print("\1n\1h\1y* " + retStr + "\1n");
console.crlf();
console.pause();
}
// Refresh things on the screen
console.clear("\1n");
// Display the message header and key help line again
this.DisplayEnhancedMsgHdr(msgHeader, pOffset+1, 1);
this.DisplayEnhancedMsgReadHelpLine(console.screen_rows, allowChgMsgArea);
// Display the scrollbar again to refresh it on the screen
solidBlockStartRow = this.msgAreaTop + Math.floor(numNonSolidScrollBlocks * fractionToLastPage);
this.DisplayEnhancedReaderWholeScrollbar(solidBlockStartRow, numSolidScrollBlocks);
writeMessage = true; // We want to refresh the message on the screen
break;
case this.enhReaderKeys.quit: // Quit
retObj.nextAction = ACTION_QUIT;
continueOn = false;
break;
default:
writeMessage = false;
break;
}
}
return retObj;
}
// Helper method for ReadMessageEnhanced() - Does the traditional (non-scrollable) reader interface
function DigDistMsgReader_ReadMessageEnhanced_Traditional(msgHeader, allowChgMsgArea, messageText, msgHasANSICodes, pOffset)
{
var retObj = new Object();
retObj.offsetValid = true;

nightfox
committed
retObj.msgNotReadable = false;
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448
5449
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
retObj.userReplied = false;
retObj.lastKeypress = "";
retObj.newMsgOffset = -1;
retObj.nextAction = ACTION_NONE;
retObj.refreshEnhancedRdrHelpLine = false;
// Separate the message text from any attachments in the message.
var msgAndAttachmentInfo = determineMsgAttachments(msgHeader, messageText, true);
// Only interpret @-codes if the user is reading personal email. There
// are many @-codes that do some action such as move the cursor, execute a
// script, etc., and I don't want users on message networks to do anything
// malicious to users on other BBSes.
if (this.readingPersonalEmail)
msgAndAttachmentInfo.msgText = replaceAtCodesInStr(msgAndAttachmentInfo.msgText); // Or this.ParseMsgAtCodes(msgAndAttachmentInfo.msgText, msgHeader) to replace only some @ codes
var msgTextWrapped = word_wrap(msgAndAttachmentInfo.msgText, console.screen_columns-1);
// Generate the key help text
var keyHelpText = "\1n\1c\1h#\1n\1b, \1c\1hLeft\1n\1b, \1c\1hRight\1n\1b, ";
if (this.CanDelete() || this.CanDeleteLastMsg())
keyHelpText += "\1c\1hDEL\1b, ";
if (this.CanEdit())
keyHelpText += "\1c\1hE\1y)\1n\1cdit\1b, ";
keyHelpText += "\1c\1hF\1y)\1n\1cirst\1b, \1c\1hL\1y)\1n\1cast\1b, \1c\1hR\1y)\1n\1ceply\1b, ";
// If the user is allowed to change to a different message area, then
// include that option.
if (allowChgMsgArea)
{
// If there's room for the private reply option, then include that
// before the change area option.
if (console.screen_columns >= 89)
keyHelpText += "\1c\1hP\1y)\1n\1crivate reply\1b, ";
keyHelpText += "\1c\1hC\1y)\1n\1chg area\1b, ";
}
else
{
// The user isn't allowed to change to a different message area.
// Go ahead and include the private reply option.
keyHelpText += "\1c\1hP\1y)\1n\1crivate reply\1b, ";
}
keyHelpText += "\1c\1hQ\1y)\1n\1cuit\1b, \1c\1h?\1g: \1c";
// User input loop
var writeMessage = true;
var writePromptText = true;
var continueOn = true;
while (continueOn)
{
if (writeMessage)
{
if (console.term_supports(USER_ANSI))
console.clear("\1n");
// Write the message header & message body to the screen
this.DisplayEnhancedMsgHdr(msgHeader, pOffset+1, 1);
console.print("\1n" + this.colors["msgBodyColor"]);
console.putmsg(msgTextWrapped, P_NOATCODES);
}
// Write the prompt text
if (writePromptText)
console.print(keyHelpText);
// Default the writing of the message & input prompt to true for the
// next iteration.
writeMessage = true;
writePromptText = true;
// Input a key from the user and take action based on the keypress.
//retObj.lastKeypress = getKeyWithESCChars(K_UPPER|K_NOCRLF|K_NOECHO|K_NOSPIN);
retObj.lastKeypress = getKeyWithESCChars(K_UPPER);
switch (retObj.lastKeypress)
{
case this.enhReaderKeys.deleteMessage: // Delete message
5508
5509
5510
5511
5512
5513
5514
5515
5516
5517
5518
5519
5520
5521
5522
5523
5524
5525
5526
5527
5528
5529
5530
5531
5532
5533
5534
5535
5536
5537
5538
console.crlf();
// Prompt the user for confirmation to delete the message.
// Note: this.PromptAndDeleteMessage() will check to see if the user
// is a sysop or the message was posted by the user.
// If the message was deleted, then exit this read method
// and return KEY_RIGHT as the last keypress so that the
// calling method will go to the next message/sub-board.
// Otherwise (if the message was not deleted), refresh the
// last 2 lines of the message on the screen.
// TODO: For the DeleteMessage() call, pass the array of file
// attachments for it to delete (i.e., msgInfo.attachments)
var msgWasDeleted = this.PromptAndDeleteMessage(pOffset);
if (msgWasDeleted)
{
var msgSearchObj = this.LookForNextOrPriorNonDeletedMsg(pOffset);
continueOn = msgSearchObj.continueInputLoop;
retObj.newMsgOffset = msgSearchObj.newMsgOffset;
retObj.nextAction = msgSearchObj.nextAction;
if (msgSearchObj.promptGoToNextArea)
{
if (console.yesno(this.text.goToNextMsgAreaPromptText))
{
// Let this method exit and let the caller go to the next sub-board
continueOn = false;
retObj.nextAction = ACTION_GO_NEXT_MSG;
}
else
writeMessage = false; // No need to refresh the message
}
}
break;
case this.enhReaderKeys.selectMessage: // Select message (for batch delete, etc.)
console.crlf();
var selectMessage = !console.noyes("Select this message");
this.ToggleSelectedMessage(this.subBoardCode, pOffset, selectMessage);
break;
case this.enhReaderKeys.batchDelete:
// TODO: Write this? Not sure yet if it makes much sense to
// have batch delete in the reader interface.
// Prompt the user for confirmation, and use
// this.DeleteSelectedMessages() to mark the selected messages
// as deleted.
// Returns an object with the following properties:
// deletedAll: Boolean - Whether or not all messages were successfully marked
// for deletion
// failureList: An object containing indexes of messages that failed to get
// marked for deletion, indexed by internal sub-board code, then
// containing messages indexes as properties. Reasons for failing
// to mark messages deleted can include the user not having permission
// to delete in a sub-board, failure to open the sub-board, etc.
writeMessage = false; // No need to refresh the message
break;

nightfox
committed
case this.enhReaderKeys.editMsg: // Edit the message
if (this.CanEdit())
{
console.crlf();
5564
5565
5566
5567
5568
5569
5570
5571
5572
5573
5574
5575
5576
5577
5578
5579
5580
5581
5582
5583
5584
5585
5586
5587
5588
// Let the user edit the message if they want to
var editReturnObj = this.EditExistingMsg(pOffset);
// If the user confirmed editing the message, then see if the
// message was edited and refresh the screen accordingly.
if (editReturnObj.userConfirmed)
{
// If the message was edited, then refresh the text lines
// array and update the other message-related variables.
if (editReturnObj.msgEdited && (editReturnObj.newMsgIdx > -1))
{
// When the message is edited, the old message will be
// deleted and the edited message will be posted as a new
// message. So we should return to the caller and have it
// go directly to that new message.
continueOn = false;
retObj.newMsgOffset = editReturnObj.newMsgIdx;
}
}
}
else
{
writeMessage = false;
writePromptText = false;
}
break;

nightfox
committed
case this.enhReaderKeys.showHelp: // Show help
if (!console.term_supports(USER_ANSI))
{
console.crlf();
console.crlf();
}
this.DisplayEnhancedReaderHelp(allowChgMsgArea, msgAndAttachmentInfo.attachments.length > 0);
if (!console.term_supports(USER_ANSI))
{
console.crlf();
console.crlf();
}
break;
case this.enhReaderKeys.reply: // Reply to the message
case this.enhReaderKeys.privateReply: // Private reply
// If the user pressed the private reply key while reading private
// mail, then do nothing (allow only the regular reply key to reply).
// If not reading personal email, go ahead and let the user reply
// with either the reply or private reply keypress.
var privateReply = (retObj.lastKeypress == this.enhReaderKeys.privateReply);
if (privateReply && this.readingPersonalEmail)
{
writeMessage = false; // Don't re-write the current message again
writePromptText = false; // Don't write the prompt text again
}
else
{
console.crlf();
// Get the message header with fields expanded so we can get the most info possible.
//var extdMsgHdr = this.GetMsgHdrByAbsoluteNum(msgHeader.number, true);
var extdMsgHdr = this.msgbase.get_msg_header(false, msgHeader.number, true);
// Let the user reply to the message
var replyRetObj = this.ReplyToMsg(extdMsgHdr, msgAndAttachmentInfo.msgText, privateReply, pOffset);
retObj.userReplied = replyRetObj.postSucceeded;

nightfox
committed
//retObj.msgNotReadable = replyRetObj.msgWasDeleted;
var msgWasDeleted = replyRetObj.msgWasDeleted;
if (msgWasDeleted)
{
var msgSearchObj = this.LookForNextOrPriorNonDeletedMsg(pOffset);
continueOn = msgSearchObj.continueInputLoop;
retObj.newMsgOffset = msgSearchObj.newMsgOffset;
retObj.nextAction = msgSearchObj.nextAction;
if (msgSearchObj.promptGoToNextArea)
{
if (console.yesno(this.text.goToNextMsgAreaPromptText))
{
// Let this method exit and let the caller go to the next sub-board
continueOn = false;
retObj.nextAction = ACTION_GO_NEXT_MSG;
}
else
writeMessage = true; // We want to refresh the message on the screen
}
}
else
{
// If the messagebase object was not successfully re-opened
// after posting the message, then we'll want to quit.
if (!replyRetObj.msgbaseReOpened)
{
retObj.nextAction = ACTION_QUIT;
continueOn = false;
// Display an error
console.print("\1n");
console.crlf();
console.print("\1h\1yMessagebase error after replying. Aborting.\1n");
mswait(ERROR_PAUSE_WAIT_MS);
}
}
}
break;

nightfox
committed
case this.enhReaderKeys.postMsg: // Post a message
if (!this.readingPersonalEmail)
{
// Let the user post a message.
if (bbs.post_msg(this.subBoardCode))
{
// TODO: If the user is doing a search, it might be
// useful to search their new message and add it to
// the search results if it's a match.. but maybe
// not?
}
5671
5672
5673
5674
5675
5676
5677
5678
5679
5680
5681
5682
5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
5693
5694
5695
5696
5697
5698
5699
5700
5701
5702
5703
5704
5705
5706
5707
console.pause();
// We'll want to refresh the message & prompt text on the screen
writeMessage = true;
writePromptText = true;
}
else
{
// Don't write the current message or prompt text in the next iteration
writeMessage = false;
writePromptText = false;
}
break;
// Numeric digit: The start of a number of a message to read
case "0":
case "1":
case "2":
case "3":
case "4":
case "5":
case "6":
case "7":
case "8":
case "9":
console.crlf();
// Put the user's input back in the input buffer to
// be used for getting the rest of the message number.
console.ungetstr(retObj.lastKeypress);
// Prompt for the message number
var msgNumInput = this.PromptForMsgNum(null, this.text.readMsgNumPromptText, false, ERROR_PAUSE_WAIT_MS, false);
// Only allow reading the message if the message number is valid
// and it's not the same message number that was passed in.
if ((msgNumInput > 0) && (msgNumInput-1 != pOffset))
{
// If the message is marked as deleted, then output an error
if (this.MessageIsDeleted(msgNumInput-1))
{
console.crlf();
console.print("\1n" + this.text.msgHasBeenDeletedText.replace("%d", msgNumInput) + "\1n");
console.crlf();
console.pause();
}
else
{
// Confirm with the user whether to read the message
var readMsg = true;
if (this.promptToReadMessage)
{
readMsg = console.yesno("\1n" + this.colors["readMsgConfirmColor"]
+ "Read message "
+ this.colors["readMsgConfirmNumberColor"]
+ msgNumInput + this.colors["readMsgConfirmColor"]
+ ": Are you sure");
}
if (readMsg)
{
continueOn = false;
retObj.newMsgOffset = msgNumInput - 1;
retObj.nextAction = ACTION_GO_SPECIFIC_MSG;
}
}
}
break;
case this.enhReaderKeys.prevMsgByTitle: // Previous message by title
case this.enhReaderKeys.prevMsgByAuthor: // Previous message by author
case this.enhReaderKeys.prevMsgByToUser: // Previous message by 'to user'
case this.enhReaderKeys.prevMsgByThreadID: // Previous message by thread ID
// Only allow this if we aren't doing a message search.
if (!this.SearchingAndResultObjsDefinedForCurSub())
{
console.crlf(); // For the "Searching..." text
var threadPrevMsgOffset = this.FindThreadPrevOffset(msgHeader,
keypressToThreadType(retObj.lastKeypress, this.enhReaderKeys),
false);
if (threadPrevMsgOffset > -1)
{
retObj.newMsgOffset = threadPrevMsgOffset;
retObj.nextAction = ACTION_GO_SPECIFIC_MSG;
continueOn = false;
}
}
else
{
writeMessage = false;
writePromptText = false;
}
break;
case this.enhReaderKeys.nextMsgByTitle: // Next message by title (subject)
case this.enhReaderKeys.nextMsgByAuthor: // Next message by author
case this.enhReaderKeys.nextMsgByToUser: // Next message by 'to user'
case this.enhReaderKeys.nextMsgByThreadID: // Next message by thread ID
// Only allow this if we aren't doing a message search.
if (!this.SearchingAndResultObjsDefinedForCurSub())
{
console.crlf(); // For the "Searching..." text
var threadNextMsgOffset = this.FindThreadNextOffset(msgHeader,
keypressToThreadType(retObj.lastKeypress, this.enhReaderKeys),
false);
if (threadNextMsgOffset > -1)
{
retObj.newMsgOffset = threadNextMsgOffset;
retObj.nextAction = ACTION_GO_SPECIFIC_MSG;
continueOn = false;
}
}
else
{
writeMessage = false;
writePromptText = false;
}
break;

nightfox
committed
case this.enhReaderKeys.previousMsg: // Previous message
// TODO: Change the key for this?
// Look for a prior message that isn't marked for deletion. Even
// if we don't find one, we'll still want to return from this
// function (with message index -1) so that this script can go
// onto the previous message sub-board/group.
retObj.newMsgOffset = this.FindNextNonDeletedMsgIdx(pOffset, false);
var goToPrevMessage = false;
if ((retObj.newMsgOffset > -1) || allowChgMsgArea)
{
if (retObj.newMsgOffset == -1 && !curMsgSubBoardIsLast())
{
console.crlf();
goToPrevMessage = console.yesno(this.text.goToPrevMsgAreaPromptText);
}
else
{
// We're not at the beginning of the sub-board, so it's okay to exit this
// method and go to the previous message.
goToPrevMessage = true;
}
}
if (goToPrevMessage)
{
continueOn = false;
retObj.nextAction = ACTION_GO_PREVIOUS_MSG;
}
break;

nightfox
committed
case this.enhReaderKeys.nextMsg: // Next message
5812
5813
5814
5815
5816
5817
5818
5819
5820
5821
5822
5823
5824
5825
5826
5827
5828
5829
5830
5831
5832
case KEY_ENTER:
// Look for a later message that isn't marked for deletion. Even
// if we don't find one, we'll still want to return from this
// function (with message index -1) so that this script can go
// onto the next message sub-board/group.
retObj.newMsgOffset = this.FindNextNonDeletedMsgIdx(pOffset, true);
// Note: Unlike the left arrow key, we want to exit this method when
// navigating to the next message, regardless of whether or not the
// user is allowed to change to a different sub-board, so that processes
// that require continuation (such as new message scan) can continue.
// Still, if there are no more readable messages in the current sub-board
// (and thus the user would go onto the next message area), prompt the
// user whether they want to continue onto the next message area.
if (retObj.newMsgOffset == -1 && !curMsgSubBoardIsLast())
{
console.print("\1n");
console.crlf();
// If configured to allow the user to post in the sub-board
// instead of going to the next message area and we're not
// scanning, then do so.
if (this.readingPostOnSubBoardInsteadOfGoToNext && !this.doingMsgScan)
{
// Ask the user if they want to post on the sub-board.
// If they say yes, then do so before exiting.
if (!console.noyes(format(this.text.postOnSubBoard, this.msgbase.cfg.grp_name, this.msgbase.cfg.description)))
bbs.post_msg(this.subBoardCode);
continueOn = false;
retObj.nextAction = ACTION_QUIT;
}
else
{
if (console.yesno(this.text.goToNextMsgAreaPromptText))
{
// Let this method exit and let the caller go to the next sub-board
continueOn = false;
retObj.nextAction = ACTION_GO_NEXT_MSG;
}
}
}
else
{
// We're not at the end of the sub-board, so it's okay to exit this
// method and go to the next message.
continueOn = false;
retObj.nextAction = ACTION_GO_NEXT_MSG;
}
break;

nightfox
committed
case this.enhReaderKeys.firstMsg: // First message
// Only leave this function if we aren't already on the first message.
if (pOffset > 0)
{
continueOn = false;
retObj.nextAction = ACTION_GO_FIRST_MSG;
}
else
{
writeMessage = false;
writePromptText = false;
}
break;

nightfox
committed
case this.enhReaderKeys.lastMsg: // Last message
5873
5874
5875
5876
5877
5878
5879
5880
5881
5882
5883
5884
5885
5886
5887
5888
5889
5890
5891
5892
5893
5894
5895
5896
5897
5898
5899
5900
5901
5902
5903
5904
5905
5906
5907
5908
// Only leave this function if we aren't already on the last message.
if (pOffset < this.NumMessages() - 1)
{
continueOn = false;
retObj.nextAction = ACTION_GO_LAST_MSG;
}
else
{
writeMessage = false;
writePromptText = false;
}
break;
case "-": // Go to the previous message area
if (allowChgMsgArea)
{
continueOn = false;
retObj.nextAction = ACTION_GO_PREV_MSG_AREA;
}
else
{
writeMessage = false;
writePromptText = false;
}
break;
case "+": // Go to the next message area
if (allowChgMsgArea || this.doingMultiSubBoardScan)
{
continueOn = false;
retObj.nextAction = ACTION_GO_NEXT_MSG_AREA;
}
else
{
writeMessage = false;
writePromptText = false;
}
break;

nightfox
committed
// H and K: Display the extended message header info/kludge lines
// (for the sysop)
case this.enhReaderKeys.showHdrInfo:
case this.enhReaderKeys.showKludgeLines:
if (gIsSysop)
{
console.crlf();
// Get an array of the extended header info/kludge lines and then
// display them.

nightfox
committed
var extdHdrInfoLines = this.GetExtdMsgHdrInfo(msgHeader, (retObj.lastKeypress == this.enhReaderKeys.showKludgeLines));
if (extdHdrInfoLines.length > 0)
{
console.crlf();
for (var infoIter = 0; infoIter < extdHdrInfoLines.length; ++infoIter)
{
console.print(extdHdrInfoLines[infoIter]);
console.crlf();
}
console.pause();
}
else
{
// There are no kludge lines for this message
console.print(this.text.noKludgeLinesForThisMsgText);
console.crlf();
console.pause();
}
}
else // The user is not a sysop
{
writeMessage = false;
writePromptText = false;
}
break;
// Message list, change message area: Quit out of this input loop
// and let the calling function, this.ReadMessages(), handle the
// action.

nightfox
committed
case this.enhReaderKeys.showMsgList: // Message list
retObj.nextAction = ACTION_DISPLAY_MSG_LIST;
continueOn = false;
break;

nightfox
committed
case this.enhReaderKeys.chgMsgArea: // Change message area, if allowed
if (allowChgMsgArea)
{
retObj.nextAction = ACTION_CHG_MSG_AREA;
continueOn = false;
}
else
{
writeMessage = false;
writePromptText = false;
}
break;
case this.enhReaderKeys.downloadAttachments: // Download attachments
if (msgAndAttachmentInfo.attachments.length > 0)
{
console.print("\1n");
console.crlf();
console.print("\1c- Download Attached Files -\1n");
// Note: sendAttachedFiles() will output a CRLF at the beginning.
sendAttachedFiles(msgAndAttachmentInfo.attachments);
// Ensure the message is refreshed on the screen
writeMessage = true;
writePromptText = true;
}
else
{
writeMessage = false;
writePromptText = false;
}
break;
case this.enhReaderKeys.saveToBBSMachine:
// Save the message to the BBS machine - Only allow this
// if the user is a sysop.
if (gIsSysop)
{
console.crlf();
console.print("\1n\1cFilename:\1h");
var inputLen = console.screen_columns - 10; // 10 = "Filename:" length + 1
var filename = console.getstr(inputLen, K_NOCRLF);
console.print("\1n");
console.crlf();
if (filename.length > 0)
{
var saveMsgRetObj = this.SaveMsgToFile(msgHeader, filename, true);
if (saveMsgRetObj.succeeded)
console.print("\1n\1cThe message has been saved.\1n");
else
console.print("\1n\1y\1hFailed: " + saveMsgRetObj.errorMsg + "\1n");
mswait(ERROR_PAUSE_WAIT_MS);