Newer
Older
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
console.print("\1n");
console.crlf();
console.print("Loading...");
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
5034
5035
5036
5037
5038
5039
5040
5041
5042
5043
5044
5045
5046
5047
5048
5049
5050
5051
5052
5053
5054
5055
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
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
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.vote: // Vote on the message
// Move the cursor to the last line in the message area so the
// vote question text prompt will appear there.
var promptPos = this.EnhReaderPrepLast2LinesForPrompt();
console.gotoxy(1, console.screen_rows-1);
// Let the user vote on the message
var voteRetObj = this.VoteOnMessage(msgHeader, true);
if (voteRetObj.BBSHasVoteFunction)
{
var msgIsPollVote = ((typeof(MSG_TYPE_POLL) != "undefined") && (msgHeader.type & MSG_TYPE_POLL) == MSG_TYPE_POLL);
if (!voteRetObj.userQuit)
{
// If the message is a poll vote, then output any error
// message on its own line and refresh the whole screen.
// Otherwise, use the last 2 rows for an error message
// and only refresh what's necessary.
if (msgIsPollVote)
console.print("\1n");
console.gotoxy(1, console.screen_rows-1);
if (voteRetObj.errorMsg.length > 0)
{
if (voteRetObj.mnemonicsRequiredForErrorMsg)
{
console.mnemonics(voteRetObj.errorMsg);
console.print("\1n");
}
else
console.print("\1y\1h* " + voteRetObj.errorMsg + "\1n");
mswait(ERROR_PAUSE_WAIT_MS);
}
else if (!voteRetObj.savedVote)
{
console.print("\1y\1h* Failed to save the vote\1n");
mswait(ERROR_PAUSE_WAIT_MS);
}
}
else
{
// Not a poll vote - Just an up/down vote
if ((voteRetObj.errorMsg.length > 0) || (!voteRetObj.savedVote))
{
console.print("\1n");
console.gotoxy(1, console.screen_rows-1);
if (voteRetObj.errorMsg.length > 0)
{
if (voteRetObj.mnemonicsRequiredForErrorMsg)
{
console.mnemonics(voteRetObj.errorMsg);
console.print("\1n");
}
else
console.print("\1y\1h* " + voteRetObj.errorMsg + "\1n");
}
else if (!voteRetObj.savedVote)
console.print("\1y\1h* Failed to save the vote\1n");
}
else
msgHeader = voteRetObj.updatedHdr; // To get updated vote information
mswait(ERROR_PAUSE_WAIT_MS);
writeMessage = false;
}
// Exit out of the reader and come back to read
// the same message again so that the voting results
// are re-loaded and displayed on the screen.
retObj.newMsgOffset = pOffset;
retObj.nextAction = ACTION_GO_SPECIFIC_MSG;
continueOn = false;
this.DisplayEnhancedMsgReadHelpLine(console.screen_rows, allowChgMsgArea);
}
else
{
// The user quit out of voting. Refresh the screen.
// Exit out of the reader and come back to read
// the same message again so that the screen is refreshed.
retObj.newMsgOffset = pOffset;
retObj.nextAction = ACTION_GO_SPECIFIC_MSG;
continueOn = false;
this.DisplayEnhancedMsgReadHelpLine(console.screen_rows, allowChgMsgArea);
}
}
else
writeMessage = false;
break;
case this.enhReaderKeys.showVotes: // Show votes
// Save the original cursor position
var originalCurPos = console.getxy();
if (msgHeader.hasOwnProperty("total_votes") && msgHeader.hasOwnProperty("upvotes"))
{

nightfox
committed
var voteInfo = this.GetUpvoteAndDownvoteInfo(msgHeader);
// Display the vote info and let the user scroll through them
// (the console height should be enough, but do this just in case)
// Calculate information for the scrollbar for the vote info lines
var infoFractionShown = this.msgAreaHeight / voteInfo.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);
}

