Added search by voice input
This commit is contained in:
parent
43d4452554
commit
16cc544314
@ -21,6 +21,8 @@ component Sidebar(user *arn.User)
|
|||||||
.sidebar-button
|
.sidebar-button
|
||||||
Icon("search")
|
Icon("search")
|
||||||
FuzzySearch
|
FuzzySearch
|
||||||
|
.speech-input.action(data-action="searchBySpeech", data-trigger="click", title="Voice input")
|
||||||
|
RawIcon("microphone")
|
||||||
|
|
||||||
//- Sidebar buttons
|
//- Sidebar buttons
|
||||||
if user != nil
|
if user != nil
|
||||||
|
@ -102,3 +102,16 @@ const sidebar-spacing-y = 0.7rem
|
|||||||
background badge-important-hover-bg-color
|
background badge-important-hover-bg-color
|
||||||
color badge-important-text-color
|
color badge-important-text-color
|
||||||
text-shadow none
|
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
|
||||||
|
@ -34,8 +34,8 @@ const fetchOptions: RequestInit = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Search
|
// Search
|
||||||
export async function search(arn: AnimeNotifier, search: HTMLInputElement, e: KeyboardEvent) {
|
export async function search(arn: AnimeNotifier, search: HTMLInputElement, evt?: KeyboardEvent) {
|
||||||
if(e.ctrlKey || e.altKey) {
|
if(evt && (evt.ctrlKey || evt.altKey)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,3 +177,49 @@ export function showSearchResults(arn: AnimeNotifier, element: HTMLElement) {
|
|||||||
arn.mountMountables(findAllInside("mountable", element))
|
arn.mountMountables(findAllInside("mountable", element))
|
||||||
arn.assignTooltipOffsets(findAllInside("tip", 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
96
scripts/Types/WebSpeechAPI.d.ts
vendored
Normal 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;
|
Loading…
Reference in New Issue
Block a user