Skip to content
Snippets Groups Projects
Select Git revision
  • dailybuild_linux-x64
  • dailybuild_win32
  • master default protected
  • sqlite
  • rip_abstraction
  • dailybuild_macos-armv8
  • dd_file_lister_filanem_in_desc_color
  • mode7
  • dd_msg_reader_are_you_there_warning_improvement
  • c23-playing
  • syncterm-1.3
  • syncterm-1.2
  • test-build
  • hide_remote_connection_with_telgate
  • 638-can-t-control-c-during-a-file-search
  • add_body_to_pager_email
  • mingw32-build
  • cryptlib-3.4.7
  • ree/mastermind
  • new_user_dat
  • sbbs320d
  • syncterm-1.6
  • syncterm-1.5
  • syncterm-1.4
  • sbbs320b
  • syncterm-1.3
  • syncterm-1.2
  • syncterm-1.2rc6
  • syncterm-1.2rc5
  • push
  • syncterm-1.2rc4
  • syncterm-1.2rc2
  • syncterm-1.2rc1
  • sbbs319b
  • sbbs318b
  • goodbuild_linux-x64_Sep-01-2020
  • goodbuild_win32_Sep-01-2020
  • goodbuild_linux-x64_Aug-31-2020
  • goodbuild_win32_Aug-31-2020
  • goodbuild_win32_Aug-30-2020
40 results

cshell.js

