Added search by voice input

This commit is contained in:
Eduard Urbach 2018-04-20 20:16:59 +02:00
parent 43d4452554
commit 16cc544314
4 changed files with 159 additions and 2 deletions

View File

@ -21,6 +21,8 @@ component Sidebar(user *arn.User)
.sidebar-button
Icon("search")
FuzzySearch
.speech-input.action(data-action="searchBySpeech", data-trigger="click", title="Voice input")
RawIcon("microphone")
//- Sidebar buttons
if user != nil

View File

@ -102,3 +102,16 @@ const sidebar-spacing-y = 0.7rem
background badge-important-hover-bg-color
color badge-important-text-color
text-shadow none
// Microphone icon
.speech-input
opacity 0.5
default-transition
:hover
cursor pointer
opacity 1
.speech-listening
color link-hover-color
opacity 1

View File

@ -34,8 +34,8 @@ const fetchOptions: RequestInit = {
}
// Search
export async function search(arn: AnimeNotifier, search: HTMLInputElement, e: KeyboardEvent) {
if(e.ctrlKey || e.altKey) {
export async function search(arn: AnimeNotifier, search: HTMLInputElement, evt?: KeyboardEvent) {
if(evt && (evt.ctrlKey || evt.altKey)) {
return
}
@ -177,3 +177,49 @@ export function showSearchResults(arn: AnimeNotifier, element: HTMLElement) {
arn.mountMountables(findAllInside("mountable", element))
arn.assignTooltipOffsets(findAllInside("tip", element))
}
export function searchBySpeech(arn: AnimeNotifier, element: HTMLElement) {
let searchInput = document.getElementById("search") as HTMLInputElement
let oldPlaceholder = searchInput.placeholder
let SpeechRecognition: SpeechRecognitionStatic = (window["SpeechRecognition"] || window["webkitSpeechRecognition"])
let recognition = new SpeechRecognition()
recognition.continuous = false
recognition.interimResults = false
recognition.lang = "en-US"
recognition.onresult = evt => {
if(evt.results.length > 0) {
let result = evt.results.item(0).item(0)
let term = result.transcript
if(term !== "") {
searchInput.value = term
arn.sideBar.hide()
search(arn, searchInput)
}
}
recognition.stop()
}
recognition.onerror = e => {
recognition.stop()
}
recognition.onend = e => {
searchInput.placeholder = oldPlaceholder
element.classList.remove("speech-listening")
}
// Focus search field
searchInput.placeholder = "Listening..."
searchInput.value = ""
searchInput.focus()
searchInput.select()
// Highlight microphone icon
element.classList.add("speech-listening")
// Start voice recognition
recognition.start()
}

96
scripts/Types/WebSpeechAPI.d.ts vendored Normal file
View File

@ -0,0 +1,96 @@
// Type definitions for Web Speech API
// Project: https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html
// Definitions by: SaschaNaz <https://github.com/saschanaz>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
// TypeScript Version: 2.2
// Spec version: 19 October 2012
// Errata version: 6 June 2014
// Corrected unofficial spec version: 6 June 2014
interface SpeechRecognition extends EventTarget {
grammars: SpeechGrammarList;
lang: string;
continuous: boolean;
interimResults: boolean;
maxAlternatives: number;
serviceURI: string;
start(): void;
stop(): void;
abort(): void;
onaudiostart: (ev: Event) => any;
onsoundstart: (ev: Event) => any;
onspeechstart: (ev: Event) => any;
onspeechend: (ev: Event) => any;
onsoundend: (ev: Event) => any;
onaudioend: (ev: Event) => any;
onresult: (ev: SpeechRecognitionEvent) => any;
onnomatch: (ev: SpeechRecognitionEvent) => any;
onerror: (ev: SpeechRecognitionError) => any;
onstart: (ev: Event) => any;
onend: (ev: Event) => any;
}
interface SpeechRecognitionStatic {
prototype: SpeechRecognition;
new (): SpeechRecognition;
}
declare var SpeechRecognition: SpeechRecognitionStatic;
declare var webkitSpeechRecognition: SpeechRecognitionStatic;
interface SpeechRecognitionError extends Event {
error: string;
message: string;
}
interface SpeechRecognitionAlternative {
transcript: string;
confidence: number;
}
interface SpeechRecognitionResult {
length: number;
item(index: number): SpeechRecognitionAlternative;
[index: number]: SpeechRecognitionAlternative;
/* Errata 02 */
isFinal: boolean;
}
interface SpeechRecognitionResultList {
length: number;
item(index: number): SpeechRecognitionResult;
[index: number]: SpeechRecognitionResult;
}
interface SpeechRecognitionEvent extends Event {
resultIndex: number;
results: SpeechRecognitionResultList;
interpretation: any;
emma: Document;
}
interface SpeechGrammar {
src: string;
weight: number;
}
interface SpeechGrammarStatic {
prototype: SpeechGrammar;
new (): SpeechGrammar;
}
declare var SpeechGrammar: SpeechGrammarStatic;
declare var webkitSpeechGrammar: SpeechGrammarStatic;
interface SpeechGrammarList {
length: number;
item(index: number): SpeechGrammar;
[index: number]: SpeechGrammar;
addFromURI(src: string, weight: number): void;
addFromString(string: string, weight: number): void;
}
interface SpeechGrammarListStatic {
prototype: SpeechGrammarList;
new (): SpeechGrammarList;
}
declare var SpeechGrammarList: SpeechGrammarListStatic;
declare var webkitSpeechGrammarList: SpeechGrammarListStatic;