51 lines
1.7 KiB
TypeScript
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();
|
|
}
|