Commit 29d97a2b authored by Michael Long's avatar Michael Long
Browse files

xtrnmenu module v3

parent d322c5e1
Pipeline #1272 passed with stage
in 14 minutes and 56 seconds
...@@ -106,4 +106,29 @@ searchagainmsg: "\x01n\x01mPress S to Search Again." ...@@ -106,4 +106,29 @@ searchagainmsg: "\x01n\x01mPress S to Search Again."
;favorte_remove_item: "Remove Item" ;favorte_remove_item: "Remove Item"
;add_favorites_msg: "\x01c\x01hAdd Favorite" ;add_favorites_msg: "\x01c\x01hAdd Favorite"
;remove_favorites_msg: "\x01c\x01hRemove Favorite" ;remove_favorites_msg: "\x01c\x01hRemove Favorite"
;custom.favorites_inst: "\x01n\x01w\x01h\x012[Up/Down/Home/End] to Navigate, [Enter] to Select, [Q] to Quit" ;favorites_inst: "\x01n\x01w\x01h\x012 [Up/Down/Home/End] to Navigate, [Enter] to Select, [Q] to Quit, [S] to Search "
;favorites_inst_rem: "\x01n\x01w\x01h\x012 [Up/Down/Home/End] to Navigate, [Enter] to Select, [Q] to Quit "
;favorite_add_search_prompt: "\x01c\x01hSearch (ESC to Cancel): \x01n"
; autocomplete (search) box on add favorite
; see cga_defs.js for color codes
; autocomplete input box
;favorite_add_search_fg=LIGHTGRAY
;favorite_add_search_bg=BG_BLACK
; autocomplete result box
;favorite_add_search_sfg=LIGHTGRAY
;favorite_add_search_sbg=BG_BLACK
; autocomplete highlighted row
;favorite_add_search_hsfg=WHITE
;favorite_add_search_hsbg=BG_MAGENTA
; scrolling menu on add favorite
; lightbar non-current item
;favorite_add_fg=LIGHTGRAY
;favorite_add_bg=BG_BLACK
; lightbar current item
;favorite_add_lfg=WHITE
;favorite_add_lbg=BG_MAGENTA
; tree heading
;favorite_add_cfg=WHITE
;favorite_add_cbg=BG_BLACK
\ No newline at end of file
...@@ -218,7 +218,7 @@ ExternalMenus.prototype.getOptions = function(menutype, menuid) { ...@@ -218,7 +218,7 @@ ExternalMenus.prototype.getOptions = function(menutype, menuid) {
} }
this.options.custom = this.xtrn_custommenu_options; this.options.custom = this.xtrn_custommenu_options;
return this.options; return this.options;
} }
...@@ -250,20 +250,20 @@ ExternalMenus.prototype.getMenu = function(menuid) { ...@@ -250,20 +250,20 @@ ExternalMenus.prototype.getMenu = function(menuid) {
xtrn_area.sec_list.forEach(function (sec) { xtrn_area.sec_list.forEach(function (sec) {
if (sec.can_access) { if (sec.can_access) {
menuitems.push({ menuitems.push({
"input": i, input: i,
"target": sec.code, target: sec.code,
"type": "xtrnmenu", type: "xtrnmenu",
"title": sec.name, title: sec.name,
"access_string": sec.ars access_string: sec.ars
}); });
i++; i++;
} }
}); });
menu = { menu = {
"id": "main", id: "main",
"title": "Main Menu", title: "Main Menu",
"items": menuitems items: menuitems
}; };
} }
return menu; return menu;
...@@ -278,12 +278,17 @@ ExternalMenus.prototype.getSectionMenu = function(menuid) { ...@@ -278,12 +278,17 @@ ExternalMenus.prototype.getSectionMenu = function(menuid) {
} }
var menuitems = []; var menuitems = [];
var menu, title; var title;
var menu = {
id: menuid,
title: null,
items: []
}
xtrn_area.sec_list.some(function (sec) { xtrn_area.sec_list.some(function (sec) {
if (sec.code.toLowerCase() == menuid.toLowerCase()) { if (sec.code.toLowerCase() == menuid.toLowerCase()) {
title = sec.name; menu.title = sec.name;
if (!sec.can_access || sec.prog_list.length < 1) { if (!sec.can_access || sec.prog_list.length < 1) {
return false; return false;
...@@ -292,22 +297,18 @@ ExternalMenus.prototype.getSectionMenu = function(menuid) { ...@@ -292,22 +297,18 @@ ExternalMenus.prototype.getSectionMenu = function(menuid) {
var i = 1; var i = 1;
sec.prog_list.some(function (prog) { sec.prog_list.some(function (prog) {
menuitems.push({ menuitems.push({
'input' : i, input : i,
'target': prog.code, target: prog.code,
'title': prog.name, title: prog.name,
'type': 'xtrnprog', type: 'xtrnprog',
'access_string': prog.ars, access_string: prog.ars,
'cost': prog.cost cost: prog.cost
}); });
i++; i++;
}); });
if (menuitems.length > 0) { if (menuitems.length > 0) {
menu = { menu.items = menuitems;
'id': menuid,
'title': title,
'items': menuitems,
};
} }
return; return;
} }
...@@ -447,6 +448,11 @@ ExternalMenus.prototype.sort_by_input = function(a, b) { ...@@ -447,6 +448,11 @@ ExternalMenus.prototype.sort_by_input = function(a, b) {
return 0; return 0;
} }
// Handle json update
ExternalMenus.prototype.processUpdate = function(update) {
log(ERROR, "Unhandled JSON DB packet: " + JSON.stringify(update));
}
// Sort for special menus, by value numerically desc // Sort for special menus, by value numerically desc
ExternalMenus.prototype.sort_special = function(obj) { ExternalMenus.prototype.sort_special = function(obj) {
var keys = []; var keys = [];
...@@ -458,6 +464,8 @@ ExternalMenus.prototype.sort_special = function(obj) { ...@@ -458,6 +464,8 @@ ExternalMenus.prototype.sort_special = function(obj) {
// return menu object for special menu (most recent, etc.) // return menu object for special menu (most recent, etc.)
ExternalMenus.prototype.getSpecial = function(menutype, title, itemcount) { ExternalMenus.prototype.getSpecial = function(menutype, title, itemcount) {
var options = this.getOptions('custommenu', menutype);
var menu; var menu;
var menuitems = []; var menuitems = [];
...@@ -476,10 +484,11 @@ ExternalMenus.prototype.getSpecial = function(menutype, title, itemcount) { ...@@ -476,10 +484,11 @@ ExternalMenus.prototype.getSpecial = function(menutype, title, itemcount) {
} }
try { try {
load("json-client.js") require("json-client.js", "JSONClient");
var jsonClient = new JSONClient(this.options.json_host, this.options.json_port); var jsonClient = new JSONClient(this.options.json_host, this.options.json_port);
jsonClient.callback = processUpdate; jsonClient.callback = this.processUpdate;
} catch (e) { } catch (e) {
writeln("NP" + e);
log(LOG_ERR, "xtrnmenulib: Could not initialize JSON database so special menu is now disabled: " + e); log(LOG_ERR, "xtrnmenulib: Could not initialize JSON database so special menu is now disabled: " + e);
return false; return false;
} }
...@@ -559,13 +568,13 @@ ExternalMenus.prototype.getSpecial = function(menutype, title, itemcount) { ...@@ -559,13 +568,13 @@ ExternalMenus.prototype.getSpecial = function(menutype, title, itemcount) {
break; break;
} }
menuitems.push({ menuitems.push({
'input': i, input: i,
'target': xtrn_area.prog[e].code, target: xtrn_area.prog[e].code,
'title': xtrn_area.prog[e].name, title: xtrn_area.prog[e].name,
'type': 'xtrnprog', type: 'xtrnprog',
'access_string': xtrn_area.prog[e].ars, access_string: xtrn_area.prog[e].ars,
'cost': xtrn_area.prog[e].cost, cost: xtrn_area.prog[e].cost,
'stats': stats, stats: stats,
}); });
i++; i++;
break; break;
...@@ -578,9 +587,9 @@ ExternalMenus.prototype.getSpecial = function(menutype, title, itemcount) { ...@@ -578,9 +587,9 @@ ExternalMenus.prototype.getSpecial = function(menutype, title, itemcount) {
} }
if (menuitems.length > 0) { if (menuitems.length > 0) {
menu = { menu = {
'id': menutype, id: menutype,
'title': title, title: title,
'items': menuitems, items: menuitems,
}; };
} }
...@@ -602,9 +611,9 @@ ExternalMenus.prototype.getFavorites = function(title, itemcount) { ...@@ -602,9 +611,9 @@ ExternalMenus.prototype.getFavorites = function(title, itemcount) {
} }
try { try {
load("json-client.js") require("json-client.js", "JSONClient");
var jsonClient = new JSONClient(this.options.json_host, this.options.json_port); var jsonClient = new JSONClient(this.options.json_host, this.options.json_port);
jsonClient.callback = processUpdate; jsonClient.callback = this.processUpdate;
} catch (e) { } catch (e) {
log(LOG_ERR, "xtrnmenulib: Could not initialize JSON database so favorites is now disabled: " + e); log(LOG_ERR, "xtrnmenulib: Could not initialize JSON database so favorites is now disabled: " + e);
return false; return false;
...@@ -624,12 +633,12 @@ ExternalMenus.prototype.getFavorites = function(title, itemcount) { ...@@ -624,12 +633,12 @@ ExternalMenus.prototype.getFavorites = function(title, itemcount) {
var stats; var stats;
menuitems.push({ menuitems.push({
'input': i, input: i,
'target': xtrn_area.prog[e].code, target: xtrn_area.prog[e].code,
'title': xtrn_area.prog[e].name, title: xtrn_area.prog[e].name,
'type': 'xtrnprog', type: 'xtrnprog',
'access_string': xtrn_area.prog[e].ars, access_string: xtrn_area.prog[e].ars,
'cost': xtrn_area.prog[e].cost, cost: xtrn_area.prog[e].cost,
}); });
i++; i++;
break; break;
...@@ -642,9 +651,9 @@ ExternalMenus.prototype.getFavorites = function(title, itemcount) { ...@@ -642,9 +651,9 @@ ExternalMenus.prototype.getFavorites = function(title, itemcount) {
} }
menu = { menu = {
'id': 'favorites', id: 'favorites',
'title': title, title: title !== undefined ? title : 'Favorites',
'items': menuitems, items: menuitems,
}; };
return menu; return menu;
......
...@@ -19,6 +19,8 @@ require("sbbsdefs.js", "K_NONE"); ...@@ -19,6 +19,8 @@ require("sbbsdefs.js", "K_NONE");
require("xtrnmenulib.js", "MENU_LOADED"); require("xtrnmenulib.js", "MENU_LOADED");
const ansiterm = load({}, 'ansiterm_lib.js');
var options, xsec = -1; var options, xsec = -1;
//// Main //// Main
...@@ -110,9 +112,9 @@ function dopre(progCode) ...@@ -110,9 +112,9 @@ function dopre(progCode)
} }
try { try {
load("json-client.js") require("json-client.js", "JSONClient");
var jsonClient = new JSONClient(options.json_host, options.json_port); var jsonClient = new JSONClient(options.json_host, options.json_port);
jsonClient.callback = processUpdate; jsonClient.callback = ExternalMenus.processUpdate;
} catch (e) { } catch (e) {
log(LOG_ERR, "xtrnmenu pre: Could not initialize JSON database so door tracking is now disabled: " + e); log(LOG_ERR, "xtrnmenu pre: Could not initialize JSON database so door tracking is now disabled: " + e);
return; return;
...@@ -218,9 +220,9 @@ function dopost(progCode) ...@@ -218,9 +220,9 @@ function dopost(progCode)
} }
try { try {
load("json-client.js") require("json-client.js", "JSONClient");
var jsonClient = new JSONClient(options.json_host, options.json_port); var jsonClient = new JSONClient(options.json_host, options.json_port);
jsonClient.callback = processUpdate; jsonClient.callback = ExternalMenus.processUpdate;
} catch (e) { } catch (e) {
log(LOG_ERR, "xtrnmenu pre: Could not initialize JSON database so door tracking is now disabled: " + e); log(LOG_ERR, "xtrnmenu pre: Could not initialize JSON database so door tracking is now disabled: " + e);
return; return;
...@@ -267,15 +269,6 @@ function dopost(progCode) ...@@ -267,15 +269,6 @@ function dopost(progCode)
} }
} }
/**
* JSON DB handler
* @param update
*/
function processUpdate(update)
{
log(ERROR, "Unhandler JSON DB packet: " + JSON.stringify(update));
}
// Runs custom commands, for gamesrv // Runs custom commands, for gamesrv
function docommand(command, commandparam1, commandparam2) function docommand(command, commandparam1, commandparam2)
{ {
...@@ -600,6 +593,12 @@ function external_menu_custom(menuid) ...@@ -600,6 +593,12 @@ function external_menu_custom(menuid)
break; break;
} }
// empty menu
if (!menuobj.items.length && (menuid != "main")) {
write(options.no_programs_msg);
break;
}
system.node_list[bbs.node_num-1].aux = 0; /* aux is 0, only if at menu */ system.node_list[bbs.node_num-1].aux = 0; /* aux is 0, only if at menu */
bbs.node_action = NODE_XTRN; bbs.node_action = NODE_XTRN;
bbs.node_sync(); bbs.node_sync();
...@@ -842,7 +841,12 @@ function external_menu_custom(menuid) ...@@ -842,7 +841,12 @@ function external_menu_custom(menuid)
// don't have ESC do anything on the main menu // don't have ESC do anything on the main menu
} else if ((keyin == 'q') || (keyin == "\x1B")) { } else if ((keyin == 'q') || (keyin == "\x1B")) {
if (gamesrv && (menuid == 'main')) { if (gamesrv && (menuid == 'main')) {
bbs.logoff(); // doing it this way rather than calling bbs.logoff()
// so that the prompt defaults to Yes
console.crlf();
if (console.yesno("Do you wish to logoff")) {
bbs.logoff(false);
}
} else { } else {
console.clear(); console.clear();
return; return;
...@@ -1397,11 +1401,11 @@ function search_menu(title, itemcount) { ...@@ -1397,11 +1401,11 @@ function search_menu(title, itemcount) {
if (menuconfig.menus[i].title.toLowerCase().indexOf(searchterm) !== -1) { if (menuconfig.menus[i].title.toLowerCase().indexOf(searchterm) !== -1) {
if (user.compare_ars(menuconfig.menus[i].title.access_string)) { if (user.compare_ars(menuconfig.menus[i].title.access_string)) {
menuitemsfiltered.push({ menuitemsfiltered.push({
'input': input++, input: input++,
'id': menuconfig.menus[i].id, id: menuconfig.menus[i].id,
'title': menuconfig.menus[i].title, title: menuconfig.menus[i].title,
'target': menuconfig.menus[i].id, target: menuconfig.menus[i].id,
'type': 'custommenu' type: 'custommenu'
}); });
} }
} }
...@@ -1414,11 +1418,11 @@ function search_menu(title, itemcount) { ...@@ -1414,11 +1418,11 @@ function search_menu(title, itemcount) {
if (xtrn_area.sec_list[i].name.toLowerCase().indexOf(searchterm) !== -1) { if (xtrn_area.sec_list[i].name.toLowerCase().indexOf(searchterm) !== -1) {
if (xtrn_area.sec_list[i].can_access) { if (xtrn_area.sec_list[i].can_access) {
menuitemsfiltered.push({ menuitemsfiltered.push({
'input': input++, input: input++,
'id': xtrn_area.sec_list[i].code, id: xtrn_area.sec_list[i].code,
'title': xtrn_area.sec_list[i].name, title: xtrn_area.sec_list[i].name,
'target': xtrn_area.sec_list[i].code, target: xtrn_area.sec_list[i].code,
'type': 'xtrnmenu' type: 'xtrnmenu'
}); });
} }
} }
...@@ -1432,11 +1436,11 @@ function search_menu(title, itemcount) { ...@@ -1432,11 +1436,11 @@ function search_menu(title, itemcount) {
if (xtrn_area.sec_list[i].prog_list[k].name.toLowerCase().indexOf(searchterm) !== -1) { if (xtrn_area.sec_list[i].prog_list[k].name.toLowerCase().indexOf(searchterm) !== -1) {
if (xtrn_area.sec_list[i].prog_list[k].can_access) { if (xtrn_area.sec_list[i].prog_list[k].can_access) {
menuitemsfiltered.push({ menuitemsfiltered.push({
'input': input++, input: input++,
'id': xtrn_area.sec_list[i].prog_list[k].code, id: xtrn_area.sec_list[i].prog_list[k].code,
'title': xtrn_area.sec_list[i].prog_list[k].name, title: xtrn_area.sec_list[i].prog_list[k].name,
'target': xtrn_area.sec_list[i].prog_list[k].code, target: xtrn_area.sec_list[i].prog_list[k].code,
'type': 'xtrnprog' type: 'xtrnprog'
}); });
} }
} }
...@@ -2054,6 +2058,16 @@ function favorites_menu(title, itemcount) { ...@@ -2054,6 +2058,16 @@ function favorites_menu(title, itemcount) {
if (keyin) { if (keyin) {
if ((keyin == '+') || (keyin == '=')) { if ((keyin == '+') || (keyin == '=')) {
add_favorite(); add_favorite();
} else if ((keyin == "\x08") || (keyin == "\x7f")) {
// delete
if (menuitemsfiltered[selected_index].type == 'xtrnprog') {
console.crlf();
if (!console.noyes("Do you wish to remove " +
menuitemsfiltered[selected_index].title)) {
remove_favorite(menuitemsfiltered[selected_index].target.toLowerCase());
}
}
} else if ((keyin == '-') || (keyin == '_')) { } else if ((keyin == '-') || (keyin == '_')) {
remove_favorite(); remove_favorite();
} else { } else {
...@@ -2084,6 +2098,12 @@ function favorites_menu(title, itemcount) { ...@@ -2084,6 +2098,12 @@ function favorites_menu(title, itemcount) {
// Add an entry to the favorites menu // Add an entry to the favorites menu
function add_favorite() function add_favorite()
{ {
require("frame.js", "Frame");
require("tree.js", "Tree");
require("scrollbar.js", "ScrollBar");
require('typeahead.js', 'Typeahead');
load(js.global, 'cga_defs.js');
var options = ExternalMenus.getOptions('custommenu', 'favorites'); var options = ExternalMenus.getOptions('custommenu', 'favorites');
if (!options.json_enabled) { if (!options.json_enabled) {
...@@ -2092,9 +2112,9 @@ function add_favorite() ...@@ -2092,9 +2112,9 @@ function add_favorite()
} }
try { try {
load("json-client.js") require("json-client.js", "JSONClient");
var jsonClient = new JSONClient(options.json_host, options.json_port); var jsonClient = new JSONClient(options.json_host, options.json_port);
jsonClient.callback = processUpdate; jsonClient.callback = ExternalMenus.processUpdate;
} catch (e) { } catch (e) {
log(LOG_ERR, "xtrnmenu add_favorites: Could not initialize JSON database so favorites is now disabled: " + e); log(LOG_ERR, "xtrnmenu add_favorites: Could not initialize JSON database so favorites is now disabled: " + e);
return false; return false;
...@@ -2107,12 +2127,10 @@ function add_favorite() ...@@ -2107,12 +2127,10 @@ function add_favorite()
jsonData = []; jsonData = [];
} }
load("frame.js"); var frame = new Frame(1, 1, console.screen_columns, console.screen_rows, WHITE);
load("tree.js"); var treeframe = new Frame(frame.x, frame.y+4, frame.width, frame.height-5, WHITE);
var frame = new Frame(1, 1, console.screen_columns, 4, WHITE);
var treeframe = new Frame(1, 5, console.screen_columns, console.screen_rows-5, WHITE);
var tree = new Tree(treeframe); var tree = new Tree(treeframe);
var s = new ScrollBar(tree);
frame.open(); frame.open();
treeframe.open(); treeframe.open();
...@@ -2120,7 +2138,7 @@ function add_favorite() ...@@ -2120,7 +2138,7 @@ function add_favorite()
? options.custom.add_favorites_msg : "\x01c\x01hAdd Favorite"); ? options.custom.add_favorites_msg : "\x01c\x01hAdd Favorite");
frame.gotoxy(1, 3); frame.gotoxy(1, 3);
frame.putmsg(options.custom.favorites_inst !== undefined frame.putmsg(options.custom.favorites_inst !== undefined
? options.custom.favorites_inst : '\x01n\x01w\x01h\x012[Up/Down/Home/End] to Navigate, [Enter] to Select, [Q] to Quit'); ? options.custom.favorites_inst : '\x01n\x01w\x01h\x012 [Up/Down/Home/End] to Navigate, [Enter] to Select, [Q] to Quit, [S] to Search ');
var xtrnwidth = 0; var xtrnwidth = 0;
var sortedItems = []; var sortedItems = [];
...@@ -2154,13 +2172,23 @@ function add_favorite() ...@@ -2154,13 +2172,23 @@ function add_favorite()
} }
treeframe.width = xtrnwidth + 2; treeframe.width = xtrnwidth + 2;
tree.colors.fg = LIGHTGRAY; // lightbar non-current item
tree.colors.bg = BG_BLACK; tree.colors.fg = options.custom.favorite_add_fg
tree.colors.lfg = WHITE; ? js.global[options.custom.favorite_add_fg] : LIGHTGRAY;
tree.colors.lbg = BG_MAGENTA; tree.colors.bg = options.custom.favorite_add_bg
tree.colors.kfg = YELLOW; ? js.global[options.custom.favorite_add_bg] : BG_BLACK;
// lightbar current item
tree.colors.lfg = options.custom.favorite_add_lfg
? js.global[options.custom.favorite_add_lfg] : WHITE;
tree.colors.lbg = options.custom.favorite_add_lbg
? js.global[options.custom.favorite_add_lbg] : BG_MAGENTA;
// tree heading
tree.colors.cfg = options.custom.favorite_add_cfg
? js.global[options.custom.favorite_add_cfg] : WHITE;
tree.colors.cbg = options.custom.favorite_add_cbg
? js.global[options.custom.favorite_add_cbg] : BG_BLACK;
// other tree color settings not applicable to this implementation
tree.open(); tree.open();
console.clear(BG_BLACK|LIGHTGRAY); console.clear(BG_BLACK|LIGHTGRAY);
...@@ -2172,37 +2200,120 @@ function add_favorite() ...@@ -2172,37 +2200,120 @@ function add_favorite()
var key; var key;
var xtrn; var xtrn;
while(bbs.online) { while(bbs.online) {
key = console.getkey(); key = console.getkey(K_NOSPIN);
if (key == "\x0d") { if (key == "\x0d") {
// hit enter, item is selected // hit enter, item is selected
break; break;
} } else if ((key.toLowerCase() == 'q') || (key == "\x1B")) {
if ((key.toLowerCase() == 'q') || (key == "\x1B")) return; return;
} else if (key.toLowerCase() == 's') {
selection = tree.getcmd({ key: key, mouse: false }); xtrn = add_favorite_search(frame, treeframe, options);
break;
if (key == KEY_UP || key == KEY_DOWN || key == KEY_HOME || key == KEY_END) {