Handle message display in TB 128
This commit is contained in:
parent
0c07479fa9
commit
d60725eb4b
3 changed files with 52 additions and 60 deletions
|
@ -333,6 +333,19 @@ async function clearCacheForMessages(idsInput) {
|
||||||
if (browser.messageDisplayAction.setLabel) {
|
if (browser.messageDisplayAction.setLabel) {
|
||||||
browser.messageDisplayAction.setLabel({ label: "Details" });
|
browser.messageDisplayAction.setLabel({ label: "Details" });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
browser.messageDisplayAction.onClicked.addListener(async (tab) => {
|
||||||
|
const header = await browser.messageDisplay.getDisplayedMessage(tab.id);
|
||||||
|
if (!header) {
|
||||||
|
console.warn("[Sortana] no displayed message in tab", tab.id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const popupUrl = `${browser.runtime.getURL("details.html")}?mid=${header.id}`;
|
||||||
|
|
||||||
|
await browser.messageDisplayAction.setPopup({ tabId: tab.id, popup: popupUrl });
|
||||||
|
await browser.messageDisplayAction.openPopup({ tabId: tab.id });
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
browser.menus.create({
|
browser.menus.create({
|
||||||
|
@ -370,7 +383,7 @@ async function clearCacheForMessages(idsInput) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
browser.menus.onClicked.addListener(async info => {
|
browser.menus.onClicked.addListener(async (info, tab) => {
|
||||||
if (info.menuItemId === "apply-ai-rules-list" || info.menuItemId === "apply-ai-rules-display") {
|
if (info.menuItemId === "apply-ai-rules-list" || info.menuItemId === "apply-ai-rules-display") {
|
||||||
const ids = info.selectedMessages?.messages?.map(m => m.id) ||
|
const ids = info.selectedMessages?.messages?.map(m => m.id) ||
|
||||||
(info.messageId ? [info.messageId] : []);
|
(info.messageId ? [info.messageId] : []);
|
||||||
|
@ -380,11 +393,12 @@ async function clearCacheForMessages(idsInput) {
|
||||||
(info.messageId ? [info.messageId] : []);
|
(info.messageId ? [info.messageId] : []);
|
||||||
await clearCacheForMessages(ids);
|
await clearCacheForMessages(ids);
|
||||||
} else if (info.menuItemId === "view-ai-reason-list" || info.menuItemId === "view-ai-reason-display") {
|
} else if (info.menuItemId === "view-ai-reason-list" || info.menuItemId === "view-ai-reason-display") {
|
||||||
const id = info.messageId || info.selectedMessages?.messages?.[0]?.id;
|
const header = await browser.messageDisplay.getDisplayedMessage(tab.id);
|
||||||
if (id) {
|
if (!header) { return; }
|
||||||
const url = browser.runtime.getURL(`details.html?mid=${id}`);
|
|
||||||
browser.tabs.create({ url });
|
const url = `${browser.runtime.getURL("details.html")}?mid=${header.id}`;
|
||||||
}
|
|
||||||
|
await browser.tabs.create({ url });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -411,19 +425,6 @@ async function clearCacheForMessages(idsInput) {
|
||||||
// rethrow so the caller sees the failure
|
// rethrow so the caller sees the failure
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
} else if (msg?.type === "sortana:getActiveMessage") {
|
|
||||||
try {
|
|
||||||
const displayed = await browser.messageDisplay.getDisplayedMessages();
|
|
||||||
let id = displayed[0]?.id;
|
|
||||||
if (!id) {
|
|
||||||
const selected = await browser.mailTabs.getSelectedMessages();
|
|
||||||
id = selected?.messages?.[0]?.id;
|
|
||||||
}
|
|
||||||
return { id: id ?? null };
|
|
||||||
} catch (e) {
|
|
||||||
logger.aiLog("failed to get active message", { level: 'error' }, e);
|
|
||||||
return { id: null };
|
|
||||||
}
|
|
||||||
} else if (msg?.type === "sortana:clearCacheForDisplayed") {
|
} else if (msg?.type === "sortana:clearCacheForDisplayed") {
|
||||||
try {
|
try {
|
||||||
const msgs = await browser.messageDisplay.getDisplayedMessages();
|
const msgs = await browser.messageDisplay.getDisplayedMessages();
|
||||||
|
|
70
details.js
70
details.js
|
@ -1,48 +1,40 @@
|
||||||
document.addEventListener('DOMContentLoaded', async () => {
|
document.addEventListener('DOMContentLoaded', async () => {
|
||||||
|
const logger = (await import(browser.runtime.getURL('logger.js'))).aiLog;
|
||||||
|
|
||||||
|
const midParam = new URLSearchParams(location.search).get('mid');
|
||||||
|
const messageId = parseInt(midParam, 10);
|
||||||
|
|
||||||
|
if (!messageId) {
|
||||||
|
logger('no ?mid → trying displayedMessage fallback');
|
||||||
|
const openerTabId = (await browser.tabs.getCurrent()).openerTabId;
|
||||||
|
const header = await browser.messageDisplay.getDisplayedMessage(openerTabId);
|
||||||
|
if (!header) {
|
||||||
|
logger('still no message – aborting');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
loadMessage(header.id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
loadMessage(messageId);
|
||||||
|
});
|
||||||
|
|
||||||
|
async function loadMessage(id) {
|
||||||
const storage = (globalThis.messenger ?? browser).storage;
|
const storage = (globalThis.messenger ?? browser).storage;
|
||||||
const logger = await import(browser.runtime.getURL('logger.js'));
|
const logMod = await import(browser.runtime.getURL('logger.js'));
|
||||||
const { debugLogging } = await storage.local.get('debugLogging');
|
const { debugLogging } = await storage.local.get('debugLogging');
|
||||||
logger.setDebug(debugLogging === true);
|
logMod.setDebug(debugLogging === true);
|
||||||
logger.aiLog('details page loaded', { debug: true });
|
const log = logMod.aiLog;
|
||||||
|
|
||||||
const params = new URLSearchParams(location.search);
|
log('details page loaded', { debug: true });
|
||||||
let id = parseInt(params.get('mid'), 10);
|
|
||||||
logger.aiLog('initial message id', { debug: true }, id);
|
|
||||||
|
|
||||||
if (!id) {
|
|
||||||
try {
|
|
||||||
const msgs = await browser.messageDisplay.getDisplayedMessages();
|
|
||||||
id = msgs[0]?.id;
|
|
||||||
logger.aiLog('message id from displayed messages', { debug: true }, id);
|
|
||||||
if (!id) {
|
|
||||||
const selected = await browser.mailTabs.getSelectedMessages();
|
|
||||||
id = selected?.messages?.[0]?.id;
|
|
||||||
logger.aiLog('message id from selected messages', { debug: true }, id);
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
logger.aiLog('failed to determine message id locally', { level: 'error' }, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!id) {
|
|
||||||
try {
|
|
||||||
const resp = await browser.runtime.sendMessage({ type: 'sortana:getActiveMessage' });
|
|
||||||
id = resp?.id;
|
|
||||||
logger.aiLog('message id from background', { debug: true }, id);
|
|
||||||
} catch (e) {
|
|
||||||
logger.aiLog('failed to get message id from background', { level: 'error' }, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!id) return;
|
|
||||||
try {
|
try {
|
||||||
logger.aiLog('requesting message details', {}, id);
|
log('requesting message details', {}, id);
|
||||||
const { subject, results } = await browser.runtime.sendMessage({ type: 'sortana:getDetails', id });
|
const { subject, results } = await browser.runtime.sendMessage({ type: 'sortana:getDetails', id });
|
||||||
logger.aiLog('received details', { debug: true }, { subject, results });
|
log('received details', { debug: true }, { subject, results });
|
||||||
document.getElementById('subject').textContent = subject;
|
document.getElementById('subject').textContent = subject;
|
||||||
const container = document.getElementById('rules');
|
const container = document.getElementById('rules');
|
||||||
for (const r of results) {
|
for (const r of results) {
|
||||||
logger.aiLog('rendering rule result', { debug: true }, r);
|
log('rendering rule result', { debug: true }, r);
|
||||||
const article = document.createElement('article');
|
const article = document.createElement('article');
|
||||||
const color = r.matched === true ? 'is-success' : 'is-danger';
|
const color = r.matched === true ? 'is-success' : 'is-danger';
|
||||||
article.className = `message ${color} mb-4`;
|
article.className = `message ${color} mb-4`;
|
||||||
|
@ -62,11 +54,11 @@ document.addEventListener('DOMContentLoaded', async () => {
|
||||||
container.appendChild(article);
|
container.appendChild(article);
|
||||||
}
|
}
|
||||||
document.getElementById('clear').addEventListener('click', async () => {
|
document.getElementById('clear').addEventListener('click', async () => {
|
||||||
logger.aiLog('clearing cache for message', {}, id);
|
log('clearing cache for message', {}, id);
|
||||||
await browser.runtime.sendMessage({ type: 'sortana:clearCacheForMessage', id });
|
await browser.runtime.sendMessage({ type: 'sortana:clearCacheForMessage', id });
|
||||||
window.close();
|
window.close();
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logger.aiLog('failed to load details', { level: 'error' }, e);
|
log('failed to load details', { level: 'error' }, e);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
|
|
@ -24,8 +24,7 @@
|
||||||
"message_display_action": {
|
"message_display_action": {
|
||||||
"default_icon": "resources/img/brain.png",
|
"default_icon": "resources/img/brain.png",
|
||||||
"default_title": "Details",
|
"default_title": "Details",
|
||||||
"default_label": "Details",
|
"default_label": "Details"
|
||||||
"default_popup": "details.html"
|
|
||||||
},
|
},
|
||||||
"background": { "scripts": [ "background.js" ] },
|
"background": { "scripts": [ "background.js" ] },
|
||||||
"options_ui": {
|
"options_ui": {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue