dankgrinder 8.83.0 → 8.84.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/ui.js +70 -42
- package/package.json +1 -1
package/lib/ui.js
CHANGED
|
@@ -31,7 +31,7 @@ function applyGradient(str) {
|
|
|
31
31
|
const SPINNER_FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
|
|
32
32
|
function getSpinner() { return SPINNER_FRAMES[Math.floor(Date.now() / 80) % SPINNER_FRAMES.length]; }
|
|
33
33
|
|
|
34
|
-
const LOAD_FRAMES = ['
|
|
34
|
+
const LOAD_FRAMES = ['⣾','⣽','⣻','⢿','⡿','⣟','⣯','⣷'];
|
|
35
35
|
function getLoader() { return LOAD_FRAMES[Math.floor(Date.now() / 150) % LOAD_FRAMES.length]; }
|
|
36
36
|
|
|
37
37
|
const ACC_COLORS = ['#ff0054', '#ffbd00', '#390099', '#9e0059', '#ff5400', '#00f5d4', '#00bbf9', '#fee440', '#f15bb5', '#9b5de5'];
|
|
@@ -107,24 +107,58 @@ function makeRow(c1, c2, c3, c4, c5, c6, wCols, logW) {
|
|
|
107
107
|
return `│ ${pad(c1, wCols.num)} │ ${pad(c2, wCols.name)} │ ${pad(c3, wCols.bal)} │ ${pad(c4, wCols.ls)} │ ${pad(c5, wCols.lv)} │ ${pad(c6, logW)} │`;
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
+
function formatBal(n) {
|
|
111
|
+
if (n === undefined || isNaN(n)) return '—';
|
|
112
|
+
if (n >= 1e9) return (n / 1e9).toFixed(2) + 'B';
|
|
113
|
+
if (n >= 1e6) return (n / 1e6).toFixed(2) + 'M';
|
|
114
|
+
if (n >= 1e3) return (n / 1e3).toFixed(1) + 'k';
|
|
115
|
+
return String(n);
|
|
116
|
+
}
|
|
117
|
+
|
|
110
118
|
function render() {
|
|
111
119
|
if (!_live) return;
|
|
112
120
|
const C = process.stdout.columns || 110;
|
|
113
|
-
|
|
114
|
-
|
|
121
|
+
|
|
122
|
+
// Clear screen to prevent duplication on resize
|
|
123
|
+
let out = '\x1b[2J\x1b[H';
|
|
124
|
+
|
|
115
125
|
// Banner
|
|
116
126
|
const titleStr = figlet.textSync('DANK GRINDER', { font: 'ANSI Shadow' });
|
|
117
127
|
out += chalk.bold(applyGradient(titleStr));
|
|
118
|
-
out += chalk.bold.magenta(`v${_version} — ${getLoader()} Running... `)
|
|
128
|
+
out += chalk.bold.magenta(` v${_version} — ${getLoader()} Running... \n`);
|
|
119
129
|
|
|
120
130
|
const wCols = { num: 4, name: 18, bal: 14, ls: 5, lv: 5 };
|
|
121
|
-
|
|
122
131
|
const overhead = 19 + wCols.num + wCols.name + wCols.bal + wCols.ls + wCols.lv;
|
|
123
132
|
const logW = Math.max(10, C - overhead);
|
|
124
133
|
const actualC = logW + overhead;
|
|
125
134
|
|
|
126
|
-
const
|
|
135
|
+
const sorted = [..._workers].sort((a, b) => {
|
|
136
|
+
if (!a.channel !== !b.channel) return a.channel ? -1 : 1;
|
|
137
|
+
const aA = a.channel && !a.paused && !a.dashboardPaused;
|
|
138
|
+
const bB = b.channel && !b.paused && !b.dashboardPaused;
|
|
139
|
+
if (aA !== bB) return aA ? -1 : 1;
|
|
140
|
+
return (b.stats.commands || 0) - (a.stats.commands || 0);
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
let totalCoins = 0, totalBal = 0, onlineCount = 0;
|
|
144
|
+
for (let i = 0; i < sorted.length; i++) {
|
|
145
|
+
const w = sorted[i];
|
|
146
|
+
totalCoins += w.stats.coins || 0;
|
|
147
|
+
totalBal += w.stats.balance || 0;
|
|
148
|
+
if (w.channel && !w.paused && !w.dashboardPaused) onlineCount++;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// High-Visibility Summary directly below the Title
|
|
152
|
+
const totC = totalCoins > 0 ? '+' + formatBal(totalCoins) : '+0';
|
|
153
|
+
const summStr = chalk.bold(' 🌟 ACT: ') + chalk.bold.magenta(_workers.length) + chalk.dim(' │ ') +
|
|
154
|
+
chalk.bold('⚡ ON: ') + chalk.bold.cyan(onlineCount) + chalk.dim(' │ ') +
|
|
155
|
+
chalk.bold('💰 BAL: ') + chalk.bold.green('⏣' + formatBal(totalBal)) + chalk.dim(' │ ') +
|
|
156
|
+
chalk.bold('📈 GAINED: ') + chalk.bold.yellow(totC) + chalk.dim(' │ ') +
|
|
157
|
+
chalk.bold('⏱ UP: ') + chalk.bold.dim(fmtUptime());
|
|
158
|
+
|
|
159
|
+
out += '\n' + summStr + '\n\n';
|
|
127
160
|
|
|
161
|
+
// Accounts Table
|
|
128
162
|
out += '╭' + '─'.repeat(wCols.num + 2) + '┬'
|
|
129
163
|
+ '─'.repeat(wCols.name + 2) + '┬'
|
|
130
164
|
+ '─'.repeat(wCols.bal + 2) + '┬'
|
|
@@ -145,26 +179,14 @@ function render() {
|
|
|
145
179
|
+ '─'.repeat(wCols.lv + 2) + '┼'
|
|
146
180
|
+ '─'.repeat(logW + 2) + '┤\n';
|
|
147
181
|
|
|
148
|
-
const sorted = [..._workers].sort((a, b) => {
|
|
149
|
-
if (!a.channel !== !b.channel) return a.channel ? -1 : 1;
|
|
150
|
-
const aA = a.channel && !a.paused && !a.dashboardPaused;
|
|
151
|
-
const bB = b.channel && !b.paused && !b.dashboardPaused;
|
|
152
|
-
if (aA !== bB) return aA ? -1 : 1;
|
|
153
|
-
return (b.stats.commands || 0) - (a.stats.commands || 0);
|
|
154
|
-
});
|
|
155
|
-
|
|
156
|
-
let totalCoins = 0, totalBal = 0, onlineCount = 0;
|
|
157
182
|
for (let i = 0; i < sorted.length; i++) {
|
|
158
183
|
const w = sorted[i];
|
|
159
|
-
totalCoins += w.stats.coins || 0;
|
|
160
|
-
totalBal += w.stats.balance || 0;
|
|
161
|
-
if (w.channel && !w.paused && !w.dashboardPaused) onlineCount++;
|
|
162
184
|
|
|
163
185
|
let logText = w.lastStatus || 'idle';
|
|
164
186
|
let activity = '';
|
|
165
187
|
if (w.globalCooldownUntil && Date.now() < w.globalCooldownUntil) {
|
|
166
188
|
const s = Math.ceil((w.globalCooldownUntil - Date.now()) / 1000);
|
|
167
|
-
logText = s > 60 ? `
|
|
189
|
+
logText = s > 60 ? `cd ${Math.ceil(s/60)}m` : `cd ${s}s`;
|
|
168
190
|
activity = chalk.yellow(getSpinner());
|
|
169
191
|
} else if (w.paused || w.dashboardPaused) {
|
|
170
192
|
logText = 'paused';
|
|
@@ -177,16 +199,29 @@ function render() {
|
|
|
177
199
|
const numStr = trunc(String(i + 1), wCols.num);
|
|
178
200
|
const dot = getDot(w);
|
|
179
201
|
|
|
180
|
-
|
|
202
|
+
// Support previous UI events format dynamically extracting name
|
|
203
|
+
const nameRaw = trunc(w.username || 'Worker ' + (i+1), wCols.name - 2);
|
|
181
204
|
const nameStr = dot.color(dot.dot) + ' ' + getAccountColor(nameRaw)(chalk.bold(nameRaw));
|
|
182
205
|
|
|
183
|
-
|
|
206
|
+
// Balance Formatter
|
|
207
|
+
const bVal = w.stats.balance !== undefined ? formatBal(w.stats.balance) : '—';
|
|
184
208
|
const balRaw = trunc(bVal === '—' ? '—' : '⏣' + bVal, wCols.bal);
|
|
185
209
|
const balStr = balRaw === '—' ? chalk.dim('—') : chalk.bold.green(balRaw);
|
|
186
210
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
211
|
+
// Heart Lifesavers
|
|
212
|
+
let lsRaw = '—';
|
|
213
|
+
let lsStr = chalk.dim('—');
|
|
214
|
+
if (w._lifesavers !== undefined) {
|
|
215
|
+
let lsCount = w._lifesavers;
|
|
216
|
+
let lsEmoji = '❤️'; // Red for 0-2
|
|
217
|
+
let lsColor = chalk.bold.red;
|
|
218
|
+
|
|
219
|
+
if (lsCount >= 5) { lsEmoji = '💚'; lsColor = chalk.bold.green; }
|
|
220
|
+
else if (lsCount >= 3) { lsEmoji = '💛'; lsColor = chalk.bold.yellow; }
|
|
221
|
+
|
|
222
|
+
lsRaw = trunc(`${lsEmoji} ${lsCount}`, wCols.ls);
|
|
223
|
+
lsStr = lsColor(lsRaw);
|
|
224
|
+
}
|
|
190
225
|
|
|
191
226
|
const lvRaw = trunc(w._level !== undefined ? String(w._level) : '—', wCols.lv);
|
|
192
227
|
const lvStr = chalk.bold.magenta(lvRaw);
|
|
@@ -197,30 +232,23 @@ function render() {
|
|
|
197
232
|
out += makeRow(numStr, nameStr, balStr, lsStr, lvStr, logStr, wCols, logW) + '\n';
|
|
198
233
|
}
|
|
199
234
|
|
|
200
|
-
|
|
235
|
+
if (sorted.length === 0) {
|
|
236
|
+
out += makeRow('—', 'No Accounts', '—', '—', '—', 'Waiting...', wCols, logW) + '\n';
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
out += '╰' + '─'.repeat(wCols.num + 2) + '┴'
|
|
201
240
|
+ '─'.repeat(wCols.name + 2) + '┴'
|
|
202
241
|
+ '─'.repeat(wCols.bal + 2) + '┴'
|
|
203
242
|
+ '─'.repeat(wCols.ls + 2) + '┴'
|
|
204
243
|
+ '─'.repeat(wCols.lv + 2) + '┴'
|
|
205
|
-
+ '─'.repeat(logW + 2) + '
|
|
244
|
+
+ '─'.repeat(logW + 2) + '╯\n\n';
|
|
206
245
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
chalk.bold('📈 GAINED: ') + chalk.bold.yellow('+' + totC) + chalk.dim(' │ ') +
|
|
212
|
-
chalk.bold('⏱ UP: ') + chalk.bold.dim(fmtUptime());
|
|
213
|
-
|
|
214
|
-
out += `│ ${pad(summLine, summaryW)} │\n`;
|
|
215
|
-
out += '├' + '─'.repeat(actualC - 2) + '┤\n';
|
|
216
|
-
out += `│ ${pad(chalk.bold.cyan('📻 LATEST EVENTS'), summaryW)} │\n`;
|
|
217
|
-
|
|
218
|
-
if (_events.length === 0) out += `│ ${pad(chalk.dim(' Quiet here...'), summaryW)} │\n`;
|
|
219
|
-
_events.forEach(ev => { out += `│ ${pad(chalk.dim(`[${ev.ts}] `) + ev.icon + ' ' + ev.msg, summaryW)} │\n`; });
|
|
220
|
-
|
|
221
|
-
out += '╰' + '─'.repeat(actualC - 2) + '╯\n';
|
|
246
|
+
// Latest events beneath the table cleanly
|
|
247
|
+
out += chalk.bold.cyan(' 📻 LATEST EVENTS') + '\n';
|
|
248
|
+
if (_events.length === 0) out += chalk.dim(' Quiet here...\n');
|
|
249
|
+
_events.forEach(ev => { out += ` ${chalk.dim(`[${ev.ts}]`)} ${ev.icon} ${ev.msg}\n`; });
|
|
222
250
|
|
|
223
|
-
|
|
251
|
+
process.stdout.write(out);
|
|
224
252
|
}
|
|
225
253
|
|
|
226
254
|
function start() {}
|