nightfox
committed
// Display the vote info lines and let the user scroll through them
this.DisplayEnhancedReaderWholeScrollbar(this.msgAreaTop, numInfoSolidScrollBlocks);
scrollTextLines(voteInfo, 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
{
this.DisplayEnhReaderError("There is no voting information for this message", msgInfo.messageLines, topMsgLineIdx, msgLineFormatStr);
console.gotoxy(originalCurPos);
writeMessage = false;
}
break;
case this.enhReaderKeys.closePoll: // Close a poll message
// Save the original cursor position
var originalCurPos = console.getxy();
var pollCloseMsg = "";
// If this message is a poll, then allow closing it.
if ((typeof(MSG_TYPE_POLL) != "undefined") && (msgHeader.type & MSG_TYPE_POLL) == MSG_TYPE_POLL)
{
if ((msgHeader.auxattr & POLL_CLOSED) == 0)
{
// Only let the user close the poll if they created it
if (userHandleAliasNameMatch(msgHeader.from))
{
// Prompt to confirm whether the user wants to close the poll
console.gotoxy(1, console.screen_rows-1);
printf("\1n%" + +(console.screen_columns-1) + "s", "");
console.gotoxy(1, console.screen_rows-1);
if (!console.noyes("Close poll"))
{
// Close the poll (open the sub-board first)
var msgbase = new MsgBase(this.subBoardCode);
if (msgbase.open())
{
if (closePollWithOpenMsgbase(msgbase, msgHeader.number))
{
msgHeader.auxattr |= POLL_CLOSED;
pollCloseMsg = "\1n\1cThis poll was successfully closed.";
}
else
pollCloseMsg = "\1n\1r\1h* Failed to close this poll!";
msgbase.close();
}
else
pollCloseMsg = "\1n\1y\1hUnable to open sub-board to close the poll";
}
}
else
pollCloseMsg = "\1n\1y\1hCan't close this poll because it's not yours";
}
else
pollCloseMsg = "\1n\1y\1hThis poll is already closed";
}
else
pollCloseMsg = "This message is not a poll";
// Display the poll closing status message
this.DisplayEnhReaderError(pollCloseMsg, msgInfo.messageLines, topMsgLineIdx, msgLineFormatStr);
console.gotoxy(originalCurPos);
writeMessage = false;
break;
case this.enhReaderKeys.validateMsg: // Validate the message
if (gIsSysop && (this.subBoardCode != "mail") && msg_area.sub[this.subBoardCode].is_moderated)
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
{
var message = "";
if (this.ValidateMsg(this.subBoardCode, msgHeader.number))
{
message = "\1n\1cMessage validation successful";
// Refresh the message header in the arrays
this.RefreshMsgHdrInArrays(msgHeader.number);
// Exit out of the reader and come back to read
// the same message again so that the voting results
// are re-loaded and displayed on the screen.
retObj.newMsgOffset = pOffset;
retObj.nextAction = ACTION_GO_SPECIFIC_MSG;
continueOn = false;
this.DisplayEnhancedMsgReadHelpLine(console.screen_rows, allowChgMsgArea);
}
else
message = "\1n\1y\1hMessage validation failed!";
this.DisplayEnhReaderError(message, msgInfo.messageLines, topMsgLineIdx, msgLineFormatStr);
}
else
writeMessage = false;
break;
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
case this.enhReaderKeys.bypassSubBoardInNewScan:
writeMessage = false; // TODO: Finish
/*
if (this.doingMsgScan)
{
console.print("\1n");
var originalCurpos = console.getxy();
// The 2nd to last row of the screen is where the user will
// be prompted for confirmation to delete the message.
// Ideally, I'd like to put the cursor on the last row of
// the screen for this, but console.noyes() lets the enter
// key shift everything on screen up one row, and there's
// no way to avoid that. So, to optimize screen refreshing,
// the cursor is placed on the 2nd to the last row on the
// screen to prompt for confirmation.
var promptPos = this.EnhReaderPrepLast2LinesForPrompt();
if (!console.noyes("Bypass this sub-board in newscans"))
{
continueOn = false;
msg_area.sub[this.subBoardCode].scan_cfg &= SCAN_CFG_NEW;
}
else
{
this.DisplayEnhReaderError("", msgInfo.messageLines, topMsgLineIdx, msgLineFormatStr);
// Move the cursor back to its original position
console.gotoxy(originalCurpos);
this.DisplayEnhancedMsgReadHelpLine(console.screen_rows, allowChgMsgArea);
}
}
else
writeMessage = false;
*/
break;

nightfox
committed
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 = {
offsetValid: true,
msgNotReadable: false,
userReplied: false,
lastKeypress: "",
newMsgOffset: -1,
nextAction: ACTION_NONE,
refreshEnhancedRdrHelpLine: false
};
5407
5408
5409
5410
5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433
5434
// 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
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
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();
5527
5528
5529
5530
5531
5532
5533
5534
5535
5536
5537
5538
5539
5540
5541
5542
5543
5544
5545
5546
5547
5548
5549
5550
5551
// 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 msgbase = new MsgBase(this.subBoardCode);
if (msgbase.open())
{
var extdMsgHdr = msgbase.get_msg_header(false, msgHeader.number, true);
msgbase.close();
// Let the user reply to the message
var replyRetObj = this.ReplyToMsg(extdMsgHdr, msgAndAttachmentInfo.msgText, privateReply, pOffset);
retObj.userReplied = replyRetObj.postSucceeded;
//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 // msgbase failed to open
{
console.print("\1n");
console.crlf();
console.print("\1h\1yFailed to open the sub-board. 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?
}
5631
5632
5633
5634
5635
5636
5637
5638
5639
5640
5641
5642
5643
5644
5645
5646
5647
5648
5649
5650
5651
5652
5653
5654
5655
5656
5657
5658
5659
5660
5661
5662
5663
5664
5665
5666
5667
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
5772
5773
5774
5775
5776
5777
5778
5779
5780
5781
5782
5783
5784
5785
5786
5787
5788
5789
5790
5791
5792
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.
var grpNameAndDesc = this.GetGroupNameAndDesc();
if (!console.noyes(format(this.text.postOnSubBoard, grpNameAndDesc.grpName, grpNameAndDesc.grpDesc)))
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
5834
5835
5836
5837
5838
5839
5840
5841
5842
5843
5844
5845
5846
5847
5848
5849
5850
5851
5852
5853
5854
5855
5856
5857
5858
5859
5860
5861
5862
5863
5864
5865
5866
5867
5868
5869
// 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
console.print("\1n");
console.crlf();
console.print("Loading...");
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);
}
else
{
console.print("\1n\1y\1hMessage not exported\1n");
mswait(ERROR_PAUSE_WAIT_MS);
}
writeMessage = true;
}
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();
}
}
writeMessage = true;
break;

nightfox
committed
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)