--- tags : client-archief --- # UI Research ## Readline All necessary operations can be performed with the readline package : ```typescript import * as rl from 'readline'; import type { KeypressEvent } from './interfaces-client.js'; ``` - Prompting a question for input of message or command, also remembering what is already in the inputprompt and prepending it the next time the screen loads : ```typescript= // Create question const i = rl.createInterface(process.stdin, process.stdout); i.question('message or cmd: ', (str) => { console.log(str); }); // Prepend the previously rememered data 'joww' process.stdin.emit('data', 'joww'); // use i.line to find out what has already been written to the question process.stdin.on('keypress', (str: string, keyEvent: KeypressEvent) => { if (keyEvent.ctrl && keyEvent.name === 'a') { process.stdout.write('\nline : ' + i.line); } if (keyEvent.ctrl && keyEvent.name === 'd') { // Clear screen enal rl.moveCursor(process.stdout, -100, -10); console.clear(); } }); ``` - Note that we could just use the 'sequence' attribute of the keyEvent to create the input string. But the problem is that special keycodes may end up in the string which we do not want (not recorded by using i.question) - Writing an error above the Quesion prompt without having to rewrite the whole screen : ```typescript= rl.moveCursor(process.stdout, -100, -1); rl.clearLine(process.stdout, 0); process.stdout.write('errorrrr'); ``` - Requesting the number of columns and rows of the console, this can be used to know how many messages (and how many lines of them) will fit on the screen : ```typescript= const nRows = process.stdout.rows; const nColumns = process.stdout.columns; process.stdout.on('resize', () => { console.log(process.stdout.columns, ' x ', process.stdout.rows); nRows = process.stdout.rows; nColumns = process.stdout.columns; }); ``` ## Blessed package The blessed package can create beautiful graphical interfaces and might help with speed while refreshing the screen (for example when a new message gets added). It is also more visually pleasing, although that is not something we should currently focuss on too much. GitHub : https://www.npmjs.com/package/blessed Intall with : ```bash npm install blessed npm i --save-dev @types/blessed ``` Example code : ```typescript= import blessed from 'blessed'; // Create a screen object. const screen2 = blessed.screen({ smartCSR: true, }); screen2.title = 'my window title'; // Create a box perfectly centered horizontally and vertically. const box2 = blessed.box({ top: 'center', left: 'center', width: '50%', height: '50%', content: 'Hello {bold}world{/bold}!', tags: true, border: { type: 'line', }, style: { fg: 'white', bg: 'magenta', border: { fg: '#f0f0f0', }, hover: { bg: 'green', }, }, }); // Append our box to the screen. screen2.append(box2); // Add a png icon to the box // If our box is clicked, change the content. box2.on('click', function (data) { box2.setContent('{center}Some different {red-fg}content{/red-fg}.{/center}'); screen2.render(); }); // If box is focused, handle `enter`/`return` and give us some more content. box2.key('enter', function (ch, key) { box2.setContent('{right}Even different {black-fg}content{/black-fg}.{/right}\n'); box2.setLine(1, 'bar'); box2.insertLine(1, 'foo'); screen2.render(); }); // Quit on Escape, q, or Control-C. screen2.key(['escape', 'q', 'C-c'], function (ch, key) { return process.exit(0); }); // Focus our element. box2.focus(); // Render the screen. screen2.render(); ``` ## Terminal-kit Terminal-kit is another package that can be used to create graphical interfaces. But it does not quite extend the functionality of readline and certainly does not come close to the functtionality of blessed.