Skip to content

Commit

Permalink
fix(useSpeechRecognition): reactive speech language (vitest-dev#741)
Browse files Browse the repository at this point in the history
Co-authored-by: Anthony Fu <anthonyfu117@hotmail.com>
  • Loading branch information
JMaylor and antfu committed Sep 17, 2021
1 parent 4440b7c commit ec310e3
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 12 deletions.
43 changes: 36 additions & 7 deletions packages/core/useSpeechRecognition/demo.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
import { ref, watch } from 'vue-demi'
import { useSpeechRecognition } from '.'
const lang = ref('en-US')
function sample<T>(arr: T[], size: number) {
const shuffled = arr.slice(0)
let i = arr.length
Expand All @@ -20,6 +22,7 @@ const colors = ['aqua', 'azure', 'beige', 'bisque', 'black', 'blue', 'brown', 'c
const grammar = `#JSGF V1.0; grammar colors; public <color> = ${colors.join(' | ')} ;`
const speech = useSpeechRecognition({
lang,
continuous: true,
})
Expand Down Expand Up @@ -52,6 +55,10 @@ const start = () => {
}
const { isListening, isSupported, stop, result } = speech
const selectedLanguage = ref(lang.value)
watch(lang, lang => isListening.value ? null : selectedLanguage.value = lang)
watch(isListening, isListening => isListening ? null : selectedLanguage.value = lang.value)
</script>

<template>
Expand All @@ -64,20 +71,42 @@ const { isListening, isSupported, stop, result } = speech
>more details</a>
</div>
<div v-else>
<div>
<input id="en-US" v-model="lang" type="radio" value="en-US" />
<label for="en-US">English (US)</label>
<input id="fr" v-model="lang" type="radio" value="fr" />
<label for="fr">French</label>
<input id="es" v-model="lang" type="radio" value="es" />
<label for="es">Spanish</label>
</div>
<button v-if="!isListening" @click="start">
Press and talk
</button>
<button v-if="isListening" class="orange" @click="stop">
Stop
</button>
<div v-if="isListening" class="mt-4">
<note class="mb-2">
<b>Please say a color</b>
</note>
<note class="mb-2">
try: {{ sampled.join(', ') }}
</note>
<p class="tag" :style="{ background: color }">
<template v-if="selectedLanguage === 'en-US'">
<note class="mb-2">
<b>Please say a color</b>
</note>
<note class="mb-2">
try: {{ sampled.join(', ') }}
</note>
</template>

<p v-else-if="selectedLanguage === 'es'">
Speak some Spanish!
</p>

<p v-else-if="selectedLanguage === 'fr'">
Speak some French!
</p>

<p
class="tag"
:style="selectedLanguage === 'en-US' ? { background: color } : {}"
>
{{ result }}
</p>
</div>
Expand Down
16 changes: 11 additions & 5 deletions packages/core/useSpeechRecognition/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// ported from https://www.reddit.com/r/vuejs/comments/jksizl/speech_recognition_as_a_vue_3_hook
// by https://github.com/wobsoriano

import { tryOnScopeDispose } from '@vueuse/shared'
import { Ref, ref, watch, shallowRef } from 'vue-demi'
import { tryOnScopeDispose, MaybeRef } from '@vueuse/shared'
import { Ref, ref, watch, shallowRef, unref } from 'vue-demi'
import { ConfigurableWindow, defaultWindow } from '../_configurable'
import type { SpeechRecognitionErrorEvent, SpeechRecognition } from './types'

Expand All @@ -24,7 +24,7 @@ export interface SpeechRecognitionOptions extends ConfigurableWindow {
*
* @default 'en-US'
*/
lang?: string
lang?: MaybeRef<string>
}

/**
Expand All @@ -36,12 +36,12 @@ export interface SpeechRecognitionOptions extends ConfigurableWindow {
*/
export function useSpeechRecognition(options: SpeechRecognitionOptions = {}) {
const {
lang = 'en-US',
interimResults = true,
continuous = true,
window = defaultWindow,
} = options

const lang = ref(options.lang || 'en-US')
const isListening = ref(false)
const isFinal = ref(false)
const result = ref('')
Expand Down Expand Up @@ -69,12 +69,17 @@ export function useSpeechRecognition(options: SpeechRecognitionOptions = {}) {

recognition.continuous = continuous
recognition.interimResults = interimResults
recognition.lang = lang
recognition.lang = unref(lang)

recognition.onstart = () => {
isFinal.value = false
}

watch(lang, (lang) => {
if (recognition && !isListening.value)
recognition.lang = lang
})

recognition.onresult = (event) => {
const transcript = Array.from(event.results)
.map((result) => {
Expand All @@ -94,6 +99,7 @@ export function useSpeechRecognition(options: SpeechRecognitionOptions = {}) {

recognition.onend = () => {
isListening.value = false
recognition!.lang = unref(lang)
}

watch(isListening, () => {
Expand Down

0 comments on commit ec310e3

Please sign in to comment.