Remove placeholder status icons

This commit is contained in:
Jordan Wages 2025-06-25 14:53:19 -05:00
commit a58b8f3632
3 changed files with 55 additions and 18 deletions

View file

@ -21,6 +21,7 @@ message meets a specified criterion.
- **Debug logging** optional colorized logs help troubleshoot interactions with the AI service. - **Debug logging** optional colorized logs help troubleshoot interactions with the AI service.
- **Automatic rules** create rules that tag or move new messages based on AI classification. - **Automatic rules** create rules that tag or move new messages based on AI classification.
- **Context menu** apply AI rules to selected messages from the message list or display. - **Context menu** apply AI rules to selected messages from the message list or display.
- **Status icons** toolbar icons indicate when messages are queued or being classified.
- **Packaging script** `build-xpi.ps1` builds an XPI ready for installation. - **Packaging script** `build-xpi.ps1` builds an XPI ready for installation.
## Architecture Overview ## Architecture Overview

View file

@ -13,6 +13,24 @@
let logger; let logger;
let AiClassifier; let AiClassifier;
let aiRules = []; let aiRules = [];
let queue = Promise.resolve();
let queuedCount = 0;
let processing = false;
function updateActionIcon() {
let path = "resources/img/logo32.png";
if (processing) {
path = "resources/img/status-classifying.png";
} else if (queuedCount > 0) {
path = "resources/img/status-queued.png";
}
if (browser.browserAction) {
browser.browserAction.setIcon({ path });
}
if (browser.messageDisplayAction) {
browser.messageDisplayAction.setIcon({ path });
}
}
async function sha256Hex(str) { async function sha256Hex(str) {
const buf = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(str)); const buf = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(str));
@ -21,7 +39,7 @@ async function sha256Hex(str) {
async function applyAiRules(idsInput) { async function applyAiRules(idsInput) {
const ids = Array.isArray(idsInput) ? idsInput : [idsInput]; const ids = Array.isArray(idsInput) ? idsInput : [idsInput];
if (!ids.length) return; if (!ids.length) return queue;
if (!aiRules.length) { if (!aiRules.length) {
const { aiRules: stored } = await browser.storage.local.get("aiRules"); const { aiRules: stored } = await browser.storage.local.get("aiRules");
@ -36,6 +54,12 @@ async function applyAiRules(idsInput) {
for (const msg of ids) { for (const msg of ids) {
const id = msg?.id ?? msg; const id = msg?.id ?? msg;
queuedCount++;
updateActionIcon();
queue = queue.then(async () => {
processing = true;
queuedCount--;
updateActionIcon();
try { try {
const full = await messenger.messages.getFull(id); const full = await messenger.messages.getFull(id);
const text = full?.parts?.[0]?.body || ""; const text = full?.parts?.[0]?.body || "";
@ -56,8 +80,14 @@ async function applyAiRules(idsInput) {
} }
} catch (e) { } catch (e) {
logger.aiLog("failed to apply AI rules", { level: 'error' }, e); logger.aiLog("failed to apply AI rules", { level: 'error' }, e);
} finally {
processing = false;
updateActionIcon();
} }
});
} }
return queue;
} }
(async () => { (async () => {

View file

@ -18,6 +18,12 @@
"96": "resources/img/logo96.png", "96": "resources/img/logo96.png",
"128": "resources/img/logo128.png" "128": "resources/img/logo128.png"
}, },
"browser_action": {
"default_icon": "resources/img/logo32.png"
},
"message_display_action": {
"default_icon": "resources/img/logo32.png"
},
"background": { "scripts": [ "background.js" ] }, "background": { "scripts": [ "background.js" ] },
"options_ui": { "options_ui": {
"page": "options/options.html", "page": "options/options.html",