diff --git a/xtrn/DDAreaChoosers/DDFileAreaChooser.js b/xtrn/DDAreaChoosers/DDFileAreaChooser.js index 5ea5fdedb903167446695a18bb7c7eb069ed3f19..eb38d794f1667a40f9bf3167dae45a5509318609 100644 --- a/xtrn/DDAreaChoosers/DDFileAreaChooser.js +++ b/xtrn/DDAreaChoosers/DDFileAreaChooser.js @@ -74,6 +74,9 @@ * create multiple levels of categories * 2025-03-17 Eric Oulashin Version 1.42 * Releasing this version + * 2025-04-10 Eric Oulashin Version 1.42b + * Fix: altName wasn't added to items if name collapsing disabled. + * Also, start of name collapsing enhancement (no empty names). */ // TODO: Failing silently when 1st argument is true @@ -114,8 +117,8 @@ if (system.version_num < 31400) } // Version & date variables -var DD_FILE_AREA_CHOOSER_VERSION = "1.42"; -var DD_FILE_AREA_CHOOSER_VER_DATE = "2025-03-17"; +var DD_FILE_AREA_CHOOSER_VERSION = "1.42b Beta"; +var DD_FILE_AREA_CHOOSER_VER_DATE = "2025-04-07"; // Keyboard input key codes var CTRL_H = "\x08"; @@ -2022,6 +2025,23 @@ function getFileDirHeirarchy(pCollapsing, pCollapsingSeparator) var fileDirHeirarchy = []; if (pCollapsing) { + // First, check the library descriptions for strings before the separator character + var libsBeforeSeparator = {}; // Will be an object indexed by description with a count as the value + for (var libIdx = 0; libIdx < file_area.lib_list.length; ++libIdx) + { + var libDesc = skipsp(truncsp(file_area.lib_list[libIdx].description)); + var sepIdx = file_area.lib_list[libIdx].description.indexOf(pCollapsingSeparator); + if (sepIdx > -1) + { + var libDescBeforeSep = file_area.lib_list[libIdx].description.substr(0, sepIdx); + if (libsBeforeSeparator.hasOwnProperty(libDescBeforeSep)) + libsBeforeSeparator[libDescBeforeSep] += 1; + else + libsBeforeSeparator[libDescBeforeSep] = 1; + } + } + + // Build the heirarchy // For each library, go through each directory for (var libIdx = 0; libIdx < file_area.lib_list.length; ++libIdx) { @@ -2040,11 +2060,22 @@ function getFileDirHeirarchy(pCollapsing, pCollapsingSeparator) var libDesc = skipsp(truncsp(file_area.lib_list[libIdx].description)); var dirDesc = skipsp(truncsp(file_area.lib_list[libIdx].dir_list[dirIdx].description)); var libAndDirName = libDesc + ":" + dirDesc; - var nameArray = libAndDirName.split(pCollapsingSeparator); + var nameArray = removeEmptyStrsFromArray(libAndDirName.split(pCollapsingSeparator)); var arrayToSearch = fileDirHeirarchy; - for (var i = 0; i < nameArray.length; ++i) + // If the library description has the separator character and the first element + // only appears once, then use the whole library name as one name + var sepCountInLibDesc = countSubstrInStr(libDesc, pCollapsingSeparator); + var startIdx = 0; + if (sepCountInLibDesc > 0 && libsBeforeSeparator.hasOwnProperty(nameArray[0]) == 1) + startIdx += sepCountInLibDesc; + for (var i = startIdx; i < nameArray.length; ++i) { - var name = skipsp(truncsp(nameArray[i])); + //var name = skipsp(truncsp(nameArray[i])); + var name = ""; + if (startIdx > 0 && i == startIdx) + name = libDesc; + else + name = skipsp(truncsp(nameArray[i])); // Look for this one in the heirarchy; if not found, add it. // Look for an entry in the array that matches the name and has its own "items" array var heirarchyIdx = -1; @@ -2097,6 +2128,7 @@ function getFileDirHeirarchy(pCollapsing, pCollapsingSeparator) fileDirHeirarchy.push( { name: file_area.lib_list[libIdx].description, + altName: file_area.lib_list[libIdx].name, libIdx: libIdx, items: [] }); @@ -2106,6 +2138,7 @@ function getFileDirHeirarchy(pCollapsing, pCollapsingSeparator) fileDirHeirarchy[libIdxInHeirarchy].items.push( { name: file_area.lib_list[libIdx].dir_list[dirIdx].description, + altName: file_area.lib_list[libIdx].dir_list[dirIdx].name, libIdx: libIdx, dirObj: file_area.lib_list[libIdx].dir_list[dirIdx] }); @@ -2136,6 +2169,25 @@ function splitStrNoSpacesBeforeSeparator(pStr, pSep) return strArray; } +// Returns the number of times a substring apears in a string +// +// Parameters: +// pStr: The string to search +// pSubstr: The substring inside the string to count +// +// Return: The number of times the substring appears in the string +function countSubstrInStr(pStr, pSubstr) +{ + var substrCount = 0; + var substrIdx = pStr.indexOf(pSubstr); + while (substrIdx > -1) + { + ++substrCount; + substrIdx = pStr.indexOf(pSubstr, substrIdx+1); + } + return substrCount; +} + // Given a file lib/directory heirarchy object built by this module, this // function returns whether it contains the user's currently selected file // directory. @@ -2195,4 +2247,17 @@ function maxNumItemsWidthInHeirarchy(pDirHeirarchyObj) } } return maxNumItemsWidth; +} + +// Removes empty strings from an array - Given an array, +// makes a new array with only the non-empty strings and returns it. +function removeEmptyStrsFromArray(pArray) +{ + var newArray = []; + for (var i = 0; i < pArray.length; ++i) + { + if (pArray[i].length > 0 && !/^\s+$/.test(pArray[i])) + newArray.push(pArray[i]); + } + return newArray; } \ No newline at end of file diff --git a/xtrn/DDAreaChoosers/DDMsgAreaChooser.js b/xtrn/DDAreaChoosers/DDMsgAreaChooser.js index 115c1dae364d4ba93a629da77a3fb6d6c71f827f..8695ffeded4322062df9b79e3ed0888d1807686d 100644 --- a/xtrn/DDAreaChoosers/DDMsgAreaChooser.js +++ b/xtrn/DDAreaChoosers/DDMsgAreaChooser.js @@ -83,6 +83,9 @@ * 2025-04-04 Eric Oulashin Version 1.42a * Fix for 'undefined' error (using the wrong object) when typing a sub-board * number to choose it. Reported by Keyop. + * 2025-04-10 Eric Oulashin Version 1.42b + * Fix: altName wasn't added to items if name collapsing disabled. + * Also, start of name collapsing enhancement (no empty names). */ /* Command-line arguments: @@ -120,8 +123,8 @@ if (system.version_num < 31400) } // Version & date variables -var DD_MSG_AREA_CHOOSER_VERSION = "1.42a"; -var DD_MSG_AREA_CHOOSER_VER_DATE = "2025-04-04"; +var DD_MSG_AREA_CHOOSER_VERSION = "1.42b Beta"; +var DD_MSG_AREA_CHOOSER_VER_DATE = "2025-04-07"; // Keyboard input key codes var CTRL_H = "\x08"; @@ -1281,7 +1284,8 @@ function DDMsgAreaChooser_CreateLightbarMenu(pMsgAreaHeirarchyObj, pHeirarchyLev { var lastMsgPostTimestamp = getLatestMsgTime(this.msgAreaHeirarchyObj[pItemIdx].subObj.code); menuItemObj.text += format(this.areaChooser.subBoardListPrintfInfo[grpIdx].printfStr, pItemIdx+1, - this.msgAreaHeirarchyObj[pItemIdx].name.substr(0, this.areaChooser.subBoardNameLen), numItems, + this.msgAreaHeirarchyObj[pItemIdx].name.substr(0, this.areaChooser.subBoardNameLen), + numItems, strftime("%Y-%m-%d", lastMsgPostTimestamp), strftime("%H:%M:%S", lastMsgPostTimestamp)); } @@ -3081,6 +3085,22 @@ function getMsgSubHeirarchy(pCollapsing, pCollapsingSeparator) var msgSubHeirarchy = []; if (pCollapsing) { + // First, check the group descriptions for strings before the separator character + var grpsBeforeSeparator = {}; // Will be an object indexed by description with a count as the value + for (var grpIdx = 0; grpIdx < msg_area.grp_list.length; ++grpIdx) + { + var grpDesc = skipsp(truncsp(msg_area.grp_list[grpIdx].description)); + var sepIdx = msg_area.grp_list[grpIdx].description.indexOf(pCollapsingSeparator); + if (sepIdx > -1) + { + var grpDescBeforeSep = msg_area.grp_list[grpIdx].description.substr(0, sepIdx); + if (grpsBeforeSeparator.hasOwnProperty(grpDescBeforeSep)) + grpsBeforeSeparator[grpDescBeforeSep] += 1; + else + grpsBeforeSeparator[grpDescBeforeSep] = 1; + } + } + // For each message group, go through each sub-board for (var grpIdx = 0; grpIdx < msg_area.grp_list.length; ++grpIdx) { @@ -3093,17 +3113,28 @@ function getMsgSubHeirarchy(pCollapsing, pCollapsingSeparator) // areas where there are no spaces before or after the :, but that // isn't how I did it before.. /* - var libAndDirName = msg_area.grp_list[grpIdx].description + ":" + msg_area.grp_list[grpIdx].sub_list[subIdx].description; - var nameArray = splitStrNoSpacesBeforeSeparator(libAndDirName, pCollapsingSeparator); + var grpAndSubname = msg_area.grp_list[grpIdx].description + ":" + msg_area.grp_list[grpIdx].sub_list[subIdx].description; + var nameArray = splitStrNoSpacesBeforeSeparator(grpAndSubname, pCollapsingSeparator); */ - var libDesc = skipsp(truncsp(msg_area.grp_list[grpIdx].description)); - var dirDesc = skipsp(truncsp(msg_area.grp_list[grpIdx].sub_list[subIdx].description)); - var libAndDirName = libDesc + pCollapsingSeparator + dirDesc; - var nameArray = libAndDirName.split(pCollapsingSeparator); + var grpDesc = skipsp(truncsp(msg_area.grp_list[grpIdx].description)); + var subDesc = skipsp(truncsp(msg_area.grp_list[grpIdx].sub_list[subIdx].description)); + var grpAndSubname = grpDesc + pCollapsingSeparator + subDesc; + var nameArray = removeEmptyStrsFromArray(grpAndSubname.split(pCollapsingSeparator)); var arrayToSearch = msgSubHeirarchy; - for (var i = 0; i < nameArray.length; ++i) + // If the group description has the separator character and the first element + // only appears once, then use the whole group name as one name + var sepCountInGrpDesc = countSubstrInStr(grpDesc, pCollapsingSeparator); + var startIdx = 0; + if (sepCountInGrpDesc > 0 && grpsBeforeSeparator.hasOwnProperty(nameArray[0]) == 1) + startIdx += sepCountInGrpDesc; + for (var i = startIdx; i < nameArray.length; ++i) { - var name = skipsp(truncsp(nameArray[i])); + //var name = skipsp(truncsp(nameArray[i])); + var name = ""; + if (startIdx > 0 && i == startIdx) + name = grpDesc; + else + name = skipsp(truncsp(nameArray[i])); // Look for this one in the heirarchy; if not found, add it. // Look for an entry in the array that matches the name and has its own "items" array var heirarchyIdx = -1; @@ -3156,6 +3187,7 @@ function getMsgSubHeirarchy(pCollapsing, pCollapsingSeparator) msgSubHeirarchy.push( { name: msg_area.grp_list[grpIdx].description, + altName: msg_area.grp_list[grpIdx].name, grpIdx: grpIdx, items: [] }); @@ -3165,6 +3197,7 @@ function getMsgSubHeirarchy(pCollapsing, pCollapsingSeparator) msgSubHeirarchy[libIdxInHeirarchy].items.push( { name: msg_area.grp_list[grpIdx].sub_list[subIdx].description, + altName: msg_area.grp_list[grpIdx].sub_list[subIdx].name, grpIdx: grpIdx, subObj: msg_area.grp_list[grpIdx].sub_list[subIdx] }); @@ -3244,6 +3277,25 @@ function splitStrNoSpacesBeforeSeparator(pStr, pSep) return strArray; } +// Returns the number of times a substring apears in a string +// +// Parameters: +// pStr: The string to search +// pSubstr: The substring inside the string to count +// +// Return: The number of times the substring appears in the string +function countSubstrInStr(pStr, pSubstr) +{ + var substrCount = 0; + var substrIdx = pStr.indexOf(pSubstr); + while (substrIdx > -1) + { + ++substrCount; + substrIdx = pStr.indexOf(pSubstr, substrIdx+1); + } + return substrCount; +} + // Given a message group/sub-board heirarchy object built by this module, this // function returns whether it contains the user's currently selected message // sub-board. @@ -3277,3 +3329,16 @@ function msgAreaStructureHasCurrentUserSubBoard(pMsgSubHeirarchyObj) } return currentUserSubBoardFound; } + +// Removes empty strings from an array - Given an array, +// makes a new array with only the non-empty strings and returns it. +function removeEmptyStrsFromArray(pArray) +{ + var newArray = []; + for (var i = 0; i < pArray.length; ++i) + { + if (pArray[i].length > 0 && !/^\s+$/.test(pArray[i])) + newArray.push(pArray[i]); + } + return newArray; +} \ No newline at end of file diff --git a/xtrn/DDAreaChoosers/readme.txt b/xtrn/DDAreaChoosers/readme.txt index 965058c6132dbcd203b3250bf471ccc85ece94bf..f82ed39f947c006b0617705e101b009dd511755c 100644 --- a/xtrn/DDAreaChoosers/readme.txt +++ b/xtrn/DDAreaChoosers/readme.txt @@ -1,6 +1,6 @@ Digital Distortion Area Choosers - Version 1.42 - Release date: 2025-03-17 + Version 1.42b + Release date: 2025-04-10 by @@ -160,26 +160,26 @@ do the following: If you would like to set up these scripts as doors, the following is an example setup of the message area chooser (assuming it is placed in sbbs/exec or sbbs/mods): -+[�][?]----------------------------------------------------+ -� Message Area Chooser � -�----------------------------------------------------------� -� �Name Message Area Chooser � -� �Internal Code MSGARCHO � -� �Start-up Directory � -� �Command Line ?DDMsgAreaChooser.js � -� �Clean-up Command Line � -� �Execution Cost None � -� �Access Requirements � -� �Execution Requirements � -� �Multiple Concurrent Users Yes � -� �Intercept Standard I/O No � -� �Native (32-bit) Executable No � -� �Use Shell to Execute No � -� �Modify User Data No � -� �Execute on Event No � -� �Pause After Execution No � -� �BBS Drop File Type None � -� �Place Drop File In Node Directory � ++[¦][?]----------------------------------------------------+ +¦ Message Area Chooser ¦ +¦----------------------------------------------------------¦ +¦ ¦Name Message Area Chooser ¦ +¦ ¦Internal Code MSGARCHO ¦ +¦ ¦Start-up Directory ¦ +¦ ¦Command Line ?DDMsgAreaChooser.js ¦ +¦ ¦Clean-up Command Line ¦ +¦ ¦Execution Cost None ¦ +¦ ¦Access Requirements ¦ +¦ ¦Execution Requirements ¦ +¦ ¦Multiple Concurrent Users Yes ¦ +¦ ¦Intercept Standard I/O No ¦ +¦ ¦Native (32-bit) Executable No ¦ +¦ ¦Use Shell to Execute No ¦ +¦ ¦Modify User Data No ¦ +¦ ¦Execute on Event No ¦ +¦ ¦Pause After Execution No ¦ +¦ ¦BBS Drop File Type None ¦ +¦ ¦Place Drop File In Node Directory ¦ +----------------------------------------------------------+ To run that from a JavaScript, include this line: bbs.exec_xtrn("MSGARCHO"); diff --git a/xtrn/DDAreaChoosers/version_history.txt b/xtrn/DDAreaChoosers/version_history.txt index aad71aef1f64b89e095d02274ee6b76f9021b078..c9f8bb2380f01c24c7c20ecee8a9e3eba0e85c6c 100644 --- a/xtrn/DDAreaChoosers/version_history.txt +++ b/xtrn/DDAreaChoosers/version_history.txt @@ -5,6 +5,10 @@ Revision History (change log) ============================= Version Date Description ------- ---- ----------- +1.42b 2025-04-10 Fix: altName wasn't added to items if name collapsing + disabled. + Also, start of name collapsing enhancement (no empty + names). 1.42 2025-03-17 For both: Name collapsing now supports an arbitrary number of areas (depth) with an arbitrary number of separators 1.41 2024-03-13 File area chooser: Fix for the directory item counts