dankgrinder 8.85.0 → 8.87.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 +39 -23
- package/package.json +1 -1
package/lib/ui.js
CHANGED
|
@@ -7,6 +7,7 @@ let _version = '0.0.0';
|
|
|
7
7
|
let _live = false;
|
|
8
8
|
let _startTime = Date.now();
|
|
9
9
|
let _events = [];
|
|
10
|
+
let _coinHistory = new Array(10).fill(0);
|
|
10
11
|
const MAX_EVENTS = 5;
|
|
11
12
|
let _refreshTimer = null;
|
|
12
13
|
|
|
@@ -49,6 +50,18 @@ const STATUS_DOT = {
|
|
|
49
50
|
connect: { dot: '◯', color: chalk.hex('#ffb450') }
|
|
50
51
|
};
|
|
51
52
|
|
|
53
|
+
|
|
54
|
+
function getSparkline() {
|
|
55
|
+
const min = Math.min(..._coinHistory);
|
|
56
|
+
const max = Math.max(..._coinHistory);
|
|
57
|
+
if (min === max) return chalk.dim('⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤');
|
|
58
|
+
const sparks = [' ', '▂', '▃', '▄', '▅', '▆', '▇', '█'];
|
|
59
|
+
return _coinHistory.map(v => {
|
|
60
|
+
const idx = Math.floor(((v - min) / (max - min)) * 7);
|
|
61
|
+
return chalk.green(sparks[idx]);
|
|
62
|
+
}).join('');
|
|
63
|
+
}
|
|
64
|
+
|
|
52
65
|
function init({ workers }) { _workers = workers; _startTime = Date.now(); _events = []; _live = false; }
|
|
53
66
|
|
|
54
67
|
function drawBanner(version) {
|
|
@@ -119,24 +132,20 @@ function render() {
|
|
|
119
132
|
if (!_live) return;
|
|
120
133
|
const C = process.stdout.columns || 110;
|
|
121
134
|
|
|
122
|
-
|
|
123
|
-
let out = '\x1b[2J\x1b[H';
|
|
135
|
+
let out = '';
|
|
124
136
|
|
|
125
137
|
// Banner
|
|
126
138
|
const titleStr = figlet.textSync('DANK GRINDER', { font: 'ANSI Shadow' });
|
|
127
139
|
out += chalk.bold(applyGradient(titleStr));
|
|
128
|
-
out += chalk.bold.magenta(` v${_version} — ${getLoader()} Running... \n`);
|
|
140
|
+
out += chalk.bold.magenta(` v${_version} — ${getLoader()} Running... \n\n`);
|
|
129
141
|
|
|
130
|
-
const wCols = { num: 4, name: 18, bal: 14, ls:
|
|
142
|
+
const wCols = { num: 4, name: 18, bal: 14, ls: 6, lv: 5 };
|
|
131
143
|
const overhead = 19 + wCols.num + wCols.name + wCols.bal + wCols.ls + wCols.lv;
|
|
132
144
|
const logW = Math.max(10, C - overhead);
|
|
133
145
|
const actualC = logW + overhead;
|
|
134
146
|
|
|
135
147
|
const sorted = [..._workers].sort((a, b) => {
|
|
136
148
|
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
149
|
return (b.stats.commands || 0) - (a.stats.commands || 0);
|
|
141
150
|
});
|
|
142
151
|
|
|
@@ -148,15 +157,23 @@ function render() {
|
|
|
148
157
|
if (w.channel && !w.paused && !w.dashboardPaused) onlineCount++;
|
|
149
158
|
}
|
|
150
159
|
|
|
151
|
-
//
|
|
160
|
+
// BIG STATS DASHBOARD
|
|
152
161
|
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
162
|
|
|
159
|
-
out += '
|
|
163
|
+
out += chalk.cyan('╭' + '─'.repeat(actualC - 2) + '╮\n');
|
|
164
|
+
out += chalk.cyan('│') + ' ' + chalk.bold('ACCOUNTS: ') + String(_workers.length).padEnd(5) +
|
|
165
|
+
chalk.bold('ONLINE: ') + String(onlineCount).padEnd(5) +
|
|
166
|
+
chalk.bold('UPTIME: ') + fmtUptime().padEnd(10) + ' '.repeat(Math.max(0, actualC - 48)) + chalk.cyan('│\n');
|
|
167
|
+
|
|
168
|
+
const balStr = '⏣ ' + formatBal(totalBal);
|
|
169
|
+
const balPadding = Math.max(0, 16 - balStr.length);
|
|
170
|
+
const profStr = totC;
|
|
171
|
+
const graph = getSparkline();
|
|
172
|
+
|
|
173
|
+
out += chalk.cyan('│') + ' ' + chalk.bold.green('BALANCE: ') + chalk.bold.greenBright(balStr) + ' '.repeat(balPadding) +
|
|
174
|
+
chalk.bold.yellow('PROFIT: ') + chalk.bold.yellowBright(profStr).padEnd(12) +
|
|
175
|
+
chalk.dim('TREND: [') + graph + chalk.dim(']') + ' '.repeat(Math.max(0, actualC - 70)) + chalk.cyan('│\n');
|
|
176
|
+
out += chalk.cyan('╰' + '─'.repeat(actualC - 2) + '╯\n');
|
|
160
177
|
|
|
161
178
|
// Accounts Table
|
|
162
179
|
out += '╭' + '─'.repeat(wCols.num + 2) + '┬'
|
|
@@ -199,25 +216,23 @@ function render() {
|
|
|
199
216
|
const numStr = trunc(String(i + 1), wCols.num);
|
|
200
217
|
const dot = getDot(w);
|
|
201
218
|
|
|
202
|
-
// Support previous UI events format dynamically extracting name
|
|
203
219
|
const nameRaw = trunc(w.username || 'Worker ' + (i+1), wCols.name - 2);
|
|
204
220
|
const nameStr = dot.color(dot.dot) + ' ' + getAccountColor(nameRaw)(chalk.bold(nameRaw));
|
|
205
221
|
|
|
206
|
-
// Balance Formatter
|
|
207
222
|
const bVal = w.stats.balance !== undefined ? formatBal(w.stats.balance) : '—';
|
|
208
223
|
const balRaw = trunc(bVal === '—' ? '—' : '⏣' + bVal, wCols.bal);
|
|
209
224
|
const balStr = balRaw === '—' ? chalk.dim('—') : chalk.bold.green(balRaw);
|
|
210
225
|
|
|
211
|
-
//
|
|
226
|
+
// Exact unicode block character, NOT an emoji
|
|
212
227
|
let lsRaw = '—';
|
|
213
228
|
let lsStr = chalk.dim('—');
|
|
214
229
|
if (w._lifesavers !== undefined) {
|
|
215
230
|
let lsCount = w._lifesavers;
|
|
216
|
-
let lsEmoji = '
|
|
231
|
+
let lsEmoji = '█'; // Solid code block character!
|
|
217
232
|
let lsColor = chalk.bold.red;
|
|
218
233
|
|
|
219
|
-
if (lsCount >= 5) {
|
|
220
|
-
else if (lsCount >= 3) {
|
|
234
|
+
if (lsCount >= 5) { lsColor = chalk.bold.green; }
|
|
235
|
+
else if (lsCount >= 3) { lsColor = chalk.bold.yellow; }
|
|
221
236
|
|
|
222
237
|
lsRaw = trunc(`${lsEmoji} ${lsCount}`, wCols.ls);
|
|
223
238
|
lsStr = lsColor(lsRaw);
|
|
@@ -243,19 +258,20 @@ function render() {
|
|
|
243
258
|
+ '─'.repeat(wCols.lv + 2) + '┴'
|
|
244
259
|
+ '─'.repeat(logW + 2) + '╯\n\n';
|
|
245
260
|
|
|
246
|
-
// Latest events beneath the table cleanly
|
|
247
261
|
out += chalk.bold.cyan(' 📻 LATEST EVENTS') + '\n';
|
|
248
262
|
if (_events.length === 0) out += chalk.dim(' Quiet here...\n');
|
|
249
263
|
_events.forEach(ev => { out += ` ${chalk.dim(`[${ev.ts}]`)} ${ev.icon} ${ev.msg}\n`; });
|
|
250
264
|
|
|
251
|
-
|
|
265
|
+
// Fixing the blank space spam by ensuring exactly no trailing newlines and NO raw buffer resets
|
|
266
|
+
logUpdate(out.trimEnd());
|
|
252
267
|
}
|
|
253
268
|
|
|
254
269
|
function start() {}
|
|
255
270
|
function draw() { render(); }
|
|
256
271
|
function setLive(val) { _live = val; if (val) render(); }
|
|
257
272
|
function setPhase(phase) {}
|
|
258
|
-
function startRefresh() { if
|
|
273
|
+
function startRefresh() { setInterval(() => { if(_live){ const tot = _workers.reduce((a,w)=>a+(w.stats.coins||0),0); _coinHistory.shift(); _coinHistory.push(tot); } }, 5000);
|
|
274
|
+
if (!_refreshTimer) _refreshTimer = setInterval(() => { if (_live) render(); }, 80); }
|
|
259
275
|
function stopRefresh() { if (_refreshTimer) { clearInterval(_refreshTimer); _refreshTimer = null; } }
|
|
260
276
|
function stop() { _live = false; stopRefresh(); logUpdate.clear(); }
|
|
261
277
|
|