From 291803c31f829fe0d32bb3207bc11def95a7408c Mon Sep 17 00:00:00 2001 From: Nevena Bojovic Date: Tue, 1 Mar 2022 20:05:50 +0100 Subject: Urađena test aplikacija. Povezan front i back. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../inquirer/lib/utils/screen-manager.js | 175 +++++++++++++++++++++ 1 file changed, 175 insertions(+) create mode 100644 sandbox/testAppNevena/Front/node_modules/inquirer/lib/utils/screen-manager.js (limited to 'sandbox/testAppNevena/Front/node_modules/inquirer/lib/utils/screen-manager.js') diff --git a/sandbox/testAppNevena/Front/node_modules/inquirer/lib/utils/screen-manager.js b/sandbox/testAppNevena/Front/node_modules/inquirer/lib/utils/screen-manager.js new file mode 100644 index 00000000..12412c64 --- /dev/null +++ b/sandbox/testAppNevena/Front/node_modules/inquirer/lib/utils/screen-manager.js @@ -0,0 +1,175 @@ +'use strict'; +const _ = { + last: require('lodash/last'), + flatten: require('lodash/flatten'), +}; +const util = require('./readline'); +const cliWidth = require('cli-width'); +const stripAnsi = require('strip-ansi'); +const stringWidth = require('string-width'); +const ora = require('ora'); + +function height(content) { + return content.split('\n').length; +} + +function lastLine(content) { + return _.last(content.split('\n')); +} + +class ScreenManager { + constructor(rl) { + // These variables are keeping information to allow correct prompt re-rendering + this.height = 0; + this.extraLinesUnderPrompt = 0; + + this.rl = rl; + } + + renderWithSpinner(content, bottomContent) { + if (this.spinnerId) { + clearInterval(this.spinnerId); + } + + let spinner; + let contentFunc; + let bottomContentFunc; + + if (bottomContent) { + spinner = ora(bottomContent); + contentFunc = () => content; + bottomContentFunc = () => spinner.frame(); + } else { + spinner = ora(content); + contentFunc = () => spinner.frame(); + bottomContentFunc = () => ''; + } + + this.spinnerId = setInterval( + () => this.render(contentFunc(), bottomContentFunc(), true), + spinner.interval + ); + } + + render(content, bottomContent, spinning = false) { + if (this.spinnerId && !spinning) { + clearInterval(this.spinnerId); + } + + this.rl.output.unmute(); + this.clean(this.extraLinesUnderPrompt); + + /** + * Write message to screen and setPrompt to control backspace + */ + + const promptLine = lastLine(content); + const rawPromptLine = stripAnsi(promptLine); + + // Remove the rl.line from our prompt. We can't rely on the content of + // rl.line (mainly because of the password prompt), so just rely on it's + // length. + let prompt = rawPromptLine; + if (this.rl.line.length) { + prompt = prompt.slice(0, -this.rl.line.length); + } + + this.rl.setPrompt(prompt); + + // SetPrompt will change cursor position, now we can get correct value + const cursorPos = this.rl._getCursorPos(); + const width = this.normalizedCliWidth(); + + content = this.forceLineReturn(content, width); + if (bottomContent) { + bottomContent = this.forceLineReturn(bottomContent, width); + } + + // Manually insert an extra line if we're at the end of the line. + // This prevent the cursor from appearing at the beginning of the + // current line. + if (rawPromptLine.length % width === 0) { + content += '\n'; + } + + const fullContent = content + (bottomContent ? '\n' + bottomContent : ''); + this.rl.output.write(fullContent); + + /** + * Re-adjust the cursor at the correct position. + */ + + // We need to consider parts of the prompt under the cursor as part of the bottom + // content in order to correctly cleanup and re-render. + const promptLineUpDiff = Math.floor(rawPromptLine.length / width) - cursorPos.rows; + const bottomContentHeight = + promptLineUpDiff + (bottomContent ? height(bottomContent) : 0); + if (bottomContentHeight > 0) { + util.up(this.rl, bottomContentHeight); + } + + // Reset cursor at the beginning of the line + util.left(this.rl, stringWidth(lastLine(fullContent))); + + // Adjust cursor on the right + if (cursorPos.cols > 0) { + util.right(this.rl, cursorPos.cols); + } + + /** + * Set up state for next re-rendering + */ + this.extraLinesUnderPrompt = bottomContentHeight; + this.height = height(fullContent); + + this.rl.output.mute(); + } + + clean(extraLines) { + if (extraLines > 0) { + util.down(this.rl, extraLines); + } + + util.clearLine(this.rl, this.height); + } + + done() { + this.rl.setPrompt(''); + this.rl.output.unmute(); + this.rl.output.write('\n'); + } + + releaseCursor() { + if (this.extraLinesUnderPrompt > 0) { + util.down(this.rl, this.extraLinesUnderPrompt); + } + } + + normalizedCliWidth() { + const width = cliWidth({ + defaultWidth: 80, + output: this.rl.output, + }); + return width; + } + + breakLines(lines, width) { + // Break lines who're longer than the cli width so we can normalize the natural line + // returns behavior across terminals. + width = width || this.normalizedCliWidth(); + const regex = new RegExp('(?:(?:\\033[[0-9;]*m)*.?){1,' + width + '}', 'g'); + return lines.map((line) => { + const chunk = line.match(regex); + // Last match is always empty + chunk.pop(); + return chunk || ''; + }); + } + + forceLineReturn(content, width) { + width = width || this.normalizedCliWidth(); + return _.flatten(this.breakLines(content.split('\n'), width)).join('\n'); + } +} + +module.exports = ScreenManager; -- cgit v1.2.3