thunderbird-patch-review

Easy-to-use patch review interface for Thunderbird

Contribute: ~marcc/thunderbird-review-plugin@lists.sr.ht

git clone git://mccd.space/thunderbird-patch-review

options.js (2815B)

      1 "use strict";
      2 
      3 const tbody = document.querySelector("#mappings tbody");
      4 
      5 function addRow(match = "", repo = "") {
      6   const tr = document.createElement("tr");
      7 
      8   const matchTd = document.createElement("td");
      9   matchTd.className = "match";
     10   const matchInput = document.createElement("input");
     11   matchInput.type = "text";
     12   matchInput.placeholder = "list-id or sender contains…";
     13   matchInput.value = match;
     14   matchTd.appendChild(matchInput);
     15 
     16   const repoTd = document.createElement("td");
     17   const repoInput = document.createElement("input");
     18   repoInput.type = "text";
     19   repoInput.placeholder = "/absolute/path/to/repo";
     20   repoInput.value = repo;
     21   repoTd.appendChild(repoInput);
     22 
     23   const browseTd = document.createElement("td");
     24   browseTd.className = "remove";
     25   const browseBtn = document.createElement("button");
     26   browseBtn.textContent = "…";
     27   browseBtn.title = "Browse for the repository directory";
     28   browseBtn.addEventListener("click", async () => {
     29     const response = await messenger.runtime.sendMessage({
     30       type: "pick-repo",
     31       start: repoInput.value.trim(),
     32     });
     33     if (response && response.ok && response.output) {
     34       repoInput.value = response.output.replace(/(.)\/$/, "$1");
     35     }
     36   });
     37   browseTd.appendChild(browseBtn);
     38 
     39   const removeTd = document.createElement("td");
     40   removeTd.className = "remove";
     41   const removeBtn = document.createElement("button");
     42   removeBtn.textContent = "✕";
     43   removeBtn.title = "Remove";
     44   removeBtn.addEventListener("click", () => tr.remove());
     45   removeTd.appendChild(removeBtn);
     46 
     47   tr.append(matchTd, repoTd, browseTd, removeTd);
     48   tbody.appendChild(tr);
     49 }
     50 
     51 async function load() {
     52   const found = await messenger.storage.local.get("config");
     53   const config = Object.assign({ editor: "", strategy: "am3", mappings: [] }, found.config);
     54   document.querySelector("#editor").value = config.editor;
     55   document.querySelector("#strategy").value = config.strategy;
     56   for (const mapping of config.mappings) {
     57     addRow(mapping.match, mapping.repo);
     58   }
     59   if (!config.mappings.length) {
     60     addRow();
     61   }
     62 }
     63 
     64 document.querySelector("#add").addEventListener("click", () => addRow());
     65 
     66 document.querySelector("#save").addEventListener("click", async () => {
     67   const mappings = [...tbody.querySelectorAll("tr")]
     68     .map((tr) => {
     69       const [match, repo] = [...tr.querySelectorAll("input")].map((el) => el.value.trim());
     70       return { match, repo };
     71     })
     72     .filter((mapping) => mapping.match && mapping.repo);
     73 
     74   await messenger.storage.local.set({
     75     config: {
     76       editor: document.querySelector("#editor").value.trim(),
     77       strategy: document.querySelector("#strategy").value,
     78       mappings,
     79     },
     80   });
     81   const saved = document.querySelector("#saved");
     82   saved.hidden = false;
     83   setTimeout(() => (saved.hidden = true), 1500);
     84 });
     85 
     86 load();