-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbackground.js
More file actions
123 lines (106 loc) · 4.05 KB
/
Copy pathbackground.js
File metadata and controls
123 lines (106 loc) · 4.05 KB
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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import { fetchSnapshot } from './api.js';
import { defaultPrefs, getPrefs, setPrefs, getCache, setCache } from './prefs.js';
import { drawIcon } from './icon-draw.js';
const ALARM_REFRESH = 'cuw-refresh';
const ALARM_HISTORY = 'cuw-history';
chrome.runtime.onInstalled.addListener(async () => {
const prefs = await getPrefs();
scheduleRefresh(prefs.pollIntervalSec);
chrome.alarms.create(ALARM_HISTORY, { periodInMinutes: 5 });
await refresh();
});
chrome.runtime.onStartup.addListener(async () => {
const prefs = await getPrefs();
scheduleRefresh(prefs.pollIntervalSec);
await refresh();
});
chrome.alarms.onAlarm.addListener(async (alarm) => {
if (alarm.name === ALARM_REFRESH) await refresh();
if (alarm.name === ALARM_HISTORY) await recordHistory();
});
// React to settings changes from the options page.
chrome.runtime.onMessage.addListener((msg, _sender, sendResponse) => {
(async () => {
if (msg?.type === 'prefs-changed') {
const prefs = await getPrefs();
scheduleRefresh(prefs.pollIntervalSec);
await updateBadge(); // re-render with new settings
} else if (msg?.type === 'refresh-now') {
await refresh();
sendResponse({ ok: true });
} else if (msg?.type === 'get-snapshot') {
const cache = await getCache();
sendResponse(cache);
}
})();
return true; // keep channel open for async sendResponse
});
function scheduleRefresh(sec) {
chrome.alarms.clear(ALARM_REFRESH);
chrome.alarms.create(ALARM_REFRESH, { periodInMinutes: Math.max(0.5, sec / 60) });
}
async function refresh() {
try {
const snap = await fetchSnapshot();
await setCache({ snapshot: snap, error: null, fetchedAt: Date.now() });
await updateBadge();
await evaluateNotifications(snap);
} catch (err) {
const cache = await getCache();
await setCache({ ...cache, error: String(err.message || err), fetchedAt: Date.now() });
await updateBadge();
}
}
async function recordHistory() {
const { snapshot } = (await getCache()) || {};
if (!snapshot) return;
const { history = [] } = await chrome.storage.local.get('history');
history.push({ t: Date.now() / 1000, v: snapshot.weeklyUtilization });
// Cap at 14 days × 24h × 12 samples/h = 4032
const trimmed = history.length > 4032 ? history.slice(history.length - 4032) : history;
await chrome.storage.local.set({ history: trimmed });
}
async function updateBadge() {
const { snapshot, error } = (await getCache()) || {};
const prefs = await getPrefs();
// Tooltip
if (snapshot) {
const pct = Math.round(snapshot.weeklyUtilization);
chrome.action.setTitle({ title: `Claude: ${pct}% this week` });
} else if (error) {
chrome.action.setTitle({ title: `Claude Usage Widget — ${error}` });
}
// Render the icon
const imageData = drawIcon(snapshot, prefs, !!error && !snapshot);
chrome.action.setIcon({ imageData });
}
async function evaluateNotifications(snap) {
const prefs = await getPrefs();
if (!prefs.notificationsEnabled) return;
const pct = Math.round(snap.weeklyUtilization);
// Reset when we drop below warn — re-arm for next cycle.
if (pct < prefs.warnThreshold && prefs.lastNotifiedLevel) {
await setPrefs({ lastNotifiedLevel: '' });
return;
}
const newLevel =
pct >= prefs.criticalThreshold ? 'critical' :
pct >= prefs.alertThreshold ? 'alert' :
pct >= prefs.warnThreshold ? 'warn' : null;
if (!newLevel) return;
const rank = { '': 0, warn: 1, alert: 2, critical: 3 };
if (rank[newLevel] <= rank[prefs.lastNotifiedLevel || '']) return;
const messages = {
warn: chrome.i18n.getMessage('notification_warn', [`${pct}`]),
alert: chrome.i18n.getMessage('notification_alert', [`${pct}`]),
critical: chrome.i18n.getMessage('notification_critical', [`${pct}`]),
};
chrome.notifications.create(`cuw-${newLevel}-${Date.now()}`, {
type: 'basic',
iconUrl: 'icons/icon-128.png',
title: 'Claude Usage Widget',
message: messages[newLevel],
priority: newLevel === 'critical' ? 2 : 1,
});
await setPrefs({ lastNotifiedLevel: newLevel });
}