diff --git a/src/main.js b/src/main.js index 3f0f6824e4fdd54ca50941682ee96bce295ccde6..917fdaea24e97b736a4b0d4288f8dead67f7d32c 100644 --- a/src/main.js +++ b/src/main.js @@ -30,16 +30,16 @@ const navigation = { path: "/menu/call/emergency", message: "Calling Emergency", }, - contact1: { + contacta: { label: "Flute Inc.", - command: "contact A", - path: "/menu/call/contact1", + command: "contact a", + path: "/menu/call/contacta", message: "Calling Flute Inc.", }, - contact2: { + contactb: { label: "Brays AG", - command: "contact B", - path: "/menu/call/contact2", + command: "contact b", + path: "/menu/call/contactb", message: "Calling Brays AG", }, }, @@ -203,6 +203,10 @@ function buildPageContents(object) { const navigationEl = document.getElementById("navigation"); navigationEl.replaceChildren(listEl); + // dispatch custom event to listen for menu updates + const updated = new CustomEvent("updated"); + navigationEl.dispatchEvent(updated); + // auto select first item // focusNavigationItem(1); @@ -337,6 +341,16 @@ function addMouseControls() { } }); + // unfocus all items + appEl.addEventListener("mouseout", (event) => { + const listItem = event.target.closest("li.link"); + if (listItem) { + // unselect all items + const navigationList = document.querySelectorAll("#navigation li"); + for (let item of navigationList) delete item.dataset.selected; + } + }); + // select on mouseclick appEl.addEventListener("click", (event) => { event.preventDefault(); @@ -370,10 +384,8 @@ function addButtonControls() { event.code === "ArrowRight" || event.code === "ArrowDown" || event.code === "ArrowLeft" - ) { + ) event.preventDefault(); - printLogMsg("key: " + event.code); - } // browsing navigation items if (event.code === "Tab" || event.code === "ArrowDown") @@ -425,23 +437,23 @@ function addButtonControls() { // add voice controls // =================== function addVoiceControls() { + // voice controls only work on google chrome! var SpeechRecognition = SpeechRecognition || webkitSpeechRecognition; var SpeechGrammarList = SpeechGrammarList || window.webkitSpeechGrammarList; var SpeechRecognitionEvent = SpeechRecognitionEvent || webkitSpeechRecognitionEvent; - var commands = [ - "menu", - "call", - "check", - "apps", - "open", - "back", - "close", - "exit", - ]; - - var recognition = new SpeechRecognition(); + let availableCommands = []; + let commands = []; + updateVoiceCommandList(); + + // listen for menu updates and refresh commands list + const navigationEl = document.getElementById("navigation"); + navigationEl.addEventListener("updated", (event) => { + updateVoiceCommandList(); + }); + + let recognition = new SpeechRecognition(); if (SpeechGrammarList) { var speechRecognitionList = new SpeechGrammarList(); var grammar = @@ -449,7 +461,7 @@ function addVoiceControls() { commands.join(" | ") + " ;"; speechRecognitionList.addFromString(grammar, 1); - recognition.grammars = speechRecognitionList; + // recognition.grammars = speechRecognitionList; } recognition.continuous = false; recognition.lang = "en-US"; @@ -457,39 +469,56 @@ function addVoiceControls() { recognition.maxAlternatives = 1; recognition.start(); - printLogMsg("recognition started"); + printLogMsg("Voice > listening"); recognition.onresult = function (event) { - let command = event.results[0][0].transcript; + let command = event.results[0][0].transcript.toLowerCase(); let confidence = event.results[0][0].confidence; + command = command.toLowerCase(); + + printLogMsg(`Voice > Received "${command}" (${confidence.toFixed(2)})`); if (commands.includes(command)) { - printLogMsg("Received: " + command + ". Confidence: " + confidence); - - if (command === "menu") navigateToPath("/menu"); - else if (command === "call") navigateToPath("/menu/call"); - else if (command === "check") navigateToPath("/menu/check"); - else if (command === "apps") navigateToPath("/menu/apps"); - else if (command === "open") navigateToSelected(); - else if (command === "back" || command === "close") - moveUpNavigationLevel(); - else if (command === "exit") navigateToPath("/"); + let index = commands.indexOf(command); // get index of command in array + let path = availableCommands[index].path; // get corresponding path in availableCommands array + navigateToPath(path); } }; recognition.onspeechend = function () { recognition.stop(); - printLogMsg("recognition stopped"); setTimeout(() => { recognition.start(); - printLogMsg("recognition started"); - }, "1000"); + printLogMsg("Voice > listening"); + }, "500"); }; recognition.onnomatch = function (event) { printLogMsg("I didn't recognise that command."); }; + + // updating voice command list + function updateVoiceCommandList() { + // search and save currently available voice commands + availableCommands = []; + const listItems = document.querySelectorAll("a[data-command]"); + for (let item of listItems) { + let command = { + command: item.dataset.command, + path: item.getAttribute("href"), + }; + availableCommands.push(command); + } + + // add custom commands + availableCommands.push({ command: "exit", path: "/" }); + availableCommands.push({ command: "emergency call", path: "/menu/call/emergency" }); + + // form commands array for grammarlist + commands = availableCommands.map((x) => x.command); + printLogMsg(`Voice > Commands: [${commands}]`); + } } // printing messages on screen for debugging