srdusr
aboutsummaryrefslogtreecommitdiffstats
path: root/web/src/pb.js
diff options
context:
space:
mode:
Diffstat (limited to 'web/src/pb.js')
-rw-r--r--web/src/pb.js56
1 files changed, 56 insertions, 0 deletions
diff --git a/web/src/pb.js b/web/src/pb.js
new file mode 100644
index 0000000..cd4413c
--- /dev/null
+++ b/web/src/pb.js
@@ -0,0 +1,56 @@
+const STORAGE_KEY = 'typerpunk:pb';
+
+function load() {
+ try {
+ const raw = JSON.parse(localStorage.getItem(STORAGE_KEY));
+ return raw && typeof raw === 'object' ? raw : {};
+ } catch {
+ return {};
+ }
+}
+
+export function getPersonalBest(modeKey) {
+ if (!modeKey) return null;
+ return load()[modeKey] || null;
+}
+
+// All recorded bests, best-WPM first, for a full stats/profile view rather
+// than a single mode's lookup.
+export function getAllPersonalBests() {
+ const all = load();
+ return Object.entries(all)
+ .map(([modeKey, record]) => ({ modeKey, ...record }))
+ .sort((a, b) => b.wpm - a.wpm);
+}
+
+// Reconciles local bests with the server's on sign-in - takes max(local,
+// remote) per mode rather than overwriting, so a best set on this device
+// before ever signing in isn't lost just because the server hadn't seen it
+// yet. Guests never call this; the account has to exist first.
+export function mergeRemoteBests(remoteBests) {
+ if (!Array.isArray(remoteBests) || remoteBests.length === 0) return;
+ const all = load();
+ for (const { mode_key: modeKey, wpm, date } of remoteBests) {
+ const local = all[modeKey];
+ if (!local || wpm > local.wpm) {
+ all[modeKey] = { wpm, date: date ? Date.parse(date) || Date.now() : Date.now() };
+ }
+ }
+ try { localStorage.setItem(STORAGE_KEY, JSON.stringify(all)); } catch {}
+}
+
+// Records a finished test's WPM against its mode's best, updating storage
+// only when it's actually a new best. Returns the previous best (or null)
+// and whether this run just beat it, so the end screen can show both in one
+// read without a separate lookup.
+export function recordResult(modeKey, wpm) {
+ if (!modeKey) return { isNewBest: false, previous: null };
+ const all = load();
+ const previous = all[modeKey] || null;
+ const isNewBest = !previous || wpm > previous.wpm;
+ if (isNewBest) {
+ all[modeKey] = { wpm, date: Date.now() };
+ try { localStorage.setItem(STORAGE_KEY, JSON.stringify(all)); } catch {}
+ }
+ return { isNewBest, previous: previous ? previous.wpm : null };
+}