UNPKG

@trap_stevo/filetide

Version:

Revolutionizing real-time file transfer with seamless, instant communication across any device. Deliver files instantly, regardless of platform, and experience unparalleled speed and control in managing transfers. Elevate your file-sharing capabilities wi

165 lines (164 loc) 5.72 kB
"use strict"; const chalk = require("chalk"); const readline = require("readline"); let progressBars = []; let logs = []; let logOutputStartLine = 0; const originalLog = console.log; console.log = function (...args) { logs.push(args.join(" ")); logOutputStartLine = progressBars.length * 2; logs.forEach((log, index) => { readline.cursorTo(process.stdout, 0, logOutputStartLine + index); process.stdout.clearLine(); process.stdout.write(log); }); progressBars.forEach((bar, index) => { if (!bar.completed) bar.render(index); }); }; class ConsoleProgressBar { constructor({ name = "Process", total = 100, useGradient = true, completedColor = "green", remainingColor = "gray", barLength = 40, showPercentage = true, showCount = true, completedChar = "■", remainingChar = " ", leftBorder = "|", rightBorder = "|", textColor = "white", boldText = true, smoothUpdate = false, animationSpeed = 100, customFormatter = null, titleAlignment = "center", progressAlignment = "right", completionMessage = null } = {}) { this.name = name; this.total = total; this.current = 0; this.useGradient = useGradient; this.completedColor = completedColor; this.remainingColor = remainingColor; this.barLength = barLength; this.showPercentage = showPercentage; this.showCount = showCount; this.completedChar = completedChar; this.remainingChar = remainingChar; this.leftBorder = leftBorder; this.rightBorder = rightBorder; this.textColor = textColor; this.boldText = boldText; this.smoothUpdate = smoothUpdate; this.animationSpeed = animationSpeed; this.customFormatter = customFormatter; this.titleAlignment = titleAlignment; this.progressAlignment = progressAlignment; this.completionMessage = completionMessage; this.completed = false; this.initialized = false; progressBars.push(this); logOutputStartLine = progressBars.length * 2; } validateColor(color, defaultColor = "gray") { try { return chalk.keyword(color); } catch { return chalk.keyword(defaultColor); } } formatText(text) { let formattedText = this.validateColor(this.textColor)(text); if (this.boldText) { formattedText = chalk.bold(formattedText); } return formattedText; } getGradientBar(fraction) { const completed = Math.round(fraction * this.barLength); const completedColor = this.validateColor(this.completedColor); const remainingColor = this.validateColor(this.remainingColor); const barArray = Array.from({ length: this.barLength }, (_, i) => i < completed ? completedColor(this.completedChar) : remainingColor(this.remainingChar)); return this.leftBorder + barArray.join("") + this.rightBorder; } getNormalBar(fraction) { const completed = Math.round(fraction * this.barLength); const completedColor = this.validateColor(this.completedColor); const remainingColor = this.validateColor(this.remainingColor); return this.leftBorder + completedColor(this.completedChar.repeat(completed)) + remainingColor(this.remainingChar.repeat(this.barLength - completed)) + this.rightBorder; } getCenteredText(text, length) { const padding = Math.max(0, Math.floor((length - text.length) / 2)); return " ".repeat(padding) + text + " ".repeat(padding); } alignText(text, alignment, totalLength) { if (alignment === "center") { return this.getCenteredText(text, totalLength); } else if (alignment === "right") { return text.padStart(totalLength); } return text; } renderTitle(index) { if (!this.initialized) { const titleText = this.alignText(this.name, this.titleAlignment, this.barLength); const titlePosition = index * 2; readline.cursorTo(process.stdout, 0, titlePosition); process.stdout.clearLine(); process.stdout.write(this.formatText(titleText)); this.initialized = true; } } render(index) { if (this.completed) return; const fraction = Math.min(this.current / this.total, 1); const percentage = Math.round(fraction * 100); const bar = this.useGradient ? this.getGradientBar(fraction) : this.getNormalBar(fraction); let progressText = ""; if (this.showPercentage || this.showCount) { progressText = `${this.showPercentage ? `${percentage}% ` : ""}${this.showCount ? `(${this.current} / ${this.total})` : ""}`; } if (this.customFormatter) { progressText = this.customFormatter(this.name, bar, percentage, this.current, this.total); } const barWithProgress = `${bar} ${progressText}`; const barPosition = index * 2 + 1; readline.cursorTo(process.stdout, 0, barPosition); process.stdout.clearLine(); process.stdout.write(this.formatText(barWithProgress)); } renderCompletionMessage() { const message = this.completionMessage ? this.completionMessage : `${this.name} complete!`; console.log(this.formatText(message)); } update(current) { this.current = Math.min(current, this.total); const index = progressBars.indexOf(this); this.renderTitle(index); if (this.current >= this.total) { if (!this.completed) { this.completed = true; this.renderCompletionMessage(); setTimeout(() => { progressBars.splice(index, 1); ConsoleProgressBar.updateLogPosition(); }, 500); } } else { this.render(index); } } static updateLogPosition() { logOutputStartLine = progressBars.length * 2; progressBars.forEach((bar, index) => bar.render(index)); } } module.exports = ConsoleProgressBar;