diff --git a/resources/webview.js b/resources/webview.js index eb3499e..77bb259 100644 --- a/resources/webview.js +++ b/resources/webview.js @@ -1,7 +1,7 @@ let counter = 1; let results; // disable the context menu (eg. the right click menu) to have a more native feel -document.addEventListener("contextmenu", e => { +document.addEventListener("contextmenu", (e) => { e.preventDefault(); }); @@ -9,14 +9,16 @@ document.addEventListener("contextmenu", e => { document.getElementById("search").addEventListener("click", () => { counter = 1; const query = document.getElementById("query").value; - window.postMessage("search", query); + const fuzzy = document.getElementById("fuzzy").checked; + window.postMessage("search", { query, searchOptions: fuzzy }); }); -document.getElementById("search-form").addEventListener("submit", e => { +document.getElementById("search-form").addEventListener("submit", (e) => { e.preventDefault(); counter = 1; const query = document.getElementById("query").value; - window.postMessage("search", query); + const fuzzy = document.getElementById("fuzzy").checked; + window.postMessage("search", { query, searchOptions: { fuzzy } }); }); // call the plugin from the webview @@ -26,13 +28,33 @@ document.getElementById("search-next").addEventListener("click", () => { window.postMessage("searchNext", results[counter - 1]); document.getElementById("counter").innerHTML = counter; } - if (counter === results.length) { - document.getElementById("search-next").style.display = "none"; + renderSearchResultsButton(); +}); + +document.getElementById("search-prev").addEventListener("click", () => { + counter -= 1; + if (counter <= results.length) { + window.postMessage("searchNext", results[counter - 1]); + document.getElementById("counter").innerHTML = counter; } + renderSearchResultsButton(); }); +const renderSearchResultsButton = () => { + if (counter === 1) { + document.getElementById("search-prev").disabled = true; + } else { + document.getElementById("search-prev").disabled = false; + } + if (counter === results.length) { + document.getElementById("search-next").disabled = true; + } else { + document.getElementById("search-next").disabled = false; + } +}; + // search results -window.saveResults = res => { +window.saveResults = (res) => { results = JSON.parse(JSON.stringify(res)); if (!results.length) { document.getElementById("result").style.display = "none"; @@ -41,11 +63,14 @@ window.saveResults = res => { document.getElementById("counter").innerHTML = counter; document.getElementById("results-length").innerHTML = results.length; document.getElementById("search-next").style.display = "initial"; + document.getElementById("search-next").disabled = false; + document.getElementById("search-prev").style.display = "initial"; + document.getElementById("search-prev").disabled = true; } }; // load theme -window.loadThemeInfo = theme => { +window.loadThemeInfo = (theme) => { if (theme === "dark") { document.querySelector("body").setAttribute("data-theme", "dark"); } diff --git a/src/my-command.js b/src/my-command.js index 93085d8..53dc482 100644 --- a/src/my-command.js +++ b/src/my-command.js @@ -16,7 +16,26 @@ const selectResult = (document, id) => { document.centerOnLayer(layer); }; -export default function() { +const checkTextLayer = (layer) => { + // TextLayer + if (layer.text) { + return true; + } + return false; +}; + +const searchLayers = (layer, textLayers) => { + if (checkTextLayer(layer)) { + textLayers.push(layer); + } + if (layer.layers && layer.layers.length) { + for (const layer of layer.layers) { + searchLayers(layer, textLayers); + } + } +}; + +export default function () { const options = { identifier: webviewIdentifier, width: 520, @@ -54,17 +73,25 @@ export default function() { }); // handler: log - webContents.on("log", query => { + webContents.on("log", (query) => { console.log("log: ", query); }); // handler: search - webContents.on("search", query => { + webContents.on("search", ({ query, searchOptions }) => { UI.message("Searching for " + query); + console.log("@searchOptions", searchOptions); console.log(query, " searching"); const document = sketch.Document.getSelectedDocument(); const selectedPage = document.selectedPage; const layers = selectedPage.layers; + console.log(layers.length); + // browserWindow.setBounds({ height: 400 }); + + const textLayers = []; + for (const layer of layers) { + searchLayers(layer, textLayers); + } const options = { shouldSort: true, threshold: 0.8, @@ -72,19 +99,26 @@ export default function() { distance: 100, maxPatternLength: 32, minMatchCharLength: 1, - keys: ["text"] + useExtendedSearch: true, + keys: ["text"], }; - const fuse = new Fuse(layers, options); - const result = fuse.search(query); - selectResult(document, result[0].id); - const resultIds = result.map(res => res.id); + const fuse = new Fuse(textLayers, options); + let searchQuery = `'${query}`; + if (searchOptions.fuzzy) { + searchQuery = query; + } + const result = fuse.search(searchQuery); + console.log("@result", result); + selectResult(document, result[0].item.id); + const resultIds = result.map((res) => res.item.id); + console.log("@resultIds", resultIds); webContents .executeJavaScript(`saveResults(${JSON.stringify(resultIds)})`) .catch(console.error); }); // handler: searchNext - webContents.on("searchNext", id => { + webContents.on("searchNext", (id) => { UI.message("Searching id " + id); const document = sketch.Document.getSelectedDocument(); selectResult(document, id);