Newer
Older
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);
}
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)
{
console.print("\1n\1h\1y* " + retStr + "\1n");
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("\1n");
console.crlf();
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");
console.crlf();
console.pause();
}
else
msgHeader = voteRetObj.updatedHdr; // To get updated vote information
}
// If this message is a poll vote, 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("\1n");
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("\1n\1h\1yThere is no voting information for this message\1n");
console.crlf();
}
console.pause();
writeMessage = true;
break;
case this.enhReaderKeys.validateMsg: // Validate the message
if (gIsSysop && (this.subBoardCode != "mail") && msg_area.sub[this.subBoardCode].is_moderated)
6213
6214
6215
6216
6217
6218
6219
6220
6221
6222
6223
6224
6225
6226
6227
6228
6229
6230
6231
6232
6233
6234
6235
6236
6237
6238
6239
6240
{
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;
}
else
{
message = "\1n\1y\1hMessage validation failed!";
writeMessage = true;
}
console.crlf();
console.print(message);
console.print("\1n");
console.crlf();
console.pause();
}
else
writeMessage = false;
break;

nightfox
committed
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;
}
6284
6285
6286
6287
6288
6289
6290
6291
6292
6293
6294
6295
6296
6297
6298
6299
6300
6301
6302
6303
6304
6305
6306
6307
6308
6309
// 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("\1n" + 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("\1n");
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;
}
6310
6311
6312
6313
6314
6315
6316
6317
6318
6319
6320
6321
6322
6323
6324
6325
6326
6327
6328
6329
6330
6331
6332
6333
6334
6335
6336
6337
6338
6339
6340
6341
6342
6343
6344
6345
6346
6347
6348
6349
6350
6351
6352
6353
6354
6355
6356
6357
6358
6359
6360
6361
6362
6363
6364
6365
6366
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
6403
6404
6405
6406
6407
6408
6409
6410
6411
6412
6413
6414
6415
6416
6417
6418
6419
6420
6421
6422
6423
6424
6425
6426
6427
6428
6429
6430
6431
6432
6433
6434
6435
6436
6437
6438
6439
6440
6441
6442
6443
6444
6445
6446
6447
// 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 = new Object();
retObj.newMsgOffset = 0;
retObj.nextAction = ACTION_NONE;
retObj.continueInputLoop = true;
retObj.promptGoToNextArea = false;
// 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)
{
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);
console.print(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
// 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
function DigDistMsgReader_GoToPrevSubBoardForEnhReader(pAllowChgMsgArea)
{
var retObj = new Object();
retObj.changedMsgArea = false;
retObj.msgIndex = -1;
retObj.shouldStopReading = false;
// 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;
// Open the new sub-board
this.msgbase.close();
this.setSubBoardCode(readMsgRetObj.subCode);
this.msgbase = new MsgBase(this.subBoardCode);
if (this.msgbase.open())
{
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);

nightfox
committed
if (retObj.msgIndex >= 0)
retObj.changedMsgArea = true;
else
{
// Look for the last message not marked as deleted
var nonDeletedMsgIdx = this.FindNextNonDeletedMsgIdx(this.NumMessages(), false);

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

nightfox
committed
retObj.msgIndex = nonDeletedMsgIdx;
else

nightfox
committed
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
// sub-board if there is search text specified. If there
// are no search results, then ask the user if they want
// to continue searching the message areas.
if (this.SearchTypePopulatesSearchResults())
{
if (this.PopulateHdrsIfSearch_DispErrorIfNoMsgs(false, true, false))
{
retObj.changedMsgArea = true;
continueGoingToPrevSubBoard = false;

nightfox
committed
retObj.msgIndex = this.NumMessages() - 1;
if (this.scrollingReaderInterface && console.term_supports(USER_ANSI))
this.DisplayEnhancedMsgReadHelpLine(console.screen_rows, pAllowChgMsgArea);
}
else // No search results in this sub-board
{
continueGoingToPrevSubBoard = !console.noyes("Continue searching");
if (!continueGoingToPrevSubBoard)
{
retObj.shouldStopReading = true;
return retObj;
}
}
}
else
{
retObj.changedMsgArea = true;
this.PopulateHdrsForCurrentSubBoard();
6504
6505
6506
6507
6508
6509
6510
6511
6512
6513
6514
6515
6516
6517
6518
6519
6520
6521
6522
6523
6524
6525
6526
6527
6528
6529
6530
6531
6532
6533
6534
6535
6536
6537
6538
6539
6540
6541
6542
6543
6544
6545
6546
6547
6548
6549
6550
6551
6552
6553
6554
6555
6556
6557
6558
6559
6560
6561
6562
6563
6564
6565
6566
6567
6568
6569
6570
6571
6572
6573
6574
6575
6576
6577
6578
6579
6580
6581
6582
6583
6584
6585
6586
6587
6588
6589
6590
6591
6592
6593
6594
6595
6596
if ((oldHotkeyHelpLine != this.enhReadHelpLine) && this.scrollingReaderInterface && console.term_supports(USER_ANSI))
this.DisplayEnhancedMsgReadHelpLine(console.screen_rows, pAllowChgMsgArea);
}
}
else // The message base failed to open
{
console.clear("\1n");
console.print("\1h\1y* \1wUnable to open message sub-board:");
console.crlf();
console.print(subBoardGrpAndName(this.subBoardCode));
console.crlf();
console.pause();
retObj.shouldStopReading = true;
continueGoingToPrevSubBoard = false;
return retObj;
}
}
else
{
// Didn't find a prior sub-board with readable messages.
// We could stop and exit the script here by doing the following,
// but I'd rather let the user exit when they want to.
continueGoingToPrevSubBoard = false;
// Show a message telling the user that there are no prior
// messages or sub-boards. Then, refresh the hotkey help line.
writeWithPause(this.msgAreaLeft, console.screen_rows,
"\1n\1h\1y* No prior messages or no message in prior message areas.",
ERROR_PAUSE_WAIT_MS, "\1n", true);
if (this.scrollingReaderInterface && console.term_supports(USER_ANSI))
this.DisplayEnhancedMsgReadHelpLine(console.screen_rows, pAllowChgMsgArea);
}
}
}
return retObj;
}
// For the DigDistMsgReader class: Goes to the next 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
// 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
function DigDistMsgReader_GoToNextSubBoardForEnhReader(pAllowChgMsgArea)
{
var retObj = new Object();
retObj.changedMsgArea = false;
retObj.msgIndex = -1;
retObj.shouldStopReading = false;
// 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"))
{
// continueGoingToNextSubBoard specifies whether or not to continue
// advancing to the next sub-boards in case there is search text
// specified.
var continueGoingToNextSubBoard = true;
while (continueGoingToNextSubBoard)
{
// Allow going to the next 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, true);
// If a different sub-board was found, then go to that sub-board.
if (readMsgRetObj.foundSubBoard && readMsgRetObj.subChanged)
{
retObj.msgIndex = 0;
bbs.cursub = 0;
bbs.curgrp = readMsgRetObj.grpIdx;
bbs.cursub = readMsgRetObj.subIdx;
// Open the new sub-board
this.msgbase.close();
this.setSubBoardCode(readMsgRetObj.subCode);
this.msgbase = new MsgBase(this.subBoardCode);
if (this.msgbase.open())
{
if ((this.searchType == SEARCH_NONE) || !this.SearchingAndResultObjsDefinedForCurSub())
{
continueGoingToNextSubBoard = false; // No search results, so don't keep going to the next sub-board.
// Go to the user's last read message. If the message index ends up
// below 0, then go to the first message not marked as deleted.
retObj.msgIndex = this.AbsMsgNumToIdx(msg_area.sub[this.subBoardCode].last_read);
// 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.GetMsgIdx(msg_area.sub[this.subBoardCode].last_read);

nightfox
committed
if (retObj.msgIndex >= 0)
retObj.changedMsgArea = true;
else
6604
6605
6606
6607
6608
6609
6610
6611
6612
6613
6614
6615
6616
6617
6618
6619
6620
6621
6622
6623
6624
6625
6626
6627
6628
6629
6630
6631
6632
6633
6634
6635
6636
{
// Set the index of the message to display - Look for the
// first message not marked as deleted
var nonDeletedMsgIdx = this.FindNextNonDeletedMsgIdx(this.NumMessages()-1, true);
// 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;
retObj.changedMsgArea = true;
var newLastRead = this.IdxToAbsMsgNum(nonDeletedMsgIdx);
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
// sub-board if there is search text specified. If there
// are no search results, then ask the user if they want
// to continue searching the message areas.
if (this.SearchTypePopulatesSearchResults())
{
if (this.PopulateHdrsIfSearch_DispErrorIfNoMsgs(false, true, false))
{
retObj.changedMsgArea = true;
continueGoingToNextSubBoard = false;
this.PopulateHdrsForCurrentSubBoard();
retObj.msgIndex = 0;
if (this.scrollingReaderInterface && console.term_supports(USER_ANSI))
this.DisplayEnhancedMsgReadHelpLine(console.screen_rows, pAllowChgMsgArea);
}
else // No search results in this sub-board
{
continueGoingToNextSubBoard = !console.noyes("Continue searching");
if (!continueGoingToNextSubBoard)
{
retObj.shouldStopReading = true;
return retObj;
}
}
}
else
{
// There is no search. Populate the arrays of all headers
// for this sub-board
this.PopulateHdrsForCurrentSubBoard();
retObj.msgIndex = this.GetMsgIdx(msg_area.sub[this.subBoardCode].last_read);

nightfox
committed
if (retObj.msgIndex == -1)
retObj.msgIndex = 0;
}
6661
6662
6663
6664
6665
6666
6667
6668
6669
6670
6671
6672
6673
6674
6675
6676
6677
6678
6679
6680
6681
6682
6683
6684
6685
6686
}
else // The message base failed to open
{
console.clear("\1n");
console.print("\1h\1y* \1wUnable to open message sub-board:");
console.crlf();
console.print(subBoardGrpAndName(this.subBoardCode));
console.crlf();
console.pause();
retObj.shouldStopReading = true;
continueGoingToNextSubBoard = false;
return retObj;
}
}
else
{
// Didn't find later sub-board with readable messages.
// We could stop and exit the script here by doing the following,
// but I'd rather let the user exit when they want to.
//retObj.shouldStopReading = true;
//return retObj;
continueGoingToNextSubBoard = false;
// Show a message telling the user that there are no more
// messages or sub-boards. Then, refresh the hotkey help line.
writeWithPause(this.msgAreaLeft, console.screen_rows,
"\1n\1h\1y* No more messages or message areas.",
ERROR_PAUSE_WAIT_MS, "\1n", true);
if (this.scrollingReaderInterface && console.term_supports(USER_ANSI))
this.DisplayEnhancedMsgReadHelpLine(console.screen_rows, pAllowChgMsgArea);
}
}
}
return retObj;
}

nightfox
committed
// For the DigDistMsgReader Class: Prepares the variables that keep track of the
// traditional-interface message list position, current messsage number, etc.
function DigDistMsgReader_SetUpTraditionalMsgListVars()
{
// If a search is specified, then just start at the first message.
// If no search is specified, then get the index of the user's last read
// message. Then, figure out which page it's on and set the lightbar list
// index & cursor position variables accordingly.
var lastReadMsgIdx = 0;
if (!this.SearchingAndResultObjsDefinedForCurSub())
{
lastReadMsgIdx = this.GetLastReadMsgIdx();
if (lastReadMsgIdx == -1)
lastReadMsgIdx = 0;
}
var pageNum = findPageNumOfItemNum(lastReadMsgIdx+1, this.tradMsgListNumLines, this.NumMessages(),
this.reverseListOrder);

nightfox
committed
this.CalcTraditionalMsgListTopIdx(pageNum);
if (!this.reverseListOrder && (this.tradListTopMsgIdx > lastReadMsgIdx))

nightfox
committed
this.tradListTopMsgIdx -= this.tradMsgListNumLines;
}
// For the DigDistMsgReader Class: Prepares the variables that keep track of the
// lightbar message list position, current messsage number, etc.
function DigDistMsgReader_SetUpLightbarMsgListVars()
{
// If no search is specified or if reading personal email, then get the index
// of the user's last read message. Then, figure out which page it's on and
// set the lightbar list index & cursor position variables accordingly.

nightfox
committed
var lastReadMsgIdx = 0;
if (!this.SearchingAndResultObjsDefinedForCurSub() || this.readingPersonalEmail)

nightfox
committed
{
lastReadMsgIdx = this.GetLastReadMsgIdx();
if (lastReadMsgIdx == -1)
lastReadMsgIdx = 0;
}
else
{
// A search was specified. If reading personal email, then set the
// message index to the last read message.
if (this.readingPersonalEmail)
{
lastReadMsgIdx = this.GetLastReadMsgIdx();
if (lastReadMsgIdx == -1)
lastReadMsgIdx = 0;
}
}

nightfox
committed
var pageNum = findPageNumOfItemNum(lastReadMsgIdx+1, this.lightbarMsgListNumLines, this.NumMessages(),
this.reverseListOrder);

nightfox
committed
this.CalcLightbarMsgListTopIdx(pageNum);
var initialCursorRow = 0;
if (this.reverseListOrder)

nightfox
committed
initialCursorRow = this.lightbarMsgListStartScreenRow+(this.lightbarListTopMsgIdx-lastReadMsgIdx);
else
{
if (this.lightbarListTopMsgIdx > lastReadMsgIdx)
this.lightbarListTopMsgIdx -= this.lightbarMsgListNumLines;
initialCursorRow = this.lightbarMsgListStartScreenRow+(lastReadMsgIdx-this.lightbarListTopMsgIdx);
}
this.lightbarListSelectedMsgIdx = lastReadMsgIdx;
this.lightbarListCurPos = { x: 1, y: initialCursorRow };
}
// For the DigDistMsgReader Class: Writes the message list column headers at the
// top of the screen.
function DigDistMsgReader_WriteMsgListScreenTopHeader()
{
console.home();
// If we will be displaying the message group and sub-board in the
// header at the top of the screen (an additional 2 lines), then
// update nMaxLines and nListStartLine to account for this.
if (this.displayBoardInfoInHeader && canDoHighASCIIAndANSI()) // console.term_supports(USER_ANSI)
{
var curpos = console.getxy();
// Figure out the message group name
var msgGroupName = "";
// For the message group name, we can also use this.msgbase.cfg.grp_name in
// Synchronet 3.12 and higher.
if (this.msgbase.cfg != null)
msgGroupName = msg_area.grp_list[this.msgbase.cfg.grp_number].description;
else
msgGroupName = "Unspecified";
// Figure out the sub-board name
var subBoardName = "";
if (this.msgbase.cfg != null)
subBoardName = this.msgbase.cfg.description;
else if ((this.msgbase.subnum == -1) || (this.msgbase.subnum == 65535))
subBoardName = "Electronic Mail";
else
subBoardName = "Unspecified";
// Display the message group name
console.print(this.colors["msgListHeaderMsgGroupTextColor"] + "Msg group: " +
this.colors["msgListHeaderMsgGroupNameColor"] + msgGroupName);
console.cleartoeol(); // Fill to the end of the line with the current colors
// Display the sub-board name on the next line
++curpos.y;
console.gotoxy(curpos);
console.print(this.colors["msgListHeaderSubBoardTextColor"] + "Sub-board: " +
this.colors["msgListHeaderMsgSubBoardName"] + subBoardName);
6799
6800
6801
6802
6803
6804
6805
6806
6807
6808
6809
6810
6811
6812
6813
6814
6815
6816
6817
6818
6819
console.cleartoeol(); // Fill to the end of the line with the current colors
++curpos.y;
console.gotoxy(curpos);
}
// Write the message listing column headers
printf(this.colors["msgListColHeader"] + this.sHdrFormatStr, "Msg#", "From", "To", "Subject", "Date", "Time");
// Set the normal text attribute
console.print("\1n");
}
// For the DigDistMsgReader Class: Lists a screenful of message header information.
//
// Parameters:
// pTopIndex: The index (offset) of the top message
// pMaxLines: The maximum number of lines to output to the screen
//
// Return value: Boolean, whether or not the last message output to the
// screen is the last message in the sub-board.
function DigDistMsgReader_ListScreenfulOfMessages(pTopIndex, pMaxLines)
{
var atLastPage = false;
var curpos = console.getxy();
var msgIndex = 0;
if (this.reverseListOrder)
{
var endIndex = pTopIndex - pMaxLines + 1; // The index of the last message to display
for (msgIndex = pTopIndex; (msgIndex >= 0) && (msgIndex >= endIndex); --msgIndex)
{
// The following line which sets console.line_counter to 0 is a
// kludge to disable Synchronet's automatic pausing after a
// screenful of text, so that this script can have more control
// over screen pausing.
console.line_counter = 0;
// Get the message header (it will be a MsgHeader object) and
// display it.
msgHeader = this.GetMsgHdrByIdx(msgIndex);
if (msgHeader == null)
continue;
// Display the message info
this.PrintMessageInfo(msgHeader, false, msgIndex+1);
if (console.term_supports(USER_ANSI))
{
++curpos.y;
console.gotoxy(curpos);
}
else
console.crlf();
}
atLastPage = (msgIndex < 0);
}
else
{
var endIndex = pTopIndex + pMaxLines; // One past the last message index to display
for (msgIndex = pTopIndex; (msgIndex < this.NumMessages()) && (msgIndex < endIndex); ++msgIndex)
{
// The following line which sets console.line_counter to 0 is a
// kludge to disable Synchronet's automatic pausing after a
// screenful of text, so that this script can have more control
// over screen pausing.
console.line_counter = 0;
// Get the message header (it will be a MsgHeader object) and
// display it.
msgHeader = this.GetMsgHdrByIdx(msgIndex);
if (msgHeader == null)
continue;
// Display the message info
this.PrintMessageInfo(msgHeader, false, msgIndex+1);
if (console.term_supports(USER_ANSI))
{
++curpos.y;
console.gotoxy(curpos);
}
else
console.crlf();
}
atLastPage = (msgIndex == this.NumMessages());
}
return atLastPage;
}

nightfox
committed
// For the DigDistMsgReader Class: Displays the help screen for the message list.
//
// Parameters:

nightfox
committed
// pChgSubBoardAllowed: Whether or not changing to another sub-board is allowed
// pPauseAtEnd: Boolean, whether or not to pause at the end.

nightfox
committed
function DigDistMsgReader_DisplayMsgListHelp(pChgSubBoardAllowed, pPauseAtEnd)
{
DisplayProgramInfo();
// Display help specific to which interface is being used.
if (this.msgListUseLightbarListInterface)

nightfox
committed
this.DisplayLightbarMsgListHelp(false, pChgSubBoardAllowed);
else

nightfox
committed
this.DisplayTraditionalMsgListHelp(false, pChgSubBoardAllowed);
// If pPauseAtEnd is true, then output a newline and
// prompt the user whether or not to continue.
if (pPauseAtEnd)
console.pause();
}

nightfox
committed
// For the DigDistMsgReader Class: Displays help for the traditional-interface
// message list
//
// Parameters:
// pDisplayHeader: Whether or not to display a help header at the beginning

nightfox
committed
// pChgSubBoardAllowed: Whether or not changing to another sub-board is allowed
// pPauseAtEnd: Boolean, whether or not to pause at the end.

nightfox
committed
function DigDistMsgReader_DisplayTraditionalMsgListHelp(pDisplayHeader, pChgSubBoardAllowed, pPauseAtEnd)
6915
6916
6917
6918
6919
6920
6921
6922
6923
6924
6925
6926
6927
6928
6929
6930
6931
6932
6933
6934
6935
6936
6937
6938
6939
6940
6941
6942
6943
6944
6945
6946
6947
6948
6949
6950
6951
6952
6953
6954
6955
6956
6957
6958
6959
6960
6961
6962
6963
6964
6965
6966
6967
6968
6969
6970
6971
6972
6973
6974
6975
6976
6977
6978
6979
{
// If pDisplayHeader is true, then display the program information.
if (pDisplayHeader)
DisplayProgramInfo();
// Display information about the current sub-board and search results.
console.print("\1n\1cCurrently reading \1g" + subBoardGrpAndName(this.subBoardCode));
console.crlf();
// If the user isn't reading personal messages (i.e., is reading a sub-board),
// then output the total number of messages in the sub-board. We probably
// shouldn't output the total number of messages in the "mail" area, because
// that includes more than the current user's email.
if (this.subBoardCode != "mail")
{
console.print("\1n\1cThere are a total of \1g" + this.msgbase.total_msgs + " \1cmessages in the current area.");
console.crlf();
}
// If there is currently a search (which also includes personal messages),
// then output the number of search results/personal messages.
if (this.SearchingAndResultObjsDefinedForCurSub())
{
var numSearchResults = this.NumMessages();
var resultsWord = (numSearchResults > 1 ? "results" : "result");
console.print("\1n\1c");
if (this.readingPersonalEmail)
console.print("You have \1g" + numSearchResults + " \1c" + (numSearchResults == 1 ? "message" : "messages") + ".");
else
{
if (numSearchResults == 1)
console.print("There is \1g1 \1csearch result.");
else
console.print("There are \1g" + numSearchResults + " \1csearch results.");
}
console.crlf();
}
console.crlf();
console.print("\1n" + this.colors["tradInterfaceHelpScreenColor"]);
displayTextWithLineBelow("Page navigation and message selection", false,
this.colors["tradInterfaceHelpScreenColor"], "\1k\1h");
console.print(this.colors["tradInterfaceHelpScreenColor"]);
console.print("The message lister will display a page of message header information. At\r\n");
console.print("the end of each page, a prompt is displayed, allowing you to navigate to\r\n");
console.print("the next page, previous page, first page, or the last page. If you would\r\n");
console.print("like to read a message, you may type the message number, followed by\r\n");
console.print("the enter key if the message number is short. To quit the listing, press\r\n");
console.print("the Q key.\r\n\r\n");
this.DisplayMessageListNotesHelp();
console.crlf();
console.crlf();
displayTextWithLineBelow("Summary of the keyboard commands:", false,
this.colors["tradInterfaceHelpScreenColor"], "\1k\1h");
console.print(this.colors["tradInterfaceHelpScreenColor"]);
console.print("\1n\1h\1cN" + this.colors["tradInterfaceHelpScreenColor"] + ": Go to the next page\r\n");
console.print("\1n\1h\1cP" + this.colors["tradInterfaceHelpScreenColor"] + ": Go to the previous page\r\n");
console.print("\1n\1h\1cF" + this.colors["tradInterfaceHelpScreenColor"] + ": Go to the first page\r\n");
console.print("\1n\1h\1cL" + this.colors["tradInterfaceHelpScreenColor"] + ": Go to the last page\r\n");
console.print("\1n\1h\1cG" + this.colors["tradInterfaceHelpScreenColor"] + ": Go to a specific message by number (the message will appear at the top\r\n" +
" of the list)\r\n");
console.print("\1n\1h\1cNumber" + this.colors["tradInterfaceHelpScreenColor"] + ": Read the message corresponding with that number\r\n");
//console.print("The following commands are available only if you have permission to do so:\r\n");
if (this.CanDelete() || this.CanDeleteLastMsg())
console.print("\1n\1h\1cD" + this.colors["tradInterfaceHelpScreenColor"] + ": Mark a message for deletion\r\n");
if (this.CanEdit())
console.print("\1n\1h\1cE" + this.colors["tradInterfaceHelpScreenColor"] + ": Edit an existing message\r\n");

nightfox
committed
if (pChgSubBoardAllowed)
console.print("\1n\1h\1cC" + this.colors["tradInterfaceHelpScreenColor"] + ": Change to another message sub-board\r\n");
console.print("\1n\1h\1cS" + this.colors["tradInterfaceHelpScreenColor"] + ": Select messages (for batch delete, etc.)\r\n");
console.print("\1n" + this.colors["tradInterfaceHelpScreenColor"] + " A message number or multiple numbers can be entered separated by commas or\r\n");
console.print("\1n" + this.colors["tradInterfaceHelpScreenColor"] + " spaces. Additionally, a range of numbers (separated by a dash) can be used.\r\n");
console.print("\1n" + this.colors["tradInterfaceHelpScreenColor"] + " Examples:\r\n");
console.print("\1n" + this.colors["tradInterfaceHelpScreenColor"] + " 125\r\n");
console.print("\1n" + this.colors["tradInterfaceHelpScreenColor"] + " 1,2,3\r\n");
console.print("\1n" + this.colors["tradInterfaceHelpScreenColor"] + " 1 2 3\r\n");
console.print("\1n" + this.colors["tradInterfaceHelpScreenColor"] + " 1,2,10-20\r\n");
console.print("\1n\1h\1cCTRL-D" + this.colors["tradInterfaceHelpScreenColor"] + ": Batch delete selected messages\r\n");

nightfox
committed
console.print("\1n\1h\1cQ" + this.colors["tradInterfaceHelpScreenColor"] + ": Quit\r\n");
console.print("\1n\1h\1c?" + this.colors["tradInterfaceHelpScreenColor"] + ": Show this help screen\r\n\r\n");
// If pPauseAtEnd is true, then output a newline and
// prompt the user whether or not to continue.
if (pPauseAtEnd)
console.pause();
}

nightfox
committed
// For the DigDistMsgReader Class: Displays help for the lightbar message list