Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions BrowserExtension/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"manifest_version": 3,
"name": "VoxClaw",
"description": "Pauses YouTube and ducks Spotify when VoxClaw speaks, restores when it finishes.",
"version": "1.1.0",
"version": "1.1.1",
"icons": {
"16": "icons/icon16.png",
"32": "icons/icon32.png",
Expand All @@ -12,7 +12,8 @@
"permissions": [
"tabs",
"scripting",
"storage"
"storage",
"alarms"
],
"host_permissions": [
"http://localhost:4140/*",
Expand Down
24 changes: 24 additions & 0 deletions BrowserExtension/service_worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,13 @@ async function pollStatus() {

wasReading = isReading;
} catch {
// This chrome.* call is load-bearing beyond the title it sets: extension API
// activity is what resets the service worker's idle timer. The success path
// above calls chrome.action every second, but without a call here the worker
// goes idle while VoxClaw is unreachable and is torn down — taking the poll
// interval with it, so ducking never resumes once VoxClaw comes back.
chrome.action.setTitle({ title: "VoxClaw (not running)" });

if (wasReading) {
wasReading = false;
if (pausedTabs.length > 0) {
Expand Down Expand Up @@ -224,6 +231,23 @@ function stopPolling() {
log("Polling stopped");
}

// A service worker is torn down after ~30s without extension API activity.
// While VoxClaw is unreachable pollStatus takes its catch path, which makes no
// chrome.* calls, so the worker dies — and setInterval dies with it. Nothing
// would restart it, because startPolling only runs on install/startup, so a
// single VoxClaw restart used to disable the extension until the browser was
// restarted. This alarm wakes the worker back up and restarts the loop.
const WATCHDOG_ALARM = "voxclaw-poll-watchdog";
// 30s is the shortest period Chrome honors for alarms.
chrome.alarms.create(WATCHDOG_ALARM, { periodInMinutes: 0.5 });

chrome.alarms.onAlarm.addListener((alarm) => {
if (alarm.name !== WATCHDOG_ALARM) return;
chrome.storage.local.get("enabled", ({ enabled }) => {
if (enabled !== false) startPolling();
});
});

chrome.storage.local.get("enabled", ({ enabled }) => {
if (enabled !== false) startPolling();
});
Expand Down
Loading