diff --git "a/barre_lat\303\251rale/sidebar.js" "b/barre_lat\303\251rale/sidebar.js" index 289ed8c09b8f6c77f0fc23c83c6224ef47624d87..a6ac96e83d6d2bb2a91b53a52b8c3b3b71a65477 100644 --- "a/barre_lat\303\251rale/sidebar.js" +++ "b/barre_lat\303\251rale/sidebar.js" @@ -382,8 +382,8 @@ async function handleAddWordClick() { return; } - // 2) Récupérer les IDs des lexiques sélectionnés (cases à cocher “add-checkboxâ€) - const checkboxList = document.querySelectorAll("#lexiques .lexique-add-checkbox:checked"); + // 2) Récupérer les IDs des lexiques sélectionnés + const checkboxList = document.querySelectorAll("#lexiques .lexique-checkbox:checked"); const selectedLexiconIds = Array.from(checkboxList).map(cb => parseInt(cb.dataset.lexiconId, 10)); if (selectedLexiconIds.length === 0) { @@ -465,22 +465,22 @@ browser.runtime.onMessage.addListener(async (message) => { await refreshSidebarState(); break; - case "mot_selectionne": - if (message.selectedText) { - console.log("ðŸ–‹ï¸ Mot sélectionné :", message.selectedText); - const selectedWordElement = document.getElementById("motSelectionne"); - if (selectedWordElement) { - selectedWordElement.textContent = message.selectedText; - } else { - console.warn("âš ï¸ Ã‰lément #motSelectionne introuvable."); - } - const lexiconResultElement = document.getElementById("lexiconResult"); - if (lexiconResultElement) { - lexiconResultElement.innerHTML = ""; - } - openBlock("etatContent"); + case "mot_selectionne": + if (message.selectedText) { + console.log("ðŸ–‹ï¸ Mot sélectionné :", message.selectedText); + const selectedWordElement = document.getElementById("motSelectionne"); + if (selectedWordElement) { + selectedWordElement.textContent = message.selectedText; + } else { + console.warn("âš ï¸ Ã‰lément #motSelectionne introuvable."); + } + const lexiconResultElement = document.getElementById("lexiconResult"); + if (lexiconResultElement) { + lexiconResultElement.innerHTML = ""; } - break; + openBlock("etatContent"); + } + break; case "getDefinition": if (message.selectedText) { @@ -514,6 +514,28 @@ browser.runtime.onMessage.addListener(async (message) => { case "authStatusChanged": break; + case "wordAdded": + { + // Affichage du message de succès dans la sidebar + const lexiconResultElement = document.getElementById("lexiconResult"); + if (lexiconResultElement) { + lexiconResultElement.innerHTML += + "<br>✅ Mot <strong>" + message.selectedWord + "</strong> ajouté avec succès dans : " + + message.lexiconIds.join(", ") + "."; + } + } + break; + + case "wordAddFailed": + { + // Affichage du message d'erreur dans la sidebar + const lexiconResultElement = document.getElementById("lexiconResult"); + if (lexiconResultElement) { + lexiconResultElement.textContent = "Erreur lors de l'ajout du mot : " + message.error; + } + } + break; + default: console.warn("âš ï¸ Action inconnue reçue :", message.action); } diff --git a/manifest.json b/manifest.json index c2b94cae3c2c3e9d69e078dd0b3301d284765db5..b652cb0dee695f2c75585dbe931f2dcc4c5dd6e3 100644 --- a/manifest.json +++ b/manifest.json @@ -22,8 +22,9 @@ "scripts": [ "background/background.js", "definitions.js", - "menu_contextuel/browser_context_menu.js", - "api.js"], + "api.js", + "menu_contextuel/browser_context_menu.js" + ], "persistent": true }, diff --git a/menu_contextuel/browser_context_menu.js b/menu_contextuel/browser_context_menu.js index a2ba1fab3be52725c98a005b6603114c0e824100..85285248a0b135cf4eaf9e8a15cc4c0b70157db4 100644 --- a/menu_contextuel/browser_context_menu.js +++ b/menu_contextuel/browser_context_menu.js @@ -1,6 +1,7 @@ console.log("browser_context_menu.js chargé correctement"); let authToken = null; +let selectedLexicons = new Set(); /** * Charge le token depuis le stockage local et le stocke dans la variable globale authToken. @@ -15,9 +16,12 @@ async function loadAuthToken() { } } -// ───────────────────────────────────────────────────────────────────────────── -// Création du menu contextuel en fonction de l'authentification -// ───────────────────────────────────────────────────────────────────────────── +/** + * Crée le menu contextuel en fonction de l'authentification. + * Si l'utilisateur est connecté, on ajoute un item pour la recherche et + * un menu parent pour l'ajout du mot avec des cases à cocher pour chaque lexique + * et un item de confirmation. + */ async function createContextMenu() { await browser.contextMenus.removeAll(); @@ -30,15 +34,58 @@ async function createContextMenu() { icons: { "16": "icons/quel_lexique.png" }, }); - // Item 2 : Ajouter un mot au lexique personnel + // Menu parent pour ajouter le mot dans les lexiques choisis browser.contextMenus.create({ - id: "addtoLexicon", - title: "Ajouter ce mot à mon lexique", + id: "parentAddLexicon", + title: "Ajouter ce mot à …", contexts: ["selection"], - icons: { "16": "icons/ajout_lexique.png" }, + }); + + // Récupérer dynamiquement les lexiques + let lexicons = []; + try { + lexicons = await window.getLexicons(authToken); + } catch (error) { + console.error("Erreur lors de la récupération des lexiques :", error); + } + + if (Array.isArray(lexicons) && lexicons.length > 0) { + lexicons.forEach(lexicon => { + let title = ""; + if (lexicon.category === "User") { + title = `Lexique personnel (${(lexicon.user && lexicon.user.pseudo) || "Inconnu"}) [${lexicon.id}]`; + } else { + title = `Lexique de groupe (${(lexicon.group && lexicon.group.name) || "Inconnu"}) [${lexicon.id}]`; + } + browser.contextMenus.create({ + id: `addWord_${lexicon.id}`, + title: title, + type: "checkbox", + contexts: ["selection"], + parentId: "parentAddLexicon", + checked: false + }); + }); + } else { + browser.contextMenus.create({ + id: "noLexiconsFound", + title: "Aucun lexique trouvé", + contexts: ["selection"], + parentId: "parentAddLexicon", + enabled: false + }); + } + + // Item de confirmation pour lancer l'ajout dans les lexiques sélectionnés + browser.contextMenus.create({ + id: "confirmAddWord", + title: "Confirmer l'ajout", + contexts: ["selection"], + parentId: "parentAddLexicon", }); } + // Séparateur browser.contextMenus.create({ id: "separatorExtension", type: "separator", @@ -59,6 +106,7 @@ async function createContextMenu() { contexts: ["all"], }); + // Item de connexion/déconnexion browser.contextMenus.create({ id: "login", title: authToken ? "Se déconnecter de BaLex" : "Se connecter à BaLex", @@ -87,7 +135,8 @@ browser.storage.onChanged.addListener((changes, area) => { // ───────────────────────────────────────────────────────────────────────────── browser.contextMenus.onClicked.addListener(async (info, tab) => { console.log("Item de menu cliqué :", info.menuItemId); - + + // Action pour le bouton de connexion/déconnexion if (info.menuItemId === "login") { console.log("🔄 Action login/déconnexion demandée."); if (typeof actuallyOpenLoginPage === "function") { @@ -102,7 +151,8 @@ browser.contextMenus.onClicked.addListener(async (info, tab) => { console.warn("Aucun texte sélectionné pour cette action :", info.menuItemId); return; } - console.log(`📩 Texte sélectionné : ${info.selectionText}`); + const selectedText = info.selectionText.trim(); + console.log(`📩 Texte sélectionné : ${selectedText}`); switch (info.menuItemId) { case "searchInLexicons": @@ -110,46 +160,122 @@ browser.contextMenus.onClicked.addListener(async (info, tab) => { alert("âš ï¸ Vous devez être connecté pour utiliser cette fonction."); return; } - await searchInLexicons(info.selectionText); + await searchInLexicons(selectedText); break; - case "addtoLexicon": + case "confirmAddWord": if (!authToken) { alert("âš ï¸ Vous devez être connecté pour utiliser cette fonction."); return; } - await addWordToLexicon(info.selectionText); + if (!selectedText || selectedText === "Aucun mot sélectionné") { + console.warn("âš ï¸ Aucun mot à ajouter."); + browser.runtime.sendMessage({ + action: "wordAddFailed", + error: "Aucun mot à ajouter." + }); + return; + } + if (selectedLexicons.size === 0) { + alert("Veuillez sélectionner au moins un lexique."); + return; + } + { + // Vérifier si le mot existe déjà dans les lexiques sélectionnés + let definitions = []; + try { + definitions = await window.fetchLexiconDefinitions(selectedText); + } catch (error) { + console.error("Erreur lors de la récupération des définitions pour vérification :", error); + } + const existingLexiconIds = new Set(); + if (Array.isArray(definitions)) { + for (const def of definitions) { + if (selectedLexicons.has(def.lexiconId)) { + existingLexiconIds.add(def.lexiconId); + } + } + } + if (existingLexiconIds.size > 0) { + alert(`Le mot "${selectedText}" existe déjà dans le(s) lexique(s) : ${Array.from(existingLexiconIds).join(", ")}`); + browser.runtime.sendMessage({ + action: "wordAlreadyExists", + selectedWord: selectedText, + lexiconIds: Array.from(existingLexiconIds) + }); + return; + } + // On détermine quels lexiques ajouter (ceux non existants) + const lexiconsToAdd = Array.from(selectedLexicons).filter(id => !existingLexiconIds.has(id)); + if (lexiconsToAdd.length === 0) { + return; // Rien à ajouter + } + // Envoi de la requête d'ajout + try { + console.log(`📡 Envoi de l'ajout du mot "${selectedText}" dans le(s) lexique(s) :`, lexiconsToAdd); + const result = await window.AddWord(authToken, selectedText, lexiconsToAdd, false); + console.log("✅ Réponse API :", result); + await browser.runtime.sendMessage({ action: "refreshUI" }); + browser.runtime.sendMessage({ + action: "wordAdded", + selectedWord: selectedText, + lexiconIds: lexiconsToAdd, + result + }); + // Réinitialiser la sélection après ajout + selectedLexicons.clear(); + } catch (error) { + console.error("⌠Erreur lors de l’ajout du mot :", error); + alert("⌠Une erreur est survenue lors de l’ajout du mot : " + error.message); + browser.runtime.sendMessage({ + action: "wordAddFailed", + selectedWord: selectedText, + lexiconIds: Array.from(selectedLexicons), + error: error.message + }); + } + } break; - case "getDefinition": - await getDefinition(info.selectionText); - break; - default: - console.error(`⌠Action inconnue : ${info.menuItemId}`); + // Gérer les items de type "checkbox" + if (info.menuItemId.startsWith("addWord_")) { + const lexiconId = parseInt(info.menuItemId.replace("addWord_", ""), 10); + if (isNaN(lexiconId)) { + console.error("⌠ID de lexique invalide :", info.menuItemId); + return; + } + if (info.checked) { + selectedLexicons.add(lexiconId); + } else { + selectedLexicons.delete(lexiconId); + } + console.log("Lexicons sélectionnés :", Array.from(selectedLexicons)); + } else if (info.menuItemId === "getDefinition") { + await browser.runtime.sendMessage({ + action: "getDefinition", + selectedText: info.selectionText.trim(), + }); + return; + } else { + console.error(`⌠Action inconnue : ${info.menuItemId}`); + } + break; } }); // ───────────────────────────────────────────────────────────────────────────── -// Fonctions liées aux définitions (definitions.js) +// Fonctions liées aux définitions // ───────────────────────────────────────────────────────────────────────────── - -/** - * 1) Recherche de la définition combinée (lexiques + Wiktionnaire) - * et envoi des résultats pour affichage. - */ async function getDefinition(selectedText) { try { let lexiconDefs = []; if (authToken) { lexiconDefs = await fetchLexiconDefinitions(selectedText); } - const wikiDefs = await fetchWiktionaryDefinition(selectedText); - const allDefinitions = [...lexiconDefs, ...wikiDefs]; console.log("📠Définitions combinées :", allDefinitions); - browser.runtime.sendMessage({ action: "showDefinitions", selectedText, @@ -160,13 +286,9 @@ async function getDefinition(selectedText) { } } -/** - * 2) Recherche dans les lexiques pour savoir dans quels lexiques se trouve le mot. - */ async function searchInLexicons(selectedText) { try { console.log("🔎 Recherche dans mes lexiques :", selectedText); - const allDefinitions = await fetchLexiconDefinitions(selectedText); if (!allDefinitions || allDefinitions.length === 0) { console.log("⌠Aucun lexique trouvé pour ce mot."); @@ -177,21 +299,17 @@ async function searchInLexicons(selectedText) { }); return; } - const lexMap = new Map(); for (const def of allDefinitions) { if (def.lexiconId) { lexMap.set(def.lexiconId, def.source); } } - const foundInLexicons = []; for (const [id, name] of lexMap.entries()) { foundInLexicons.push({ id, name }); } - console.log("📩 Envoi du message 'showLexiconResult' avec :", foundInLexicons); - browser.runtime.sendMessage({ action: "showLexiconResult", lexicons: foundInLexicons, @@ -207,24 +325,3 @@ async function searchInLexicons(selectedText) { } } -/** - * 3) Ajouter un mot dans le lexique personnel. - */ -async function addWordToLexicon(selectedText) { - try { - console.log("🔠Ajout du mot à mon lexique :", selectedText); - alert(`(Exemple) Le mot "${selectedText}" a été ajouté à votre lexique personnel !`); - } catch (error) { - console.error("⌠Erreur lors de l'ajout au lexique :", error); - alert("⌠Impossible d'ajouter ce mot au lexique."); - } -} - -// ───────────────────────────────────────────────────────────────────────────── -// Écouteur interne pour d’autres messages éventuels -// ───────────────────────────────────────────────────────────────────────────── -browser.runtime.onMessage.addListener(async (message) => { - if (message.action === "getDefinitionAll") { - await getDefinition(message.selectedText); - } -});