Blame
  • cshell.js 14.27 KiB
    /*
    	JAVASCRIPT CHAT MENU SHELL - For Synchronet v3.15+ - Matt Johnson(2010)
    	$ID: $ 
    
    	
    	*****************************************************************************
    	*	IMPORTANT INFORMATION:
    	*	Without customizing some binary "wallpaper" this shell is very boring
    	*	If you wish to use this, I recommend creating a folder in your 
    	*	system.text_dir called "cshell" ("/sbbs/text/cshell/") and another within 
    	*	called "xtrn" ("/sbbs/text/cshell/xtrn/"). 
    	*
    	*	WALLPAPER: 
    	*		file: <menu_name>.<width>x<height>.bin
    	*	RIGHT WINDOW ICON:
    	*		file: icon.16x10.bin
    	*
    	*	NOTE: for a standard 80 x 24 terminal, menu wallpaper has a maximum
    	*	size of 34 x 22, and the main wallpaper has a maximum size of 60 x 22,
    	*	though these numbers largely depend on the size of the side menu and
    	*	right window. The max width can be determined by this formula:
    	*		WALLPAPER WIDTH = 
    	*			SCREEN COLUMNS - RIGHT WINDOW WIDTH - (SIDE MENU WIDTH + 1) - 2
    	*
    	*		DEFAULT SIDE MENU WIDTH: 25 
    	*		DEFAULT RIGHT WINDOW WIDTH: 18
    	******************************************************************************
    
    	This shell relies on having commservice.js, commclient.js, and all other related
    	"/sbbs/exec/" & "/sbbs/exec/load/" files up to date. The shell will automatically
    	be linked to inter-BBS chat if you are running commservice.js as a node
    	
    	Much of the lightbar menu code has been taken from lbshell.js, by Deuce. 
    
    */
    
    bbs.command_str='';	// clear STR (Contains the EXEC for default.js)
    load("nodedefs.js");
    load("lightbar.js");
    load("str_cmds.js");
    load("chateng.js");
    load("graphic.js");
    load("funclib.js");
    load("clock.js");
    load("cshell_menu.js");
    load("cshell_obj.js");
    
    const root=js.exec_dir;
    var settings_file=new File(
    	system.data_dir + 	"user/" + printPadded(user.number,4,"0","right") + ".shell.ini"
    );
    
    var screen_rows=console.screen_rows;
    var screen_columns=console.screen_columns;
    var full_redraw=false;
    var orig_passthru=console.ctrlkey_passthru;
    
    var cmdlist=new CommandList();
    var settings=new Settings();
    var favorites=new Favorites();
    var bottom=new BottomLine();
    var right=new RightWindow();
    var center=new MainWindow();
    var left=new LeftWindow();
    
    /* SHELL FUNCTIONS */
    function init()
    {
    	loadSettings();
    	bottom.init();
    	right.init();
    	center.init();
    	left.init();
    	
     	if(favorites.items.length > 0) {
    		loadMenu("favorites");
    		showLeftWindow();
    	}
    	redraw();
    	if(left.menu && left.menu.node_action) bbs.node_action=left.menu.node_action;
    	else bbs.node_action=NODE_MAIN;
    }
    function shell()
    {
    	while(!js.terminated) {
    		cycle();
    		var cmd="";
    		if(left.menu) {
    			cmd=left.menu.getval();
    			/* LEFT MENU COMMAND PROCESSING */
    			switch(cmd)
    			{
    			case ctrl('R'): /* CTRL-R (Quick Redraw in SyncEdit) */
    			case ctrl('O'): /* CTRL-O - Pause */
    			case ctrl('U'): /* CTRL-U User List */
    			case ctrl('T'): /* CTRL-T Time Info */
    			case ctrl('K'): /* CTRL-K Control Key Menu */
    			case ctrl('P'): /* Ctrl-P Messages */
    			case ctrl('C'): /* Ctrl-P ABORT */
    				handleCtrlKey(cmd);
    				continue;
    			case KEY_UP:
    				lightBarUp(left.menu);
    				break;
    			case KEY_DOWN:
    				lightBarDown(left.menu);
    				break;
    			case KEY_HOME:
    				lightBarHome(left.menu);
    				break;
    			case KEY_END:
    				lightBarEnd(left.menu);
    				break;
    			case KEY_LEFT:
    				previousMenu();
    				break;
    			case KEY_RIGHT:
    			case "Q":
    			case "\x1b":
    				hideLeftWindow();
    				center.restore();
    				bottom.restore();
    				continue;
    			case "+":
    				if(left.currentmenu == "favorites" || 
    					left.currentmenu == "addfavorite" ||
    					left.currentmenu == "removefavorite") {
    					break;
    				}
    				favorites.mi=left.currentmenu;
    				favorites.mt=left.menu.title;
    				favorites.ii=left.menu.current;
    				favorites.it=left.menu.items[favorites.ii].text.substr(3);
    				loadMenu("addfavorite");
    				break;
    			default:
    				if(left.menu.items[cmd]) {
    					var item_id=left.menu.items[cmd].id;
    					left.process(item_id);
    				}
    				break;
    			}
    		}
    		
    		if(!cmd) cmd=console.inkey(K_NOCRLF|K_NOSPIN|K_NOECHO|K_UPPER,5);
    		if(!cmd) continue;
    		
    		/* MAIN MENU PROCESS */
    		switch(cmd)
    		{
    		case ctrl('R'): /* CTRL-R (Quick Redraw in SyncEdit) */
    		case ctrl('O'): /* CTRL-O - Pause */
    		case ctrl('U'): /* CTRL-U User List */
    		case ctrl('T'): /* CTRL-T Time Info */
    		case ctrl('K'): /* CTRL-K Control Key Menu */
    		case ctrl('P'): /* Ctrl-P Messages */
    		case ctrl('C'): /* Ctrl-P ABORT */
    			handleCtrlKey(cmd);
    			continue;
    		case " ":
    			redraw();
    			break;
    		case "-":
    			if(!favorites.items.length > 0) {
    				break;
    			}
    			loadMenu("delfavorite");
    			break;
    		case "\x1b":
    		case "Q":
    			center.quitChat();
    			return false;
    		default:
    			var sc=bottom.menu.items[cmd];
    			if(sc && sc.enabled) {
    				cmdlist[sc.command].apply(cmdlist[sc.command],sc.parameters);
    			}
    			break;
    		}
    		
    		if(!left.menu) continue;
    		if(!left.menu_shown) showLeftWindow();
    		if(!left.title_shown) left.drawTitle();
    		
    		if(menuinfo[left.currentmenu]) {
    			menuinfo[left.currentmenu]();
    		}
    	}
    }
    function cycle()
    {
    	/* Update node action */
    	if(bbs.node_action != system.node_list[bbs.node_num-1].action)
    		system.node_list[bbs.node_num-1].action = bbs.node_action;
    
    	/* Check for messages */
    	if(system.node_list[bbs.node_num-1].misc & NODE_MSGW) {
    		if(!center.in_chat) right.addNotice();
    		center.notice(system.get_telegram(user.number));
    	}
    	if(system.node_list[bbs.node_num-1].misc & NODE_NMSG) {
    		if(!center.in_chat) right.addNotice();
    		center.notice(system.get_node_message(bbs.node_num));
    	}	
    
    	/* Fix up node status */
    	if(system.node_list[bbs.node_num-1].status==NODE_WFC) {
    		system.node_list[bbs.node_num-1].status=NODE_INUSE;
    	}
    
    	/* Check if user data has changed */
    	if((system.node_list[bbs.node_num-1].misc & NODE_UDAT) && user.compare_ars("REST NOT G")) {
    		user.cached=false;
    		system.node_list[bbs.node_num-1].misc &= ~NODE_UDAT;
    	}
    
    	/* Interrupted? */
    	if(system.node_list[bbs.node_num-1].misc & NODE_INTR) {
    		bbs.hangup();
    	}
    
    	/* Sysop Chat? */
    	if(system.node_list[bbs.node_num-1].misc & NODE_LCHAT) {
    		// TODO: No way of calling bbs.priave_chat(true)
    		// bbs.private_chat();
    		bbs.nodesync();
    		full_redraw=true;
    	}
    
    	right.cycle();
    	center.cycle();
    	left.cycle();
    	
    	if(full_redraw) {
    		redraw();
    	}
    }
    
    /* GLOBAL FUNCTIONS */
    function handleCtrlKey(key)
    {
    	switch(key) {
    		case ctrl('C'): /* Ctrl-P ABORT */
    			console.aborted=false;
    			break;
    	}
    }
    function getHotkey(item)
    {
    	var index=item.indexOf("|")+1;
    	return item[index].toUpperCase();
    }	
    function redraw()
    {
    	console.clear(ANSI_NORMAL);
    	drawTopline();
    	drawOutline();
    	
    	center.redraw();
    	right.redraw();
    	left.redraw();
    	bottom.redraw();
    	
    	if(menuinfo[left.currentmenu]) {
    		menuinfo[left.currentmenu]();
    	}
    	
    	bbs.sys_status|=SS_PAUSEOFF;	
    	console.ctrlkey_passthru="+KOPTUC";
    	full_redraw=false;
    }
    function loadWallPaper(file)
    {
    	if(!file_exists(file)) return false;
    	
    	var width=0;
    	var height=0;
    	var size=file_getname(file).split(".")[1].split("x");
    	if(size[0]) width=Number(size[0]);
    	if(size[1]) height=Number(size[1]);
    	
    	var wp=new Graphic(width,height);
    	wp.load(file);
    	return wp;
    }
    function drawTitle(x,y,str)
    {
    	console.attributes=BG_LIGHTGRAY + BLACK;
    	var top=printPadded("",str.length,"\xDF");
    	var middle=str;
    	var bottom=printPadded("",str.length,"\xDC");
    	console.gotoxy(x,y);
    	console.pushxy();
    	console.putmsg(top,P_SAVEATR);
    	console.popxy();
    	console.down();
    	console.pushxy();
    	console.putmsg(middle,P_SAVEATR);
    	console.popxy();
    	console.down();
    	console.putmsg(bottom,P_SAVEATR);
    }
    function drawSeparator(x,y)
    {
    	console.gotoxy(x,y);
    	console.pushxy();
    	console.attributes=BG_BLACK + (settings.shell_bg>>4);
    	for(var i=0;i<settings.main_height;i++) {
    		console.putmsg("\xB3",P_SAVEATR);
    		console.popxy();
    		console.down();
    		console.pushxy();
    	}
    }
    function drawTopline()
    {
    	var sysname=" \1k" + system.name + " : \1b" + system.location;
    	var sysop="\1kSysOp : \1b" + system.operator + " ";
    	var title=splitPadded(sysname,sysop,console.screen_columns," ");
    
    	console.home();
    	console.attributes=settings.shell_bg;
    	console.putmsg(title,P_SAVEATR);
    }
    function drawOutline()
    {
    	console.attributes=BG_BLACK + (settings.shell_bg>>4);
    	var outline=splitPadded("\xDD","\xDE",console.screen_columns," ");
    	for(var l=2;l<console.screen_rows;l++) {
    		console.gotoxy(1,l);
    		console.putmsg(outline,P_SAVEATR);
    	}
    }
    function displayInfo(text)
    {
    	console.putmsg(text);
    	console.popxy();
    	console.down();
    	console.pushxy();
    }
    function setPosition(x,y)
    {
    	console.gotoxy(x,y);
    	console.pushxy();
    }
    function logoff()
    {
    	center.quitChat();
    	if(bbs.batch_dnload_total) {
    		if(console.yesno(bbs.text(Menu_downloadBatchQ))) {
    			bbs.batch_download();
    			bbs.logoff();
    		}
    	} else bbs.hangup();
    }
    function chatInput()
    {
    	showChat();
    	while(center.in_chat) {
    		cycle();
    		var key=console.inkey(K_NOCRLF|K_NOSPIN|K_NOECHO,5);
    		if(!key) continue;
    		
    		switch(key) {
    		case '\r':
    			if(!center.chat.input_line.buffer.length) {
    				center.in_chat=false;
    			}
    			break;
    		case '\x09':	/* CTRL-I TAB */
    			center.toggleChannel();
    			continue;
    		case '\x1b':
    			center.in_chat=false;
    			break;
    		default:
    			break;
    		}
    		center.chat.processKey(key);
    	}
    	hideChat();
    }
    
    /* MAIN MENU */
    function hideChat()
    {
    	if(left.menu && left.menu.node_action) bbs.node_action=left.menu.node_action;
    	else bbs.node_action=NODE_MAIN;
    	center.chat.chatroom.active=false;
    	center.redraw();
    	bottom.restore();
    }
    function showChat()
    {
    	center.in_chat=true;
    	right.chat_msgs=0;
    	right.notices=0;
    	right.update=true;
    	bbs.node_action=NODE_CHAT;
    	center.chat.chatroom.active=true;
    	center.redraw();
    	console.gotoxy(1,center.chat.input_line.y);
    	console.cleartoeol(settings.shell_bg);
    	console.right();
    	console.attributes=BG_LIGHTGRAY;
    	console.putmsg("\1k\xDDCHAT:",P_SAVEATR);
    	console.attributes=settings.shell_bg;
    	console.putmsg("\1k\xDD",P_SAVEATR);
    	center.chat.input_line.clear();
    }
     
    /* MAIN WINDOW */
    function stretchCenter(height)
    {
    	var rows=this.rows;
    	rows+=height;
    	center.chat.resize(undefined,rows,undefined,undefined);
    }
    function expandCenter(width,side)
    {
    	var cols=center.chat.chatroom.columns;
    	var x=center.chat.chatroom.x;
    	if(side=="left"){
    		x-=width;
    		cols+=width;
    	}
    	if(side=="right"){
    		cols+=width;
    	}
    	center.chat.resize(cols,undefined,x,undefined);
    }
    
    /* LEFT MENU */
    function hideLeftWindow()
    {
    	expandCenter(settings.menu_width+1,"left");
    	delete left.menu;
    	left.currentmenu="";
    	left.menu_shown=false;
    	left.title_shown=false;
    	left.previous=[];
    }
    function showLeftWindow()
    {
    	expandCenter(-(settings.menu_width+1),"left");
    	drawSeparator(settings.menu_width+2,2,settings.main_height);
    	left.menu_shown=true;
    }
    function lightBarUp(m)
    {
    	do {
    		if(m.current==0)
    			m.current=m.items.length;
    		m.current--;
    	} while(m.items[m.current].disabled || m.items[m.current].retval==undefined);
    }
    function lightBarHome(m)
    {
    	m.current=0;
    	while(m.items[m.current].disabled || m.items[m.current].retval==undefined) {
    		m.current++;
    		if(m.current==m.items.length)
    			m.current=0;
    	}
    }
    function lighBarEnd(m)
    {
    	left.menu.current=left.menu.items.length-1;
    	while(left.menu.items[left.menu.current].disabled || left.menu.items[left.menu.current].retval==undefined) {
    		if(m.current==0)
    			m.current=m.items.length;
    		m.current--;
    	}
    }
    function lightBarDown(m)
    {
    	do {
    		m.current++;
    		if(m.current==m.items.length)
    			m.current=0;
    	} while(m.items[m.current].disabled || m.items[m.current].retval==undefined);
    }
    function previousMenu()
    {
    	left.previousMenu();
    }
    function addcmd(text,id,disabled)
    {
    	this.add(text,undefined,settings.menu_width,undefined,undefined,disabled);
    	this.items[this.items.length-1].id=id;
    }
    function fill_menu(lb)
    {
    	if(left.previous.length) offset=5;
    	else offset=4;
    	
    	while(lb.items.length<settings.main_height-offset)
    	{
    		lb.add("","",settings.menu_width,undefined,undefined,true);
    	}
    	
    	if(left.previous.length) lb.add(format_opt("Previous Menu",settings.menu_width,-1),KEY_LEFT,settings.menu_width);
    	lb.add(format_opt("Main Menu",settings.menu_width,0),KEY_RIGHT,settings.menu_width);
    }
    function set_hotkeys(lb)
    {
    	/* USE FIRST AVAILABLE HOTKEY AS TRIGGER */
    	/* RETURN VALUE = ITEM INDEX FOR MENU COMMAND REFERENCE */
    	var hotkeys="1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    	var index=0;
    	for(var i=0;i<lb.items.length;i++) {
    		if(lb.items[i].disabled) continue;
    		
    		while(bottom.menu.items[hotkeys[index]]) index++;
    		lb.items[i].text="|" + hotkeys[index++] + " " + lb.items[i].text;
    		lb.items[i].retval=i;
    	}
    }
    function loadMenu()
    {
    	return left.loadMenu.apply(left,arguments);
    }
    
    /* MENU FUNCTIONS */
    function format_opt(str, width, expand)
    {
    	var spaces80="                                                                               ";
    	if(expand == -1) {
    		opt='|< ';
    		var cleaned=str;
    		cleaned=cleaned.replace(/\|/g,'');
    		opt+=str+spaces80.substr(0,width-cleaned.length-2);
    		return opt;
    	} else if(expand == 0) {
    		opt=str;
    		var cleaned=opt;
    		cleaned=cleaned.replace(/\|/g,'');
    		opt+=spaces80.substr(0,width-cleaned.length-2);
    		opt+=' |>';
    		return opt;
    	} else if(expand == 1) {
    		opt=str;
    		var cleaned=opt;
    		cleaned=cleaned.replace(/\|/g,'');
    		opt+=spaces80.substr(0,width-cleaned.length-2);
    		opt+=' |+';
    		return opt;
    	}
    	return(str);
    }
    function todo_getfiles(lib, dir)
    {
    	var path=format("%s%s.ixb", file_area.lib_list[lib].dir_list[dir].data_dir, file_area.lib_list[lib].dir_list[dir].code);
    	return(file_size(path)/22);	/* F_IXBSIZE */
    }
    function clear_screen()
    {
    	/*
    	 * Called whenever a command needs to exit the menu for user interaction.
    	 *
    	 * If you'd like a header before non-menu stuff, this is the place to put
    	 * it.
    	 */
    
    	bbs.sys_status&=~SS_PAUSEOFF;
    	console.clear(ANSI_NORMAL);
    	full_redraw=true;
    	
    	/* We are going to a line-mode thing... re-enable CTRL keys. */
    }
    
    /* USER SETTINGS */
    function saveSettings() 
    {
    	settings_file.open('w+',false);
    	if(!settings_file.is_open) {
    		log("error opening user settings",LOG_WARNING);
    		return;
    	}
    	settings_file.iniSetObject("settings",settings);
    	for(var f=0;f<favorites.items.length;f++) {
    		var fav=favorites.items[f];
    		var value=
    			fav.menuID + "," + 
    			fav.menuTitle + "," + 
    			fav.itemID + "," + 
    			fav.itemTitle + "," + 
    			fav.xtrnsec;
    		settings_file.iniSetValue("favorites",f,value);
    	}
    	settings_file.close();
    }
    function loadSettings()
    {
    	if(file_exists(settings_file.name)) {
    		settings_file.open('r',true);
    		if(!settings_file.is_open) {
    			log("error opening user settings",LOG_WARNING);
    			return;
    		}
    		var set=settings_file.iniGetObject("settings");
    		var fav=settings_file.iniGetObject("favorites");
    		settings=new Settings(set);
    		favorites=new Favorites(fav);
    		settings_file.close();
    	}
    }
    
    init();
    shell();