token-larper 1.8.1 → 1.9.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/package.json
CHANGED
package/src/client/App.tsx
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
2
|
-
import { AlertTriangle,
|
|
2
|
+
import { AlertTriangle, Moon, Power, RefreshCw, Search, Settings, Sun } from "lucide-react";
|
|
3
3
|
import type { DashboardPayload, HarnessId, StartupConfig } from "../types.ts";
|
|
4
4
|
import { OTHER_SERIES, SERIES_SLOTS, seriesColor, type SeriesInfo } from "./charts.tsx";
|
|
5
5
|
import { DashboardProvider, type Dashboard } from "./context.tsx";
|
|
6
6
|
import { DateRangePicker } from "./components/DateRangePicker.tsx";
|
|
7
|
+
import { AppFooter } from "./components/AppFooter.tsx";
|
|
7
8
|
import { Logo } from "./components/Logo.tsx";
|
|
8
9
|
import { RankChip } from "./components/RankChip.tsx";
|
|
9
10
|
import { SettingsDialog } from "./components/SettingsDialog.tsx";
|
|
@@ -553,14 +554,7 @@ export function App() {
|
|
|
553
554
|
{view.id === "rank" && <Rank />}
|
|
554
555
|
</main>
|
|
555
556
|
|
|
556
|
-
<
|
|
557
|
-
<span>
|
|
558
|
-
Made with <Heart size={12} aria-label="love" className="credit-heart" /> by{" "}
|
|
559
|
-
<a href="https://github.com/YarooqH" target="_blank" rel="noreferrer">qray</a>
|
|
560
|
-
</span>
|
|
561
|
-
<span aria-hidden="true">·</span>
|
|
562
|
-
<a href="https://github.com/YarooqH/token-larper" target="_blank" rel="noreferrer">Source on GitHub</a>
|
|
563
|
-
</footer>
|
|
557
|
+
<AppFooter />
|
|
564
558
|
|
|
565
559
|
{showSettings && (
|
|
566
560
|
<SettingsDialog
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
const JOKES = [
|
|
4
|
+
"Tokens were harmed in the making.",
|
|
5
|
+
"The context window remembers.",
|
|
6
|
+
"One more prompt. Famous last words.",
|
|
7
|
+
"Your cache misses have been noted.",
|
|
8
|
+
"The bill has entered the chat.",
|
|
9
|
+
"This footer also cost tokens.",
|
|
10
|
+
"The tokens know what they did.",
|
|
11
|
+
] as const;
|
|
12
|
+
|
|
13
|
+
const LAST_JOKE_KEY = "token-larper-last-footer-joke";
|
|
14
|
+
|
|
15
|
+
function pickJoke(): string {
|
|
16
|
+
let previous = -1;
|
|
17
|
+
try {
|
|
18
|
+
const saved = sessionStorage.getItem(LAST_JOKE_KEY);
|
|
19
|
+
if (saved !== null) previous = Number(saved);
|
|
20
|
+
} catch {
|
|
21
|
+
// The footer still works when storage is unavailable.
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const choices = JOKES.map((_, index) => index).filter((index) => index !== previous);
|
|
25
|
+
const index = choices[Math.floor(Math.random() * choices.length)]!;
|
|
26
|
+
try { sessionStorage.setItem(LAST_JOKE_KEY, String(index)); } catch {}
|
|
27
|
+
return JOKES[index];
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const joke = pickJoke();
|
|
31
|
+
|
|
32
|
+
export function AppFooter() {
|
|
33
|
+
return (
|
|
34
|
+
<footer className="app-footer">
|
|
35
|
+
<span>Made by <a href="https://github.com/YarooqH" target="_blank" rel="noopener noreferrer">qray</a></span>
|
|
36
|
+
<span className="footer-separator" aria-hidden="true">·</span>
|
|
37
|
+
<span>{joke}</span>
|
|
38
|
+
<span className="footer-separator" aria-hidden="true">·</span>
|
|
39
|
+
<a className="footer-source" href="https://github.com/YarooqH/token-larper" target="_blank" rel="noopener noreferrer">
|
|
40
|
+
<svg width="13" height="13" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true">
|
|
41
|
+
<path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.23.48-2.69-1.08-2.69-1.08-.36-.92-.89-1.16-.89-1.16-.73-.5.06-.49.06-.49.81.06 1.24.83 1.24.83.72 1.23 1.88.88 2.34.67.07-.52.28-.88.51-1.08-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.22 2.2.82a7.65 7.65 0 0 1 4.01 0c1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.28.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.08-.01 1.95-.01 2.21 0 .21.15.46.55.38A8.02 8.02 0 0 0 16 8c0-4.42-3.58-8-8-8Z" />
|
|
42
|
+
</svg>
|
|
43
|
+
<span>Source on GitHub</span>
|
|
44
|
+
</a>
|
|
45
|
+
</footer>
|
|
46
|
+
);
|
|
47
|
+
}
|
package/src/client/styles.css
CHANGED
|
@@ -310,9 +310,32 @@ img { display: block; }
|
|
|
310
310
|
|
|
311
311
|
.app {
|
|
312
312
|
max-width: 1240px;
|
|
313
|
+
min-height: 100vh;
|
|
314
|
+
display: flex;
|
|
315
|
+
flex-direction: column;
|
|
313
316
|
margin: 0 auto;
|
|
314
|
-
padding: 0 32px
|
|
317
|
+
padding: 0 32px 24px;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
.app-footer {
|
|
321
|
+
display: flex;
|
|
322
|
+
align-items: center;
|
|
323
|
+
justify-content: center;
|
|
324
|
+
flex-wrap: wrap;
|
|
325
|
+
column-gap: 8px;
|
|
326
|
+
row-gap: 4px;
|
|
327
|
+
margin-top: auto;
|
|
328
|
+
padding-top: 64px;
|
|
329
|
+
color: var(--text-3);
|
|
330
|
+
font-size: 11px;
|
|
331
|
+
line-height: 1.5;
|
|
332
|
+
text-align: center;
|
|
315
333
|
}
|
|
334
|
+
.app-footer a { color: var(--text-2); text-decoration: none; }
|
|
335
|
+
.app-footer a:hover { color: var(--text); text-decoration: underline; text-underline-offset: 3px; }
|
|
336
|
+
.app-footer a:focus-visible { outline: 2px solid var(--focus); outline-offset: 3px; border-radius: 2px; }
|
|
337
|
+
.footer-source { display: inline-flex; align-items: center; gap: 5px; white-space: nowrap; }
|
|
338
|
+
.footer-separator { color: var(--text-3); }
|
|
316
339
|
|
|
317
340
|
.topbar {
|
|
318
341
|
display: flex;
|
|
@@ -1161,10 +1184,6 @@ html[data-theme="dark"] .toggle.on .toggle-knob { background: var(--accent-ink);
|
|
|
1161
1184
|
|
|
1162
1185
|
/* ---------- Credit ---------- */
|
|
1163
1186
|
|
|
1164
|
-
.credit { display: flex; justify-content: center; flex-wrap: wrap; gap: 6px 10px; margin-top: 48px; color: var(--text-3); font-size: 12px; }
|
|
1165
|
-
.credit a { color: inherit; text-decoration: underline; text-decoration-color: var(--border-strong); text-underline-offset: 3px; }
|
|
1166
|
-
.credit a:hover { color: var(--text); text-decoration-color: currentColor; }
|
|
1167
|
-
.credit-heart { vertical-align: -1px; color: var(--accent); fill: currentColor; }
|
|
1168
1187
|
|
|
1169
1188
|
/* ---------- Splash screens ---------- */
|
|
1170
1189
|
|
|
@@ -1329,7 +1348,8 @@ html[data-theme="dark"] .toggle.on .toggle-knob { background: var(--accent-ink);
|
|
|
1329
1348
|
@media (max-width: 700px) {
|
|
1330
1349
|
.update-banner { flex-wrap: wrap; }
|
|
1331
1350
|
.update-banner-actions { width: 100%; justify-content: flex-end; }
|
|
1332
|
-
.app { padding: 0 16px
|
|
1351
|
+
.app { padding: 0 16px 24px; }
|
|
1352
|
+
.app-footer { padding-top: 48px; }
|
|
1333
1353
|
.topbar { margin: 0 -16px; padding: 12px 16px; }
|
|
1334
1354
|
.updated { display: none; }
|
|
1335
1355
|
.filters { margin: 0 -16px 16px; padding: 8px 16px 10px; }
|