Скачать архив с кодом проекта: pb-hello-world.rar
Шаг 1.
Добавьте подписку на события onAction() от диалогового сервиса. Это позволит переходить с экрана на экран с помощью голосовых команд. Сделать это нужно на следующих экранах:
VideoStreamAcquaintanceFormMainMenuChat
Добавьте следующий текст в mounted() в defineComponent компонента VideoStream.
this.$robot.dialogService.onAction(actions => {
if (actions.find(action => action.toLowerCase() === 'next') && !this.disabled) {
this.moveNext() // Имитирование нажатия кнопки Продолжить
}
})
Добавьте следующий текст в mounted() в defineComponent компонента AcquaintanceForm.
this.$robot.dialogService.onAction(actions => {
if (actions.find(action => action.toLowerCase() === 'save_and_continue') && this.isNotEmptyName) {
this.saveUser() // Имитирование нажатия кнопки Продолжить
}
})
Добавьте следующий текст в mounted() в defineComponent компонента MainMenu.
this.$robot.dialogService.onAction(actions => {
if (actions.find(action => action.toLowerCase() === 'about-hotel')) {
this.aboutHotel() // Имитирование нажатия кнопки Об отеле
}
if (actions.find(action => action.toLowerCase() === 'to-chat')) {
this.toChat() // Имитирование нажатия кнопки Поболтать
}
if (actions.find(action => action.toLowerCase() === 'to-data')) {
this.toData() // Имитирование нажатия кнопки Персональные данные
}
})
Добавьте следующий текст в mounted() в defineComponent компонента Header.
this.$robot.dialogService.onAction(actions => {
if (actions.find(action => action.toLowerCase() === 'back')) {
this.$router.back() // Имитирование нажатия кнопки Назад на экране Поболтать
}
})
Шаг 2.
Добавьте компонент-обертку. Создайте файл VoiceInput.vue в папке components.
Шаг 3.
Добавьте div с pb-input в VoiceInput.vue. Укажите ссылку ref, она понадобится позже. Добавьте input-options и mask-options, а также двустороннее связывание через modelValue. Добавьте кнопку Микрофон, которая позволит включать голосовой способ ввода для поля (компонент pb-icon-button с SVG-картинкой). Для этого замените содержимое файла VoiceInput.vue на следующий текст.
<template>
<div class="voice-input">
<pb-input
ref="input-wrap"
:input-options="inputOptions"
:mask-options="maskOptions"
@accept="$emit('update:modelValue', $event.target.value)"
:modelValue="modelValue"
/>
<pb-icon-button>
<svg width="14" height="20" viewBox="0 0 14 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M3.33337 3.5C3.33337 1.567 4.90038 0 6.83337 0V0C8.76637 0 10.3334 1.567 10.3334 3.5V9.5C10.3334 11.433 8.76637 13 6.83337 13V13C4.90038 13 3.33337 11.433 3.33337 9.5V3.5Z" fill="#2D68FF"/>
<path d="M0.833374 9V9.5C0.833374 12.8137 3.51967 15.5 6.83337 15.5V15.5C10.1471 15.5 12.8334 12.8137 12.8334 9.5V9" stroke="#2D68FF"/>
<path d="M6.83337 15.5V20" stroke="#2D68FF"/>
<path d="M4.33337 19.5H9.33337" stroke="#2D68FF"/>
</svg>
</pb-icon-button>
</div>
</template>
<script lang="ts">
import { defineComponent, PropType } from 'vue'
export default defineComponent({
name: 'VoiceInput',
})
</script>
<style lang="scss" scoped>
</style>
Шаг 4.
Задайте кнопке Микрофон (pb-icon-button) необходимые классы: статичный класс от voice-input и динамический класс, который будет отвечать за анимацию прослушивания. Добавьте реакцию на клик — метод toggleListen, логику которого мы реализуем позднее. Для этого замените тег <pb-icon-button> файла VoiceInput.vue на следующий текст.
<pb-icon-button
:class="['voice-input__icon _transparent', { '_animated': isListening }]"
@click="toggleListen"
>
Шаг 5.
Заполните props. Укажите modelValue, inputOptions, maskOptions. Для этого добавьте следующий текст в defineComponent компонента VoiceInput.
props: {
modelValue: [String, Number],
inputOptions: {
type: Object as PropType<InputTextareaOptions>,
// eslint-disable-next-line @typescript-eslint/no-empty-function
default: () => {}
},
maskOptions: {
type: Object as PropType<MaskOptions>,
// eslint-disable-next-line @typescript-eslint/no-empty-function
default: () => {}
}
}
Шаг 6.
Добавьте импорт для inputOptions и maskOptions. Для этого добавьте следующий текст в <script> </script> файла VoiceInput.vue.
import { InputTextareaOptions, MaskOptions } from '@pb/ui-kit/src/components/input/inputTextareaMixin'
Шаг 7.
Заполните data(), которая будет возвращать inputElement и isListening. inputElement потребуется для фокусирования и вставки текста непосредственно в компонент. Для этого добавьте следующий текст в defineComponent компонента VoiceInput.
data (): { inputElement: null | HTMLInputElement, isListening: boolean } {
return {
inputElement: null,
isListening: false
}
}
Шаг 8.
Реализуйте метод toggleListen(), который позволит включать голосовой ввод для поля (обработчик кнопки Микрофон). Первым делом в теле метода происходит проверка, включен или выключен бесшумный режим. Если включен, то вызывается метод muteOff(), иначе — muteOn(). Это нужно для того, чтобы во время вставки текста в input'ы, не срабатывали userAction'ы. В конце метода isListening меняется на противоположное ему значение. Добавьте следующий текст в methods в defineComponent компонента VoiceInput.
toggleListen (): void {
this.$robot.dialogService.isMute
? this.$robot.dialogService.muteOff()
: this.$robot.dialogService.muteOn()
this.isListening = !this.isListening
}
Шаг 9.
Заполните mounted(). Для этого добавьте следующий текст в mounted в defineComponent компонента VoiceInput.
this.inputElement = this.$el.querySelector('input')
this.$robot.dialogService.onUserReplic((text, isFinished) => {
if (this.isListening && isFinished) {
(this.inputElement as HTMLInputElement).focus();
(this.inputElement as HTMLInputElement).value = text; // Текст из лингвобазы
(this.inputElement as HTMLInputElement).blur()
// Если тихий режим выключать сразу, то сработают userAction'ы, поэтому используем таймаут.
setTimeout(() => {
this.toggleListen()
}, TIMEOUT_FOR_MUTE_OFF)
}
})
Шаг 10.
Задайте значение константы TIMEOUT_FOR_MUTE_OFF. Для этого добавьте следующий текст в <script> </script> файла VoiceInput.vue.
const TIMEOUT_FOR_MUTE_OFF = 500
Шаг 11.
Добавьте watch. Для этого добавьте следующий текст в defineComponent компонента VoiceInput.
watch: {
isListening (newValue) {
if (newValue) {
(this.inputElement as HTMLInputElement).focus()
}
}
}
Шаг 12.
Добавьте стили для voice-input. Для этого добавьте следующий текст в <style lang="scss" scoped> </style> файла VoiceInput.vue.
.voice-input {
position: relative;
&__icon {
position: absolute;
right: 0;
&._animated {
animation: pulse 1.5s linear infinite;
border-radius: 50%;
box-shadow: 0 0 0 0 #2D68FF;
filter: invert(30%) sepia(100%) saturate(1265%) hue-rotate(209deg) brightness(101%) contrast(109%);
}
}
}
Шаг 13.
Добавьте стили для анимации кнопки Микрофон через @keyframes. Для этого добавьте следующий текст в <style lang="scss" scoped> </style> файла VoiceInput.vue.
@keyframes pulse {
0% {
box-shadow: 0 0 0 0 #2D68FF;
}
70% {
box-shadow: 0 0 0 3px rgba(45, 104, 255, 0);
}
100% {
box-shadow: 0 0 0 0 rgba(45, 104, 255, 0);
}
}
Шаг 14.
Добавьте VoiceInput в список компонентов — components в defineComponent компонента DataEntry в файле DataEntry.vue. Сверьтесь со списком ниже.
Шаг 15.
Замените pb-input на VoiceInput в div в файле DataEntry.vue. Сверьтесь с текстом ниже.
Шаг 16.
Добавьте голосовое управление кнопкой Продолжить и ссылкой на модальное окно Персональные данные в файле DataEntry.vue. Для этого добавьте следующий текст в mounted в defineComponent компонента DataEntry.
this.$robot.dialogService.onAction(actions => {
if (actions.find(action => action.toLowerCase() === 'confirm') && this.isNotEmptyFields) {
this.confirm()
}
if (actions.find(action => action.toLowerCase() === 'open-modal') && !this.isShowModal) {
this.isShowModal = true
}
if (actions.find(action => action.toLowerCase() === 'close-modal') && this.isShowModal) {
this.isShowModal = false
}
})
Шаг 17.
Добавьте голосовое управление кнопкой На главную в файле SuccessScreen.vue. Для этого добавьте следующий текст в mounted() в defineComponent компонента SuccessScreen.
this.$robot.dialogService.onAction(actions => {
if (actions.find(action => action.toLowerCase() === 'to-main')) {
this.$router.push('/')
}
})
Добавить комментарий