srdusr
aboutsummaryrefslogtreecommitdiffstats
path: root/web/src/profileStats.js
blob: c88da15b0b79f5fa7c4b718a984db06de4acd0b8 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
const STORAGE_KEY = 'typerpunk:profile';
// Caps how many past results the progress chart can show - unbounded
// growth would slowly bloat localStorage for a long-lived install with no
// benefit, since the chart only ever renders the most recent entries anyway.
const MAX_HISTORY = 100;

function defaults() {
    return {
        testsCompleted: 0,
        totalTimeSeconds: 0,
        totalWpm: 0,
        totalAccuracy: 0,
        bestWpm: 0,
        lastTestDate: null,
        streakDays: 0,
        history: [],
    };
}

function load() {
    try {
        const raw = JSON.parse(localStorage.getItem(STORAGE_KEY));
        return raw && typeof raw === 'object' ? { ...defaults(), ...raw } : defaults();
    } catch {
        return defaults();
    }
}

export function getProfileStats() {
    const s = load();
    return {
        ...s,
        averageWpm: s.testsCompleted ? Math.round(s.totalWpm / s.testsCompleted) : 0,
        averageAccuracy: s.testsCompleted ? Math.round(s.totalAccuracy / s.testsCompleted) : 0,
    };
}

// Called once per finished test (any mode, including custom text) - these
// are lifetime activity totals, not per-mode bests, so unlike pb.js every
// completed test counts, not just new records.
export function recordTest({ wpm, accuracy, time }) {
    const s = load();
    s.testsCompleted += 1;
    s.totalTimeSeconds += time;
    s.totalWpm += wpm;
    s.totalAccuracy += accuracy;
    s.bestWpm = Math.max(s.bestWpm, wpm);

    const today = new Date().toDateString();
    const lastDay = s.lastTestDate ? new Date(s.lastTestDate).toDateString() : null;
    if (lastDay !== today) {
        const yesterday = new Date(Date.now() - 86400000).toDateString();
        s.streakDays = lastDay === yesterday ? s.streakDays + 1 : 1;
    }
    s.lastTestDate = Date.now();

    s.history.push({ wpm, accuracy, date: s.lastTestDate });
    if (s.history.length > MAX_HISTORY) s.history = s.history.slice(-MAX_HISTORY);

    try { localStorage.setItem(STORAGE_KEY, JSON.stringify(s)); } catch {}
    return s;
}