...
Скачать архив с кодом проекта: pb-hello-world.rar
Шаг 1.
Добавьте подписку на события onAction()
от диалогового сервиса. Это позволит переходить с экрана на экран с помощью голосовых команд. Сделать это нужно на следующих экранах:
VideoStream
AcquaintanceForm
MainMenu
Chat
Добавьте следующий текст в 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
. Сверьтесь со списком ниже.
Блок кода |
---|
|
components: {
Header,
Modal,
VoiceInput
} |
Шаг 15.
Замените pb-input
на VoiceInput
в div
в файле DataEntry.vue
. Сверьтесь с текстом ниже.
Блок кода |
---|
|
<div class="data-entry__input-wrapper">
<VoiceInput
v-model="name"
:input-options="{
label: 'Фамилия'
}"
:mask-options="{
type: 'text'
}"
/>
<VoiceInput
v-model="name"
:input-options="{
label: 'Имя'
}"
:mask-options="{
type: 'text'
}"
/>
<VoiceInput
v-model="patronymic"
:input-options="{
label: 'Отчество'
}"
:mask-options="{
type: 'text'
}"
/>
</div> |
Шаг 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('/')
}
}) |