Интегрируйте чат-бот для реагирования на приложение
Недавно я получил требование интеграции реагировать-простой-чат-бот к существующему реагирующему приложению. Сложность состояла в том, чтобы понять макет существующего приложения и немного научиться реагировать на простой чат-бот. Внешний вид приложения не очень впечатлил, и мне пришлось его немного изменить, чтобы получить желаемый результат. Поэтому вместо того, чтобы вносить изменения в существующее приложение, я разрабатываю макет, используя сетку и стили с фиксированным положением. Когда приложение запускается, оно выглядит так:
Рабочий стол
Просмотр телефона
Этот пост поможет всем тем, кто изо всех сил пытается создать приложение и, наконец, интегрировать простого чат-бота в существующее приложение. Полный исходный код можно загрузить из репозитория Git. реагирующий чат-бот.
Установите следующие 2 пакета —
"react-simple-chatbot": "^0.6.1",
"styled-components": "^4.3.2"
Вы можете запустить следующую команду в терминале
npm install react-native-chatbot --save
npm install styled-components --save
Простая форма .js
import React, { Component } from 'react';
import ChatBot from 'react-simple-chatbot';
import Review from './Review';
class SimpleForm extends Component {
render() {
return (
<ChatBot
steps={[
{
id: '1',
message: 'What is your name?',
trigger: 'name',
},
{
id: 'name',
user: true,
trigger: '3',
},
{
id: '3',
message: 'Hi {previousValue}! What is your gender?',
trigger: 'gender',
},
{
id: 'gender',
options: [
{ value: 'male', label: 'Male', trigger: '5' },
{ value: 'female', label: 'Female', trigger: '5' },
],
},
{
id: '5',
message: 'How old are you?',
trigger: 'age',
},
{
id: 'age',
user: true,
trigger: '7',
validator: (value) => {
if (isNaN(value)) {
return 'value must be a number';
} else if (value < 0) {
return 'value must be positive';
} else if (value > 120) {
return `${value}? Come on!`;
}
return true;
},
},
{
id: '7',
message: 'Great! Check out your summary',
trigger: 'review',
},
{
id: 'review',
component: <Review />,
asMessage: true,
trigger: 'update',
},
{
id: 'update',
message: 'Would you like to update some field?',
trigger: 'update-question',
},
{
id: 'update-question',
options: [
{ value: 'yes', label: 'Yes', trigger: 'update-yes' },
{ value: 'no', label: 'No', trigger: 'end-message' },
],
},
{
id: 'update-yes',
message: 'What field would you like to update?',
trigger: 'update-fields',
},
{
id: 'update-fields',
options: [
{ value: 'name', label: 'Name', trigger: 'update-name' },
{ value: 'gender', label: 'Gender', trigger: 'update-gender' },
{ value: 'age', label: 'Age', trigger: 'update-age' },
],
},
{
id: 'update-name',
update: 'name',
trigger: '7',
},
{
id: 'update-gender',
update: 'gender',
trigger: '7',
},
{
id: 'update-age',
update: 'age',
trigger: '7',
},
{
id: 'end-message',
message: 'Thanks! Your data was submitted successfully!',
end: true,
},
]}
/>
);
}
}
export default SimpleForm;
Вы могли заметить, что в шаге с идентификатором «обзор» в конце пользовательского ввода мы визуализируем компонент «Обзор». Здесь важно отметить, что пользовательские данные передаются этому компоненту в качестве реквизита.
Обзор .js
import React, { useState, useEffect } from 'react';
import PropTypes from 'prop-types';
const Review = (props) => {
const [state, setState] = useState({ name: '', gender: '', age: ''});
useEffect(() => {
const { steps } = props;
const { name, gender, age } = steps;
setState({ name, gender, age });
}, [props])
const { name, gender, age } = state;
return (
<div style={{ width: '100%' }}>
<h3>Summary</h3>
<table>
<tbody>
<tr>
<td>Name</td>
<td>{name.value}</td>
</tr>
<tr>
<td>Gender</td>
<td>{gender.value}</td>
</tr>
<tr>
<td>Age</td>
<td>{age.value}</td>
</tr>
</tbody>
</table>
</div>
);
}
Review.propTypes = {
steps: PropTypes.object,
};
Review.defaultProps = {
steps: undefined,
};
export default Review;
Справочник по API чат-бота и шаги можно найти здесь.
Сначала посмотрите на код компонента приложения и его стиль, а позже объясним ключевые моменты.
App.js
import React, { useState } from 'react';
import SimpleForm from './SimpleForm';
import './App.css';
const App = (props) => {
let [showChat, setShowChat] = useState(false);
const startChat = () => { setShowChat(true); }
const hideChat = () => { setShowChat(false); }
return (
<>
<div className = "header">
<h2>My Application!!!</h2>
</div>
<div className = "main">
<div className ="nav">
<h3>My Navigation</h3>
</div>
<div className ="content">
<div style = {{padding:"20px"}}>
<h1>Content of my application will go here.....</h1>
<p>Sample content to fill the gap as much as possible. Sample content to fill the gap as much as possible.
Sample content to fill the gap as much as possible.Sample content to fill the gap as much as possible.</p>
<p>More content to fill the available area of the main contect. More content to fill the available area of the main contect.
More content to fill the available area of the main contect.More content to fill the available area of the main contect. </p>
</div>
</div>
</div>
<div className = "footer">Footer</div>
<div className = "bot">
<div style ={{display: showChat ? "" : "none"}}>
<SimpleForm></SimpleForm>
</div>
{/* <div> {showChat ? <SimpleForm></SimpleForm> : null} </div> */}
<div>
{!showChat
? <button className="btn" onClick={() => startChat()}>click to chat... </button>
: <button className="btn" onClick={() => hideChat()}>click to hide... </button>}
</div>
</div>
</>
)
}
export default App;
App.css
body {
font-size: 20px;
}
.header {
position: fixed;
top: 0;
width: 100%;
text-align: center;
background-color: rgb(28, 18, 78);
color: white;
padding: 20px;
}
.main {
display: grid;
height: 800px;
padding-top: 130px;
/* grid-template-columns: 1fr 6fr; */
grid-template-columns: repeat(auto-fit, minmax(479px, auto));
}
.nav {
background-color: rgba(115, 110, 192, 0.466);
text-align: center;
}
.content {
background-color: rgba(160, 157, 195, 0.466);
}
.footer {
height: 400px;
text-align: center;
padding: 20px;
background-color: rgb(223, 223, 223);
}
.bot {
bottom: 0;
right : 0;
position: fixed;
width: 350px;
}
.btn {
font-size: 20px;
float: right;
width: 100%;
padding: 8px;
background-color: rgb(183, 0, 255)
}
Объяснение —
Здесь div с классом «бот» обертывает SimpleForm и кнопку внизу. Стиль отображения обертки div переключается на скрытие/отображение в зависимости от состояния showChat. Мы не хотим размонтировать компонент здесь, потому что если мы размонтируем/монтируем, то история чата будет потеряна. Вы можете увидеть приведенный ниже код с комментариями, который монтируется/размонтируется на основе значения showChat.
Кроме того, кнопки «нажмите, чтобы начать чат…», «нажмите, чтобы скрыть…» динамически монтируются в зависимости от состояния showChat.
<div className = "bot">
<div style ={{display: showChat ? "" : "none"}}>
<SimpleForm></SimpleForm>
</div>
{/* <div> {showChat ? <SimpleForm></SimpleForm> : null} </div> */}
<div>
{!showChat
? <button className="btn" onClick={() => startChat()}>click to chat... </button>
: <button className="btn" onClick={() => hideChat()}>click to hide... </button>}
</div>
</div>
Теперь я объясню часть css, я устанавливаю position: fixed и top: 0 для класса заголовка. Причина в том, что заголовок остается видимым, когда пользователь прокручивает страницу вниз.
position: fixed;
top: 0;
В соответствии с приведенной выше логикой я устанавливаю фиксированный класс бота с 0 внизу и 0 справа.
.bot {
bottom: 0;
right : 0;
position: fixed;
width: 350px;
}
Еще один интересный класс, требующий внимания, — main. Вы можете заметить, что я делаю навигацию и контент по-прежнему отзывчивыми, а также поддерживаю ширину 30–70% для навигации и контента соответственно на рабочем столе.