Show classification progress and results via toolbar icons
This commit is contained in:
parent
0f0584c4f5
commit
e78478ab9a
2 changed files with 22 additions and 12 deletions
|
@ -22,7 +22,7 @@ message meets a specified criterion.
|
||||||
- **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.
|
||||||
- **Rule ordering** – drag rules to prioritize them and optionally stop processing after a match.
|
- **Rule ordering** – drag rules to prioritize them and optionally stop processing after a match.
|
||||||
- **Context menu** – apply AI rules from the message list or the message display action button.
|
- **Context menu** – apply AI rules from the message list or the message display action button.
|
||||||
- **Status icons** – toolbar icons indicate when messages are queued or being classified.
|
- **Status icons** – toolbar icons show when classification is in progress and briefly display success or error states.
|
||||||
- **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
|
||||||
|
|
|
@ -18,14 +18,9 @@ let aiRules = [];
|
||||||
let queue = Promise.resolve();
|
let queue = Promise.resolve();
|
||||||
let queuedCount = 0;
|
let queuedCount = 0;
|
||||||
let processing = false;
|
let processing = false;
|
||||||
|
let iconTimer = null;
|
||||||
|
|
||||||
function updateActionIcon() {
|
function setIcon(path) {
|
||||||
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) {
|
if (browser.browserAction) {
|
||||||
browser.browserAction.setIcon({ path });
|
browser.browserAction.setIcon({ path });
|
||||||
}
|
}
|
||||||
|
@ -34,6 +29,20 @@ function updateActionIcon() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function updateActionIcon() {
|
||||||
|
let path = "resources/img/logo32.png";
|
||||||
|
if (processing || queuedCount > 0) {
|
||||||
|
path = "resources/img/busy.png";
|
||||||
|
}
|
||||||
|
setIcon(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
function showTransientIcon(path, delay = 1500) {
|
||||||
|
clearTimeout(iconTimer);
|
||||||
|
setIcon(path);
|
||||||
|
iconTimer = setTimeout(updateActionIcon, delay);
|
||||||
|
}
|
||||||
|
|
||||||
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));
|
||||||
return Array.from(new Uint8Array(buf), b => b.toString(16).padStart(2, '0')).join('');
|
return Array.from(new Uint8Array(buf), b => b.toString(16).padStart(2, '0')).join('');
|
||||||
|
@ -125,11 +134,12 @@ async function applyAiRules(idsInput) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e) {
|
|
||||||
logger.aiLog("failed to apply AI rules", { level: 'error' }, e);
|
|
||||||
} finally {
|
|
||||||
processing = false;
|
processing = false;
|
||||||
updateActionIcon();
|
showTransientIcon("resources/img/done.png");
|
||||||
|
} catch (e) {
|
||||||
|
processing = false;
|
||||||
|
logger.aiLog("failed to apply AI rules", { level: 'error' }, e);
|
||||||
|
showTransientIcon("resources/img/error.png");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue