From 7e205215fe0446526f7418f7cde20b3f2c7fe145 Mon Sep 17 00:00:00 2001 From: Paul-Louis NECH Date: Sun, 3 Dec 2023 12:16:18 +0100 Subject: [PATCH 1/4] feat(search): MVP --- lib/sound-browser.js | 48 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 2 deletions(-) diff --git a/lib/sound-browser.js b/lib/sound-browser.js index 87f55dd..b2ef5c7 100644 --- a/lib/sound-browser.js +++ b/lib/sound-browser.js @@ -15,6 +15,8 @@ export default class SoundBrowser { this.browser.classList.add('atom-sound-browser') this.browser.style.overflowY = 'scroll' + this.initSearch() + let trees = soundFolders .map(folder => { let tree = dirTree(folder, { @@ -50,7 +52,7 @@ export default class SoundBrowser { if (tree.type === 'directory') { element.textContent = tree.name - element.classList.add('icon', 'icon-open') + element.classList.add('icon', 'icon-open', 'tidal-dir') let directoryElement = document.createElement('ul') element.onclick = _ => { @@ -67,7 +69,7 @@ export default class SoundBrowser { let dirName = path.basename(path.dirname(tree.path)) let filename = path.basename(tree.path, path.extname(tree.path)) element.textContent = `${dirName}:${number} / ${filename}` - element.classList.add('icon', 'icon-speaker') + element.classList.add('icon', 'icon-speaker', 'tidal-sample') let audioIcon = document.createElement('span'); element.appendChild(audioIcon); @@ -118,6 +120,48 @@ export default class SoundBrowser { element.classList.remove('icon-speaker'); } + initSearch() { + + this.searchBox = document.createElement("input") + this.searchBox.type = "text" + this.searchBox.id = "search" + this.searchBox.classList.add("searchBox") + this.searchBox.style.backgroundColor= "#333" + + let searchText = "" + + const filterElement = function(element, searchText) { + const dir = element.parentNode.previousSibling + const rootDir = element.parentNode.parentNode.previousSibling + searchText = searchText.toLowerCase().trim() + let weight = "normal" + + if (searchText.length != 0) { + var selected = element.innerText.toLowerCase().includes(searchText) + weight = selected ? "bold" : "lighter" + + if (selected) { + console.log(`Matched ${element.innerText}! (${dir.innerText})`) + } + } + element.style.fontWeight = weight + dir.style.fontWeight = weight + rootDir.style.fontWeight = weight + } + + const onchange = function(e) { + this.searchText = e.target.value + let samples = document.getElementsByClassName("tidal-sample") + let dirs = document.getElementsByClassName("tidal-dir") + Array.from(samples).forEach((sample) => filterElement(sample, this.searchText)) + } + + this.searchBox.addEventListener('input', onchange); + this.searchBox.addEventListener('propertychange', onchange); + + this.browser.appendChild(this.searchBox) + } + toggleDisplay(parent, element) { parent.classList.toggle('icon-open'); parent.classList.toggle('icon-close'); From a4bf27a8b233dc0dbb66e61202326f24b680bc5f Mon Sep 17 00:00:00 2001 From: Paul-Louis NECH Date: Sun, 3 Dec 2023 13:10:47 +0100 Subject: [PATCH 2/4] feat(search): Filter folder, WIP --- lib/sound-browser.js | 37 ++++++++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/lib/sound-browser.js b/lib/sound-browser.js index b2ef5c7..e481ee6 100644 --- a/lib/sound-browser.js +++ b/lib/sound-browser.js @@ -130,30 +130,57 @@ export default class SoundBrowser { let searchText = "" - const filterElement = function(element, searchText) { + const filterElement = function(element, searchText, folders) { const dir = element.parentNode.previousSibling const rootDir = element.parentNode.parentNode.previousSibling searchText = searchText.toLowerCase().trim() + let display = "block" let weight = "normal" if (searchText.length != 0) { var selected = element.innerText.toLowerCase().includes(searchText) - weight = selected ? "bold" : "lighter" + display = selected ? "block" : "none" + weight = selected ? "bold": "normal" if (selected) { - console.log(`Matched ${element.innerText}! (${dir.innerText})`) + console.log(`Matched ${element.innerText}! (${dir.innerText}) -> ${display}/${weight}`) } } + element.style.display = display element.style.fontWeight = weight + dir.style.display = display dir.style.fontWeight = weight rootDir.style.fontWeight = weight } + const filterEmptyDir = (dir) => { + console.log(dir) + } + + function debounce(func, timeout = 300){ + let timer; + return (...args) => { + clearTimeout(timer); + timer = setTimeout(() => { + console.log("TIMEOUT"); + func.apply(this, args); + }, timeout); + }; + } + + // const processChange = debounce(() => saveInput()); + const onchange = function(e) { - this.searchText = e.target.value + searchText = e.target.value + console.log(searchText) let samples = document.getElementsByClassName("tidal-sample") let dirs = document.getElementsByClassName("tidal-dir") - Array.from(samples).forEach((sample) => filterElement(sample, this.searchText)) + Array.from(samples).forEach( + (sample) => filterElement(sample, searchText, this.soundFolders) + ) + Array.from(dirs).forEach( + (dir) => filterEmptyDir(dir) + ) } this.searchBox.addEventListener('input', onchange); From d065a25d10dbf23bef58649d1fee015a2e41b2fb Mon Sep 17 00:00:00 2001 From: Paul-Louis NECH Date: Sun, 1 Sep 2024 15:24:20 +0200 Subject: [PATCH 3/4] wip(search): Timings, button --- lib/sound-browser.js | 61 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 49 insertions(+), 12 deletions(-) diff --git a/lib/sound-browser.js b/lib/sound-browser.js index e481ee6..7a53d23 100644 --- a/lib/sound-browser.js +++ b/lib/sound-browser.js @@ -15,7 +15,9 @@ export default class SoundBrowser { this.browser.classList.add('atom-sound-browser') this.browser.style.overflowY = 'scroll' + console.time("Init Search"); this.initSearch() + console.timeEnd("Init Search"); let trees = soundFolders .map(folder => { @@ -34,12 +36,14 @@ export default class SoundBrowser { if (trees.length > 0) { trees.forEach(tree => this.render(this.browser, tree, 0)) + console.time("OpenWS"); atom.workspace.open({ element: this.browser, getTitle: () => 'Sound Browser', getURI: () => 'atom://tidalcycles/sound-browser', getDefaultLocation: () => 'left' }, { activatePane: false }); + console.timeEnd("OpenWS"); } } @@ -125,10 +129,21 @@ export default class SoundBrowser { this.searchBox = document.createElement("input") this.searchBox.type = "text" this.searchBox.id = "search" + this.searchBox.placeholder = "Search your Samples" this.searchBox.classList.add("searchBox") this.searchBox.style.backgroundColor= "#333" - let searchText = "" + this.clearButton = document.createElement("button") + this.clearButton.type = "button" + this.clearButton.style.cursor = "pointer" + this.clearButton.style.backgroundColor = "#046DAA;" + this.clearButton.style.padding = "5px" + this.clearButton.textContent = "[X]" + + // this.clearButton.onClick = (this.searchBox) => { + // searchBox.textContent = "" + // console.log("Reset query.") + // } const filterElement = function(element, searchText, folders) { const dir = element.parentNode.previousSibling @@ -138,13 +153,13 @@ export default class SoundBrowser { let weight = "normal" if (searchText.length != 0) { - var selected = element.innerText.toLowerCase().includes(searchText) - display = selected ? "block" : "none" - weight = selected ? "bold": "normal" + var isMatch = element.innerText.toLowerCase().includes(searchText) + display = isMatch ? "block" : "none" + weight = isMatch ? "bold": "normal" - if (selected) { - console.log(`Matched ${element.innerText}! (${dir.innerText}) -> ${display}/${weight}`) - } + // if (selected) { + // console.log(`Matched ${element.innerText}! (${dir.innerText}) -> ${display}/${weight}`) + // } } element.style.display = display element.style.fontWeight = weight @@ -154,9 +169,17 @@ export default class SoundBrowser { } const filterEmptyDir = (dir) => { - console.log(dir) + if (dir.children.length > 0) { + console.log("Dir ", dir.innerText, ":", dir.classList, " has ", dir.children.length, " children:"); + for (var i=0;i { @@ -167,20 +190,34 @@ export default class SoundBrowser { }, timeout); }; } - // const processChange = debounce(() => saveInput()); const onchange = function(e) { - searchText = e.target.value - console.log(searchText) + let searchText = e.target.value let samples = document.getElementsByClassName("tidal-sample") let dirs = document.getElementsByClassName("tidal-dir") + console.log("Q: ", searchText, "L(D)=", dirs.length, "L(S)=", samples.length); + if (searchText.length < 2) { + console.error("DEBOUNCE: Ignoring tiny query ", searchText, ".") + return + } + console.time('samples'); Array.from(samples).forEach( (sample) => filterElement(sample, searchText, this.soundFolders) ) + console.timeEnd('samples'); + console.time('dirs'); + var printed=0; Array.from(dirs).forEach( - (dir) => filterEmptyDir(dir) + (dir) => { + if (printed++ < 3) { + console.log(`Processing ${dir}...`); + console.log(dir); + } + filterEmptyDir(dir) + } ) + console.timeEnd('dirs'); } this.searchBox.addEventListener('input', onchange); From 10ebd4082c18d6a8d84c279bfd4e6fc1b029374c Mon Sep 17 00:00:00 2001 From: Paul-Louis NECH Date: Sun, 1 Sep 2024 16:41:24 +0200 Subject: [PATCH 4/4] chore: Comment out some debug prints --- lib/sound-browser.js | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/lib/sound-browser.js b/lib/sound-browser.js index 7a53d23..51a3a48 100644 --- a/lib/sound-browser.js +++ b/lib/sound-browser.js @@ -196,8 +196,9 @@ export default class SoundBrowser { let searchText = e.target.value let samples = document.getElementsByClassName("tidal-sample") let dirs = document.getElementsByClassName("tidal-dir") - console.log("Q: ", searchText, "L(D)=", dirs.length, "L(S)=", samples.length); - if (searchText.length < 2) { + // DEBUG PRINT: Helps see when query is received + // console.log("Q: ", searchText, "L(D)=", dirs.length, "L(S)=", samples.length); + if (searchText.length < 2 && searchText != " ") { console.error("DEBOUNCE: Ignoring tiny query ", searchText, ".") return } @@ -207,13 +208,13 @@ export default class SoundBrowser { ) console.timeEnd('samples'); console.time('dirs'); - var printed=0; + // var printed=0; Array.from(dirs).forEach( (dir) => { - if (printed++ < 3) { - console.log(`Processing ${dir}...`); - console.log(dir); - } + // if (printed++ < 3) { + // console.log(`Processing ${dir}...`); + // console.log(dir); + // } filterEmptyDir(dir) } )