This repository has been archived on 2022-12-29. You can view files and clone it, but cannot push or open issues or pull requests.
zeropod/src/menu/console.ts

83 lines
2.4 KiB
TypeScript

import { MenuConfig, MenuPrinter, MenuType } from './interface';
import * as readline from 'readline';
type Key = {name: string, ctrl: boolean};
export class ConsolePrinter implements MenuPrinter {
private _path: number[] = [];
private _selectedIndex: number = 0;
private _config: MenuConfig[];
private _curMenu: MenuConfig[];
constructor(config: MenuConfig[]) {
this._config = config;
this._curMenu = config;
readline.emitKeypressEvents(process.stdin);
process.stdin.setRawMode(true);
}
private async keypress(): Promise<Key> {
return new Promise((resolve) => {
const listener = (_letter: string, key: Key): void => {
process.stdin.removeListener('keypress', listener);
resolve(key);
}
process.stdin.on('keypress', listener);
});
}
private printMenu(): void {
console.clear();
for (let i = 0; i < this._curMenu.length; i++) {
const line = (i === this._selectedIndex
? "> "
: " ") + this._curMenu[i].display;
console.log(line);
}
}
public async getSelection(): Promise<MenuConfig> {
return new Promise(async (resolve) => {
while (true) {
// print menu
this.printMenu();
// get user input
const key = await this.keypress();
if (key.ctrl && key.name === 'c') {
process.exit();
} else if (key.name === 'up') {
this._selectedIndex--;
if (this._selectedIndex < 0) {
this._selectedIndex = 0;
}
} else if (key.name ==='down') {
this._selectedIndex++
if (this._selectedIndex > this._curMenu.length - 1) {
this._selectedIndex = this._curMenu.length - 1;
}
} else if (key.name === 'left') {
if (this._path.length > 0) {
this._path.pop();
this._selectedIndex = 0;
}
} else if (key.name === 'right' || key.name === 'return') {
this._path.push(this._selectedIndex);
}
this._curMenu = this._config;
for (let i = 0; i < this._path.length; i++) {
if (this._curMenu[this._path[i]].type === MenuType.SubMenu) {
this._curMenu = this._curMenu[this._path[i]].subMenu!;
this._selectedIndex = 0;
} else {
resolve(this._curMenu[this._path[i]]);
this._path.pop();
return;
}
}
}
});
}
}