Skip to content
Snippets Groups Projects
Commit 8dbcf694 authored by echicken's avatar echicken :chicken:
Browse files

yarg

parent 1616c529
Branches
No related tags found
No related merge requests found
...@@ -36,11 +36,7 @@ main(); ...@@ -36,11 +36,7 @@ main();
/** /**
* To do: * To do:
* - Line input / console.getstr equivalent in swindows * - Line input / console.getstr equivalent in swindows
* - Help text / motd in activity window on start
* - ctrlkey shortcut for who's online (print to activity window)
* - ctrlkey shortcut for node message, telegram, pop up line input box * - ctrlkey shortcut for node message, telegram, pop up line input box
* - ctrlkey shortcut for logoff
* - scroll / scrollTo logic in swindows is suspect; scrolling down in a window with dataheight < height drops contents to bottom for example.
* - mystery bug in swindows where returning from clear screen and calling wm.draw didn't set attribute correctly in some rows/cells for an avatar in an imsg * - mystery bug in swindows where returning from clear screen and calling wm.draw didn't set attribute correctly in some rows/cells for an avatar in an imsg
* - add HOME/END handling in LightBar * - scrollback limit in swindows
*/ */
\ No newline at end of file
import type { IKeyDefs } from '@swag/ts4s'; import type { IKeyDefs } from '@swag/ts4s';
import { load } from '@swag/ts4s'; import { load } from '@swag/ts4s';
import { WindowManager, defs } from 'swindows'; import { WindowManager, defs } from 'swindows';
import { IPosition, ISize } from 'swindows/src/types'; import { IBorderText, IPosition, ISize } from 'swindows/src/types';
import ShellWindow from './ShellWindow'; import ShellWindow from './ShellWindow';
import { getPresence } from './presence';
const keydefs: IKeyDefs = load('key_defs.js'); const keydefs: IKeyDefs = load('key_defs.js');
const { user, bbs, system, time } = js.global; const { user, bbs, system, time } = js.global;
const queue = js.global.load(true, `${js.exec_dir}background.js`, `${user.number}`, `${bbs.node_num}`); const queue = js.global.load(true, `${js.exec_dir}background.js`, `${user.number}`, `${bbs.node_num}`);
const HELP =
'\r\n\x01h\x01wHelp:\r\n'
+ '\x01nUse your \x01h\x01ctab \x01n\x01wor \x01h\x01cleft\x01n\x01w/\x01h\x01cright \x01n\x01warrow keys to navigate between windows.\r\n'
+ 'Use your \x01h\x01cup\x01n\x01w,\x01h\x01c down\x01n\x01w,\x01h\x01c page up\x01n\x01w,\x01h\x01c page down\x01n\x01w,\x01h\x01c home\x01n\x01w, and \x01h\x01cend \x01n\x01wkeys to scroll.\r\n'
+ '\x01h\x01cCTRL-W\x01n\x01who\'s online \x01h\x01cCTRL-L\x01n\x01wog off \x01h\x01cCTRL-D\x01n\x01wisconnect'
export default class ActivityWindow extends ShellWindow { export default class ActivityWindow extends ShellWindow {
constructor(name: string, wm: WindowManager, position: IPosition, size: ISize) { constructor(name: string, wm: WindowManager, position: IPosition, size: ISize, footer: IBorderText) {
super(name, wm, position, size); super(name, wm, position, size, footer);
this.window.wrap = defs.WRAP.NONE; this.window.wrap = defs.WRAP.NONE;
this.window.write(HELP.split('\r\n').slice(2).join('\r\n'));
} }
getCmd(cmd: string): void { getCmd(cmd: string): void {
...@@ -21,7 +29,7 @@ export default class ActivityWindow extends ShellWindow { ...@@ -21,7 +29,7 @@ export default class ActivityWindow extends ShellWindow {
this.window.scroll(0, -1); this.window.scroll(0, -1);
break; break;
case keydefs.KEY_PAGEUP: case keydefs.KEY_PAGEUP:
this.window.scroll(0, -this.window.size.height); this.window.scroll(0, -this.window.contentWindow.size.height);
break; break;
case keydefs.KEY_HOME: case keydefs.KEY_HOME:
this.window.scrollTo({ x: 0, y: 0 }); this.window.scrollTo({ x: 0, y: 0 });
...@@ -30,10 +38,18 @@ export default class ActivityWindow extends ShellWindow { ...@@ -30,10 +38,18 @@ export default class ActivityWindow extends ShellWindow {
this.window.scroll(0, 1); this.window.scroll(0, 1);
break; break;
case keydefs.KEY_PAGEDN: case keydefs.KEY_PAGEDN:
this.window.scroll(0, this.window.size.height); this.window.scroll(0, this.window.contentWindow.size.height);
break; break;
case keydefs.KEY_END: case keydefs.KEY_END:
this.window.scrollTo({ x: 0, y: this.window.dataHeight - this.window.size.height }); this.window.scrollTo({ x: 0, y: this.window.contentWindow.dataHeight - this.window.contentWindow.size.height });
break;
case keydefs.CTRL_H: // Help
if (this.window.cursor.y > 0) this.window.write('\r\n');
this.window.write(HELP);
break;
case keydefs.CTRL_W: // Who's Online
const presence = getPresence();
if (presence !== undefined) this.window.write(presence);
break; break;
default: default:
break; break;
...@@ -46,8 +62,7 @@ export default class ActivityWindow extends ShellWindow { ...@@ -46,8 +62,7 @@ export default class ActivityWindow extends ShellWindow {
msg.push(queue.read()); msg.push(queue.read());
} }
if (msg.length < 1) return; if (msg.length < 1) return;
if (this.window.cursor.y > 0) this.window.write('\r\n'); this.window.write(`\r\n\r\n\x01n\x01m${system.timestr(time())}\x01n\x01w\r\n`);
this.window.write(`\x01h\x01w${system.timestr(time())}\x01n\x01w\r\n`);
this.window.write(msg.join('\r\n')); this.window.write(msg.join('\r\n'));
} }
......
...@@ -9,7 +9,7 @@ export default abstract class ShellWindow { ...@@ -9,7 +9,7 @@ export default abstract class ShellWindow {
window: swindows.types.IControlledWindow; window: swindows.types.IControlledWindow;
windowManager: swindows.WindowManager; windowManager: swindows.WindowManager;
constructor(name: string, windowManager: swindows.WindowManager, position: swindows.types.IPosition, size: swindows.types.ISize) { constructor(name: string, windowManager: swindows.WindowManager, position: swindows.types.IPosition, size: swindows.types.ISize, footer?: swindows.types.IBorderText) {
this.name = name; this.name = name;
this.windowManager = windowManager; this.windowManager = windowManager;
...@@ -28,6 +28,7 @@ export default abstract class ShellWindow { ...@@ -28,6 +28,7 @@ export default abstract class ShellWindow {
text: name, text: name,
attr: ((cgadefs.BG_BLACK|cgadefs.WHITE) as swindows.types.attr), attr: ((cgadefs.BG_BLACK|cgadefs.WHITE) as swindows.types.attr),
}, },
footer,
position, position,
size, size,
scrollBar: { scrollBar: {
......
...@@ -8,7 +8,7 @@ import MenuWindow from './MenuWindow'; ...@@ -8,7 +8,7 @@ import MenuWindow from './MenuWindow';
const sbbsdefs: ISbbsDefs = load('sbbsdefs.js'); const sbbsdefs: ISbbsDefs = load('sbbsdefs.js');
const keydefs: IKeyDefs = load('key_defs.js'); const keydefs: IKeyDefs = load('key_defs.js');
const cgadefs: ICgaDefs = load('cga_defs.js'); const cgadefs: ICgaDefs = load('cga_defs.js');
const { console } = js.global; const { bbs, console } = js.global;
function getWindows(windowManager: swindows.WindowManager): IShellWindow[] { function getWindows(windowManager: swindows.WindowManager): IShellWindow[] {
const windows: IShellWindow[] = [ const windows: IShellWindow[] = [
...@@ -21,6 +21,10 @@ function getWindows(windowManager: swindows.WindowManager): IShellWindow[] { ...@@ -21,6 +21,10 @@ function getWindows(windowManager: swindows.WindowManager): IShellWindow[] {
{ width: windowManager.size.width, { width: windowManager.size.width,
height: Math.ceil(windowManager.size.height / 2) height: Math.ceil(windowManager.size.height / 2)
}, },
{ text: 'Help: CTRL-H',
attr: ((cgadefs.BG_BLACK|cgadefs.WHITE) as swindows.types.attr),
alignment: swindows.defs.ALIGNMENT.RIGHT,
},
), ),
new MenuWindow( new MenuWindow(
'Main', 'Main',
...@@ -104,6 +108,7 @@ export default class UI { ...@@ -104,6 +108,7 @@ export default class UI {
if (input === '') return; if (input === '') return;
if (input === 'q') js.global.exit(0); if (input === 'q') js.global.exit(0);
switch (input) { switch (input) {
// Window navigation commands
case '\t': case '\t':
case keydefs.KEY_RIGHT: case keydefs.KEY_RIGHT:
this.focusWindow(1); this.focusWindow(1);
...@@ -111,6 +116,19 @@ export default class UI { ...@@ -111,6 +116,19 @@ export default class UI {
case keydefs.KEY_LEFT: case keydefs.KEY_LEFT:
this.focusWindow(-1); this.focusWindow(-1);
break; break;
// Global ActivityWindow commands regardless of which window has focus
case keydefs.CTRL_H: // Help
case keydefs.CTRL_W: // Who's Online
this.windows[0].getCmd(input);
break;
// Global commands not handled by any window
case keydefs.CTRL_D: // Disconnect immediately
bbs.hangup();
break;
case keydefs.CTRL_L: // Log off
bbs.logoff(true);
break;
// Pass input to the focused window
default: default:
this.windows[this.activeWindow].getCmd(input); this.windows[this.activeWindow].getCmd(input);
break; break;
......
...@@ -60,14 +60,20 @@ export function loadItems(filename: string, wm: WindowManager): ILightBarItem[] ...@@ -60,14 +60,20 @@ export function loadItems(filename: string, wm: WindowManager): ILightBarItem[]
export class FileWatcher { export class FileWatcher {
date: number; date: number;
filePath: string; filePath: string;
lastCheck: number = time();
interval: number = 1;
constructor(filePath: string) { constructor(filePath: string, interval?: number) {
if (!file_exists(filePath)) throw new Error(`FileWatcher: ${filePath} not found`); if (!file_exists(filePath)) throw new Error(`FileWatcher: ${filePath} not found`);
this.date = file_date(filePath); this.date = file_date(filePath);
this.filePath = filePath; this.filePath = filePath;
if (interval !== undefined && interval > 1) this.interval = interval;
} }
get updated(): boolean { get updated(): boolean {
const now = time();
if (now - this.lastCheck < this.interval) return false;
this.lastCheck = now;
const fd = file_date(this.filePath); const fd = file_date(this.filePath);
if (fd > this.date) { if (fd > this.date) {
this.date = fd; this.date = fd;
......
import type { INodeDefs } from '@swag/ts4s';
import { load } from '@swag/ts4s';
const nodedefs: INodeDefs = load('nodedefs.js');
const { system } = js.global;
export function getPresence(): string | undefined {
const ret: string[] = [];
for (const node of system.node_list) {
if (node.status !== nodedefs.NODE_INUSE) continue;
const conn = node.connection;
if ((conn < 65532 && conn !== 0) || conn > 65535) continue;
ret.push(`\x01h\x01w${system.username(node.useron)} \x01c${nodedefs.NodeAction[node.action]} \x01nvia \x01c${nodedefs.NodeConnectionProper[conn as keyof typeof nodedefs.NodeConnectionProper]}`);
}
if (ret.length < 1) return;
return `\r\n\r\n\x01h\x01mWho's Online:\r\n${ret.join('\r\n')}`;
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment