From d8c7db0170ad6db8e176996b3c9d19bd8aa886ec Mon Sep 17 00:00:00 2001 From: Mattk70 Date: Wed, 16 Mar 2022 15:47:58 +0000 Subject: [PATCH] Species exclude filter & spinners for long execution time --- js/ui.js | 172 ++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 126 insertions(+), 46 deletions(-) diff --git a/js/ui.js b/js/ui.js index e50bb68f..cfc1cec9 100644 --- a/js/ui.js +++ b/js/ui.js @@ -34,7 +34,8 @@ let completeDiv = $('.complete'); const resultTable = $('#resultTableBody') const modalTable = $('#modalBody'); const feedbackTable = $('#feedbackModalBody'); -let predictions = {}, correctedSpecies, speciesListItems, action, clickedNode, clickedIndex, speciesName; +let predictions = {}, correctedSpecies, speciesListItems, action, clickedNode, + clickedIndex, speciesName, speciesFilter, speciesExclude, subRows, scrolled; let currentBuffer, bufferBegin = 0, windowLength = 20; // seconds let workerLoaded = false; @@ -399,11 +400,6 @@ function disableMenuItem(id) { $('#' + id).addClass('disabled'); } -function toggleAlternates(row) { - $(row).toggle('slow'); - return false -} - function showElement(id, makeFlex = true, empty = false) { const thisElement = $('#' + id); thisElement.removeClass('d-none'); @@ -1059,6 +1055,7 @@ ipcRenderer.on('progress', async (event, arg) => { }); ipcRenderer.on('prediction-done', async (event, arg) => { + scrolled = false; AUDACITY_LABELS = arg.labels; progressDiv.hide(); progressBar.width(0 + '%'); @@ -1092,40 +1089,95 @@ ipcRenderer.on('prediction-done', async (event, arg) => { let summaryHTML = ` - + + `; for (const [key, value] of Object.entries(summarySorted)) { summaryHTML += ` - + + `; } summaryHTML += '
FilterFilterExclude Species Count
filter_alt + filter_alt + + clear + ${key} ${value}
'; modalTable.append(summaryHTML); + speciesName = document.querySelectorAll('.cname'); + subRows = document.querySelectorAll('.subrow') + const materialIcons = document.querySelectorAll('.rotate') + speciesFilter = document.querySelectorAll('.speciesFilter'); + speciesExclude = document.querySelectorAll('.speciesExclude'); + + $(document).on('click', '.speciesExclude', function (e) { + const spinner = e.target.parentNode.firstChild.classList; + spinner.remove('d-none'); + const targetClass = e.target.classList; + targetClass.add('d-none'); + if (targetClass.contains('text-danger')) { + targetClass.remove('text-danger') + const setDelay = setTimeout(matchSpecies, 10, e, 'unfilter'); + } else { + targetClass.add('text-danger'); + const setDelay = setTimeout(matchSpecies, 1, e, 'exclude'); + } + e.stopImmediatePropagation(); + }); $(document).on('click', '.speciesFilter', function (e) { - const speciesName = document.querySelectorAll('.cname'); - if (e.target.classList.contains('text-success')) { - e.target.classList.remove('text-success') - speciesName.forEach(function(el){ - el.parentNode.classList.remove('d-none') + const spinner = e.target.parentNode.firstChild.classList; + // Remove any exclusion from the species to filter + e.target.parentNode.nextElementSibling.children[1].classList.remove('text-danger'); + const targetClass = e.target.classList; + if (targetClass.contains('text-success')) { + // Clicked on filtered species icon + targetClass.remove('text-success') + speciesExclude.forEach(function (el) { + el.classList.remove('text-danger'); }) - } else { - $('.speciesFilter').removeClass('text-success'); - e.target.classList.add('text-success'); speciesName.forEach(function (el) { el.parentNode.classList.remove('d-none') - if (el.innerText !== e.target.id) { - el.parentNode.classList.add('d-none') - } - }); + }) + } else { + // Clicked on unfiltered species icon + speciesFilter.forEach(function (el) { + el.classList.remove('text-success'); + }) + // Hide open subrows + subRows.forEach(function (el) { + el.classList.add('d-none'); + }) + // Flip open icon back up + materialIcons.forEach(function (el) { + el.classList.remove('down'); + }) + targetClass.add('text-success'); + targetClass.add('d-none'); + spinner.remove('d-none'); + // Allow spinner to show + const setDelay = setTimeout(matchSpecies, 1, e, 'include'); } e.stopImmediatePropagation(); }); }); +function matchSpecies(e, mode) { + const spinner = e.target.parentNode.firstChild.classList; + const targetClass = e.target.classList; + speciesName.forEach(function (el) { + const classes = el.parentNode.classList; + if (el.innerText === e.target.id) { + (mode === 'include' || mode === 'unfilter') ? classes.remove('d-none') : classes.add('d-none') + } else if (mode === 'include') classes.add('d-none') + }) + spinner.add('d-none'); + targetClass.remove('d-none'); +} + ipcRenderer.on('prediction-ongoing', async (event, arg) => { completeDiv.hide(); const result = arg.result; @@ -1154,16 +1206,16 @@ ipcRenderer.on('prediction-ongoing', async (event, arg) => { } else { summary[result.cname] = 1 } - +//onclick='toggleAlternates("${index}")' const regex = /:/g; const start = result.start, end = result.end; result.filename = result.cname.replace(/'/g, "\\'") + ' ' + result.timestamp.replace(regex, '.') + '.mp3'; tr += `${index}`; - tr += "expand_more"; tr += "" + result.timestamp + ""; tr += "" + result.cname + ""; tr += "" + result.sname + ""; tr += "" + iconizeScore(result.score) + ""; + tr += `expand_more`; tr += "play_circle_filled"; tr += ` Search ${result.cname} on Xeno Canto` @@ -1172,42 +1224,62 @@ ipcRenderer.on('prediction-ongoing', async (event, arg) => { tr += ` thumb_up_alt thumb_down_alt`; tr += ""; - - tr += " "; - tr += " "; - tr += " "; - tr += "" + result.cname2 + ""; - tr += "" + result.sname2 + ""; - tr += "" + iconizeScore(result.score2) + ""; - tr += " "; - tr += ` + if (result.score2 > 0.2) { + tr += `${index}`; + tr += " "; + tr += "" + result.cname2 + ""; + tr += "" + result.sname2 + ""; + tr += "" + iconizeScore(result.score2) + ""; + tr += " "; + tr += " "; + tr += ` Search ${result.cname2} on Xeno Canto `; - tr += ""; - - tr += " "; - tr += " "; - tr += " "; - tr += "" + result.cname3 + ""; - tr += "" + result.sname3 + ""; - tr += "" + iconizeScore(result.score3) + ""; - tr += " "; - tr += ` + tr += " "; + tr += " "; + tr += ""; + if (result.score3 > 0.2) { + tr += `${index}`; + tr += " "; + tr += "" + result.cname3 + ""; + tr += "" + result.sname3 + ""; + tr += "" + iconizeScore(result.score3) + ""; + tr += " "; + tr += " "; + tr += ` Search ${result.cname3} on Xeno Canto `; - tr += " "; - tr += ""; + tr += " "; + tr += " "; + tr += ""; + } + } } selection ? resultTable.prepend(tr) : resultTable.append(tr) - + const tableRows = document.querySelectorAll('#results tr'); + +// line is zero-based +// line is the row number that you want to see into view after scroll + if (!scrolled) { + tableRows[0].scrollIntoView({ + behavior: 'smooth', + block: 'nearest' + }) + scrolled = true + } + // Show the alternate detections toggle: + if (result.score2 > 0.2) { + document.getElementById(index).classList.remove('d-none') + } if (!config.spectrogram) $('.specFeature').hide(); - $(".material-icons").click(function () { + $(document).on('click', '.material-icons', function (e) { $(this).toggleClass("down"); }) let filterMode = null; const toprow = $('.top-row') - + speciesName = document.querySelectorAll('.cname'); $(document).on('click', '.filter', function (e) { if (!filterMode) { filterMode = 'low'; + $('.score.text-danger').parent().parent().hide(); e.target.classList.add('text-warning') } else if (filterMode === 'low') { @@ -1220,6 +1292,7 @@ ipcRenderer.on('prediction-ongoing', async (event, arg) => { $('.score').parent().parent('.top-row').show(); e.target.classList.remove('text-success'); } + e.stopImmediatePropagation(); }); $(document).on('click', '.download', function (e) { @@ -1248,6 +1321,13 @@ ipcRenderer.on('prediction-ongoing', async (event, arg) => { e.stopImmediatePropagation(); }); + $(document).on('click', '.rotate', function (e) { + const row1 = e.target.parentNode.parentNode.nextSibling; + const row2 = row1.nextSibling; + row1.classList.toggle('d-none') + if (!row2.classList.contains('top-row')) row2.classList.toggle('d-none') + e.stopImmediatePropagation(); + }) toprow.click(function () { toprow.each(function () {