Major work on breaking up menus

This commit is contained in:
Bryan Ashby 2020-07-05 14:06:34 -06:00
parent 35ef2db446
commit 965e845834
No known key found for this signature in database
GPG Key ID: B49EB437951D2542
12 changed files with 4147 additions and 4612 deletions

View File

@ -4,6 +4,11 @@
author: Luciano Ayres author: Luciano Ayres
group: blocktronics group: blocktronics
enabled: true enabled: true
//
// Also check out Luciano's ANSIGARDEN:
// http://www.ansigarden.com/
//
} }
customization: { customization: {
@ -241,7 +246,7 @@
} }
} }
messageAreaMessageList: { messageBaseMessageList: {
config: { config: {
dateTimeFormat: ddd MMM Do dateTimeFormat: ddd MMM Do
allViewsInfoFormat10: "|00|15{msgNumSelected:>4.4} |08/ |15{msgNumTotal:<4.4}" allViewsInfoFormat10: "|00|15{msgNumSelected:>4.4} |08/ |15{msgNumTotal:<4.4}"
@ -256,7 +261,7 @@
} }
} }
messageAreaChangeCurrentConference: { messageBaseChangeCurrentConference: {
mci: { mci: {
VM1: { VM1: {
width: 26 width: 26
@ -267,7 +272,7 @@
} }
} }
messageAreaChangeCurrentArea: { messageBaseChangeCurrentArea: {
mci: { mci: {
VM1: { VM1: {
width: 26 width: 26
@ -278,7 +283,7 @@
} }
} }
messageAreaSetNewScanDate: { messageBaseSetNewScanDate: {
mci: { mci: {
SM2: { SM2: {
width: 54 width: 54
@ -299,7 +304,7 @@
} }
} }
mailMenuCreateMessage: { privateMailMenuCreateMessage: {
0: { 0: {
mci: { mci: {
TL1: { width: 19, textOverflow: "..." } TL1: { width: 19, textOverflow: "..." }
@ -314,7 +319,7 @@
} }
} }
mailMenuInbox: { privateMailMenuInbox: {
config: { config: {
dateTimeFormat: ddd MMM Do dateTimeFormat: ddd MMM Do
allViewsInfoFormat10: "|00|15{msgNumSelected:>4.4} |08/ |15{msgNumTotal:<4.4}" allViewsInfoFormat10: "|00|15{msgNumSelected:>4.4} |08/ |15{msgNumTotal:<4.4}"
@ -500,7 +505,7 @@
} }
} }
messageAreaSearchMessageList: { messageBaseSearchMessageList: {
config: { config: {
allViewsInfoFormat10: "|00|15{msgNumSelected:>4.4} |08/ |15{msgNumTotal:<4.4}" allViewsInfoFormat10: "|00|15{msgNumSelected:>4.4} |08/ |15{msgNumTotal:<4.4}"
// Fri Sep 25th // Fri Sep 25th
@ -516,7 +521,7 @@
} }
} }
messageAreaMyMessagesList: { messageBaseMyMessagesList: {
config: { config: {
// Fri Sep 25th // Fri Sep 25th
dateTimeFormat: ddd MMM Do dateTimeFormat: ddd MMM Do
@ -531,6 +536,7 @@
} }
} }
// The 'msg_list' module looks for this entry by default
messageAreaViewPost: { messageAreaViewPost: {
0: { 0: {
mci: { mci: {
@ -566,7 +572,7 @@
} }
} }
messageAreaNewPost: { messageBaseNewPost: {
0: { 0: {
mci: { mci: {
TL1: { width: 19, textOverflow: "..." } TL1: { width: 19, textOverflow: "..." }
@ -582,7 +588,7 @@
} }
} }
messageAreaReplyPost: { messageBaseReplyPost: {
0: { 0: {
mci: { mci: {
TL1: { width: 19, textOverflow: "..." } TL1: { width: 19, textOverflow: "..." }
@ -977,7 +983,7 @@
} }
} }
fileAreaFilterEditor: { fileBaseFilterEditor: {
mci: { mci: {
ET1: { ET1: {
width: 26 width: 26

View File

@ -227,32 +227,50 @@ function buildNewConfig() {
if(err) { return; if(err) { return;
} }
const bn = sanatizeFilename(config.general.boardName) const boardName = sanatizeFilename(config.general.boardName)
.replace(/[^a-z0-9_-]/ig, '_') .replace(/[^a-z0-9_-]/ig, '_')
.replace(/_+/g, '_') .replace(/_+/g, '_')
.toLowerCase(); .toLowerCase();
const menuFile = `${bn}-menu.hjson`; const menuFile = `menus/${boardName}-main.hjson`;
const mainTemplate = hjson.rt.parse(fs.readFileSync(paths.join(__dirname, '../../misc/menu_templates/main.in.hjson'), 'utf8'));
const includeFiles = [
'message_base.in.hjson',
'private_mail.in.hjson',
'login.in.hjson',
'new_user.in.hjson',
'doors.in.hjson',
'file_base.in.hjson',
];
includeFiles.forEach(incFile => {
const outName = `${boardName}-${incFile.replace('.in', '')}`;
copyFileSyncSilent( copyFileSyncSilent(
paths.join(__dirname, '../../misc/menu_template.in.hjson'), paths.join(__dirname, '../../misc/menu_templates', incFile),
paths.join(__dirname, '../../config/', menuFile), paths.join(__dirname, '../../config/menus', outName),
fs.constants.COPYFILE_EXCL fs.constants.COPYFILE_EXCL
); );
});
const promptFile = `${bn}-prompt.hjson`; mainTemplate.includes = includeFiles.map(incFile => {
copyFileSyncSilent( return `${boardName}-${incFile.replace('.in', '')}`;
paths.join(__dirname, '../../misc/prompt_template.in.hjson'), });
paths.join(__dirname, '../../config/', promptFile),
fs.constants.COPYFILE_EXCL
);
if (writeConfig(
mainTemplate,
paths.join(__dirname, '../../config/menus', `${boardName}-main.hjson`)))
{
config.general.menuFile = menuFile; config.general.menuFile = menuFile;
config.general.promptFile = promptFile;
if(writeConfig(config, configPath)) { if(writeConfig(config, configPath)) {
console.info('Configuration generated'); console.info('Configuration generated');
} else { } else {
console.error('Failed writing configuration'); console.error('Failed writing configuration');
} }
} else {
console.error('Failed writing configuration');
}
}); });
} }

View File

@ -369,7 +369,7 @@
storageTags: { storageTags: {
// //
// Example storage tag: "super_l33t_warez": // Example storage tag: "super_l33t_warez":
// super_l33t_warez: "/path/to/super/l33t/warez" // super_l33t_warez: /path/to/super/l33t/warez
// //
} }
@ -377,10 +377,10 @@
// //
// Example area with the areaTag of "an_example_area": // Example area with the areaTag of "an_example_area":
// an_example_area: { // an_example_area: {
// name: "Example File Area" // name: Example File Area
// desc: "It's just an example, yo!" // desc: It's just an example, yo!
// storageTags: [ // storageTags: [
// "super_l33t_warez" // super_l33t_warez
// ] // ]
// } // }
// //

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,132 @@
{
menus: {
doorsMainMenu: {
desc: Doors Menu
art: DOORMNU
prompt: menuCommand
config: {
interrupt: realtime
}
submit: [
{
value: { command: "G" }
action: @menu:fullLogoffSequence
}
{
value: { command: "Q" }
action: @systemMethod:prevMenu
}
//
// The system supports many ways of launching doors including
// modules for DoorParty!, BBSLink, etc.
//
// Below are some examples. See the documentation for more info.
//
{
value: { command: "ABRACADABRA" }
action: @menu:doorAbracadabraExample
}
{
value: { command: "TWBBSLINK" }
action: @menu:doorTradeWars2002BBSLinkExample
}
{
value: { command: "DP" }
action: @menu:doorPartyExample
}
{
value: { command: "CN" }
action: @menu:doorCombatNetExample
}
{
value: { command: "EXODUS" }
action: @menu:doorExodusCataclysm
}
]
}
//
// Local Door Example via abracadabra module
//
// This example assumes launch_door.sh (which is passed args)
// launches the door.
//
doorAbracadabraExample: {
desc: Abracadabra Example
module: abracadabra
config: {
name: Example Door
dropFileType: DORINFO
cmd: /home/enigma/DOS/scripts/launch_door.sh
args: [
"{node}",
"{dropFile}",
"{srvPort}",
],
nodeMax: 1
tooManyArt: DOORMANY
io: socket
}
}
//
// BBSLink Example (TradeWars 2000)
//
// Register @ https://bbslink.net/
//
doorTradeWars2002BBSLinkExample: {
desc: Playing TW 2002 (BBSLink)
module: bbs_link
config: {
sysCode: XXXXXXXX
authCode: XXXXXXXX
schemeCode: XXXXXXXX
door: tw
}
}
//
// DoorParty! Example
//
// Register @ http://throwbackbbs.com/
//
doorPartyExample: {
desc: Using DoorParty!
module: door_party
config: {
username: XXXXXXXX
password: XXXXXXXX
bbsTag: XX
}
}
//
// CombatNet Example
//
// Register @ http://combatnet.us/
//
doorCombatNetExample: {
desc: Using CombatNet
module: combatnet
config: {
bbsTag: CBNxxx
password: XXXXXXXXX
}
}
//
// Exodus Example (cataclysm)
// Register @ https://oddnetwork.org/exodus/
//
doorExodusCataclysm: {
desc: Cataclysm
module: exodus
config: {
rejectUnauthorized: false
board: XXX
key: XXXXXXXX
door: cataclysm
}
}
}
}

View File

@ -0,0 +1,918 @@
{
menus: {
fileBaseMainMenu: {
desc: File Base
art: FMENU
prompt: fileMenuCommand
config: {
interrupt: realtime
}
submit: [
{
value: { menuOption: "L" }
action: @menu:fileBaseListEntries
}
{
value: { menuOption: "B" }
action: @menu:fileBaseBrowseByAreaSelect
}
{
value: { menuOption: "F" }
action: @menu:fileBaseFilterEditor
}
{
value: { menuOption: "Q" }
action: @systemMethod:prevMenu
}
{
value: { menuOption: "G" }
action: @menu:fullLogoffSequence
}
{
value: { menuOption: "D" }
action: @menu:fileBaseDownloadManager
}
{
value: { menuOption: "W" }
action: @menu:fileBaseWebDownloadManager
}
{
value: { menuOption: "U" }
action: @menu:fileBaseUploadFiles
}
{
value: { menuOption: "S" }
action: @menu:fileBaseSearch
}
{
value: { menuOption: "P" }
action: @menu:fileBaseSetNewScanDate
}
{
value: { menuOption: "E" }
action: @menu:fileBaseExportListFilter
}
]
}
fileBaseListEntries: {
module: file_area_list
desc: Browsing Files
config: {
art: {
browse: FBRWSE
details: FDETAIL
detailsGeneral: FDETGEN
detailsNfo: FDETNFO
detailsFileList: FDETLST
help: FBHELP
}
}
form: {
0: {
mci: {
MT1: {
mode: preview
}
HM2: {
focus: true
submit: true
argName: navSelect
items: [
"prev", "next", "details", "toggle queue", "rate", "change filter", "help", "quit"
]
focusItemIndex: 1
}
}
submit: {
*: [
{
value: { navSelect: 0 }
action: @method:prevFile
}
{
value: { navSelect: 1 }
action: @method:nextFile
}
{
value: { navSelect: 2 }
action: @method:viewDetails
}
{
value: { navSelect: 3 }
action: @method:toggleQueue
}
{
value: { navSelect: 4 }
action: @menu:fileBaseGetRatingForSelectedEntry
}
{
value: { navSelect: 5 }
action: @menu:fileBaseFilterEditor
}
{
value: { navSelect: 6 }
action: @method:displayHelp
}
{
value: { navSelect: 7 }
action: @systemMethod:prevMenu
}
]
}
actionKeys: [
{
keys: [ "w", "shift + w" ]
action: @method:showWebDownloadLink
}
{
keys: [ "escape", "q", "shift + q" ]
action: @systemMethod:prevMenu
}
{
keys: [ "t", "shift + t" ]
action: @method:toggleQueue
}
{
keys: [ "f", "shift + f" ]
action: @menu:fileBaseFilterEditor
}
{
keys: [ "v", "shift + v" ]
action: @method:viewDetails
}
{
keys: [ "r", "shift + r" ]
action: @menu:fileBaseGetRatingForSelectedEntry
}
{
keys: [ "?" ]
action: @method:displayHelp
}
]
}
1: {
mci: {
HM1: {
focus: true
submit: true
argName: navSelect
items: [
"general", "nfo/readme", "file listing"
]
}
}
actionKeys: [
{
keys: [ "escape", "q", "shift + q" ]
action: @method:detailsQuit
}
]
}
2: {
// details - general
mci: {}
}
3: {
// details - nfo/readme
mci: {
MT1: {
mode: preview
}
}
}
4: {
// details - file listing
mci: {
VM1: {
}
}
}
}
}
fileBaseBrowseByAreaSelect: {
desc: Browsing File Areas
module: file_base_area_select
art: FAREASEL
form: {
0: {
mci: {
VM1: {
focus: true
argName: areaTag
}
}
submit: {
*: [
{
value: { areaTag: null }
action: @method:selectArea
}
]
}
actionKeys: @reference:common.quitToPrev
}
}
}
fileBaseFilterEditor: {
desc: File Filter Editor
module: file_area_filter_edit
art: FFILEDT
form: {
0: {
mci: {
ET1: {
argName: searchTerms
}
ET2: {
maxLength: 64
argName: tags
}
SM3: {
maxLength: 64
argName: areaIndex
}
SM4: {
items: [
"upload date",
"uploaded by",
"downloads",
"rating",
"estimated year",
"size",
]
argName: sortByIndex
}
SM5: {
items: [
"decending",
"ascending"
]
argName: orderByIndex
}
ET6: {
maxLength: 64
argName: name
validate: @systemMethod:validateNonEmpty
}
HM7: {
focus: true
items: [
"prev", "next", "make active", "save", "new", "delete"
]
argName: navSelect
focusItemIndex: 1
}
}
submit: {
*: [
{
value: { navSelect: 0 }
action: @method:prevFilter
}
{
value: { navSelect: 1 }
action: @method:nextFilter
}
{
value: { navSelect: 2 }
action: @method:makeFilterActive
}
{
value: { navSelect: 3 }
action: @method:saveFilter
}
{
value: { navSelect: 4 }
action: @method:newFilter
}
{
value: { navSelect: 5 }
action: @method:deleteFilter
}
]
}
actionKeys: [
{
keys: [ "escape" ]
action: @systemMethod:prevMenu
}
]
}
}
}
fileBaseDownloadManager: {
desc: Download Manager
module: file_base_download_manager
config: {
art: {
queueManager: FDLMGR
/*
NYI
details: FDLDET
*/
}
emptyQueueMenu: fileBaseDownloadManagerEmptyQueue
}
form: {
0: {
mci: {
VM1: {
argName: queueItem
}
HM2: {
focus: true
items: [ "download all", "quit" ]
argName: navSelect
}
}
submit: {
*: [
{
value: { navSelect: 0 }
action: @method:downloadAll
}
{
value: { navSelect: 1 }
action: @systemMethod:prevMenu
}
]
}
actionKeys: [
{
keys: [ "a", "shift + a" ]
action: @method:downloadAll
}
{
keys: [ "delete", "r", "shift + r" ]
action: @method:removeItem
}
{
keys: [ "c", "shift + c" ]
action: @method:clearQueue
}
{
keys: [ "escape", "q", "shift + q" ]
action: @systemMethod:prevMenu
}
]
}
}
}
fileBaseDownloadManagerEmptyQueue: {
desc: Empty Download Queue
art: FEMPTYQ
config: {
pause: true
menuFlags: [ "noHistory", "popParent" ]
}
}
fileBaseWebDownloadManager: {
desc: Web D/L Manager
module: file_base_web_download_manager
config: {
art: {
queueManager: FWDLMGR
batchList: BATDLINF
}
emptyQueueMenu: fileBaseDownloadManagerEmptyQueue
}
form: {
0: {
mci: {
VM1: {
argName: queueItem
}
HM2: {
focus: true
items: [ "get batch link", "quit", "help" ]
argName: navSelect
}
}
submit: {
*: [
{
value: { navSelect: 0 }
action: @method:getBatchLink
}
{
value: { navSelect: 1 }
action: @systemMethod:prevMenu
}
]
}
actionKeys: [
{
keys: [ "b", "shift + b" ]
action: @method:getBatchLink
}
{
keys: [ "delete", "r", "shift + r" ]
action: @method:removeItem
}
{
keys: [ "c", "shift + c" ]
action: @method:clearQueue
}
{
keys: [ "escape", "q", "shift + q" ]
action: @systemMethod:prevMenu
}
]
}
}
}
fileBaseUploadFiles: {
desc: Uploading
module: upload
config: {
interrupt: never
art: {
options: ULOPTS
fileDetails: ULDETAIL
processing: ULCHECK
dupes: ULDUPES
}
}
form: {
// options
0: {
mci: {
SM1: {
argName: areaSelect
focus: true
}
TM2: {
argName: uploadType
items: [ "blind", "supply filename" ]
}
ET3: {
argName: fileName
maxLength: 255
validate: @method:validateNonBlindFileName
}
HM4: {
argName: navSelect
items: [ "continue", "cancel" ]
submit: true
}
}
submit: {
*: [
{
value: { navSelect: 0 }
action: @method:optionsNavContinue
}
{
value: { navSelect: 1 }
action: @systemMethod:prevMenu
}
]
}
"actionKeys" : [
{
"keys" : [ "escape" ],
action: @systemMethod:prevMenu
}
]
}
1: {
mci: { }
}
// file details entry
2: {
mci: {
MT1: {
argName: shortDesc
tabSwitchesView: true
focus: true
}
ET2: {
argName: tags
}
ME3: {
argName: estYear
maskPattern: "####"
}
BT4: {
argName: continue
text: continue
submit: true
}
}
submit: {
*: [
{
value: { continue: null }
action: @method:fileDetailsContinue
}
]
}
}
// dupes
3: {
mci: {
VM1: {
/*
Use 'dupeInfoFormat' to custom format:
areaDesc
areaName
areaTag
desc
descLong
fileId
fileName
fileSha256
storageTag
uploadTimestamp
*/
mode: preview
}
}
}
}
}
fileBaseSearch: {
module: file_base_search
desc: Searching Files
art: FSEARCH
form: {
0: {
mci: {
ET1: {
focus: true
argName: searchTerms
}
BT2: {
argName: search
text: search
submit: true
}
ET3: {
maxLength: 64
argName: tags
}
SM4: {
maxLength: 64
argName: areaIndex
}
SM5: {
items: [
"upload date",
"uploaded by",
"downloads",
"rating",
"estimated year",
"size",
"filename",
]
argName: sortByIndex
}
SM6: {
items: [
"decending",
"ascending"
]
argName: orderByIndex
}
BT7: {
argName: advancedSearch
text: advanced search
submit: true
}
}
submit: {
*: [
{
value: { search: null }
action: @method:search
}
{
value: { advancedSearch: null }
action: @method:search
}
]
}
actionKeys: [
{
keys: [ "escape" ]
action: @systemMethod:prevMenu
}
]
}
}
}
fileBaseSetNewScanDate: {
module: set_newscan_date
desc: File Base
art: SETFNSDATE
config: {
target: file
scanDateFormat: YYYYMMDD
}
form: {
0: {
mci: {
ME1: {
focus: true
submit: true
argName: scanDate
maskPattern: "####/##/##"
}
}
submit: {
*: [
{
value: { scanDate: null }
action: @method:scanDateSubmit
}
]
}
actionKeys: @reference:common.quitToPrev
}
}
}
fileBaseExportListFilter: {
module: file_base_search
art: FBLISTEXPSEARCH
config: {
fileBaseListEntriesMenu: fileBaseExportList
}
form: {
0: {
mci: {
ET1: {
focus: true
argName: searchTerms
}
BT2: {
argName: search
text: search
submit: true
}
ET3: {
maxLength: 64
argName: tags
}
SM4: {
maxLength: 64
argName: areaIndex
}
SM5: {
items: [
"upload date",
"uploaded by",
"downloads",
"rating",
"estimated year",
"size",
"filename"
]
argName: sortByIndex
}
SM6: {
items: [
"decending",
"ascending"
]
argName: orderByIndex
}
BT7: {
argName: advancedSearch
text: advanced search
submit: true
}
}
submit: {
*: [
{
value: { search: null }
action: @method:search
}
{
value: { advancedSearch: null }
action: @method:search
}
]
}
actionKeys: [
{
keys: [ "escape" ]
action: @systemMethod:prevMenu
}
]
}
}
}
fileBaseExportList: {
module: file_base_user_list_export
art: FBLISTEXP
config: {
pause: true
templates: {
entry: file_list_entry.asc
}
}
form: {
0: {
mci: {
TL1: { }
TL2: { }
}
}
}
}
fileBaseExportListNoResults: {
desc: Browsing Files
art: FBNORES
config: {
pause: true
menuFlags: [ "noHistory", "popParent" ]
}
}
// Referenced by various menus
fileBaseGetRatingForSelectedEntry: {
desc: Rating a File
prompt: fileBaseRateEntryPrompt
config: {
cls: true
}
submit: [
// :TODO: handle esc/q
{
// pass data back to caller
value: { rating: null }
action: @systemMethod:prevMenu
}
]
}
// default menu entry used by the 'file_area_list' module
// when there are no search results for the provided criteria
fileBaseListEntriesNoResults: {
desc: Browsing Files
art: FBNORES
config: {
pause: true
menuFlags: [ "noHistory", "popParent" ]
}
}
// default menu entry used by the 'file_base_download_manager' module
// for protocol selection
fileTransferProtocolSelection: {
desc: Protocol selection
module: file_transfer_protocol_select
art: FPROSEL
form: {
0: {
mci: {
VM1: {
focus: true
argName: protocol
}
}
submit: {
*: [
{
value: { protocol: null }
action: @method:selectProtocol
}
]
}
actionKeys: [
{
keys: [ "escape" ]
action: @systemMethod:prevMenu
}
]
}
}
}
// default menu entry used by the 'upload' module for when
// no areas are available for the user to upload to
fileBaseNoUploadAreasAvail: {
desc: File Base
art: ULNOAREA
config: {
pause: true
menuFlags: [ "noHistory", "popParent" ]
}
}
// default menu entry used by the 'file_transfer_protocol_select' module
// when performing user downloads
sendFilesToUser: {
desc: Downloading
module: file_transfer
config: {
// defaults - generally use extraArgs
protocol: zmodem8kSexyz
direction: send
}
}
// default menu entry used by the 'file_transfer_protocol_select' module
// when performing user uploads
recvFilesFromUser: {
desc: Uploading
module: file_transfer
config: {
// defaults - generally use extraArgs
protocol: zmodem8kSexyz
direction: recv
}
}
}
prompts: {
fileMenuCommand: {
art: FILPMPT
mci: {
TL1: {}
ET2: {
argName: menuOption
width: 20
maxLength: 20
textStyle: upper
focus: true
}
}
}
fileBaseRateEntryPrompt: {
art: RATEFILE
mci: {
SM1: {
argName: rating
items: [ "-----", "*----", "**---", "***--", "****-", "*****" ]
}
}
actionKeys: [
{
keys: [ "escape" ]
action: @systemMethod:prevMenu
}
]
}
fileBaseTagEntryPrompt: {
art: TAGFILE
mci: {
ET1: {
argName: tags
}
}
}
}
}

View File

@ -0,0 +1,607 @@
{
menus: {
//
// Send telnet connections to matrix where users can login, apply, etc.
//
telnetConnected: {
art: CONNECT
next: matrix
config: { nextTimeout: 1500 }
}
//
// SSH connections are pre-authenticated via the SSH server itself.
// Jump directly to either the 2FA/OTP auth or the login sequence
// depending on user ACS.
//
sshConnected: {
art: CONNECT
next: [
{
acs: AR2
next: loginTwoFactorAuthOTPLoop
}
{
next: fullLoginSequenceLoginArt
}
]
config: { nextTimeout: 1500 }
}
//
// Another SSH specialization: If the user logs in with a new user
// name (e.g. "new", "apply", ...) they will be directed to the
// application process.
//
sshConnectedNewUser: {
art: CONNECT
next: newUserApplicationPreSsh
config: { nextTimeout: 1500 }
}
// Ye ol' standard matrix
matrix: {
art: matrix
form: {
0: {
VM: {
mci: {
VM1: {
submit: true
focus: true
argName: navSelect
items: [
{
text: login
data: login
}
{
text: apply
data: apply
}
//
// To enable the forgot password option, you'll need to have
// the web server & email configured. Once that is in place,
// uncomment the section below.
//
// See docs for more information
//
/*
{
text: forgot pass
data: forgot
}
*/
{
text: log off
data: logoff
}
]
}
}
submit: {
*: [
{
value: { navSelect: "login" }
action: @menu:login
}
{
value: { navSelect: "apply" }
action: @menu:newUserApplicationPre
}
{
value: { navSelect: "forgot" }
action: @menu:forgotPassword
}
{
value: { navSelect: "logoff" }
action: @menu:logoff
}
]
}
}
}
}
}
login: {
art: USERLOG
next: [
{
//
// Users with 2FA/OTP enabled *must* go through
// an additional OTP authentication step
//
acs: AR2
next: loginTwoFactorAuthOTPLoop
}
{
// ...everyone else can carry on as per usual
next: fullLoginSequenceLoginArt
}
]
config: {
tooNodeMenu: loginAttemptTooNode
inactive: loginAttemptAccountInactive
disabled: loginAttemptAccountDisabled
locked: loginAttemptAccountLocked
}
form: {
0: {
mci: {
ET1: {
maxLength: @config:users.usernameMax
argName: username
focus: true
}
ET2: {
password: true
maxLength: @config:users.passwordMax
argName: password
submit: true
}
}
submit: {
*: [
{
value: { password: null }
action: @systemMethod:login
}
]
}
actionKeys: @reference:common.escToPrev
}
}
}
loginAttemptTooNode: {
art: TOONODE
config: {
cls: true
nextTimeout: 2000
}
next: logoff
}
loginAttemptAccountLocked: {
art: ACCOUNTLOCKED
config: {
cls: true
nextTimeout: 2000
}
next: logoff
}
loginAttemptAccountDisabled: {
art: ACCOUNTDISABLED
config: {
cls: true
nextTimeout: 2000
}
next: logoff
}
loginAttemptAccountInactive: {
art: ACCOUNTINACTIVE
config: {
cls: true
nextTimeout: 2000
}
next: logoff
}
forgotPassword: {
desc: Forgot password
prompt: forgotPasswordPrompt
submit: [
{
value: { username: null }
action: @systemMethod:sendForgotPasswordEmail
extraArgs: { next: "forgotPasswordSubmitted" }
}
]
}
forgotPasswordSubmitted: {
desc: Forgot password
art: FORGOTPWSENT
config: {
cls: true
pause: true
}
next: @systemMethod:logoff
}
fullLoginSequenceLoginArt: {
desc: Logging In
art: WELCOME
config: { pause: true }
next: fullLoginSequenceLastCallers
}
fullLoginSequenceLastCallers: {
desc: Last Callers
module: last_callers
art: LASTCALL
config: {
pause: true
font: cp437
}
next: fullLoginSequenceWhosOnline
}
fullLoginSequenceWhosOnline: {
desc: Who's Online
module: whos_online
art: WHOSON
config: { pause: true }
next: fullLoginSequenceOnelinerz
}
fullLoginSequenceOnelinerz: {
desc: Viewing Onelinerz
module: onelinerz
next: [
{
// calls >= 2
acs: NC2
next: fullLoginSequenceNewScanConfirm
}
{
// new users - skip new scan
next: fullLoginSequenceUserStats
}
]
config: {
cls: true
art: {
view: ONELINER
add: ONEADD
}
}
form: {
0: {
mci: {
VM1: {
focus: false
height: 10
}
TM2: {
argName: addOrExit
items: [ "yeah!", "nah" ]
"hotKeys" : { "Y" : 0, "N" : 1, "Q" : 1 }
submit: true
focus: true
}
}
submit: {
*: [
{
value: { addOrExit: 0 }
action: @method:viewAddScreen
}
{
value: { addOrExit: null }
action: @systemMethod:nextMenu
}
]
}
actionKeys: [
{
keys: [ "escape" ]
action: @systemMethod:nextMenu
}
]
},
1: {
mci: {
ET1: {
focus: true
maxLength: 70
argName: oneliner
}
TL2: {
width: 60
}
TM3: {
argName: addOrCancel
items: [ "add", "cancel" ]
"hotKeys" : { "A" : 0, "C" : 1, "Q" : 1 }
submit: true
}
}
submit: {
*: [
{
value: { addOrCancel: 0 }
action: @method:addEntry
}
{
value: { addOrCancel: 1 }
action: @method:cancelAdd
}
]
}
actionKeys: [
{
keys: [ "escape" ]
action: @method:cancelAdd
}
]
}
}
}
fullLoginSequenceNewScanConfirm: {
desc: Logging In
prompt: loginGlobalNewScan
submit: [
{
value: { promptValue: 0 }
action: @menu:fullLoginSequenceNewScan
}
{
value: { promptValue: 1 }
action: @menu:fullLoginSequenceUserStats
}
]
}
fullLoginSequenceNewScan: {
desc: Performing New Scan
module: new_scan
art: NEWSCAN
next: fullLoginSequenceSysStats
config: {
messageListMenu: newScanMessageList
}
}
newScanMessageList: {
desc: New Messages
module: msg_list
art: NEWMSGS
config: {
menuViewPost: messageBaseViewPost
}
form: {
0: {
mci: {
VM1: {
focus: true
submit: true
argName: message
}
TL6: { }
}
submit: {
*: [
{
value: { message: null }
action: @method:selectMessage
}
]
}
actionKeys: [
{
keys: [ "escape", "q", "shift + q" ]
action: @systemMethod:prevMenu
}
{
keys: [ "x", "shift + x" ]
action: @method:fullExit
}
{
keys: [ "m", "shift + m" ]
action: @method:markAllRead
}
]
}
}
}
newScanFileBaseList: {
module: file_area_list
desc: New Files
config: {
art: {
browse: FNEWBRWSE
details: FDETAIL
detailsGeneral: FDETGEN
detailsNfo: FDETNFO
detailsFileList: FDETLST
help: FBHELP
}
}
form: {
0: {
mci: {
MT1: {
mode: preview
ansiView: true
}
HM2: {
focus: true
submit: true
argName: navSelect
items: [
"prev", "next", "details", "toggle queue", "rate", "help", "quit"
]
focusItemIndex: 1
}
}
submit: {
*: [
{
value: { navSelect: 0 }
action: @method:prevFile
}
{
value: { navSelect: 1 }
action: @method:nextFile
}
{
value: { navSelect: 2 }
action: @method:viewDetails
}
{
value: { navSelect: 3 }
action: @method:toggleQueue
}
{
value: { navSelect: 4 }
action: @menu:fileBaseGetRatingForSelectedEntry
}
{
value: { navSelect: 5 }
action: @method:displayHelp
}
{
value: { navSelect: 6 }
action: @systemMethod:prevMenu
}
]
}
actionKeys: [
{
keys: [ "w", "shift + w" ]
action: @method:showWebDownloadLink
}
{
keys: [ "escape", "q", "shift + q" ]
action: @systemMethod:prevMenu
}
{
keys: [ "t", "shift + t" ]
action: @method:toggleQueue
}
{
keys: [ "v", "shift + v" ]
action: @method:viewDetails
}
{
keys: [ "r", "shift + r" ]
action: @menu:fileBaseGetRatingForSelectedEntry
}
{
keys: [ "?" ]
action: @method:displayHelp
}
]
}
1: {
mci: {
HM1: {
focus: true
submit: true
argName: navSelect
items: [
"general", "nfo/readme", "file listing"
]
}
}
actionKeys: @reference:common.quitToPrev
}
2: {
// details - general
mci: { }
}
3: {
// details - nfo/readme
mci: {
MT1: {
mode: preview
}
}
}
4: {
// details - file listing
mci: {
VM1: { }
}
}
}
}
fullLoginSequenceSysStats: {
desc: System Stats
art: SYSSTAT
config: { pause: true }
next: fullLoginSequenceUserStats
}
fullLoginSequenceUserStats: {
desc: User Stats
art: STATUS
config: { pause: true }
next: mainMenu
}
//
// Empty menu to catch us in a 2FA/OTP auth loop
// until the user either authenticates successfully
// or the system boots them.
//
loginTwoFactorAuthOTPLoop: {
next: loginTwoFactorAuthOTP
}
loginTwoFactorAuthOTP: {
art: 2FAOTP
next: fullLoginSequenceLoginArt
form: {
0: {
mci: {
ET1: {
argName: token
focus: true
submit: true
}
}
submit: {
*: [
{
value: { token: null }
action: @systemMethod:login2FA_OTP
}
]
}
actionKeys: [
{
// no turning back at this point...
keys: [ "escape" ]
action: @systemMethod:logoff
}
]
}
}
}
}
prompts: {
loginGlobalNewScan: {
art: GNSPMPT
mci: {
TM1: {
argName: promptValue
items: [ "yes", "no" ]
focus: true
hotKeys: { Y: 0, N: 1 }
hotKeySubmit: true
}
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,816 @@
{
menus: {
messageBaseMainMenu: {
art: MSGMNU
desc: Message Area
prompt: messageBaseMenuPrompt
config: {
interrupt: realtime
}
submit: [
{
value: { command: "P" }
action: @menu:messageBaseNewPost
}
{
value: { command: "J" }
action: @menu:messageBaseChangeCurrentConference
}
{
value: { command: "C" }
action: @menu:messageBaseChangeCurrentArea
}
{
value: { command: "L" }
action: @menu:messageBaseMessageList
}
{
value: { command: "<" }
action: @systemMethod:prevConf
}
{
value: { command: ">" }
action: @systemMethod:nextConf
}
{
value: { command: "[" }
action: @systemMethod:prevArea
}
{
value: { command: "]" }
action: @systemMethod:nextArea
}
{
value: { command: "D" }
action: @menu:messageBaseSetNewScanDate
}
{
value: { command: "S" }
action: @menu:messageBaseSearch
}
{
value: { command: "M" }
action: @menu:messageBaseMyMessages
}
{
value: { command: "A" }
action: @menu:editAutoSignature
}
{
value: { command: "Q" }
action: @systemMethod:prevMenu
}
{
value: { command: "G" }
action: @menu:fullLogoffSequence
}
]
}
messageBaseNewPost: {
desc: Posting message,
module: msg_area_post_fse
config: {
art: {
header: MSGEHDR
body: MSGBODY
footerEditor: MSGEFTR
footerEditorMenu: MSGEMFT
help: MSGEHLP
}
editorMode: edit
editorType: area
}
form: {
0: {
mci: {
TL1: {
argName: from
}
ET2: {
argName: to
focus: true
text: All
validate: @systemMethod:validateNonEmpty
maxLength: 36
}
ET3: {
argName: subject
maxLength: 72
submit: true
validate: @systemMethod:validateNonEmpty
}
}
submit: {
3: [
{
value: { subject: null }
action: @method:headerSubmit
}
]
}
actionKeys: [
{
keys: [ "escape" ]
action: @systemMethod:prevMenu
}
]
}
1: {
"mci" : {
MT1: {
width: 79
argName: message
mode: edit
}
}
submit: {
*: [ { "value": "message", "action": "@method:editModeEscPressed" } ]
}
actionKeys: [
{
keys: [ "escape" ]
viewId: 1
}
]
}
2: {
TLTL: {
mci: {
TL1: { width: 5 }
TL2: { width: 4 }
}
}
}
3: {
HM: {
mci: {
HM1: {
"items" : [ "save", "discard", "help" ]
}
}
submit: {
*: [
{
value: { 1: 0 }
action: @method:editModeMenuSave
}
{
value: { 1: 1 }
action: @systemMethod:prevMenu
}
{
value: { 1: 2 }
action: @method:editModeMenuHelp
}
]
}
actionKeys: [
{
keys: [ "escape" ]
action: @method:editModeEscPressed
}
{
keys: [ "?" ]
action: @method:editModeMenuHelp
}
]
}
}
}
}
messageBaseChangeCurrentConference: {
art: CCHANGE
module: msg_conf_list
form: {
0: {
mci: {
VM1: {
focus: true
submit: true
argName: conf
}
}
submit: {
*: [
{
value: { conf: null }
action: @method:changeConference
}
]
}
actionKeys: @reference:common.quitToPrev
}
}
}
messageBaseChangeCurrentArea: {
art: CHANGE
module: msg_area_list
form: {
0: {
mci: {
VM1: {
focus: true
submit: true
argName: area
}
}
submit: {
*: [
{
value: { area: null }
action: @method:changeArea
}
]
}
actionKeys: @reference:common.quitToPrev
}
}
}
messageBaseMessageList: {
module: msg_list
art: MSGLIST
config: {
menuViewPost: messageAreaViewPost
}
form: {
0: {
mci: {
VM1: {
focus: true
submit: true
argName: message
}
}
submit: {
*: [
{
value: { message: null }
action: @method:selectMessage
}
]
}
actionKeys: @reference:common.quitToPrev
}
}
}
messageBaseSetNewScanDate: {
module: set_newscan_date
desc: Message Base
art: SETMNSDATE
config: {
target: message
scanDateFormat: YYYYMMDD
}
form: {
0: {
mci: {
ME1: {
focus: true
submit: true
argName: scanDate
maskPattern: "####/##/##"
}
SM2: {
argName: targetSelection
submit: false
}
}
submit: {
*: [
{
value: { scanDate: null }
action: @method:scanDateSubmit
}
]
}
actionKeys: @reference:common.quitToPrev
}
}
}
messageBaseSearch: {
desc: Message Search
module: message_base_search
art: MSEARCH
config: {
messageListMenu: messageBaseSearchResultsMessageList
}
form: {
0: {
mci: {
ET1: {
focus: true
argName: searchTerms
}
BT2: {
argName: search
text: search
submit: true
}
SM3: {
argName: confTag
}
SM4: {
argName: areaTag
}
ET5: {
argName: toUserName
maxLength: @config:users.usernameMax
}
ET6: {
argName: fromUserName
maxLength: @config:users.usernameMax
}
BT7: {
argName: advancedSearch
text: advanced search
submit: true
}
}
submit: {
*: [
{
value: { search: null }
action: @method:search
}
{
value: { advancedSearch: null }
action: @method:search
}
]
}
actionKeys: [
{
keys: [ "escape" ]
action: @systemMethod:prevMenu
}
]
}
}
}
messageBaseSearchResultsMessageList: {
desc: Message Search
module: msg_list
art: MSRCHLST
config: {
menuViewPost: messageAreaViewPost
}
form: {
0: {
mci: {
VM1: {
focus: true
submit: true
argName: message
}
TL6: {
// theme me!
}
}
submit: {
*: [
{
value: { message: null }
action: @method:selectMessage
}
]
}
actionKeys: @reference:common.quitToPrev
}
}
}
// The message_base_search module looks for this entry by default
messageSearchNoResults: {
desc: Message Search
art: MSRCNORES
config: {
pause: true
}
}
messageBaseMyMessages: {
desc: Personal Messages
module: my_messages
config: {
messageListMenu: messageBaseMyMessagesList
}
}
messageBaseMyMessagesList: {
desc: Personal Messages
module: msg_list
art: MYMSGLST
config: {
menuViewPost: messageAreaViewPost
}
form: {
0: {
mci: {
VM1: {
focus: true
submit: true
argName: message
}
}
submit: {
*: [
{
value: { message: null }
action: @method:selectMessage
}
]
}
actionKeys: @reference:common.quitToPrev
}
}
}
editAutoSignature: {
desc: Auto Sig Editor
module: autosig_edit
art: autosig
form: {
0: {
mci: {
MT1: {
argName: signature
tabSwitchesView: true
}
BT2: {
text: save
argName: save
submit: true
}
}
submit: {
*: [
{
value: { save: null }
action: @method:saveChanges
}
]
}
actionKeys: [
{
keys: [ "escape" ]
action: @systemMethod:prevMenu
}
]
}
}
}
messageAreaViewPost: {
module: msg_area_view_fse
config: {
art: {
header: MSGVHDR
body: MSGBODY
footerView: MSGVFTR
help: MSGVHLP
},
editorMode: view
editorType: area
}
form: {
0: {
mci: {
// :TODO: ensure this block isn't even req. for theme to apply...
}
}
1: {
mci: {
MT1: {
width: 79
mode: preview
}
}
submit: {
*: [
{
value: message
action: @method:editModeEscPressed
}
]
}
actionKeys: [
{
keys: [ "escape" ]
viewId: 1
}
]
}
2: {
TLTL: {
mci: {
TL1: { width: 5 }
TL2: { width: 4 }
}
}
}
4: {
mci: {
HM1: {
// :TODO: (#)Jump/(L)Index (msg list)/Last
items: [ "prev", "next", "reply", "quit", "help" ]
focusItemIndex: 1
}
}
submit: {
*: [
{
value: { 1: 0 }
action: @method:prevMessage
}
{
value: { 1: 1 }
action: @method:nextMessage
}
{
value: { 1: 2 }
action: @method:replyMessage
extraArgs: {
menu: messageAreaReplyPost
}
}
{
value: { 1: 3 }
action: @systemMethod:prevMenu
}
{
value: { 1: 4 }
action: @method:viewModeMenuHelp
}
]
}
actionKeys: [
{
keys: [ "p", "shift + p" ]
action: @method:prevMessage
}
{
keys: [ "n", "shift + n" ]
action: @method:nextMessage
}
{
keys: [ "r", "shift + r" ]
action: @method:replyMessage
extraArgs: {
menu: messageAreaReplyPost
}
}
{
keys: [ "escape", "q", "shift + q" ]
action: @systemMethod:prevMenu
}
{
keys: [ "?" ]
action: @method:viewModeMenuHelp
}
{
keys: [ "down arrow", "up arrow", "page up", "page down" ]
action: @method:movementKeyPressed
}
]
}
}
}
messageAreaReplyPost: {
module: msg_area_post_fse
config: {
art: {
header: MSGEHDR
body: MSGBODY
quote: MSGQUOT
footerEditor: MSGEFTR
footerEditorMenu: MSGEMFT
help: MSGEHLP
}
editorMode: edit
editorType: area
}
form: {
0: {
mci: {
// :TODO: use appropriate system properties for max lengths
TL1: {
argName: from
}
ET2: {
argName: to
focus: true
validate: @systemMethod:validateNonEmpty
maxLength: 36
}
ET3: {
argName: subject
maxLength: 72
submit: true
validate: @systemMethod:validateNonEmpty
}
TL4: {
// :TODO: this is for RE: line (NYI)
//width: 27
//textOverflow: ...
}
}
submit: {
3: [
{
value: { subject: null }
action: @method:headerSubmit
}
]
}
actionKeys: [
{
keys: [ "escape" ]
action: @systemMethod:prevMenu
}
]
}
1: {
mci: {
MT1: {
width: 79
height: 14
argName: message
mode: edit
}
}
submit: {
*: [ { "value": "message", "action": "@method:editModeEscPressed" } ]
}
actionKeys: [
{
keys: [ "escape" ],
viewId: 1
}
]
}
3: {
mci: {
HM1: {
items: [ "save", "discard", "quote", "help" ]
}
}
submit: {
*: [
{
value: { 1: 0 }
action: @method:editModeMenuSave
}
{
value: { 1: 1 }
action: @systemMethod:prevMenu
}
{
value: { 1: 2 },
action: @method:editModeMenuQuote
}
{
value: { 1: 3 }
action: @method:editModeMenuHelp
}
]
}
actionKeys: [
{
keys: [ "escape" ]
action: @method:editModeEscPressed
}
{
keys: [ "s", "shift + s" ]
action: @method:editModeMenuSave
}
{
keys: [ "d", "shift + d" ]
action: @systemMethod:prevMenu
}
{
keys: [ "q", "shift + q" ]
action: @method:editModeMenuQuote
}
{
keys: [ "?" ]
action: @method:editModeMenuHelp
}
]
}
// Quote builder
5: {
mci: {
MT1: {
width: 79
height: 7
}
VM3: {
width: 79
height: 4
argName: quote
}
}
submit: {
*: [
{
value: { quote: null }
action: @method:appendQuoteEntry
}
]
}
actionKeys: [
{
keys: [ "escape" ]
action: @method:quoteBuilderEscPressed
}
]
}
}
}
//
// The 'msg_conf_list' module defaults to looking for
// a menu entry of 'changeConfPreArtMenu'. If found,
// this menu will be executed upon changing message
// conferences using the conference tag as an art spec.
//
changeMessageConfPreArt: {
module: show_art
config: {
method: messageConf
key: confTag
pause: true
cls: true
menuFlags: [ "popParent", "noHistory" ]
}
}
//
// The 'msg_area_list' module defaults to looking for
// a menu entry of 'changeMessageAreaPreArt'. If found,
// this menu will be executed upon changing message
// areas using the area tag as an art spec.
//
changeMessageAreaPreArt: {
module: show_art
config: {
method: messageArea
key: areaTag
pause: true
cls: true
menuFlags: [ "popParent", "noHistory" ]
}
}
}
prompts: {
messageBaseMenuPrompt: {
art: MSGPMPT
mci: {
//TL1: {}
ET2: {
argName: command
width: 20
maxLength: 20
submit: true
textStyle: upper
focus: true
}
}
},
// default prompt entry used by the 'msg_lsit' module
deleteMessageFromListPrompt: {
art: MSGDELPMPT
mci: {
TM1: {
argName: promptValue
items: [ "yes", "no" ]
focus: true
hotKeys: { Y: 0, N: 1 }
hotKeySubmit: true
}
}
}
}
}

View File

@ -0,0 +1,362 @@
{
menus: {
// A quick preamble - defaults to warning about broken terminals
newUserApplicationPre: {
art: NEWUSER1
next: newUserApplication
desc: Applying
config: {
pause: true
cls: true
menuFlags: [ "noHistory" ]
}
}
newUserApplication: {
module: nua
art: NUA
next: [
{
// Initial SysOp does not send feedback to themselves
acs: ID1
next: fullLoginSequenceLoginArt
}
{
// ...everyone else does
next: newUserFeedbackToSysOpPreamble
}
]
form: {
0: {
mci: {
ET1: {
focus: true
argName: username
maxLength: @config:users.usernameMax
validate: @systemMethod:validateUserNameAvail
}
ET2: {
argName: realName
maxLength: @config:users.realNameMax
validate: @systemMethod:validateNonEmpty
}
MET3: {
argName: birthdate
maskPattern: "####/##/##"
validate: @systemMethod:validateBirthdate
}
ME4: {
argName: sex
maskPattern: A
textStyle: upper
validate: @systemMethod:validateNonEmpty
}
ET5: {
argName: location
maxLength: @config:users.locationMax
validate: @systemMethod:validateNonEmpty
}
ET6: {
argName: affils
maxLength: @config:users.affilsMax
}
ET7: {
argName: email
maxLength: @config:users.emailMax
validate: @systemMethod:validateEmailAvail
}
ET8: {
argName: web
maxLength: @config:users.webMax
}
ET9: {
argName: password
password: true
maxLength: @config:users.passwordMax
validate: @systemMethod:validatePasswordSpec
}
ET10: {
argName: passwordConfirm
password: true
maxLength: @config:users.passwordMax
validate: @method:validatePassConfirmMatch
}
TM12: {
argName: submission
items: [ "apply", "cancel" ]
submit: true
}
}
submit: {
*: [
{
value: { "submission" : 0 }
action: @method:submitApplication
extraArgs: {
inactive: userNeedsActivated
error: newUserCreateError
}
}
{
value: { "submission" : 1 }
action: @systemMethod:prevMenu
}
]
}
actionKeys: @reference:common.escToPrev
}
}
}
// A quick preamble - defaults to warning about broken terminals (SSH version)
newUserApplicationPreSsh: {
art: NEWUSER1
next: newUserApplicationSsh
desc: Applying
config: {
pause: true
cls: true
menuFlags: [ "noHistory" ]
}
}
//
// SSH specialization of NUA
// Canceling this form logs off vs falling back to matrix
//
newUserApplicationSsh: {
module: nua
art: NUA
fallback: logoff
next: newUserFeedbackToSysOpPreamble
form: {
0: {
mci: {
ET1: {
focus: true
argName: username
maxLength: @config:users.usernameMax
validate: @systemMethod:validateUserNameAvail
}
ET2: {
argName: realName
maxLength: @config:users.realNameMax
validate: @systemMethod:validateNonEmpty
}
MET3: {
argName: birthdate
maskPattern: "####/##/##"
validate: @systemMethod:validateBirthdate
}
ME4: {
argName: sex
maskPattern: A
textStyle: upper
validate: @systemMethod:validateNonEmpty
}
ET5: {
argName: location
maxLength: @config:users.locationMax
validate: @systemMethod:validateNonEmpty
}
ET6: {
argName: affils
maxLength: @config:users.affilsMax
}
ET7: {
argName: email
maxLength: @config:users.emailMax
validate: @systemMethod:validateEmailAvail
}
ET8: {
argName: web
maxLength: @config:users.webMax
}
ET9: {
argName: password
password: true
maxLength: @config:users.passwordMax
validate: @systemMethod:validatePasswordSpec
}
ET10: {
argName: passwordConfirm
password: true
maxLength: @config:users.passwordMax
validate: @method:validatePassConfirmMatch
}
TM12: {
argName: submission
items: [ "apply", "cancel" ]
submit: true
}
}
submit: {
*: [
{
value: { "submission" : 0 }
action: @method:submitApplication
extraArgs: {
inactive: userNeedsActivated
error: newUserCreateError
}
}
{
value: { "submission" : 1 }
action: @systemMethod:logoff
}
]
}
actionKeys: [
{
keys: [ "escape" ]
action: @systemMethod:logoff
}
]
}
}
}
newUserFeedbackToSysOpPreamble: {
art: LETTER
config: { pause: true }
next: newUserFeedbackToSysOp
}
newUserFeedbackToSysOp: {
desc: Feedback to SysOp
module: msg_area_post_fse
next: [
{
acs: AS2
next: fullLoginSequenceLoginArt
}
{
next: newUserInactiveDone
}
]
config: {
art: {
header: MSGEHDR
body: MSGBODY
footerEditor: MSGEFTR
footerEditorMenu: MSGEMFT
help: MSGEHLP
},
editorMode: edit
editorType: email
messageAreaTag: private_mail
toUserId: 1 /* always to +op */
}
form: {
0: {
mci: {
TL1: {
argName: from
}
ET2: {
argName: to
focus: true
text: @sysStat:sysop_username
maxLength: 36
// :TODO: readOnly: true
}
ET3: {
argName: subject
maxLength: 72
submit: true
text: New user feedback
validate: @systemMethod:validateMessageSubject
}
}
submit: {
3: [
{
value: { subject: null }
action: @method:headerSubmit
}
]
}
}
1: {
mci: {
MT1: {
width: 79
argName: message
mode: edit
}
}
submit: {
*: [
{
value: message
action: @method:editModeEscPressed
}
]
}
actionKeys: [
{
keys: [ "escape" ]
viewId: 1
}
]
},
2: {
TLTL: {
mci: {
TL1: {
width: 5
}
TL2: {
width: 4
}
}
}
}
3: {
HM: {
mci: {
HM1: {
// :TODO: clear
items: [ "save", "help" ]
}
}
submit: {
*: [
{
value: { 1: 0 }
action: @method:editModeMenuSave
}
{
value: { 1: 1 }
action: @method:editModeMenuHelp
}
]
}
actionKeys: [
{
keys: [ "escape" ]
action: @method:editModeEscPressed
}
{
keys: [ "?" ]
action: @method:editModeMenuHelp
}
]
}
}
}
}
newUserInactiveDone: {
desc: Finished with NUA
art: DONE
config: { pause: true }
next: @menu:logoff
}
}
}

View File

@ -0,0 +1,197 @@
{
menus: {
privateMailMenu: {
art: MAILMNU
desc: Private Mail
prompt: menuCommand
config: {
interrupt: realtime
}
submit: [
{
value: { command: "C" }
action: @menu:privateMailMenuCreateMessage
}
{
value: { command: "I" }
action: @menu:privateMailMenuInbox
}
{
value: { command: "Q" }
action: @systemMethod:prevMenu
}
{
value: { command: "G" }
action: @menu:fullLogoffSequence
}
]
}
privateMailMenuCreateMessage: {
desc: Mailing Someone
module: msg_area_post_fse
config: {
art: {
header: MSGEHDR
body: MSGBODY
footerEditor: MSGEFTR
footerEditorMenu: MSGEMFT
help: MSGEHLP
},
editorMode: edit
editorType: email
messageAreaTag: private_mail
}
form: {
0: {
mci: {
TL1: {
argName: from
}
ET2: {
argName: to
focus: true
validate: @systemMethod:validateGeneralMailAddressedTo
maxLength: 36
}
ET3: {
argName: subject
maxLength: 72
submit: true
validate: @systemMethod:validateMessageSubject
}
}
submit: {
3: [
{
value: { subject: null }
action: @method:headerSubmit
}
]
}
actionKeys: @reference: common.escToPrev
}
1: {
mci: {
MT1: {
width: 79
argName: message
mode: edit
}
}
submit: {
*: [ { value: "message", action: "@method:editModeEscPressed" } ]
}
actionKeys: [
{
keys: [ "escape" ]
viewId: 1
}
]
},
2: {
TLTL: {
mci: {
TL1: {
width: 5
}
TL2: {
width: 4
}
}
}
}
3: {
HM: {
mci: {
HM1: {
// :TODO: clear
items: [ "save", "discard", "help" ]
}
}
submit: {
*: [
{
value: { 1: 0 }
action: @method:editModeMenuSave
}
{
value: { 1: 1 }
action: @systemMethod:prevMenu
}
{
value: { 1: 2 }
action: @method:editModeMenuHelp
}
]
}
actionKeys: [
{
keys: [ "escape" ]
action: @method:editModeEscPressed
}
{
keys: [ "?" ]
action: @method:editModeMenuHelp
}
]
}
}
}
}
privateMailMenuInbox: {
module: msg_list
art: PRVMSGLIST
config: {
menuViewPost: messageAreaViewPost
messageAreaTag: private_mail
}
form: {
0: { // main list
mci: {
VM1: {
focus: true
submit: true
argName: message
}
}
submit: {
*: [
{
value: { message: null }
action: @method:selectMessage
}
]
}
actionKeys: [
{
keys: [ "escape", "q", "shift + q" ]
action: @systemMethod:prevMenu
}
{
keys: [ "delete", "d", "shift + d" ]
action: @method:deleteSelected
}
]
}
1: { // delete prompt form
submit: {
*: [
{
value: { promptValue: 0 }
action: @method:deleteMessageYes
}
{
value: { promptValue: 1 }
action: @method:deleteMessageNo
}
]
}
}
}
}
}
}

View File

@ -28,6 +28,7 @@
// :TODO: this entire file needs cleaned up a LOT // :TODO: this entire file needs cleaned up a LOT
// :TODO: Convert all of this to HJSON // :TODO: Convert all of this to HJSON
prompts: { prompts: {
/*
userCredentials: { userCredentials: {
"art" : "usercred", "art" : "usercred",
"mci" : { "mci" : {
@ -58,20 +59,9 @@
} }
} }
}, },
*/
logoffConfirmation: { /*
art: LOGPMPT
mci: {
TM1: {
argName: promptValue
items: [ "yes", "no" ]
focus: true
hotKeys: { Y: 0, N: 1 }
hotKeySubmit: true
}
}
}
loginSequenceFlavorSelect: { loginSequenceFlavorSelect: {
art: LOGINSEL art: LOGINSEL
mci: { mci: {
@ -85,66 +75,8 @@
} }
} }
} }
*/
loginGlobalNewScan: {
art: GNSPMPT
mci: {
TM1: {
argName: promptValue
items: [ "yes", "no" ]
focus: true
hotKeys: { Y: 0, N: 1 }
hotKeySubmit: true
}
}
}
menuCommand: {
art: MNUPRMT
mci: {
TL1: {
// theme me!
}
ET2: {
argName: command
width: 20
maxLength: 20
submit: true
textStyle: upper
focus: true
}
}
},
messageMenuCommand: {
art: MSGPMPT
mci: {
TL1: {
// theme me!
}
ET2: {
argName: command
width: 20
maxLength: 20
submit: true
textStyle: upper
focus: true
}
}
},
deleteMessageFromListPrompt: {
art: MSGDELPMPT
mci: {
TM1: {
argName: promptValue
items: [ "yes", "no" ]
focus: true
hotKeys: { Y: 0, N: 1 }
hotKeySubmit: true
}
}
}
"newAreaPostPrompt" : { "newAreaPostPrompt" : {
"art" : "message_area_new_post", "art" : "message_area_new_post",
@ -160,66 +92,10 @@
} }
}, },
forgotPasswordPrompt: {
art: FORGOTPW
mci: {
ET1: {
argName: username
maxLength: @config:users.usernameMax
width: 32
focus: true
}
}
actionKeys: [
{
keys: [ "escape" ]
action: @systemMethod:prevMenu
}
]
}
/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
// File Base Related // File Base Related
/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
fileMenuCommand: {
art: FILPMPT
mci: {
TL1: {}
ET2: {
argName: menuOption
width: 20
maxLength: 20
textStyle: upper
focus: true
}
}
}
fileBaseRateEntryPrompt: {
art: RATEFILE
mci: {
SM1: {
argName: rating
items: [ "-----", "*----", "**---", "***--", "****-", "*****" ]
}
}
actionKeys: [
{
keys: [ "escape" ]
action: @systemMethod:prevMenu
}
]
}
fileBaseTagEntryPrompt: {
art: TAGFILE
mci: {
ET1: {
argName: tags
}
}
}
/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
// Standard / Required // Standard / Required