spamfilter settings page updated. see #438
This commit is contained in:
parent
6cb2cffd27
commit
124b31c830
4 changed files with 125 additions and 11 deletions
|
|
@ -1151,11 +1151,11 @@
|
||||||
"message": "If checked, the AI will only add tags to emails received in the inbox folder.",
|
"message": "If checked, the AI will only add tags to emails received in the inbox folder.",
|
||||||
"description": ""
|
"description": ""
|
||||||
},
|
},
|
||||||
"prefs_OptionText_add_tags_use_specific_integration": {
|
"prefs_OptionText_use_specific_integration": {
|
||||||
"message": "Use specific Model and API",
|
"message": "Use specific Model and API",
|
||||||
"description": ""
|
"description": ""
|
||||||
},
|
},
|
||||||
"prefs_OptionText_add_tags_use_specific_integration_Info": {
|
"prefs_OptionText_use_specific_integration_Info": {
|
||||||
"message": "If checked, the Model and API specified below will be used for adding tags to emails, regardless the one choosen in the ThunderAI options page.",
|
"message": "If checked, the Model and API specified below will be used for adding tags to emails, regardless the one choosen in the ThunderAI options page.",
|
||||||
"description": ""
|
"description": ""
|
||||||
},
|
},
|
||||||
|
|
@ -1211,6 +1211,14 @@
|
||||||
"message": "Spam Filter Options",
|
"message": "Spam Filter Options",
|
||||||
"description": ""
|
"description": ""
|
||||||
},
|
},
|
||||||
|
"prefs_OptionText_spamfilter_use_specific_integration": {
|
||||||
|
"message": "Use specific Model and API",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"prefs_OptionText_spamfilter_use_specific_integration_Info": {
|
||||||
|
"message": "If checked, the Model and API specified below will be used for the spam filter, regardless the one chosen in the ThunderAI options page.",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
"prefs_OptionText_spamfilter_threshold": {
|
"prefs_OptionText_spamfilter_threshold": {
|
||||||
"message": "Spam threshold",
|
"message": "Spam threshold",
|
||||||
"description": ""
|
"description": ""
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,7 @@ export const prefs_default = {
|
||||||
spamfilter_context_menu: true,
|
spamfilter_context_menu: true,
|
||||||
spamfilter_enabled_accounts: [],
|
spamfilter_enabled_accounts: [],
|
||||||
spamfilter_use_specific_integration: false,
|
spamfilter_use_specific_integration: false,
|
||||||
spamfilter_connection_type: '',
|
spamfilter_connection_type: 'chatgpt_api',
|
||||||
spamfilter_chatgpt_model: '',
|
spamfilter_chatgpt_model: '',
|
||||||
spamfilter_ollama_model: '',
|
spamfilter_ollama_model: '',
|
||||||
spamfilter_openai_comp_model: '',
|
spamfilter_openai_comp_model: '',
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>ThunderAI - __MSG_SpamFilter_PageTitle__</title>
|
<title>ThunderAI - __MSG_SpamFilter_PageTitle__</title>
|
||||||
<link rel="stylesheet" href="mzta-spamfilter.css">
|
<link rel="stylesheet" href="mzta-spamfilter.css">
|
||||||
|
<link rel="stylesheet" href="../_lib/connection-ui.css">
|
||||||
<link rel="icon" href="../../images/icon-16px.png">
|
<link rel="icon" href="../../images/icon-16px.png">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
@ -13,6 +14,18 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="spamfilter_table_title section_title">__MSG_SpamFilter_prompt_prefs_title__</div>
|
<div class="spamfilter_table_title section_title">__MSG_SpamFilter_prompt_prefs_title__</div>
|
||||||
<table id="miczPrefs">
|
<table id="miczPrefs">
|
||||||
|
<tr class="spamfilter_tr specific_integration">
|
||||||
|
<td><span>__MSG_prefs_OptionText_use_specific_integration__</span>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" id="spamfilter_use_specific_integration" name="spamfilter_use_specific_integration" class="option-input" />
|
||||||
|
__MSG_prefs_OptionText_spamfilter_use_specific_integration_Info__
|
||||||
|
</label>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr id="connection_ui_anchor"></tr>
|
||||||
|
<tr id="connection_ui_end"><td colspan="2"></td></tr>
|
||||||
<tr class="spamfilter_tr">
|
<tr class="spamfilter_tr">
|
||||||
<td><span>__MSG_prefs_OptionText_spamfilter_threshold__</span></td>
|
<td><span>__MSG_prefs_OptionText_spamfilter_threshold__</span></td>
|
||||||
<td>
|
<td>
|
||||||
|
|
|
||||||
|
|
@ -18,18 +18,39 @@
|
||||||
|
|
||||||
import { prefs_default } from '../../options/mzta-options-default.js';
|
import { prefs_default } from '../../options/mzta-options-default.js';
|
||||||
import { taLogger } from '../../js/mzta-logger.js';
|
import { taLogger } from '../../js/mzta-logger.js';
|
||||||
import { getSpecialPrompts, setSpecialPrompts } from "../../js/mzta-prompts.js";
|
import { getSpecialPrompts, setSpecialPrompts, loadPrompt, savePrompt, clearPromptAPI } from "../../js/mzta-prompts.js";
|
||||||
import { getPlaceholders } from "../../js/mzta-placeholders.js";
|
import { getPlaceholders } from "../../js/mzta-placeholders.js";
|
||||||
import { textareaAutocomplete } from "../../js/mzta-placeholders-autocomplete.js";
|
import { textareaAutocomplete } from "../../js/mzta-placeholders-autocomplete.js";
|
||||||
import { taSpamReport } from '../../js/mzta-spamreport.js';
|
import { taSpamReport } from '../../js/mzta-spamreport.js';
|
||||||
import { getAccountsList, isAPIKeyValue } from "../../js/mzta-utils.js";
|
import { getAccountsList, isAPIKeyValue } from "../../js/mzta-utils.js";
|
||||||
|
import {
|
||||||
|
injectConnectionUI,
|
||||||
|
updateWarnings,
|
||||||
|
changeConnTypeRowColor
|
||||||
|
} from "../_lib/connection-ui.js";
|
||||||
|
|
||||||
let autocompleteSuggestions = [];
|
let autocompleteSuggestions = [];
|
||||||
let taLog = new taLogger("mzta-spamfilter-page",true);
|
let taLog = new taLogger("mzta-spamfilter-page",true);
|
||||||
taSpamReport.logger = taLog;
|
taSpamReport.logger = taLog;
|
||||||
|
|
||||||
|
let conntype_select_id = 'spamfilter_connection_type';
|
||||||
|
let model_prefix = 'spamfilter_';
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', async () => {
|
document.addEventListener('DOMContentLoaded', async () => {
|
||||||
|
|
||||||
|
try {
|
||||||
|
await injectConnectionUI({
|
||||||
|
afterTrId: 'connection_ui_anchor',
|
||||||
|
tr_class: 'specific_integration_sub',
|
||||||
|
selectId: conntype_select_id,
|
||||||
|
modelId_prefix: model_prefix,
|
||||||
|
no_chatgpt_web: true,
|
||||||
|
taLog: taLog
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
console.error('Failed to inject connection UI (spamfilter)', e);
|
||||||
|
}
|
||||||
|
|
||||||
i18n.updateDocument();
|
i18n.updateDocument();
|
||||||
await restoreOptions();
|
await restoreOptions();
|
||||||
|
|
||||||
|
|
@ -40,6 +61,48 @@ document.addEventListener('DOMContentLoaded', async () => {
|
||||||
document.getElementById("spamfilter_threshold").addEventListener("input", check_spamfilter_threshold);
|
document.getElementById("spamfilter_threshold").addEventListener("input", check_spamfilter_threshold);
|
||||||
check_spamfilter_threshold({target: document.getElementById("spamfilter_threshold")});
|
check_spamfilter_threshold({target: document.getElementById("spamfilter_threshold")});
|
||||||
|
|
||||||
|
// Bind prompt API updates to connection type and model selects
|
||||||
|
document.querySelectorAll(".option-input-model").forEach(element => {
|
||||||
|
element.addEventListener("change", updatePromptAPIInfo);
|
||||||
|
});
|
||||||
|
const conntype_el = document.getElementById(conntype_select_id);
|
||||||
|
if (conntype_el) {
|
||||||
|
conntype_el.addEventListener('change', updatePromptAPIInfo);
|
||||||
|
const conntype_row = document.getElementById(conntype_select_id + '_tr');
|
||||||
|
if (conntype_row) changeConnTypeRowColor(conntype_row, conntype_el);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Specific integration toggle behavior
|
||||||
|
const spamfilter_use_specific_integration_el = document.getElementById('spamfilter_use_specific_integration');
|
||||||
|
let prefs_spamfilter_init = await browser.storage.sync.get({ spamfilter_enabled_accounts: [], connection_type: 'chatgpt_web' });
|
||||||
|
if(prefs_spamfilter_init.connection_type == 'chatgpt_web'){
|
||||||
|
spamfilter_use_specific_integration_el.checked = true;
|
||||||
|
spamfilter_use_specific_integration_el.dispatchEvent(new Event('change'));
|
||||||
|
spamfilter_use_specific_integration_el.disabled = true;
|
||||||
|
}
|
||||||
|
const conntype_end_el = document.getElementById('connection_ui_end');
|
||||||
|
const conntype_row = document.getElementById(conntype_select_id + '_tr');
|
||||||
|
spamfilter_use_specific_integration_el.addEventListener('change', async (event) => {
|
||||||
|
document.querySelectorAll('.specific_integration_sub').forEach(tr => {
|
||||||
|
tr.style.display = event.target.checked && tr.classList.contains('conntype_' + conntype_el.value) ? 'table-row' : 'none';
|
||||||
|
});
|
||||||
|
if (conntype_row) conntype_row.style.display = event.target.checked ? 'table-row' : 'none';
|
||||||
|
if (conntype_end_el) conntype_end_el.style.display = event.target.checked ? 'table-row' : 'none';
|
||||||
|
if(!event.target.checked){
|
||||||
|
await clearPromptAPI('prompt_spamfilter');
|
||||||
|
}else{
|
||||||
|
updatePromptAPIInfo();
|
||||||
|
}
|
||||||
|
if (conntype_row) changeConnTypeRowColor(conntype_row, conntype_el);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Initialize visibility per current toggle value
|
||||||
|
document.querySelectorAll('.specific_integration_sub').forEach(tr => {
|
||||||
|
tr.style.display = spamfilter_use_specific_integration_el.checked && tr.classList.contains('conntype_' + conntype_el.value) ? 'table-row' : 'none';
|
||||||
|
});
|
||||||
|
if (conntype_row) conntype_row.style.display = spamfilter_use_specific_integration_el.checked ? 'table-row' : 'none';
|
||||||
|
if (conntype_end_el) conntype_end_el.style.display = spamfilter_use_specific_integration_el.checked ? 'table-row' : 'none';
|
||||||
|
|
||||||
let spamfilter_textarea = document.getElementById('spamfilter_prompt_text');
|
let spamfilter_textarea = document.getElementById('spamfilter_prompt_text');
|
||||||
let spamfilter_save_btn = document.getElementById('btn_save_prompt');
|
let spamfilter_save_btn = document.getElementById('btn_save_prompt');
|
||||||
let spamfilter_reset_btn = document.getElementById('btn_reset_prompt');
|
let spamfilter_reset_btn = document.getElementById('btn_reset_prompt');
|
||||||
|
|
@ -136,6 +199,9 @@ document.addEventListener('DOMContentLoaded', async () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
loadSpamReport();
|
loadSpamReport();
|
||||||
|
updateWarnings(model_prefix);
|
||||||
|
// Sync prompt API/model once on load
|
||||||
|
updatePromptAPIInfo();
|
||||||
});
|
});
|
||||||
|
|
||||||
function check_spamfilter_threshold(event) {
|
function check_spamfilter_threshold(event) {
|
||||||
|
|
@ -165,6 +231,21 @@ async function loadSpamReport(){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function updatePromptAPIInfo(){
|
||||||
|
const conntypeEl = document.getElementById(conntype_select_id);
|
||||||
|
if (!conntypeEl || !conntypeEl.value) return;
|
||||||
|
const conntype = conntypeEl.value;
|
||||||
|
const model_value = conntype.substring(0, conntype.length - 4) + '_model';
|
||||||
|
const modelEl = document.getElementById(model_prefix + model_value);
|
||||||
|
if (!modelEl) return;
|
||||||
|
const model = modelEl.value;
|
||||||
|
let spamfilter_prompt = await loadPrompt('prompt_spamfilter');
|
||||||
|
if (!spamfilter_prompt) return;
|
||||||
|
spamfilter_prompt.api = conntype;
|
||||||
|
spamfilter_prompt.model = model;
|
||||||
|
await savePrompt(spamfilter_prompt);
|
||||||
|
}
|
||||||
|
|
||||||
// Function to populate the table
|
// Function to populate the table
|
||||||
function populateTable(data) {
|
function populateTable(data) {
|
||||||
const tableBody = document.getElementById("report_data_body");
|
const tableBody = document.getElementById("report_data_body");
|
||||||
|
|
@ -228,13 +309,16 @@ function saveOptions(e) {
|
||||||
case 'number':
|
case 'number':
|
||||||
options[element.id] = element.valueAsNumber;
|
options[element.id] = element.valueAsNumber;
|
||||||
break;
|
break;
|
||||||
case 'text':
|
case 'text':
|
||||||
case 'password':
|
case 'password':
|
||||||
options[element.id] = element.value.trim();
|
options[element.id] = element.value.trim();
|
||||||
break;
|
break;
|
||||||
case 'select-one':
|
case 'select-one':
|
||||||
options[element.id] = element.value;
|
options[element.id] = element.value;
|
||||||
break;
|
break;
|
||||||
|
case 'textarea':
|
||||||
|
options[element.id] = element.value;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
console.error("[ThunderAI] Unhandled input type:", element.type);
|
console.error("[ThunderAI] Unhandled input type:", element.type);
|
||||||
}
|
}
|
||||||
|
|
@ -257,6 +341,7 @@ async function restoreOptions() {
|
||||||
element.value = result[element.id] ?? default_number_value;
|
element.value = result[element.id] ?? default_number_value;
|
||||||
break;
|
break;
|
||||||
case 'text':
|
case 'text':
|
||||||
|
case 'textarea':
|
||||||
case 'password':
|
case 'password':
|
||||||
let default_text_value = '';
|
let default_text_value = '';
|
||||||
if(element.id == 'default_chatgpt_lang') default_text_value = prefs_default.default_chatgpt_lang;
|
if(element.id == 'default_chatgpt_lang') default_text_value = prefs_default.default_chatgpt_lang;
|
||||||
|
|
@ -267,7 +352,15 @@ async function restoreOptions() {
|
||||||
let default_select_value = '';
|
let default_select_value = '';
|
||||||
if(element.id == 'reply_type') default_select_value = 'reply_all';
|
if(element.id == 'reply_type') default_select_value = 'reply_all';
|
||||||
if(element.id == 'connection_type') default_select_value = 'chatgpt_web';
|
if(element.id == 'connection_type') default_select_value = 'chatgpt_web';
|
||||||
element.value = result[element.id] || default_select_value;
|
if(element.id == 'spamfilter_connection_type') default_select_value = 'chatgpt_api';
|
||||||
|
const restoreValue = result[element.id] || default_select_value;
|
||||||
|
// Ensure option exists before restoring
|
||||||
|
let optionExists = Array.from(element.options).some(opt => opt.value === restoreValue);
|
||||||
|
if (!optionExists && restoreValue !== '') {
|
||||||
|
let newOption = new Option(restoreValue, restoreValue);
|
||||||
|
element.add(newOption);
|
||||||
|
}
|
||||||
|
element.value = restoreValue;
|
||||||
if (element.value === '') {
|
if (element.value === '') {
|
||||||
element.selectedIndex = -1;
|
element.selectedIndex = -1;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue