Skip to content

Commit

Permalink
Add voiceover of words
Browse files Browse the repository at this point in the history
  • Loading branch information
kvestus committed Mar 3, 2024
1 parent 2dfc609 commit 3c8f2c6
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 7 deletions.
9 changes: 6 additions & 3 deletions src/composables/useLearningLanguage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,12 @@ export const useLearningLanguage = () => {
const { getTranslatedLanguageName, languagesAvailableForLearning } = useConfigStore()
const { updateActiveLearningLanguage } = useUserStore()

const activeLearningLanguage = computed(() => unref(customData)?.activeLearningLanguage ?? -1)
const activeLearningLanguageName = computed(() => getTranslatedLanguageName(unref(activeLearningLanguage) ?? BASE_INTERFACE_LANGUAGE))
const activeLearningLanguageId = computed(() => unref(customData)?.activeLearningLanguage ?? BASE_INTERFACE_LANGUAGE)
const activeLearningLanguage = computed(() => ({
id: unref(activeLearningLanguageId),
name: getTranslatedLanguageName(unref(activeLearningLanguageId), 'full'),
nameShort: getTranslatedLanguageName(unref(activeLearningLanguageId), 'short'),
}))
const availableLearningLanguagesOptions = computed(() =>
languagesAvailableForLearning
.map(languageId => ({
Expand All @@ -17,7 +21,6 @@ export const useLearningLanguage = () => {

return {
activeLearningLanguage,
activeLearningLanguageName,
availableLearningLanguagesOptions,
availableLearningLanguagesOptionsExceptActive,
updateActiveLearningLanguage,
Expand Down
42 changes: 42 additions & 0 deletions src/composables/useVoiceover.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { useSpeechSynthesis } from '@vueuse/core'
import { useNotification } from 'naive-ui'

export const useVoiceover = ({
language,
}: {
language?: string
} = {}) => {
const { t } = useI18n()
const notification = useNotification()
const { activeLearningLanguage } = useLearningLanguage()

const textToSpeak = ref('')
const speech = useSpeechSynthesis(textToSpeak, {
lang: language ?? unref(activeLearningLanguage).nameShort ?? BASE_INTERFACE_LANGUAGE_NAME,
pitch: 1,
rate: 1,
volume: 1,
})

const speak = (text: string) => {
textToSpeak.value = text

if (!unref(speech.isSupported)) {
notification.error({
content: t('compatibility_error'),
meta: t('your_browser_does_not_support_the_text_to_speech_feature'),
duration: 1000,
keepAliveOnHover: true,
})

return
}

speech.speak()
textToSpeak.value = ''
}

return {
speak,
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script setup lang="ts">
const { isUserDataLoaded } = storeToRefs(useUserStore())
const { availableLearningLanguagesOptionsExceptActive, activeLearningLanguageName, updateActiveLearningLanguage } = useLearningLanguage()
const { availableLearningLanguagesOptionsExceptActive, activeLearningLanguage, updateActiveLearningLanguage } = useLearningLanguage()
const { t } = useI18n()
const learningLanguagesOptions = computed(() => ([
Expand All @@ -23,7 +23,7 @@ const learningLanguagesOptions = computed(() => ([
icon-placement="right"
type="primary"
ghost>
{{ $t('learn') }} {{ activeLearningLanguageName }}
{{ $t('learn') }} {{ activeLearningLanguage.name }}
</n-button>
</n-dropdown>
<n-skeleton
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ const nativeLanguagesOptions = computed(() => Object.keys(unref(languages)).map(
<n-select
v-if="isUserDataLoaded"
@update-value="updateActiveLearningLanguage"
:value="activeLearningLanguage"
:value="activeLearningLanguage.id"
:placeholder="$t('select')"
:options="availableLearningLanguagesOptions"
value-field="key"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ const {
updateWordTranslations,
updateWordStatus,
} = useWordsContainerStore()
const { speak } = useVoiceover()
const wordListItem = ref(null)
Expand Down Expand Up @@ -89,7 +90,9 @@ const toggleChangeableView = () => {
<n-grid-item
span="3 s:2 m:1"
class="words-container-words-list-item__property">
<n-button text>
<n-button
@click="() => speak(source.word)"
text>
<template #icon>
<n-icon
size="20"
Expand Down

0 comments on commit 3c8f2c6

Please sign in to comment.