@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
JavaScript
"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;