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.
Files changed (2) hide show
  1. package/lib/ui.js +53 -49
  2. 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
- return chalk.hex(ACC_COLORS[Math.abs(hash) % ACC_COLORS.length]);
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
- // 2. GLOBAL STATS (Ultra Modern Borderless Design)
161
- const bar = chalk.dim(''.repeat(Math.min(C, 90)));
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 += ' ' + bar + '\n';
165
- out += ' ' + chalk.bold.blue('⚡ ONLINE: ') + chalk.whiteBright(onlineCount + ' / ' + _workers.length).padEnd(20) +
166
- chalk.bold.gray(' UPTIME: ') + chalk.whiteBright(fmtUptime()) + '\n';
167
- out += ' ' + chalk.bold.green('💰 BALANCE: ') + chalk.whiteBright('' + formatBal(totalBal)).padEnd(20) +
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
- out += headRow + '\n';
176
- out += ' ' + chalk.dim('─'.repeat(Math.min(C - 4, 100))) + '\n';
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(getSpinner());
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(getSpinner());
191
+ activity = chalk.cyan('▶');
191
192
  } else {
192
- activity = chalk.gray(getLoader());
193
+ activity = chalk.gray('◎');
193
194
  }
194
195
 
195
- const numStr = chalk.dim('#' + (i + 1));
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 === '—' ? '—' : '⏣ ' + bVal, wCols.bal - 1);
203
- const balStr = balRaw === '—' ? chalk.dim('—') : chalk.bold.green(balRaw);
204
+ const balRaw = trunc(bVal === '—' ? '—' : bVal, wCols.bal - 1);
205
+ const balStr = balRaw === '—' ? chalk.dim('—') : chalk.greenBright(balRaw);
204
206
 
205
- // Clean Bracket numbers for stats instead of emojis
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.bold.red;
210
- if (lsCount >= 5) lsColor = chalk.bold.green;
211
- else if (lsCount >= 3) lsColor = chalk.bold.yellow;
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.bold.magenta(`[ ${w._level} ]`) : chalk.dim('[ - ]');
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 Accounts Running...\n')}`;
223
+ out += ` ${chalk.dim('No accounts configured...')}\n`;
224
224
  }
225
-
226
- out += '\n';
227
225
 
228
- // 4. LATEST EVENTS (Compact layout)
229
- out += chalk.bold.cyan(' LATEST EVENTS') + '\n';
230
- if (_events.length === 0) out += chalk.dim(' Quiet here...\n');
231
- _events.forEach(ev => {
232
- out += ` ${chalk.dim(`[${ev.ts}]`)} ${ev.icon} ${ev.msg}\n`;
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); }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dankgrinder",
3
- "version": "8.88.0",
3
+ "version": "8.90.0",
4
4
  "description": "Dank Memer automation engine — grind coins while you sleep",
5
5
  "bin": {
6
6
  "dankgrinder": "bin/dankgrinder.js"