Skip to content
Snippets Groups Projects
Commit 517c1865 authored by Eric Oulashin's avatar Eric Oulashin Committed by Rob Swindell
Browse files

DDMsgReader: Settings for being able to read deleted messages now apply to...

DDMsgReader: Settings for being able to read deleted messages now apply to personal email (not just sub-boards), and not just appearing in the message list. (SCFG > Message Options > Users Can View Deleted Messages)
parent 07e8506a
No related branches found
No related tags found
2 merge requests!463MRC mods by Codefenix (2024-10-20),!290DDMsgReader: Settings for being able to read deleted messages now apply to personal email (not just sub-boards), and not just appearing in the message list. (SCFG > Message Options > Users Can View Deleted Messages)
...@@ -131,6 +131,10 @@ ...@@ -131,6 +131,10 @@
* 2023-04-25 Eric Oulashin Version 1.73a * 2023-04-25 Eric Oulashin Version 1.73a
* Refactored the functions for getting message header lines. Also, now * Refactored the functions for getting message header lines. Also, now
* all message header information is retrieved. * all message header information is retrieved.
* 2023-05-13 Eric Oulashin Version 1.74
* Settings for users being able to read deleted messages now applies to
* personal email. Also, allows reading messages that are marked for deletion
* in addition to just seeing them in the message list.
*/ */
   
"use strict"; "use strict";
...@@ -237,8 +241,8 @@ var ansiterm = require("ansiterm_lib.js", 'expand_ctrl_a'); ...@@ -237,8 +241,8 @@ var ansiterm = require("ansiterm_lib.js", 'expand_ctrl_a');
   
   
// Reader version information // Reader version information
var READER_VERSION = "1.73a"; var READER_VERSION = "1.74";
var READER_DATE = "2023-04-25"; var READER_DATE = "2023-05-13";
   
