@@ -37,6 +37,7 @@ let LOCATIONS, pagination,
3737 loadingTimeout ,
3838 LIST_MAP ;
3939
40+ let VERSION ;
4041let APPLICATION_LOADED = false ;
4142let LABELS = [ ] ,
4243 HISTORY = [ ] ;
@@ -49,10 +50,11 @@ window.addEventListener("unhandledrejection", function (event) {
4950
5051 // Track the unhandled promise rejection
5152 trackEvent (
52- config . UUID ,
53- "Unhandled UI PR" ,
54- errorMessage ,
55- customURLEncode ( stackTrace )
53+ { uuid :config . UUID ,
54+ event : "Unhandled UI PR" ,
55+ action : errorMessage ,
56+ name : customURLEncode ( stackTrace ) ,
57+ version : config . VERSION }
5658 ) ;
5759} ) ;
5860
@@ -64,10 +66,11 @@ window.addEventListener("rejectionhandled", function (event) {
6466
6567 // Track the unhandled promise rejection
6668 trackEvent (
67- config . UUID ,
68- "Handled UI PR" ,
69- errorMessage ,
70- customURLEncode ( stackTrace )
69+ { uuid :config . UUID ,
70+ event : "Handled UI PR" ,
71+ action : errorMessage ,
72+ name : customURLEncode ( stackTrace ) ,
73+ version : config . VERSION }
7174 ) ;
7275} ) ;
7376
@@ -346,7 +349,7 @@ window.electron.onFileOpen((filePath) => {
346349// Is this CI / playwright?
347350const isTestEnv = window . env . TEST_ENV === "true" ;
348351const trackVisit = isTestEnv ? ( ) => { } : _trackVisit ;
349- isTestEnv || installConsoleTracking ( ( ) => config . UUID , "UI" ) ;
352+ isTestEnv || installConsoleTracking ( ( ) => [ config . UUID , config . VERSION ] , "UI" ) ;
350353const trackEvent = isTestEnv ? ( ) => { } : _trackEvent ;
351354isTestEnv && console . log ( "Running in test environment" ) ;
352355
@@ -387,7 +390,6 @@ async function getPaths() {
387390 return [ appPath , tempPath , locale , dirname ] ;
388391}
389392
390- let VERSION ;
391393let DIAGNOSTICS = { } ;
392394
393395let appVersionLoaded = new Promise ( ( resolve , reject ) => {
@@ -441,7 +443,7 @@ DOM.controlsWrapper.addEventListener("mousedown", (e) => {
441443 // Remove event listener on mouseup
442444 const onMouseUp = ( ) => {
443445 document . removeEventListener ( "mousemove" , onMouseMove ) ;
444- trackEvent ( config . UUID , "Drag" , "Spec Resize" , newHeight ) ;
446+ trackEvent ( { uuid : config . UUID , event : "Drag" , action : "Spec Resize" , value : newHeight , version : config . VERSION } ) ;
445447 } ;
446448 // Attach event listeners for mousemove and mouseup
447449 document . addEventListener ( "mousemove" , onMouseMove ) ;
@@ -466,7 +468,7 @@ chartContainer.addEventListener("mousedown", (e) => {
466468 const onMouseUp = ( ) => {
467469 document . body . style . cursor = "default" ;
468470 document . removeEventListener ( "mousemove" , onMouseMove ) ;
469- trackEvent ( config . UUID , "Drag" , "Chart Resize" , newHeight ) ;
471+ trackEvent ( { uuid : config . UUID , event : "Drag" , action : "Chart Resize" , value : newHeight , version : config . VERSION } ) ;
470472 } ;
471473 // Attach event listeners for mousemove and mouseup
472474 document . addEventListener ( "mousemove" , onMouseMove ) ;
@@ -745,7 +747,7 @@ function showDatePicker() {
745747 start : timestamp ,
746748 refreshResults : STATE . analysisDone , // Only refresh results if analysis has already been done
747749 } ) ;
748- trackEvent ( config . UUID , "Settings Change" , "fileStart" , newStart ) ;
750+ trackEvent ( { uuid : config . UUID , event : "Settings Change" , action : "fileStart" , name : newStart , version : config . VERSION } ) ;
749751 resetResults ( ) ;
750752 STATE . fileStart = timestamp ;
751753 // Remove the form from the DOM
@@ -2054,10 +2056,7 @@ window.onload = async () => {
20542056 // Attach an error event listener to the window object
20552057 window . onerror = function ( message , file , lineno , colno , error ) {
20562058 trackEvent (
2057- config . UUID ,
2058- "Error" ,
2059- error . message ,
2060- encodeURIComponent ( error . stack )
2059+ { uuid : config . UUID , event : "Error" , action : error . message , name : encodeURIComponent ( error . stack ) , version : config . VERSION }
20612060 ) ;
20622061 // Return false not to inhibit the default error handling
20632062 return false ;
@@ -2129,6 +2128,7 @@ window.onload = async () => {
21292128 debug,
21302129 fileStartMtime,
21312130 specDetections,
2131+ VERSION
21322132 } ) ;
21332133 t0_warmup = Date . now ( ) ;
21342134 if ( isTestEnv ) {
@@ -3069,7 +3069,7 @@ function handleKeyDown(e) {
30693069 : e . metaKey
30703070 ? "Alt"
30713071 : "no" ;
3072- trackEvent ( config . UUID , "KeyPress" , action , modifier ) ;
3072+ trackEvent ( { uuid : config . UUID , event : "KeyPress" , action, name : modifier , version : config . VERSION } ) ;
30733073 GLOBAL_ACTIONS [ action ] ( e ) ;
30743074 } else {
30753075 GLOBAL_ACTIONS . handleNumberKeys ( e ) ;
@@ -3920,37 +3920,25 @@ function onAnalysisComplete({ quiet }) {
39203920 ? STATE . selection . end - STATE . selection . start
39213921 : DIAGNOSTICS [ "Audio Duration" ] ;
39223922 const rate = duration / parseFloat ( analysisTime ) ;
3923-
3923+ if ( rate > 10_000 ) return // must be a database fetch - skip the diagnostics which are only relevant to audio analysis
3924+ const backend = config . models [ config . selectedModel ] . backend ;
3925+ const event = `${ config . selectedModel } -${ backend } `
39243926 trackEvent (
3925- config . UUID ,
3926- `${ config . selectedModel } -${ config . models [ config . selectedModel ] . backend } ` ,
3927- "Audio Duration" ,
3928- config . models [ config . selectedModel ] . backend ,
3929- Math . round ( duration )
3927+ { uuid :config . UUID , event, action :"Audio Duration" , name : backend , value :Math . round ( duration ) , version : config . VERSION }
39303928 ) ;
3931-
39323929 if ( ! STATE . selection ) {
39333930 trackEvent (
3934- config . UUID ,
3935- `${ config . selectedModel } -${ config . models [ config . selectedModel ] . backend } ` ,
3936- "Analysis Rate" ,
3937- config . models [ config . selectedModel ] . backend ,
3938- parseInt ( rate )
3931+ { uuid : config . UUID , event, action : "Analysis Rate" , name : backend , value : parseInt ( rate ) , version : config . VERSION }
39393932 ) ;
39403933 trackEvent (
3941- config . UUID ,
3942- `${ config . selectedModel } -${ config . models [ config . selectedModel ] . backend } ` ,
3943- "Analysis Duration" ,
3944- config . models [ config . selectedModel ] . backend ,
3945- parseInt ( analysisTime )
3934+ { uuid : config . UUID , event, action : "Analysis Duration" , name : backend , value : parseInt ( analysisTime ) , version : config . VERSION }
39463935 ) ;
39473936 DIAGNOSTICS [ "Analysis Duration" ] = utils . formatDuration ( analysisTime ) ;
39483937 DIAGNOSTICS [ "Analysis Rate" ] =
39493938 rate . toFixed ( 0 ) + "x faster than real time performance." ;
39503939 generateToast ( { message : "complete" } ) ;
39513940 displayProgress ( { percent : 100 } ) ;
39523941 }
3953- worker . postMessage ( { action : "update-state" , selection : false } ) ;
39543942}
39553943
39563944function removeNoEntry ( ) {
@@ -5543,6 +5531,7 @@ async function handleUIClicks(e) {
55435531 break ;
55445532 }
55455533 case "clear-database-location" : {
5534+ if ( PREDICTING ) break ;
55465535 config . database . location = undefined ;
55475536 document . getElementById ( "database-location" ) . value = "" ;
55485537 worker . postMessage ( {
@@ -6143,7 +6132,7 @@ async function handleUIClicks(e) {
61436132 config . debug && console . log ( "clicked" , target ) ;
61446133 target &&
61456134 target !== "result1" &&
6146- trackEvent ( config . UUID , "UI" , "Click" , target ) ;
6135+ trackEvent ( { uuid : config . UUID , event : "UI" , action : "Click" , name : target , version : VERSION } ) ;
61476136} ;
61486137
61496138/**
@@ -6710,7 +6699,7 @@ document.addEventListener("change", async function (e) {
67106699 updatePrefs ( "config.json" , config ) ;
67116700 const value = element . type === "checkbox" ? element . checked : element . value ;
67126701 target === "fileStart" ||
6713- trackEvent ( config . UUID , "Settings Change" , target , value ) ;
6702+ trackEvent ( { uuid : config . UUID , event : "Settings Change" , action : target , value : value , version : VERSION } ) ;
67146703 }
67156704} ) ;
67166705
@@ -6830,7 +6819,7 @@ async function readLabels(labelFile, updating) {
68306819 refreshResults : STATE . analysisDone && STATE . mode !== 'chart' ,
68316820 member : STATE . isMember ,
68326821 } ) ;
6833- trackEvent ( config . UUID , "UI" , "Create" , "Custom list" , labels . length ) ;
6822+ trackEvent ( { uuid : config . UUID , event : "UI" , action : "Create" , name : "Custom list" , value : labels . length , version : VERSION } ) ;
68346823 } else {
68356824 LABELS = labels ;
68366825 worker . postMessage ( {
@@ -6909,9 +6898,7 @@ async function createContextMenu(e) {
69096898 return ;
69106899 } else if ( target . classList . contains ( "circle" ) || target . closest ( "thead" ) )
69116900 return ;
6912- let hideInSummary = "" ,
6913- hideInSelection = "" ,
6914- plural = "" ;
6901+ let hideInSummary = "" , hideInSelection = "" , disableWhenPredicting = "" , plural = "" ;
69156902 const inSummary = target . closest ( "#speciesFilter" ) ;
69166903 const resultContext = ! target . closest ( "#summaryTable" ) ;
69176904 if ( inSummary ) {
@@ -6920,6 +6907,7 @@ async function createContextMenu(e) {
69206907 } else if ( target . closest ( "#selectionResultTableBody" ) ) {
69216908 hideInSelection = "d-none" ;
69226909 }
6910+ if ( PREDICTING ) disableWhenPredicting = "disabled" ;
69236911 const hideFindSimilar = ( [ 'analyse' , 'archive' ] ) . includes ( STATE . mode ) && ! [ 'chirpity' , 'nocmig' ] . includes ( config . selectedModel ) ? '' : 'd-none' ;
69246912 // If we haven't clicked the active row or we cleared the region, load the row we clicked
69256913 if ( resultContext || hideInSelection || hideInSummary ) {
@@ -6942,36 +6930,28 @@ async function createContextMenu(e) {
69426930 DOM . contextMenu . innerHTML = `
69436931 <div id="${ inSummary ? "inSummary" : "inResults" } ">
69446932 <ul class="list-unstyled mb-1">
6945- <li class="dropdown-item ${ hideInSummary } " id="play-region"><span class='material-symbols-outlined'>play_circle</span> ${
6946- i18 . play
6947- } </li>
6948- <li class="dropdown-item ${ hideInSummary } ${ hideInSelection } " id="context-analyse-selection">
6949- <span class="material-symbols-outlined">search</span> ${ i18 . analyse }
6933+ <li class="dropdown-item ${ hideInSummary } " id="play-region"><span class='material-symbols-outlined'>play_circle</span> ${ i18 . play } </li>
6934+ <li class="dropdown-item ${ hideInSummary } ${ hideInSelection } ${ disableWhenPredicting } " id="context-analyse-selection">
6935+ <span class="material-symbols-outlined">search</span> ${ i18 . analyse }
69506936 </li>
6951- <li class="dropdown-item ${ hideFindSimilar } ${ hideInSummary } ${ hideInSelection } ${ disabled } " id="context-find-similar">
6952- <span class="material-symbols-outlined">search</span> ${ i18 . find }
6937+ <li class="dropdown-item ${ disableWhenPredicting } ${ hideFindSimilar } ${ hideInSummary } ${ hideInSelection } ${ disabled } " id="context-find-similar">
6938+ <span class="material-symbols-outlined">search</span> ${ i18 . find }
69536939 </li>
69546940 <div class="dropdown-divider ${ hideInSummary } "></div>
69556941 <li class="dropdown-item ${ hideInSelection } " id="create-manual-record">
6956- <span class="material-symbols-outlined">edit_document</span> ${ createOrEdit } ${
6957- i18 . record
6958- }
6942+ <span class="material-symbols-outlined">edit_document</span> ${ createOrEdit } ${ i18 . record }
69596943 </li>
69606944 <li class="dropdown-item" id="context-create-clip">
6961- <span class="material-symbols-outlined">music_note</span> ${ i18 . export }
6945+ <span class="material-symbols-outlined">music_note</span> ${ i18 . export }
69626946 </li>
6963- <span class="dropdown-item" id="context-xc" target="xc">
6964- <img src='img/logo/XC.png' alt='' style="filter:grayscale(100%);height: 1.5em"> ${
6965- i18 . compare
6966- }
6967- </span>
6947+ <span class="dropdown-item" id="context-xc" target="xc">
6948+ <img src='img/logo/XC.png' alt='' style="filter:grayscale(100%);height: 1.5em"> ${ i18 . compare }
6949+ </span>
69686950 <div class="dropdown-divider ${ hideInSelection } "></div>
69696951 <li class="dropdown-item ${ hideInSelection } " id="context-delete">
6970- <span class='delete material-symbols-outlined'>delete_forever</span> ${
6971- i18 . delete
6972- }
6952+ <span class='delete material-symbols-outlined'>delete_forever</span> ${ i18 . delete }
69736953 </li>
6974- </ul>
6954+ </ul>
69756955 </div>
69766956 ` ;
69776957 const modalTitle = document . getElementById ( "record-entry-modal-label" ) ;
@@ -7550,12 +7530,12 @@ async function getXCComparisons() {
75507530 const content = "Loading Xeno-Canto data..." ;
75517531 loadingFiles ( { hide :false , content} )
75527532 const bats = config . selectedModel . includes ( 'bats' ) ;
7553- const quality = " +q:%22>C%22" ;
7554- const defaultLength = bats ? " +len:0.5-10" : " +len:3-15";
7533+ const quality = ' +q:">C"' ;
7534+ const defaultLength = bats ? ' +len:" 0.5-10"' : ' +len:" 3-15"' ;
75557535 sname = XCtaxon [ sname ] || sname ;
75567536 const types = bats
7557- ? [ '" distress call" ' , '" feeding buzz" ' , '" social call" ' , 'ecolocation ' , 'song' ]
7558- : [ '" nocturnal flight call" ' , '" flight call" ' , 'call' , 'song' ] ;
7537+ ? [ 'distress call' , 'feeding buzz' , 'social call' , 'echolocation ' , 'song' ]
7538+ : [ 'nocturnal flight call' , 'flight call' , 'call' , 'song' ] ;
75597539 const filteredLists = { }
75607540 types . forEach ( ( type ) => {
75617541 filteredLists [ type ] = [ ] ; // Initialize each type with an empty array
@@ -7565,8 +7545,8 @@ async function getXCComparisons() {
75657545 const fetchRequests = types . map ( ( type ) => {
75667546 type = type . replaceAll ( " " , "%20" ) ; // Replace spaces with entities for the API query
75677547 // Use a different length parameter for "song"
7568- const typeLength = type === "song" ? " +len:10-30" : defaultLength ;
7569- const query = `https://xeno-canto.org/api/3/recordings?key=d5e2d2775c7f2b2fb8325ffacc41b9e6aa94679e&query=sp:"${ sname } "${ quality } ${ typeLength } +type:= ${ type } ` ;
7548+ const typeLength = type === "song" ? ' +len:" 10-30"' : defaultLength ;
7549+ const query = `https://xeno-canto.org/api/3/recordings?key=d5e2d2775c7f2b2fb8325ffacc41b9e6aa94679e&query=sp:"${ sname } "${ quality } ${ typeLength } +type:" ${ type } " ` ;
75707550
75717551 return fetch ( query )
75727552 . then ( ( response ) =>
@@ -8433,10 +8413,7 @@ function checkForIntelMacUpdates() {
84338413 "warning"
84348414 ) ;
84358415 trackEvent (
8436- config . UUID ,
8437- "Update message" ,
8438- `From ${ VERSION } ` ,
8439- `To: ${ latestVersion } `
8416+ { uuid :config . UUID , event : "Update message" , action : `From ${ VERSION } ` , name : `To: ${ latestVersion } ` , version : VERSION }
84408417 ) ;
84418418 }
84428419 config . lastUpdateCheck = latestCheck ;
0 commit comments