Newer
Older
//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
console.crlf();
// Prompt the user for confirmation to delete the message.
// Note: this.PromptAndDeleteOrUndeleteMessage() 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.
var msgWasDeleted = this.PromptAndDeleteOrUndeleteMessage(pOffset, null, true);
if (msgWasDeleted && !canViewDeletedMsgs())
{
var msgSearchObj = this.LookForNextOrPriorNonDeletedMsg(pOffset);
continueOn = msgSearchObj.continueInputLoop;
retObj.newMsgOffset = msgSearchObj.newMsgOffset;
retObj.nextAction = msgSearchObj.nextAction;
if (msgSearchObj.promptGoToNextArea)
{
Eric Oulashin
committed
if (console.yesno(replaceAtCodesInStr(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.DeleteOrUndeleteSelectedMessages() 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();
6060
6061
6062
6063
6064
6065
6066
6067
6068
6069
6070
6071
6072
6073
6074
6075
6076
6077
6078
6079
6080
6081
6082
6083
6084
// 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, msgHasAttachments);
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, messageText, privateReply, pOffset);
retObj.userReplied = replyRetObj.postSucceeded;
//retObj.msgNotReadable = replyRetObj.msgWasDeleted;
var msgWasDeleted = replyRetObj.msgWasDeleted;
if (msgWasDeleted && !canViewDeletedMsgs())
{
var msgSearchObj = this.LookForNextOrPriorNonDeletedMsg(pOffset);
continueOn = msgSearchObj.continueInputLoop;
retObj.newMsgOffset = msgSearchObj.newMsgOffset;
retObj.nextAction = msgSearchObj.nextAction;
if (msgSearchObj.promptGoToNextArea)
{
Eric Oulashin
committed
if (console.yesno(replaceAtCodesInStr(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("\x01n");
console.crlf();
console.print("\x01h\x01yFailed to open the sub-board. Aborting.\x01n");
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?
}
6164
6165
6166
6167
6168
6169
6170
6171
6172
6173
6174
6175
6176
6177
6178
6179
6180
6181
6182
6183
6184
6185
6186
6187
6188
6189
6190
6191
6192
6193
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
Eric Oulashin
committed
var msgNumInput = this.PromptForMsgNum(null, replaceAtCodesInStr(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("\x01n" + replaceAtCodesInStr(format(this.text.msgHasBeenDeletedText, msgNumInput)) + "\x01n");
console.crlf();
console.pause();
}
else
{
// Confirm with the user whether to read the message
var readMsg = true;
if (this.promptToReadMessage)
{
readMsg = console.yesno("\x01n" + 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();
Eric Oulashin
committed
goToPrevMessage = console.yesno(replaceAtCodesInStr(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
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("\x01n");
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();
Eric Oulashin
committed
if (!console.noyes(replaceAtCodesInStr(format(this.text.postOnSubBoard, grpNameAndDesc.grpName, grpNameAndDesc.grpDesc))))
bbs.post_msg(this.subBoardCode);
continueOn = false;
retObj.nextAction = ACTION_QUIT;
}
else
{
Eric Oulashin
committed
if (console.yesno(replaceAtCodesInStr(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
6367
6368
6369
6370
6371
6372
6373
6374
6375
6376
6377
6378
6379
6380
6381
6382
6383
6384
6385
6386
6387
6388
6389
6390
6391
6392
6393
6394
6395
6396
6397
6398
6399
6400
6401
6402
// 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:
Eric Oulashin
committed
if (user.is_sysop)
{
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
Eric Oulashin
committed
console.print(replaceAtCodesInStr(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("\x01n");
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 (msgHasAttachments)
{
console.print("\x01n");
console.crlf();
console.print("\x01c- Download Attached Files -\x01n");
allowUserToDownloadMessage_NewInterface(msgHeader, this.subBoardCode);
// 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.
Eric Oulashin
committed
if (user.is_sysop)
{
console.crlf();
console.print("\x01n\x01cFilename:\x01h");
var inputLen = console.screen_columns - 10; // 10 = "Filename:" length + 1
var filename = console.getstr(inputLen, K_NOCRLF);
console.print("\x01n");
console.crlf();
if (filename.length > 0)
{
var saveMsgRetObj = this.SaveMsgToFile(msgHeader, filename);
if (saveMsgRetObj.succeeded)
console.print("\x01n\x01cThe message has been saved.\x01n");
if (msgHdrHasAttachmentFlag(msgHeader))
console.print(" Attachments not saved.");
console.print("\x01n");
else
console.print("\x01n\x01y\x01hFailed: " + saveMsgRetObj.errorMsg + "\x01n");
mswait(ERROR_PAUSE_WAIT_MS);
}
else
{
console.print("\x01n\x01y\x01hMessage not exported\x01n");
mswait(ERROR_PAUSE_WAIT_MS);
}
writeMessage = true;
}
else
writeMessage = false;
break;

nightfox
committed
case this.enhReaderKeys.userEdit: // Edit the user who wrote the message
Eric Oulashin
committed
if (user.is_sysop)
{
console.print("\x01n");
console.crlf();
console.print("- Edit user " + msgHeader.from);
console.crlf();
var editObj = editUser(msgHeader.from);
if (editObj.errorMsg.length != 0)
{
console.print("\x01n");
console.crlf();
console.print("\x01y\x01h" + editObj.errorMsg + "\x01n");
console.crlf();
console.pause();
}
}
writeMessage = true;
break;

nightfox
committed
case this.enhReaderKeys.forwardMsg: // Forward the message
console.print("\x01n");

nightfox
committed
console.crlf();
console.print("\x01c- Forward message\x01n");

nightfox
committed
console.crlf();
var retStr = this.ForwardMessage(msgHeader, messageText);
if (retStr.length > 0)
{
console.print("\x01n\x01h\x01y* " + retStr + "\x01n");

nightfox
committed
console.crlf();
console.pause();
}
writeMessage = true;
break;
case this.enhReaderKeys.vote: // Vote on the message
var voteRetObj = this.VoteOnMessage(msgHeader);
if (voteRetObj.BBSHasVoteFunction)
{
if (!voteRetObj.userQuit)
{
if ((voteRetObj.errorMsg.length > 0) || (!voteRetObj.savedVote))
{
console.print("\x01n");
console.crlf();
if (voteRetObj.errorMsg.length > 0)
{
if (voteRetObj.mnemonicsRequiredForErrorMsg)
{
console.mnemonics(voteRetObj.errorMsg);
console.print("\x01n");
}
else
console.print("\x01y\x01h* " + voteRetObj.errorMsg + "\x01n");
}
else if (!voteRetObj.savedVote)
console.print("\x01y\x01h* Failed to save the vote\x01n");
console.crlf();
console.pause();
}
else
msgHeader = voteRetObj.updatedHdr; // To get updated vote information
}
// If this message is a poll, then 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.
if ((typeof(MSG_TYPE_POLL) != "undefined") && (msgHeader.type & MSG_TYPE_POLL) == MSG_TYPE_POLL)
{
retObj.newMsgOffset = pOffset;
retObj.nextAction = ACTION_GO_SPECIFIC_MSG;
continueOn = false;
}
else
writeMessage = true; // We want to refresh the message on the screen
}
else
writeMessage = false;
break;
case this.enhReaderKeys.showVotes: // Show votes
if (msgHeader.hasOwnProperty("total_votes") && msgHeader.hasOwnProperty("upvotes"))
{
console.print("\x01n");
console.crlf();

nightfox
committed
var voteInfo = this.GetUpvoteAndDownvoteInfo(msgHeader);
for (var voteInfoIdx = 0; voteInfoIdx < voteInfo.length; ++voteInfoIdx)
{

nightfox
committed
console.print(voteInfo[voteInfoIdx]);
console.crlf();
}
}
else
{
console.print("\x01n\x01h\x01yThere is no voting information for this message\x01n");
console.crlf();
}
console.pause();
writeMessage = true;
break;
case this.enhReaderKeys.closePoll: // Close a poll message
var pollCloseMsg = "";
console.print("\x01n");
console.crlf();
// 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
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 = "\x01n\x01cThis poll was successfully closed.";
}
else
pollCloseMsg = "\x01n\x01r\x01h* Failed to close this poll!";
msgbase.close();
}
else
pollCloseMsg = "\x01n\x01r\x01h* Failed to open the sub-board!";
}
}
else
pollCloseMsg = "\x01n\x01y\x01hCan't close this poll because it's not yours";
}
else
pollCloseMsg = "\x01n\x01y\x01hThis poll is already closed";
}
else
pollCloseMsg = "This message is not a poll";
// Display the poll closing status message
if (strip_ctrl(pollCloseMsg).length > 0)
{
console.print("\x01n" + pollCloseMsg + "\x01n");
console.crlf();
console.pause();
}
writeMessage = true;
break;
case this.enhReaderKeys.validateMsg: // Validate the message
Eric Oulashin
committed
if (user.is_sysop && (this.subBoardCode != "mail") && msg_area.sub[this.subBoardCode].is_moderated)
{
var message = "";
if (this.ValidateMsg(this.subBoardCode, msgHeader.number))
{
message = "\x01n\x01cMessage 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;
}
else
{
message = "\x01n\x01y\x01hMessage validation failed!";
writeMessage = true;
}
console.crlf();
console.print(message);
console.print("\x01n");
console.crlf();
console.pause();
}
else
writeMessage = false;
break;
case this.enhReaderKeys.bypassSubBoardInNewScan:
// TODO: Finish
writeMessage = false;
/*
if (this.doingMsgScan)
{
console.print("\x01n");
console.crlf();
if (!console.noyes("Bypass this sub-board in newscans"))
{
continueOn = false;
msg_area.sub[this.subBoardCode].scan_cfg &= SCAN_CFG_NEW;
}
else
writeMessage = true;
}
else
writeMessage = false;
*/
break;

Eric Oulashin
committed
6709
6710
6711
6712
6713
6714
6715
6716
6717
6718
6719
6720
6721
6722
6723
6724
6725
6726
6727
6728
6729
6730
6731
6732
6733
6734
6735
6736
6737
6738
6739
6740
6741
6742
6743
6744
6745
6746
6747
6748
6749
6750
6751
6752
6753
6754
6755
6756
6757
6758
6759
6760
6761
6762
6763
6764
6765
6766
6767
6768
6769
6770
6771
6772
6773
6774
6775
6776
6777
6778
6779
6780
6781
6782
6783
case this.enhReaderKeys.userSettings:
var userSettingsRetObj = this.DoUserSettings_Traditional();
// In case the user changed their twitlist, re-filter the messages for this sub-board
if (userSettingsRetObj.userTwitListChanged)
{
console.crlf();
console.print("\x01nTwitlist changed; re-filtering..");
var tmpMsgbase = new MsgBase(this.subBoardCode);
if (tmpMsgbase.open())
{
continueOn = false;
writeMessage = false;
var tmpAllMsgHdrs = tmpMsgbase.get_all_msg_headers(true);
tmpMsgbase.close();
this.FilterMsgHdrsIntoHdrsForCurrentSubBoard(tmpAllMsgHdrs, true);
// If the user is currently reading a message a message by someone who is now
// in their twit list, change the message currently being viewed.
if (this.MsgHdrFromOrToInUserTwitlist(msgHeader))
{
var newReadableMsgOffset = this.FindNextNonDeletedMsgIdx(pOffset, true);
if (newReadableMsgOffset > -1)
{
retObj.newMsgOffset = newReadableMsgOffset;
retObj.offsetValid = true;
retObj.nextAction = ACTION_GO_SPECIFIC_MSG;
}
else
retObj.nextAction = ACTION_GO_NEXT_MSG_AREA;
}
else
{
// If there are still messages in this sub-board, and the message offset is beyond the last
// message, then show the last message in the sub-board. Otherwise, go to the next message area.
if (this.hdrsForCurrentSubBoard.length > 0)
{
if (pOffset > this.hdrsForCurrentSubBoard.length)
{
//this.hdrsForCurrentSubBoard[this.hdrsForCurrentSubBoard.length-1].number
retObj.newMsgOffset = this.hdrsForCurrentSubBoard.length - 1;
retObj.offsetValid = true;
retObj.nextAction = ACTION_GO_SPECIFIC_MSG;
}
}
else
retObj.nextAction = ACTION_GO_NEXT_MSG_AREA;
}
}
else
console.print("\x01y\x01hFailed to open the messagbase!\x01\r\n\x01p");
this.SetUpLightbarMsgListVars();
writeMessage = true;
}
break;
case this.enhReaderKeys.quit: // Quit
retObj.nextAction = ACTION_QUIT;
continueOn = false;
break;
default:
// No need to do anything
writeMessage = false;
writePromptText = false;
break;
}
}
return retObj;
}
// For the ReadMessageEnhanced methods: This function converts a thread navigation
// key character to its corresponding thread type value
function keypressToThreadType(pKeypress, pEnhReaderKeys)
{
var threadType = THREAD_BY_ID;
switch (pKeypress)
{
case pEnhReaderKeys.prevMsgByTitle:
case pEnhReaderKeys.nextMsgByTitle:
threadType = THREAD_BY_TITLE;
break;
case pEnhReaderKeys.prevMsgByAuthor:
case pEnhReaderKeys.nextMsgByAuthor:
threadType = THREAD_BY_AUTHOR;
break;
case pEnhReaderKeys.prevMsgByToUser:
case pEnhReaderKeys.nextMsgByToUser:
threadType = THREAD_BY_TO_USER;
break;
case pEnhReaderKeys.prevMsgByThreadID:
case pEnhReaderKeys.nextMsgByThreadID:
default:
threadType = THREAD_BY_ID;
break;
}
return threadType;
}
// For the DigDistMsgReader class: For the enhanced reader method - Prepares the
// last 2 lines on the screen for propmting the user for something.
//
// Return value: An object containing x and y values representing the cursor
// position, ready to prompt the user.
function DigDistMsgReader_EnhReaderPrepLast2LinesForPrompt()
{
var promptPos = { x: this.msgAreaLeft, y: this.msgAreaBottom };
// Write a line of characters above where the prompt will be placed,
// to help get the user's attention.
console.gotoxy(promptPos.x, promptPos.y-1);
console.print("\x01n" + this.colors.enhReaderPromptSepLineColor);
for (var lineCounter = 0; lineCounter < this.msgAreaWidth; ++lineCounter)
console.print(HORIZONTAL_SINGLE);
// Clear the inside of the message area, so as not to overwrite
// the scrollbar character
console.print("\x01n");
console.gotoxy(promptPos);
for (var lineCounter = 0; lineCounter < this.msgAreaWidth; ++lineCounter)
console.print(" ");
// Position the cursor at the prompt location
console.gotoxy(promptPos);
return promptPos;
}
// For the DigDistMsgReader class: For the enhanced reader method - Looks for a
// later method that isn't marked for deletion. If none is found, looks for a
// prior message that isn't marked for deletion.
//
// Parameters:
// pOffset: The offset of the message to start at
//
// Return value: An object with the following properties:
// newMsgOffset: The offset of the next readable message
// nextAction: The next action (code) for the enhanced reader
// continueInputLoop: Boolean - Whether or not to continue the input loop
// promptGoToNextArea: Boolean - Whether or not to prompt the user to go
// to the next message area
function DigDistMsgReader_LookForNextOrPriorNonDeletedMsg(pOffset)
{
var retObj = {
newMsgOffset: 0,
nextAction: ACTION_NONE,
continueInputLoop: true,
promptGoToNextArea: false
};
6852
6853
6854
6855
6856
6857
6858
6859
6860
6861
6862
6863
6864
6865
6866
6867
6868
6869
6870
6871
6872
6873
6874
6875
6876
6877
6878
6879
6880
6881
6882
6883
6884
6885
6886
6887
6888
6889
6890
6891
6892
6893
6894
6895
6896
6897
6898
6899
6900
6901
6902
6903
6904
6905
6906
6907
6908
6909
// Look for a later message that isn't marked for deletion.
// If none is found, then look for a prior message that isn't
// marked for deletion.
retObj.newMsgOffset = this.FindNextNonDeletedMsgIdx(pOffset, true);
if (retObj.newMsgOffset > -1)
{
retObj.continueInputLoop = false;
retObj.nextAction = ACTION_GO_NEXT_MSG;
}
else
{
// No later message found, so look for a prior message.
retObj.newMsgOffset = this.FindNextNonDeletedMsgIdx(pOffset, false);
if (retObj.newMsgOffset > -1)
{
retObj.continueInputLoop = false;
retObj.nextAction = ACTION_GO_PREVIOUS_MSG;
}
else
{
// No prior message found. We'll want to return from the enhanced
// reader function (with message index -1) so that this script can
// go onto the next message sub-board/group. Also, set the next
// action such that the calling method will go on to the next
// message/sub-board.
if (!curMsgSubBoardIsLast())
{
if (this.readingPersonalEmail)
{
retObj.continueInputLoop = false;
retObj.nextAction = ACTION_QUIT;
}
else
retObj.promptGoToNextArea = true;
}
else
{
// We're not at the end of the sub-board or the current sub-board
// is the last, so go ahead and exit.
retObj.continueInputLoop = false;
retObj.nextAction = ACTION_GO_NEXT_MSG;
}
}
}
return retObj;
}
// For the DigDistMsgReader class: Writes the help line for enhanced reader
// mode.
//
// Parameters:
// pScreenRow: Optional - The screen row to write the help line on. If not
// specified, the last row on the screen will be used.
// pDisplayChgAreaOpt: Optional boolean - Whether or not to show the "change area" option.
// Defaults to true.
function DigDistMsgReader_DisplayEnhancedMsgReadHelpLine(pScreenRow, pDisplayChgAreaOpt)
{
Eric Oulashin
committed
var displayChgAreaOpt = (typeof(pDisplayChgAreaOpt) == "boolean" ? pDisplayChgAreaOpt : true);
// Move the cursor to the desired location on the screen and display the help line
console.gotoxy(1, typeof(pScreenRow) == "number" ? pScreenRow : console.screen_rows);

Eric Oulashin
committed
// TODO: Mouse: console.print replaced with console.putmsg for mouse click hotspots
Eric Oulashin
committed
//console.print(displayChgAreaOpt ? this.enhReadHelpLine : this.enhReadHelpLineWithoutChgArea);
// console.putmsg() handles @-codes, which we use for mouse click tracking
console.putmsg(displayChgAreaOpt ? this.enhReadHelpLine : this.enhReadHelpLineWithoutChgArea);
}
// For the DigDistMsgReader class: Goes back to the prior readable sub-board
// (accounting for search results, etc.). Changes the object's subBoardCode,
// msgbase object, etc.
//
// Parameters:
// pAllowChgMsgArea: Boolean - Whether or not the user is allowed to change
// to another message area
Eric Oulashin
committed
// pPromptPrevIfNoResults: Optional boolean - Whether or not to prompt the user to
// go to the previous area if there are no search results.
//
// Return value: An object with the following properties:
// changedMsgArea: Boolean - Whether or not this method successfully
// changed to a prior message area
// msgIndex: The message index for the new sub-board. Will be -1
// if there is no new sub-board or otherwise invalid
// scenario.
// shouldStopReading: Whether or not the script should stop letting
// the user read messages
Eric Oulashin
committed
function DigDistMsgReader_GoToPrevSubBoardForEnhReader(pAllowChgMsgArea, pPromptPrevIfNoResults)
{
var retObj = {
changedMsgArea: false,
msgIndex: -1,
shouldStopReading: false
};
6944
6945
6946
6947
6948
6949
6950
6951
6952
6953
6954
6955
6956
6957
6958
6959
6960
6961
6962
6963
6964
6965
6966
// Only allow this if pAllowChgMsgArea is true and we're not reading personal
// email. If we're reading personal email, then msg_area.sub is unavailable
// for the "mail" internal code.
if (pAllowChgMsgArea && (this.subBoardCode != "mail"))
{
// continueGoingToPrevSubBoard specifies whether or not to continue
// going to the previous sub-boards in case there is search text
// specified.
var continueGoingToPrevSubBoard = true;
while (continueGoingToPrevSubBoard)
{
// Allow going to the previous message sub-board/group.
var msgGrpIdx = msg_area.sub[this.subBoardCode].grp_index;
var subBoardIdx = msg_area.sub[this.subBoardCode].index;
var readMsgRetObj = findNextOrPrevNonEmptySubBoard(msgGrpIdx, subBoardIdx, false);
// If a different sub-board was found, then go to that sub-board.
if (readMsgRetObj.foundSubBoard && readMsgRetObj.subChanged)
{
bbs.cursub = 0;
bbs.curgrp = readMsgRetObj.grpIdx;
bbs.cursub = readMsgRetObj.subIdx;
this.setSubBoardCode(readMsgRetObj.subCode);
if (this.searchType == SEARCH_NONE || !this.SearchingAndResultObjsDefinedForCurSub())
{
continueGoingToPrevSubBoard = false; // No search results, so don't keep going to the previous sub-board.
// Go to the user's last read message. If the message index ends up
// below 0, then go to the last message not marked as deleted.
// We probably shouldn't use GetMsgIdx() yet because the arrays of
// message headers have not been populated for the next area yet
retObj.msgIndex = this.AbsMsgNumToIdx(msg_area.sub[this.subBoardCode].last_read);
//retObj.msgIndex = this.GetMsgIdx(msg_area.sub[this.subBoardCode].last_read);
if (retObj.msgIndex >= 0)
retObj.changedMsgArea = true;
else
{
// Look for the last message not marked as deleted
var nonDeletedMsgIdx = this.FindNextNonDeletedMsgIdx(this.NumMessages(), false);
// If a non-deleted message was found, then set retObj.msgIndex to it.
// Otherwise, tell the user there are no messages in this sub-board
// and return.
if (nonDeletedMsgIdx > -1)
retObj.msgIndex = nonDeletedMsgIdx;

nightfox
committed
else
retObj.msgIndex = this.NumMessages() - 1; // Shouldn't get here
var newLastRead = this.IdxToAbsMsgNum(retObj.msgIndex);
if (newLastRead > -1)
msg_area.sub[this.subBoardCode].last_read = newLastRead;
}
}
// Set the hotkey help line again, as this sub-board might have
// different settings for whether messages can be edited or deleted,
// then refresh it on the screen.
var oldHotkeyHelpLine = this.enhReadHelpLine;
this.SetEnhancedReaderHelpLine();
// If a search is is specified that would populate the search
// results, then populate this.msgSearchHdrs for the current