queue/source/background/action.ts

51 lines
1.7 KiB
TypeScript

// Code for the WebExtension icon (AKA the "browser action").
import browser from "webextension-polyfill";
import {createValue} from "@holllo/webextension-storage";
import {
nextItem,
setBadgeText,
openNextItemOrOptionsPage,
} from "../item/item.js";
/**
* Handle single and double clicks for Firefox.
* - For single click: open the next queued item or the options page if none are
* in the queue.
* - For double click: open the options page.
*
* The reason this can't be done in Chromium is due to Manifest V3 running
* background scripts in service workers where `setTimeout` doesn't work
* reliably. The solution is to use `browser.alarms` instead, however, alarms
* also don't work reliably for this use case because they can only run every
* minute and we need milliseconds for this. And so, Chromium doesn't get double
* click functionality.
*/
export async function firefoxActionClick(): Promise<void> {
const timeoutId = await createValue<number | undefined>({
deserialize: Number,
key: "actionClickTimeoutId",
value: undefined,
});
// If no ID is in storage, this is the first click so start a timeout and
// save its ID.
if (timeoutId.value === undefined) {
timeoutId.value = window.setTimeout(async () => {
// When no second click happens, open the next item or the options page.
await openNextItemOrOptionsPage();
await timeoutId.remove();
}, 500);
await timeoutId.save();
return;
}
// If an ID is present in storage, this is the second click and we want to
// open the options page instead.
window.clearTimeout(timeoutId.value);
await browser.runtime.openOptionsPage();
await timeoutId.remove();
}