dankgrinder 8.88.0 → 8.90.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 +53 -49
- package/package.json +1 -1
package/lib/ui.js
CHANGED
|
@@ -39,7 +39,8 @@ const ACC_COLORS = ['#ff0054', '#ffbd00', '#390099', '#9e0059', '#ff5400', '#00f
|
|
|
39
39
|
function getAccountColor(str) {
|
|
40
40
|
let hash = 0;
|
|
41
41
|
for (let i = 0; i < str.length; i++) hash = str.charCodeAt(i) + ((hash << 5) - hash);
|
|
42
|
-
|
|
42
|
+
const h = Math.abs(hash) % 360;
|
|
43
|
+
return chalk.hsl(h, 90, 65); // 360 distinct hues, visually scaled for 10k unique accounts!
|
|
43
44
|
}
|
|
44
45
|
|
|
45
46
|
const STATUS_DOT = {
|
|
@@ -134,16 +135,6 @@ function render() {
|
|
|
134
135
|
|
|
135
136
|
let out = '';
|
|
136
137
|
|
|
137
|
-
// 1. BRANDING
|
|
138
|
-
const titleStr = figlet.textSync('DANK GRINDER', { font: 'ANSI Shadow' });
|
|
139
|
-
out += chalk.bold(applyGradient(titleStr));
|
|
140
|
-
out += chalk.dim(' v' + _version + ' | ') + chalk.cyan.bold(getLoader() + ' RUNNING') + '\n\n';
|
|
141
|
-
|
|
142
|
-
const wCols = { num: 4, name: 20, bal: 15, ls: 8, lv: 7 };
|
|
143
|
-
const overhead = 2 + wCols.num + 1 + wCols.name + 1 + wCols.bal + 1 + wCols.ls + 1 + wCols.lv + 1;
|
|
144
|
-
const logW = Math.max(15, C - overhead - 2);
|
|
145
|
-
const actualC = logW + overhead;
|
|
146
|
-
|
|
147
138
|
const sorted = [..._workers].sort((a, b) => {
|
|
148
139
|
if (!a.channel !== !b.channel) return a.channel ? -1 : 1;
|
|
149
140
|
return (b.stats.commands || 0) - (a.stats.commands || 0);
|
|
@@ -157,23 +148,32 @@ function render() {
|
|
|
157
148
|
if (w.channel && !w.paused && !w.dashboardPaused) onlineCount++;
|
|
158
149
|
}
|
|
159
150
|
|
|
160
|
-
//
|
|
161
|
-
const
|
|
151
|
+
// 1. BIG ASCI TITLE IS BACK (With Gradient)
|
|
152
|
+
const titleStr = figlet.textSync('DANK GRINDER', { font: 'ANSI Shadow' });
|
|
153
|
+
out += chalk.bold(applyGradient(titleStr));
|
|
154
|
+
out += ' ' + chalk.dim('v' + _version + ' │ ') + chalk.cyan('● ' + getLoader() + ' Running') + '\n\n';
|
|
155
|
+
|
|
156
|
+
// 2. MINIMALIST STATS + TREND SPARKLINE
|
|
162
157
|
const profStr = totalCoins > 0 ? '+' + formatBal(totalCoins) : '+0';
|
|
158
|
+
const graph = getSparkline();
|
|
163
159
|
|
|
164
|
-
out += ' ' +
|
|
165
|
-
out += '
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
chalk.bold.yellow('📈 PROFIT: ') + chalk.whiteBright(profStr).padEnd(16) +
|
|
169
|
-
chalk.bold.cyan('📊 TREND: ') + getSparkline() + '\n';
|
|
170
|
-
out += ' ' + bar + '\n\n';
|
|
171
|
-
|
|
172
|
-
// 3. WORKER DATAGRID (Clean rows, no chunky boxes)
|
|
173
|
-
const headRow = ` ${chalk.bold.gray(pad('ID', wCols.num))} ${chalk.bold.gray(pad('ACCOUNT', wCols.name))} ${chalk.bold.gray(pad('BALANCE', wCols.bal))} ${chalk.bold.gray(pad('LIFE', wCols.ls))} ${chalk.bold.gray(pad('LVL', wCols.lv))} ${chalk.bold.gray('ACTIVITY')}`;
|
|
160
|
+
out += ' ' + chalk.cyan('◆') + chalk.bold(' ONLINE ') + chalk.white(onlineCount + ' / ' + _workers.length) + '\n';
|
|
161
|
+
out += ' ' + chalk.blue('◆') + chalk.bold(' UPTIME ') + chalk.white(fmtUptime()) + '\n';
|
|
162
|
+
out += ' ' + chalk.green('◆') + chalk.bold(' BALANCE ') + chalk.white('⏣ ' + formatBal(totalBal)) +
|
|
163
|
+
chalk.green(' (profit: ' + profStr + ')') + chalk.dim(' │ TREND: [') + graph + chalk.dim(']') + '\n';
|
|
174
164
|
|
|
175
|
-
|
|
176
|
-
|
|
165
|
+
// Divider
|
|
166
|
+
const divWidth = Math.min(C - 4, 100);
|
|
167
|
+
out += '\n ' + chalk.dim('─'.repeat(divWidth)) + '\n\n';
|
|
168
|
+
|
|
169
|
+
// 3. TABLE DATA (Clean spacing, dimmed headers)
|
|
170
|
+
const wCols = { num: 4, name: 20, bal: 12, ls: 6, lv: 5 };
|
|
171
|
+
const overhead = 2 + wCols.num + 1 + wCols.name + 1 + wCols.bal + 1 + wCols.ls + 1 + wCols.lv + 1;
|
|
172
|
+
const logW = Math.max(15, C - overhead - 4);
|
|
173
|
+
|
|
174
|
+
const headRow = ` ${chalk.dim(pad('ID', wCols.num))} ${chalk.dim(pad('ACCOUNT', wCols.name))} ${chalk.dim(pad('BAL', wCols.bal))} ${chalk.dim(pad('LIFE', wCols.ls))} ${chalk.dim(pad('LVL', wCols.lv))} ${chalk.dim('PROCESS')}`;
|
|
175
|
+
|
|
176
|
+
out += headRow + '\n\n';
|
|
177
177
|
|
|
178
178
|
for (let i = 0; i < sorted.length; i++) {
|
|
179
179
|
const w = sorted[i];
|
|
@@ -183,60 +183,64 @@ function render() {
|
|
|
183
183
|
if (w.globalCooldownUntil && Date.now() < w.globalCooldownUntil) {
|
|
184
184
|
const s = Math.ceil((w.globalCooldownUntil - Date.now()) / 1000);
|
|
185
185
|
logText = s > 60 ? `cd ${Math.ceil(s/60)}m` : `cd ${s}s`;
|
|
186
|
-
activity = chalk.yellow(
|
|
186
|
+
activity = chalk.yellow('⏸');
|
|
187
187
|
} else if (w.paused || w.dashboardPaused) {
|
|
188
188
|
logText = 'paused';
|
|
189
|
+
activity = chalk.dim('⏸');
|
|
189
190
|
} else if (w.channel) {
|
|
190
|
-
activity = chalk.cyan(
|
|
191
|
+
activity = chalk.cyan('▶');
|
|
191
192
|
} else {
|
|
192
|
-
activity = chalk.gray(
|
|
193
|
+
activity = chalk.gray('◎');
|
|
193
194
|
}
|
|
194
195
|
|
|
195
|
-
const numStr = chalk.dim('
|
|
196
|
+
const numStr = chalk.dim('0' + (i + 1).toString().slice(-2));
|
|
196
197
|
const dot = getDot(w);
|
|
197
198
|
|
|
198
199
|
const nameRaw = trunc(w.username || 'Worker ' + (i+1), wCols.name - 3);
|
|
200
|
+
// INDIVIDUAL SMART COLORS TRIGGERED HERE
|
|
199
201
|
const nameStr = dot.color(dot.dot) + ' ' + getAccountColor(nameRaw)(chalk.bold(nameRaw));
|
|
200
202
|
|
|
201
203
|
const bVal = w.stats.balance !== undefined ? formatBal(w.stats.balance) : '—';
|
|
202
|
-
const balRaw = trunc(bVal === '—' ? '—' :
|
|
203
|
-
const balStr = balRaw === '—' ? chalk.dim('—') : chalk.
|
|
204
|
+
const balRaw = trunc(bVal === '—' ? '—' : bVal, wCols.bal - 1);
|
|
205
|
+
const balStr = balRaw === '—' ? chalk.dim('—') : chalk.greenBright(balRaw);
|
|
204
206
|
|
|
205
|
-
|
|
206
|
-
let lsStr = chalk.dim('[ - ]');
|
|
207
|
+
let lsStr = chalk.dim('-');
|
|
207
208
|
if (w._lifesavers !== undefined) {
|
|
208
209
|
let lsCount = w._lifesavers;
|
|
209
|
-
let lsColor = chalk.
|
|
210
|
-
if (lsCount >= 5) lsColor = chalk.
|
|
211
|
-
else if (lsCount >= 3) lsColor = chalk.
|
|
212
|
-
|
|
213
|
-
lsStr = lsColor(`[ ${lsCount} ]`);
|
|
210
|
+
let lsColor = chalk.red;
|
|
211
|
+
if (lsCount >= 5) lsColor = chalk.green;
|
|
212
|
+
else if (lsCount >= 3) lsColor = chalk.yellow;
|
|
213
|
+
lsStr = lsColor(lsCount);
|
|
214
214
|
}
|
|
215
215
|
|
|
216
|
-
const lvStr = w._level !== undefined ? chalk.
|
|
216
|
+
const lvStr = w._level !== undefined ? chalk.magenta(w._level) : chalk.dim('-');
|
|
217
217
|
const logStr = activity + ' ' + chalk.dim(trunc(logText, logW - 2));
|
|
218
218
|
|
|
219
219
|
out += ` ${pad(numStr, wCols.num)} ${pad(nameStr, wCols.name)} ${pad(balStr, wCols.bal)} ${pad(lsStr, wCols.ls)} ${pad(lvStr, wCols.lv)} ${logStr}\n`;
|
|
220
220
|
}
|
|
221
221
|
|
|
222
222
|
if (sorted.length === 0) {
|
|
223
|
-
out += ` ${chalk.dim('No
|
|
223
|
+
out += ` ${chalk.dim('No accounts configured...')}\n`;
|
|
224
224
|
}
|
|
225
|
-
|
|
226
|
-
out += '\n';
|
|
227
225
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
226
|
+
out += '\n ' + chalk.dim('─'.repeat(divWidth)) + '\n\n';
|
|
227
|
+
|
|
228
|
+
// 4. ACTIVITY STREAM
|
|
229
|
+
out += chalk.gray(' ACTIVITY LOG') + '\n';
|
|
230
|
+
if (_events.length === 0) {
|
|
231
|
+
out += chalk.dim(' No recent events.\n');
|
|
232
|
+
} else {
|
|
233
|
+
_events.forEach(ev => {
|
|
234
|
+
// Enhanced event log with nice contrast
|
|
235
|
+
out += ` ${chalk.dim(ev.ts)} ${ev.icon} ${chalk.white(ev.msg)}\n`;
|
|
236
|
+
});
|
|
237
|
+
}
|
|
234
238
|
|
|
235
239
|
logUpdate(out.trimEnd());
|
|
236
240
|
}
|
|
237
241
|
function start() {}
|
|
238
242
|
function draw() { render(); }
|
|
239
|
-
function setLive(val) { _live = val; if (val) render(); }
|
|
243
|
+
function setLive(val) { _live = val; if (val) { process.stdout.write('\x1b[2J\x1b[3J\x1b[H'); render(); } }
|
|
240
244
|
function setPhase(phase) {}
|
|
241
245
|
function startRefresh() { setInterval(() => { if(_live){ const tot = _workers.reduce((a,w)=>a+(w.stats.coins||0),0); _coinHistory.shift(); _coinHistory.push(tot); } }, 5000);
|
|
242
246
|
if (!_refreshTimer) _refreshTimer = setInterval(() => { if (_live) render(); }, 80); }
|