UNPKG

2.38 kBJavaScriptView Raw
1'use strict';
2/**
3 * Sticky bottom bar user interface
4 */
5
6const through = require('through');
7const Base = require('./baseUI');
8const rlUtils = require('../utils/readline');
9const _ = {
10 last: require('lodash/last'),
11};
12
13class BottomBar extends Base {
14 constructor(opt) {
15 opt = opt || {};
16
17 super(opt);
18
19 this.log = through(this.writeLog.bind(this));
20 this.bottomBar = opt.bottomBar || '';
21 this.render();
22 }
23
24 /**
25 * Render the prompt to screen
26 * @return {BottomBar} self
27 */
28
29 render() {
30 this.write(this.bottomBar);
31 return this;
32 }
33
34 clean() {
35 rlUtils.clearLine(this.rl, this.bottomBar.split('\n').length);
36 return this;
37 }
38
39 /**
40 * Update the bottom bar content and rerender
41 * @param {String} bottomBar Bottom bar content
42 * @return {BottomBar} self
43 */
44
45 updateBottomBar(bottomBar) {
46 rlUtils.clearLine(this.rl, 1);
47 this.rl.output.unmute();
48 this.clean();
49 this.bottomBar = bottomBar;
50 this.render();
51 this.rl.output.mute();
52 return this;
53 }
54
55 /**
56 * Write out log data
57 * @param {String} data - The log data to be output
58 * @return {BottomBar} self
59 */
60
61 writeLog(data) {
62 this.rl.output.unmute();
63 this.clean();
64 this.rl.output.write(this.enforceLF(data.toString()));
65 this.render();
66 this.rl.output.mute();
67 return this;
68 }
69
70 /**
71 * Make sure line end on a line feed
72 * @param {String} str Input string
73 * @return {String} The input string with a final line feed
74 */
75
76 enforceLF(str) {
77 return str.match(/[\r\n]$/) ? str : str + '\n';
78 }
79
80 /**
81 * Helper for writing message in Prompt
82 * @param {BottomBar} prompt - The Prompt object that extends tty
83 * @param {String} message - The message to be output
84 */
85 write(message) {
86 const msgLines = message.split(/\n/);
87 this.height = msgLines.length;
88
89 // Write message to screen and setPrompt to control backspace
90 this.rl.setPrompt(_.last(msgLines));
91
92 if (this.rl.output.rows === 0 && this.rl.output.columns === 0) {
93 /* When it's a tty through serial port there's no terminal info and the render will malfunction,
94 so we need enforce the cursor to locate to the leftmost position for rendering. */
95 rlUtils.left(this.rl, message.length + this.rl.line.length);
96 }
97
98 this.rl.output.write(message);
99 }
100}
101
102module.exports = BottomBar;