// Keyboard key codes for displaying on the screen // Keyboard key codes for displaying on the screen
var UP_ARROW = ascii(24); var UP_ARROW = ascii(24);
...@@ -2102,7 +2106,7 @@ function DigDistMsgReader_ReadOrListSubBoard(pSubBoardCode, pStartingMsgOffset, ...@@ -2102,7 +2106,7 @@ function DigDistMsgReader_ReadOrListSubBoard(pSubBoardCode, pStartingMsgOffset,
   
// Set the sub-board code if applicable // Set the sub-board code if applicable
var previousSubBoardCode = this.subBoardCode; var previousSubBoardCode = this.subBoardCode;
if (typeof(pSubBoardCode) == "string") if (typeof(pSubBoardCode) === "string")
{ {
if (subBoardCodeIsValid(pSubBoardCode)) if (subBoardCodeIsValid(pSubBoardCode))
this.setSubBoardCode(pSubBoardCode); this.setSubBoardCode(pSubBoardCode);
...@@ -2830,9 +2834,10 @@ function DigDistMsgReader_ReadMessages(pSubBoardCode, pStartingMsgOffset, pRetur ...@@ -2830,9 +2834,10 @@ function DigDistMsgReader_ReadMessages(pSubBoardCode, pStartingMsgOffset, pRetur
} }
   
// If the current message index is for a message that has been // If the current message index is for a message that has been
// deleted, then find the next non-deleted message. // deleted and the user is not able to read deleted messages, then find the next non-deleted message.
var testMsgHdr = this.GetMsgHdrByIdx(msgIndex); var testMsgHdr = this.GetMsgHdrByIdx(msgIndex);
if ((testMsgHdr == null) || ((testMsgHdr.attr & MSG_DELETE) == MSG_DELETE)) // TODO: Should this really allow reading messages that are marked for deletion?
if ((testMsgHdr == null) || (((testMsgHdr.attr & MSG_DELETE) == MSG_DELETE) && !canViewDeletedMsgs()))
{ {
// First try going forward // First try going forward
var nonDeletedMsgIdx = this.FindNextNonDeletedMsgIdx(msgIndex, true); var nonDeletedMsgIdx = this.FindNextNonDeletedMsgIdx(msgIndex, true);
...@@ -3018,9 +3023,10 @@ function DigDistMsgReader_ReadMessages(pSubBoardCode, pStartingMsgOffset, pRetur ...@@ -3018,9 +3023,10 @@ function DigDistMsgReader_ReadMessages(pSubBoardCode, pStartingMsgOffset, pRetur
else else
msgIndex = chgSubBoardRetObj.lastReadMsgIdx; msgIndex = chgSubBoardRetObj.lastReadMsgIdx;
// If the current message index is for a message that has been // If the current message index is for a message that has been
// deleted, then find the next non-deleted message. // deleted and the user is not able to read deleted messages, then find the next non-deleted message.
testMsgHdr = this.GetMsgHdrByIdx(msgIndex); testMsgHdr = this.GetMsgHdrByIdx(msgIndex);
if ((testMsgHdr == null) || ((testMsgHdr.attr & MSG_DELETE) == MSG_DELETE)) // TODO: Should this really allow reading deleted messages?
if ((testMsgHdr == null) || (((testMsgHdr.attr & MSG_DELETE) == MSG_DELETE) && !canViewDeletedMsgs()))
{ {
// First try going forward // First try going forward
var nonDeletedMsgIdx = this.FindNextNonDeletedMsgIdx(msgIndex, true); var nonDeletedMsgIdx = this.FindNextNonDeletedMsgIdx(msgIndex, true);
...@@ -8342,129 +8348,82 @@ function DigDistMsgReader_ReadConfigFile() ...@@ -8342,129 +8348,82 @@ function DigDistMsgReader_ReadConfigFile()
if (cfgFile.open("r")) if (cfgFile.open("r"))
{ {
this.cfgFileSuccessfullyRead = true; this.cfgFileSuccessfullyRead = true;
var settingsObj = cfgFile.iniGetObject();
cfgFile.close();
   
var fileLine = null; // A line read from the file var numSpaces = parseInt(settingsObj["tabSpaces"]);
var equalsPos = 0; // Position of a = in the line if (!isNaN(numSpaces) && numSpaces > 0)
var commentPos = 0; // Position of the start of a comment this.numTabSpaces = numSpaces;
var setting = null; // A setting name (string) var maxNumLines = parseInt(settingsObj["areaChooserHdrMaxLines"]);
var settingUpper = null; // Upper-case setting name if (!isNaN(maxNumLines) && maxNumLines > 0)
var value = null; // To store a value for a setting (string) this.areaChooserHdrMaxLines = maxNumLines;
var valueUpper = null; // Upper-cased value for a setting (string) var numberVal = parseInt(settingsObj["quickUserValSetIndex"]);
while (!cfgFile.eof) if (!isNaN(numberVal) && numberVal > -1)
{ this.quickUserValSetIndex = numberVal;
// Read the next line from the config file. if (settingsObj.hasOwnProperty("listInterfaceStyle") && typeof(settingsObj.listInterfaceStyle) === "string")
fileLine = cfgFile.readln(2048); this.msgListUseLightbarListInterface = (settingsObj.listInterfaceStyle.toUpperCase() == "LIGHTBAR");
if (settingsObj.hasOwnProperty("reverseListOrder"))
// fileLine should be a string, but I've seen some cases {
// where it isn't, so check its type. var valType = typeof(settingsObj.reverseListOrder);
if (typeof(fileLine) != "string") if (valType === "boolean")
continue; this.reverseListOrder = settingsObj.reverseListOrder;
else if (valType === "string")
// If the line starts with with a semicolon (the comment this.reverseListOrder = (settingsObj.reverseListOrder.toUpperCase() == "ASK");
// character) or is blank, then skip it. }
if ((fileLine.substr(0, 1) == ";") || (fileLine.length == 0)) if (typeof(settingsObj["readerInterfaceStyle"]) === "string")
continue; this.scrollingReaderInterface = (settingsObj.readerInterfaceStyle.toUpperCase() == "SCROLLABLE");
if (typeof(settingsObj["readerInterfaceStyleForANSIMessages"]) === "string")
// If the line has a semicolon anywhere in it, then remove this.useScrollingInterfaceForANSIMessages = (settingsObj.readerInterfaceStyleForANSIMessages.toUpperCase() == "SCROLLABLE");
// everything from the semicolon onward. if (typeof(settingsObj["displayBoardInfoInHeader"]) === "boolean")
commentPos = fileLine.indexOf(";"); this.displayBoardInfoInHeader = settingsObj.displayBoardInfoInHeader;
if (commentPos > -1) if (typeof(settingsObj["promptToContinueListingMessages"]) === "boolean")
fileLine = fileLine.substr(0, commentPos); this.promptToContinueListingMessages = settingsObj.promptToContinueListingMessages;
if (typeof(settingsObj["promptConfirmReadMessage"]) === "boolean")
// Look for an equals sign, and if found, separate the line this.promptToReadMessage = settingsObj.promptConfirmReadMessage;
// into the setting name (before the =) and the value (after the if (typeof(settingsObj["msgListDisplayTime"]) === "string")
// equals sign). this.msgList_displayMessageDateImported = (settingsObj.msgListDisplayTime.toUpperCase() == "IMPORTED");
equalsPos = fileLine.indexOf("="); if (typeof(settingsObj["msgAreaList_lastImportedMsg_time"]) === "string")
if (equalsPos > 0) this.msgAreaList_lastImportedMsg_showImportTime = (settingsObj.msgAreaList_lastImportedMsg_time.toUpperCase() == "IMPORTED");
{ if (typeof(settingsObj["startMode"]) === "string")
// Read the setting & value, and trim leading & trailing spaces. {
setting = trimSpaces(fileLine.substr(0, equalsPos), true, false, true); var valueUpper = settingsObj.startMode.toUpperCase();
settingUpper = setting.toUpperCase();
value = trimSpaces(fileLine.substr(equalsPos+1), true, false, true);
valueUpper = value.toUpperCase();
// Set the appropriate valueUpper in the settings object.
if (settingUpper == "LISTINTERFACESTYLE")
this.msgListUseLightbarListInterface = (valueUpper == "LIGHTBAR");
else if (settingUpper == "READERINTERFACESTYLE")
this.scrollingReaderInterface = (valueUpper == "SCROLLABLE");
else if (settingUpper == "READERINTERFACESTYLEFORANSIMESSAGES")
this.useScrollingInterfaceForANSIMessages = (valueUpper == "SCROLLABLE");
else if (settingUpper == "DISPLAYBOARDINFOINHEADER")
this.displayBoardInfoInHeader = (valueUpper == "TRUE");
// Note: this.reverseListOrder can be true, false, or "ASK"
else if (settingUpper == "REVERSELISTORDER")
this.reverseListOrder = (valueUpper == "ASK" ? "ASK" : (valueUpper == "TRUE"));
else if (settingUpper == "PROMPTTOCONTINUELISTINGMESSAGES")
this.promptToContinueListingMessages = (valueUpper == "TRUE");
else if (settingUpper == "PROMPTCONFIRMREADMESSAGE")
this.promptToReadMessage = (valueUpper == "TRUE");
else if (settingUpper == "MSGLISTDISPLAYTIME")
this.msgList_displayMessageDateImported = (valueUpper == "IMPORTED");
else if (settingUpper == "MSGAREALIST_LASTIMPORTEDMSG_TIME")
this.msgAreaList_lastImportedMsg_showImportTime = (valueUpper == "IMPORTED");
else if (settingUpper == "STARTMODE")
{
if ((valueUpper == "READER") || (valueUpper == "READ")) if ((valueUpper == "READER") || (valueUpper == "READ"))
this.startMode = READER_MODE_READ; this.startMode = READER_MODE_READ;
else if ((valueUpper == "LISTER") || (valueUpper == "LIST")) else if ((valueUpper == "LISTER") || (valueUpper == "LIST"))
this.startMode = READER_MODE_LIST; this.startMode = READER_MODE_LIST;
} }
else if (settingUpper == "TABSPACES") if (typeof(settingsObj["pauseAfterNewMsgScan"]) === "boolean")
{ this.pauseAfterNewMsgScan = settingsObj.pauseAfterNewMsgScan;
var numSpaces = parseInt(value); if (typeof(settingsObj["readingPostOnSubBoardInsteadOfGoToNext"]) === "boolean")
// If greater than 0, then set this.numTabSpaces this.readingPostOnSubBoardInsteadOfGoToNext = settingsObj.readingPostOnSubBoardInsteadOfGoToNext;
if (!isNaN(numSpaces) && numSpaces > 0) if (typeof(settingsObj["areaChooserHdrFilenameBase"]) === "string")
this.numTabSpaces = numSpaces; this.areaChooserHdrFilenameBase = settingsObj.areaChooserHdrFilenameBase;
} if (typeof(settingsObj["displayAvatars"]) === "boolean")
else if (settingUpper == "PAUSEAFTERNEWMSGSCAN") this.displayAvatars = settingsObj.displayAvatars;
this.pauseAfterNewMsgScan = (valueUpper == "TRUE"); if (typeof(settingsObj["rightJustifyAvatars"]) === "boolean")
else if (settingUpper == "READINGPOSTONSUBBOARDINSTEADOFGOTONEXT") this.rightJustifyAvatar = settingsObj.rightJustifyAvatars;
this.readingPostOnSubBoardInsteadOfGoToNext = (valueUpper == "TRUE"); if (typeof(settingsObj["msgListSort"]) === "string")
else if (settingUpper == "AREACHOOSERHDRFILENAMEBASE") {
this.areaChooserHdrFilenameBase = value; if (settingsObj.msgListSort.toUpperCase() == "WRITTEN")
else if (settingUpper == "AREACHOOSERHDRMAXLINES") this.msgListSort = MSG_LIST_SORT_DATETIME_WRITTEN;
{
var maxNumLines = parseInt(value);
if (!isNaN(maxNumLines) && maxNumLines > 0)
this.areaChooserHdrMaxLines = maxNumLines;
} }
else if (settingUpper == "THEMEFILENAME") if (typeof(settingsObj["convertYStyleMCIAttrsToSync"]) === "boolean")
this.convertYStyleMCIAttrsToSync = settingsObj.convertYStyleMCIAttrsToSync;
if (typeof(settingsObj["prependFowardMsgSubject"]) === "boolean")
this.prependFowardMsgSubject = settingsObj.prependFowardMsgSubject;
if (typeof(settingsObj["enableIndexedModeMsgListCache"]) === "boolean")
this.enableIndexedModeMsgListCache = settingsObj.enableIndexedModeMsgListCache;
if (typeof(settingsObj["themeFilename"]) === "string")
{ {
// First look for the theme config file in the sbbs/mods // First look for the theme config file in the sbbs/mods
// directory, then sbbs/ctrl, then the same directory as // directory, then sbbs/ctrl, then the same directory as
// this script. // this script.
themeFilename = system.mods_dir + value; themeFilename = system.mods_dir + settingsObj.themeFilename;
if (!file_exists(themeFilename)) if (!file_exists(themeFilename))
themeFilename = system.ctrl_dir + value; themeFilename = system.ctrl_dir + settingsObj.themeFilename;
if (!file_exists(themeFilename)) if (!file_exists(themeFilename))
themeFilename = gStartupPath + value; themeFilename = gStartupPath + settingsObj.themeFilename;
}
else if (settingUpper == "DISPLAYAVATARS")
this.displayAvatars = (valueUpper == "TRUE");
else if (settingUpper == "RIGHTJUSTIFYAVATARS")
this.rightJustifyAvatar = (valueUpper == "TRUE");
else if (settingUpper == "MSGLISTSORT")
{
if (valueUpper == "WRITTEN")
this.msgListSort = MSG_LIST_SORT_DATETIME_WRITTEN;
} }
else if (settingUpper == "CONVERTYSTYLEMCIATTRSTOSYNC")
this.convertYStyleMCIAttrsToSync = (valueUpper == "TRUE");
else if (settingUpper == "PREPENDFOWARDMSGSUBJECT")
this.prependFowardMsgSubject = (valueUpper == "TRUE");
else if (settingUpper == "ENABLEINDEXEDMODEMSGLISTCACHE")
this.enableIndexedModeMsgListCache = (valueUpper == "TRUE");
else if (settingUpper == "QUICKUSERVALSETINDEX")
{
var numberVal = parseInt(value);
if (!isNaN(numberVal) && numberVal > -1)
this.quickUserValSetIndex = numberVal;
}
}
}
cfgFile.close();
} }
else else
{ {
...@@ -8482,157 +8441,42 @@ function DigDistMsgReader_ReadConfigFile() ...@@ -8482,157 +8441,42 @@ function DigDistMsgReader_ReadConfigFile()
// from it. // from it.
if (themeFilename.length > 0) if (themeFilename.length > 0)
{ {
var onlySyncAttrsRegexWholeWord = new RegExp("^[\x01krgybmcw01234567hinq,;\.dtlasz]+$", 'i');
var themeFile = new File(themeFilename); var themeFile = new File(themeFilename);
if (themeFile.open("r")) if (themeFile.open("r"))
{ {
var fileLine = null; // A line read from the file var themeSettingsObj = themeFile.iniGetObject();
var equalsPos = 0; // Position of a = in the line themeFile.close();
var commentPos = 0; // Position of the start of a comment
var setting = null; // A setting name (string)
var value = null; // To store a value for a setting (string)
// A regex for attribute settings - Note that this doesn't contain some of the control codes
var onlySyncAttrsRegexWholeWord = new RegExp("^[\x01krgybmcw01234567hinq,;\.dtlasz]+$", 'i');
while (!themeFile.eof)
{
// Read the next line from the config file.
fileLine = themeFile.readln(2048);
// fileLine should be a string, but I've seen some cases
// where it isn't, so check its type.
if (typeof(fileLine) != "string")
continue;
// If the line starts with with a semicolon (the comment
// character) or is blank, then skip it.
if ((fileLine.substr(0, 1) == ";") || (fileLine.length == 0))
continue;
   
// If the line has a semicolon anywhere in it, then remove // Set any color values specified
// everything from the semicolon onward. for (var prop in this.colors)
commentPos = fileLine.indexOf(";"); {
if (commentPos > -1) //themeSettingsObj.hasOwnProperty(prop)
fileLine = fileLine.substr(0, commentPos); if (typeof(themeSettingsObj[prop]) === "string")
// Look for an equals sign, and if found, separate the line
// into the setting name (before the =) and the value (after the
// equals sign).
equalsPos = fileLine.indexOf("=");
if (equalsPos > 0)
{
// Read the setting (without leading/trailing spaces) & value
setting = trimSpaces(fileLine.substr(0, equalsPos), true, false, true);
value = fileLine.substr(equalsPos+1);
// Colors
if ((setting == "msgListHeaderMsgGroupTextColor") || (setting == "msgListHeaderMsgGroupNameColor") ||
(setting == "msgListHeaderSubBoardTextColor") || (setting == "msgListHeaderMsgSubBoardName") ||
(setting == "msgListColHeader") ||
(setting == "msgListMsgNumColor") || (setting == "msgListFromColor") ||
(setting == "msgListToColor") || (setting == "msgListSubjectColor") ||
(setting == "msgListDateColor") || (setting == "msgListTimeColor") ||
(setting == "msgListToUserMsgNumColor") || (setting == "msgListToUserFromColor") ||
(setting == "msgListToUserToColor") || (setting == "msgListToUserSubjectColor") ||
(setting == "msgListToUserDateColor") || (setting == "msgListToUserTimeColor") ||
(setting == "msgListFromUserMsgNumColor") || (setting == "msgListFromUserFromColor") ||
(setting == "msgListFromUserToColor") || (setting == "msgListFromUserSubjectColor") ||
(setting == "msgListFromUserDateColor") || (setting == "msgListFromUserTimeColor") ||
(setting == "msgListHighlightBkgColor") || (setting == "msgListMsgNumHighlightColor") ||
(setting == "msgListFromHighlightColor") || (setting == "msgListToHighlightColor") ||
(setting == "msgListSubjHighlightColor") || (setting == "msgListDateHighlightColor") ||
(setting == "msgListTimeHighlightColor") || (setting == "lightbarMsgListHelpLineBkgColor") ||
(setting == "lightbarMsgListHelpLineGeneralColor") || (setting == "lightbarMsgListHelpLineHotkeyColor") ||
(setting == "lightbarMsgListHelpLineParenColor") || (setting == "tradInterfaceContPromptMainColor") ||
(setting == "tradInterfaceContPromptHotkeyColor") || (setting == "tradInterfaceContPromptUserInputColor") ||
(setting == "msgBodyColor") || (setting == "readMsgConfirmColor") ||
(setting == "readMsgConfirmNumberColor") ||
(setting == "afterReadMsg_ListMorePromptColor") ||
(setting == "tradInterfaceHelpScreenColor") || (setting == "areaChooserMsgAreaNumColor") ||
(setting == "areaChooserMsgAreaDescColor") || (setting == "areaChooserMsgAreaNumItemsColor") ||
(setting == "areaChooserMsgAreaHeaderColor") || (setting == "areaChooserSubBoardHeaderColor") ||
(setting == "areaChooserMsgAreaMarkColor") || (setting == "areaChooserMsgAreaLatestDateColor") ||
(setting == "areaChooserMsgAreaLatestTimeColor") || (setting == "areaChooserMsgAreaBkgHighlightColor") ||
(setting == "areaChooserMsgAreaNumHighlightColor") || (setting == "areaChooserMsgAreaDescHighlightColor") ||
(setting == "areaChooserMsgAreaDateHighlightColor") || (setting == "areaChooserMsgAreaTimeHighlightColor") ||
(setting == "areaChooserMsgAreaNumItemsHighlightColor") || (setting == "lightbarAreaChooserHelpLineBkgColor") ||
(setting == "lightbarAreaChooserHelpLineGeneralColor") || (setting == "lightbarAreaChooserHelpLineHotkeyColor") ||
(setting == "lightbarAreaChooserHelpLineParenColor") || (setting == "scrollbarBGColor") ||
(setting == "scrollbarScrollBlockColor") || (setting == "enhReaderPromptSepLineColor") ||
(setting == "enhReaderHelpLineBkgColor") || (setting == "enhReaderHelpLineGeneralColor") ||
(setting == "enhReaderHelpLineHotkeyColor") || (setting == "enhReaderHelpLineParenColor") ||
(setting == "hdrLineLabelColor") || (setting == "hdrLineValueColor") ||
(setting == "selectedMsgMarkColor") || (setting == "msgListScoreColor") ||
(setting == "msgListToUserScoreColor") || (setting == "msgListFromUserScoreColor") ||
(setting == "msgListScoreHighlightColor") || (setting == "msgHdrMsgNumColor") ||
(setting == "msgHdrFromColor") || (setting == "msgHdrToColor") ||
(setting == "msgHdrToUserColor") || (setting == "msgHdrSubjColor") ||
(setting == "msgHdrDateColor") || (setting == "lightbarIndexedModeHelpLineBkgColor") ||
(setting == "lightbarIndexedModeHelpLineHotkeyColor") || (setting == "lightbarIndexedModeHelpLineGeneralColor") ||
(setting == "lightbarIndexedModeHelpLineParenColor") || (setting == "indexMenuDesc") || (setting == "indexMenuTotalMsgs") ||
(setting == "indexMenuNumNewMsgs") || (setting == "indexMenuLastPostDate") ||
(setting == "indexMenuHighlightBkg") || (setting == "indexMenuDescHighlight") ||
(setting == "indexMenuTotalMsgsHighlight") || (setting == "indexMenuNumNewMsgsHighlight") ||
(setting == "indexMenuLastPostDateHighlight"))
{ {
// Trim spaces from the color value // Trim spaces from the color value
value = trimSpaces(value, true, true, true); var value = trimSpaces(themeSettingsObj[prop], true, true, true);
value = value.replace(/\\x01/g, "\x01"); // Replace "\x01" with control character value = value.replace(/\\x01/g, "\x01"); // Replace "\x01" with control character
// If the value doesn't have any control characters, then add the control character // If the value doesn't have any control characters, then add the control character
// before attribute characters // before attribute characters
if (!/\x01/.test(value)) if (!/\x01/.test(value))
value = attrCodeStr(value); value = attrCodeStr(value);
if (onlySyncAttrsRegexWholeWord.test(value)) if (onlySyncAttrsRegexWholeWord.test(value))
this.colors[setting] = value; this.colors[prop] = value;
} }
// Text values }
else if ((setting == "scrollbarBGChar") || // Set any text strings specified
(setting == "scrollbarScrollBlockChar") || for (var prop in this.text)
(setting == "goToPrevMsgAreaPromptText") || {
(setting == "goToNextMsgAreaPromptText") || if (typeof(themeSettingsObj[prop]) === "string")
(setting == "newMsgScanText") ||
(setting == "newToYouMsgScanText") ||
(setting == "allToYouMsgScanText") ||
(setting == "goToMsgNumPromptText") ||
(setting == "msgScanCompleteText") ||
(setting == "msgScanAbortedText") ||
(setting == "msgSearchAbortedText") ||
(setting == "deleteMsgNumPromptText") ||
(setting == "editMsgNumPromptText") ||
(setting == "noMessagesInSubBoardText") ||
(setting == "noSearchResultsInSubBoardText") ||
(setting == "invalidMsgNumText") ||
(setting == "readMsgNumPromptText") ||
(setting == "msgHasBeenDeletedText") ||
(setting == "noHdrLinesForThisMsgText") ||
(setting == "noKludgeLinesForThisMsgText") ||
(setting == "searchingPersonalMailText") ||
(setting == "searchingSubBoardAbovePromptText") ||
(setting == "searchingSubBoardText") ||
(setting == "scanningSubBoardText") ||
(setting == "searchTextPromptText") ||
(setting == "fromNamePromptText") ||
(setting == "toNamePromptText") ||
(setting == "abortedText") ||
(setting == "loadingPersonalMailText") ||
(setting == "msgDelConfirmText") ||
(setting == "msgUndelConfirmText") ||
(setting == "selectedMsgsUndeletedText") ||
(setting == "msgDeletedText") ||
(setting == "msgUndeletedText") ||
(setting == "cannotDeleteMsgText_notYoursNotASysop") ||
(setting == "cannotDeleteMsgText_notLastPostedMsg") ||
(setting == "msgEditConfirmText") ||
(setting == "noPersonalEmailText") ||
(setting == "postOnSubBoard"))
{ {
// Replace any instances of "\x01" with the Synchronet // Replace any instances of "\x01" with the Synchronet
// attribute control character // attribute control character
this.text[setting] = value.replace(/\\x01/g, "\x01"); this.text[prop] = themeSettingsObj[prop].replace(/\\x01/g, "\x01");
}
} }
} }
   
themeFile.close();
// Ensure that scrollbarBGChar and scrollbarScrollBlockChar are // Ensure that scrollbarBGChar and scrollbarScrollBlockChar are
// only one character. If they're longer, use only the first // only one character. If they're longer, use only the first
// character. // character.
...@@ -13526,7 +13370,7 @@ function DigDistMsgReader_FindThreadNextOffset(pMsgHdr, pThreadType, pPositionCu ...@@ -13526,7 +13370,7 @@ function DigDistMsgReader_FindThreadNextOffset(pMsgHdr, pThreadType, pPositionCu
for (var messageIdx = this.GetMsgIdx(pMsgHdr.number)+1; (messageIdx < numOfMessages) && (nextMsgOffset == -1); ++messageIdx) for (var messageIdx = this.GetMsgIdx(pMsgHdr.number)+1; (messageIdx < numOfMessages) && (nextMsgOffset == -1); ++messageIdx)
{ {
nextMsgHdr = this.GetMsgHdrByIdx(messageIdx); nextMsgHdr = this.GetMsgHdrByIdx(messageIdx);
if (((nextMsgHdr.attr & MSG_DELETE) == 0) && (typeof(nextMsgHdr.thread_id) == "number") && (nextMsgHdr.thread_id == pMsgHdr.thread_id)) if ((((nextMsgHdr.attr & MSG_DELETE) == 0) || canViewDeletedMsgs()) && (typeof(nextMsgHdr.thread_id) == "number") && (nextMsgHdr.thread_id == pMsgHdr.thread_id))
{ {
//nextMsgOffset = nextMsgHdr.offset; //nextMsgOffset = nextMsgHdr.offset;
nextMsgOffset = this.GetMsgIdx(nextMsgHdr.number); nextMsgOffset = this.GetMsgIdx(nextMsgHdr.number);
...@@ -13573,21 +13417,21 @@ function DigDistMsgReader_FindThreadNextOffset(pMsgHdr, pThreadType, pPositionCu ...@@ -13573,21 +13417,21 @@ function DigDistMsgReader_FindThreadNextOffset(pMsgHdr, pThreadType, pPositionCu
// Remove any leading & trailing whitespace from the subject // Remove any leading & trailing whitespace from the subject
subjUppercase = trimSpaces(subjUppercase, true, true, true); subjUppercase = trimSpaces(subjUppercase, true, true, true);
msgHdrMatch = function(pMsgHdr) { msgHdrMatch = function(pMsgHdr) {
return (((pMsgHdr.attr & MSG_DELETE) == 0) && (pMsgHdr.subject.toUpperCase().indexOf(subjUppercase, 0) > -1)); return ((((pMsgHdr.attr & MSG_DELETE) == 0) || canViewDeletedMsgs()) && (pMsgHdr.subject.toUpperCase().indexOf(subjUppercase, 0) > -1));
}; };
} }
else if (pThreadType == THREAD_BY_AUTHOR) else if (pThreadType == THREAD_BY_AUTHOR)
{ {
fromNameUppercase = pMsgHdr.from.toUpperCase(); fromNameUppercase = pMsgHdr.from.toUpperCase();
msgHdrMatch = function(pMsgHdr) { msgHdrMatch = function(pMsgHdr) {
return (((pMsgHdr.attr & MSG_DELETE) == 0) && (pMsgHdr.from.toUpperCase() == fromNameUppercase)); return ((((pMsgHdr.attr & MSG_DELETE) == 0) || canViewDeletedMsgs()) && (pMsgHdr.from.toUpperCase() == fromNameUppercase));
}; };
} }
else if (pThreadType == THREAD_BY_TO_USER) else if (pThreadType == THREAD_BY_TO_USER)
{ {
toNameUppercase = pMsgHdr.to.toUpperCase(); toNameUppercase = pMsgHdr.to.toUpperCase();
msgHdrMatch = function(pMsgHdr) { msgHdrMatch = function(pMsgHdr) {
return (((pMsgHdr.attr & MSG_DELETE) == 0) && (pMsgHdr.to.toUpperCase() == toNameUppercase)); return ((((pMsgHdr.attr & MSG_DELETE) == 0) || canViewDeletedMsgs()) && (pMsgHdr.to.toUpperCase() == toNameUppercase));
}; };
} }
   
...@@ -13716,7 +13560,7 @@ function DigDistMsgReader_FindThreadPrevOffset(pMsgHdr, pThreadType, pPositionCu ...@@ -13716,7 +13560,7 @@ function DigDistMsgReader_FindThreadPrevOffset(pMsgHdr, pThreadType, pPositionCu
for (var messageIdx = this.GetMsgIdx(pMsgHdr.number)-1; (messageIdx >= 0) && (nextMsgOffset == -1); --messageIdx) for (var messageIdx = this.GetMsgIdx(pMsgHdr.number)-1; (messageIdx >= 0) && (nextMsgOffset == -1); --messageIdx)
{ {
prevMsgHdr = this.GetMsgHdrByIdx(messageIdx); prevMsgHdr = this.GetMsgHdrByIdx(messageIdx);
if (((prevMsgHdr.attr & MSG_DELETE) == 0) && (typeof(prevMsgHdr.thread_id) == "number") && (prevMsgHdr.thread_id == pMsgHdr.thread_id)) if ((((prevMsgHdr.attr & MSG_DELETE) == 0) || canViewDeletedMsgs()) && (typeof(prevMsgHdr.thread_id) == "number") && (prevMsgHdr.thread_id == pMsgHdr.thread_id))
{ {
//nextMsgOffset = prevMsgHdr.offset; //nextMsgOffset = prevMsgHdr.offset;
nextMsgOffset = this.GetMsgIdx(prevMsgHdr.number); nextMsgOffset = this.GetMsgIdx(prevMsgHdr.number);
...@@ -13817,21 +13661,21 @@ function DigDistMsgReader_FindThreadPrevOffset(pMsgHdr, pThreadType, pPositionCu ...@@ -13817,21 +13661,21 @@ function DigDistMsgReader_FindThreadPrevOffset(pMsgHdr, pThreadType, pPositionCu
// Remove any leading & trailing whitespace from the subject // Remove any leading & trailing whitespace from the subject
subjUppercase = trimSpaces(subjUppercase, true, true, true); subjUppercase = trimSpaces(subjUppercase, true, true, true);
msgHdrMatch = function(pMsgHdr) { msgHdrMatch = function(pMsgHdr) {
return (((pMsgHdr.attr & MSG_DELETE) == 0) && (pMsgHdr.subject.toUpperCase().indexOf(subjUppercase, 0) > -1)); return ((((pMsgHdr.attr & MSG_DELETE) == 0) || canViewDeletedMsgs()) && (pMsgHdr.subject.toUpperCase().indexOf(subjUppercase, 0) > -1));
}; };
} }
else if (pThreadType == THREAD_BY_AUTHOR) else if (pThreadType == THREAD_BY_AUTHOR)
{ {
fromNameUppercase = pMsgHdr.from.toUpperCase(); fromNameUppercase = pMsgHdr.from.toUpperCase();
msgHdrMatch = function(pMsgHdr) { msgHdrMatch = function(pMsgHdr) {
return (((pMsgHdr.attr & MSG_DELETE) == 0) && (pMsgHdr.from.toUpperCase() == fromNameUppercase)); return ((((pMsgHdr.attr & MSG_DELETE) == 0) || canViewDeletedMsgs()) && (pMsgHdr.from.toUpperCase() == fromNameUppercase));
}; };
} }
else if (pThreadType == THREAD_BY_TO_USER) else if (pThreadType == THREAD_BY_TO_USER)
{ {
toNameUppercase = pMsgHdr.to.toUpperCase(); toNameUppercase = pMsgHdr.to.toUpperCase();
msgHdrMatch = function(pMsgHdr) { msgHdrMatch = function(pMsgHdr) {
return (((pMsgHdr.attr & MSG_DELETE) == 0) && (pMsgHdr.to.toUpperCase() == toNameUppercase)); return ((((pMsgHdr.attr & MSG_DELETE) == 0) || canViewDeletedMsgs()) && (pMsgHdr.to.toUpperCase() == toNameUppercase));
}; };
} }
   
...@@ -16127,6 +15971,17 @@ function DigDistMsgReader_GetMsgBody(pMsgHdr) ...@@ -16127,6 +15971,17 @@ function DigDistMsgReader_GetMsgBody(pMsgHdr)
} }
} }
   
// If this message has been marked for deletion, prepend a couple lines saying so
if ((pMsgHdr.attr & MSG_DELETE) == MSG_DELETE)
{
var deletedNotice = "\x01n\x01h\x01yThis message has been marked for deletion.";
if (user.is_sysop)
deletedNotice += " To un-mark, return to the message list and press U to un-mark this message.";
deletedNotice += "\x01n\r\n\r\n";
retObj.msgBody = deletedNotice + retObj.msgBody;
}
return retObj; return retObj;
} }
   
...@@ -17032,7 +16887,7 @@ function numMsgsInSubBoard(pSubBoardCode, pIncludeDeleted) ...@@ -17032,7 +16887,7 @@ function numMsgsInSubBoard(pSubBoardCode, pIncludeDeleted)
for (var msgIdx = 0; msgIdx < msgbase.total_msgs; ++msgIdx) for (var msgIdx = 0; msgIdx < msgbase.total_msgs; ++msgIdx)
{ {
var msgHdr = msgbase.get_msg_header(true, msgIdx, false); var msgHdr = msgbase.get_msg_header(true, msgIdx, false);
if ((msgHdr != null) && ((msgHdr.attr & MSG_DELETE) == 0)) if ((msgHdr != null) && (((msgHdr.attr & MSG_DELETE) == 0) || canViewDeletedMsgs()))
++numMessages; ++numMessages;
} }
} }
...@@ -17646,7 +17501,7 @@ function searchMsgbase(pSubCode, pSearchType, pSearchString, pListingPersonalEma ...@@ -17646,7 +17501,7 @@ function searchMsgbase(pSubCode, pSearchType, pSearchString, pListingPersonalEma
matchFn = function(pSearchStr, pMsgHdr, pMsgBase, pSubBoardCode) { matchFn = function(pSearchStr, pMsgHdr, pMsgBase, pSubBoardCode) {
// See if the message is not marked as deleted and the 'To' name // See if the message is not marked as deleted and the 'To' name
// matches the user's handle, alias, and/or username. // matches the user's handle, alias, and/or username.
return (((pMsgHdr.attr & MSG_DELETE) == 0) && userNameHandleAliasMatch(pMsgHdr.to)); return ((((pMsgHdr.attr & MSG_DELETE) == 0) || canViewDeletedMsgs()) && userNameHandleAliasMatch(pMsgHdr.to));
} }
break; break;
case SEARCH_TO_USER_NEW_SCAN: case SEARCH_TO_USER_NEW_SCAN:
...@@ -17694,7 +17549,7 @@ function searchMsgbase(pSubCode, pSearchType, pSearchString, pListingPersonalEma ...@@ -17694,7 +17549,7 @@ function searchMsgbase(pSubCode, pSearchType, pSearchString, pListingPersonalEma
// Note: This assumes pSubBoardCode is not "mail" (personal mail). // Note: This assumes pSubBoardCode is not "mail" (personal mail).
// See if the message 'To' name matches the user's handle, alias, // See if the message 'To' name matches the user's handle, alias,
// and/or username and is not marked as deleted and is unread. // and/or username and is not marked as deleted and is unread.
return (((pMsgHdr.attr & MSG_DELETE) == 0) && ((pMsgHdr.attr & MSG_READ) == 0) && userNameHandleAliasMatch(pMsgHdr.to)); return ((((pMsgHdr.attr & MSG_DELETE) == 0) || canViewDeletedMsgs()) && ((pMsgHdr.attr & MSG_READ) == 0) && userNameHandleAliasMatch(pMsgHdr.to));
} }
break; break;
case SEARCH_MSG_NEWSCAN: case SEARCH_MSG_NEWSCAN:
...@@ -17792,8 +17647,8 @@ function msgIsToUserByNum(pMsgHdr, pUserNum) ...@@ -17792,8 +17647,8 @@ function msgIsToUserByNum(pMsgHdr, pUserNum)
{ {
if (typeof(pMsgHdr) != "object") if (typeof(pMsgHdr) != "object")
return false; return false;
// Return false if the message is marked as deleted // Return false if the message is marked as deleted and the user can't read deleted messages
if ((pMsgHdr.attr & MSG_DELETE) == MSG_DELETE) if (((pMsgHdr.attr & MSG_DELETE) == MSG_DELETE) && !canViewDeletedMsgs())
return false; return false;
   
var userNum = user.number; var userNum = user.number;
...@@ -17825,8 +17680,8 @@ function msgIsFromUser(pMsgHdr, pUserNum) ...@@ -17825,8 +17680,8 @@ function msgIsFromUser(pMsgHdr, pUserNum)
{ {
if (typeof(pMsgHdr) != "object") if (typeof(pMsgHdr) != "object")
return false; return false;
// Return false if the message is marked as deleted // Return false if the message is marked as deleted and the user can't read deleted messages
if ((pMsgHdr.attr & MSG_DELETE) == MSG_DELETE) if (((pMsgHdr.attr & MSG_DELETE) == MSG_DELETE) && !canViewDeletedMsgs())
return false; return false;
   
var pUserNumIsValid = (typeof(pUserNum) === "number" && pUserNum > 0 && pUserNum <= system.lastuser); var pUserNumIsValid = (typeof(pUserNum) === "number" && pUserNum > 0 && pUserNum <= system.lastuser);
...@@ -18945,21 +18800,8 @@ function isReadableMsgHdr(pMsgHdr, pSubBoardCode) ...@@ -18945,21 +18800,8 @@ function isReadableMsgHdr(pMsgHdr, pSubBoardCode)
} }
// If the message is deleted, determine whether it should be viewable, based // If the message is deleted, determine whether it should be viewable, based
// on the system settings. // on the system settings.
if ((pMsgHdr.attr & MSG_DELETE) == MSG_DELETE) if (((pMsgHdr.attr & MSG_DELETE) == MSG_DELETE) && !canViewDeletedMsgs())
{
// If the user is a sysop, check whether sysops can view deleted messages.
// Otherwise, check whether users can view deleted messages.
if (user.is_sysop)
{
if ((system.settings & SYS_SYSVDELM) == 0)
return false;
}
else
{
if ((system.settings & SYS_USRVDELM) == 0)
return false; return false;
}
}
// The message voting and poll variables were added in sbbsdefs.js for // The message voting and poll variables were added in sbbsdefs.js for
// Synchronet 3.17. Make sure they're defined before referencing them. // Synchronet 3.17. Make sure they're defined before referencing them.
if (typeof(MSG_UPVOTE) != "undefined") if (typeof(MSG_UPVOTE) != "undefined")
......
Digital Distortion Message Reader Digital Distortion Message Reader
Version 1.73a Version 1.74
Release date: 2023-04-25 Release date: 2023-04-25
by by
......
...@@ -5,6 +5,10 @@ Revision History (change log) ...@@ -5,6 +5,10 @@ Revision History (change log)
============================= =============================
Version Date Description Version Date Description
------- ---- ----------- ------- ---- -----------
1.74 2023-04-29 Settings for users being able to read deleted messages now
applies to personal email. Also, allows reading messages
that are marked for deletion in addition to just seeing
them in the message list
1.73a 2023-04-25 For viewing message headers, now all message header 1.73a 2023-04-25 For viewing message headers, now all message header
information is displayed & sorted alphabetically by field information is displayed & sorted alphabetically by field
name (same with saving a message to a file). name (same with saving a message to a file).
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment