Рубрики
Без рубрики

Как построить современное приложение в чате с React.js

В этом руководстве я направляю вас, чтобы построить собственное приложение Group Chat с использованием React, React Router и Cometchat Pro. Да, вместо того, чтобы развернуть наш собственный сервер, мы вместо этого будем использовать Comethat Pro для обработки отправки в режиме реального времени и получать сообщения чата. Когда вы закончите, ты

В этом руководстве я направляю вас, чтобы построить собственное приложение для группового чата, используя React, React Router, а также Cometchat Pro. . Да, вместо того, чтобы развернуть наш собственный сервер, мы вместо этого будем использовать Comethat Pro для обработки отправки в режиме реального времени и получать сообщения чата.

Когда вы закончите, вы должны иметь функциональное приложение в чате, которое выглядит что-то вроде этого (конечно, вы добро пожаловать на твик и экспериментировать с вещами, когда вы идете вместе):

Я структурировал этот учебник как серию шагов, чтобы легко следовать. Если вам просто хотел бы проверить код, Нажмите здесь Отказ

Настройка проекта

Прежде чем мы зайдем слишком далеко, мы должны сначала настроить наш реагированный проект. Для этого мы будем использовать меньшее известный драгоценный камень под названием «Создание приложения React».

Лучшая вещь? Поскольку у вас установлен NPM, вы можете использовать NPX для установки и запуска Create-React-App за один шаг:

NPX Create-React-App ChatApp//Примечание: NPM V5.2 +

После запуска этой команды будет создана новая папка «ChatApp», будет создана со следующей структурой:

Кроме того, реагировать, нам также нужно будет установить React Router и Cometchat Pro SDK. Для этого отправляйтесь в каталог ChatApp и запустите:

NPM установить React-Marriter-DOM @ Comethat-Pro/Chat –save

Добавить React Router

В конце концов, наше приложение будет иметь две страницы – один под названием Вход Где пользователь войдет, а другой под названием Групповой чат где мы сделаем комнату чата. Мы будем использовать React Router для маршрута пользователей к вам нужны страницу.

Чтобы настроить React Router, мы должны сначала импортировать Маршрутизатор обертка Компонент в нашем файле index.js. Я называю это компонентом обертки, потому что мы охватываем наши Приложение внутри Маршрутизатор составная часть.

Заменить index.js с этим фрагментом:

import React from 'react';
import { BrowserRouter as Router } from 'react-router-dom'; // added
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
ReactDOM.render(
  
    
  
  , document.getElementById('root'));

index.js Является ли точка входа для нашего приложения. Его единственная реальная работа состоит в том, чтобы сделать наше приложение по реагированию. Большая часть нашей «реальной» логики происходит в файле под названием App.js, который мы будем изменять дальше.

В приложении. Например, если пользователь переходит на маршрут «/login», мы должны рендер компонент входа в систему. Аналогично, если пользователь переходит на маршрут «/чат», мы должны сделать GroupChat составная часть:

import React, { Component } from "react";
import { Route, Redirect, Switch } from "react-router-dom";
import "./App.css";
// the below components will be created shortly
import Login from "./components/Login";
import Groupchat from "./components/Groupchat";
class App extends Component {
  constructor(props) {
    super(props);
  }
render() {
    return (
      
        
        
        
      
    );
  }
}
export default App;

Если вы попытаетесь запустить этот код, это определенно бросит некоторые ошибки, потому что мы не сделали Вход а также GroupChat компоненты. Давайте сделаем это сейчас.

Создайте компонент входа

Чтобы сохранить наш проект Nice и Tidy, создайте папку под названием Компоненты держать нашими пользовательскими компонентами.

Затем в этой недавно созданной папке создайте файл под названием login.js со следующим кодом:

import React from "react";
class Login extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
    };
  }
  render() {
    return ( 
      

Login

); } } export default Login;

Все, что мы делаем здесь, экспортирует компонент с текстом заголовка, «вход». Мы скоро понравится этот компонент, но сейчас, мы просто создаем ботинку.

Создайте компонент GroupChat

В папке тех же компонентов создайте новый компонент называемый GroupChat.js:

import React from "react";
class Groupchat extends React.Component {
  constructor(props) {
    super(props);
  }
  render() {
    return 
; } } export default Groupchat;

Когда мы проходим через учебное пособие, мы разработаем этот скромный компонент в ядро нашего приложения чата.

С GroupChat а также Вход Компоненты на месте, вы должны иметь возможность запускать приложение без ошибки. Откройте приложение на localhost и перейдите к localhost: 3000/login, а затем localhost: 3000/чат, чтобы увидеть компоненты в действии.

Создайте идентификатор приложения Comethat и ключ API

Как я уже упоминал в начале учебника, мы не будем выкатывать наш собственный сервер в этом руководстве. Вместо этого мы будем использовать размещенную услугу Comethat Pro Отказ

Прежде чем мы сможем подключиться к Comethat, мы должны сначала создать приложение Comethat с помощью приборной панели:

Как только ваше приложение будет создано, нажмите «Explore», затем отправляйтесь на вкладку «Ключи API»:

Нажмите «Создать ключ API» и заполните форму, выбирая AUTH TOMPORE. Из таблицы вы можете отметить свой идентификатор приложения и ключ приложения, нам понадобится в ближайшее время.

Создайте идентификатор группы Comethat

Пока у нас открыта приборная панель, давайте также создадим группа . Обычно вы сделаете это с кодом (например, вы можете позволить пользователю создавать пользовательскую группу чата для своей команды или проекта через ваше приложение), но для обучения и тестирования приборная панель в порядке.

Отправляйтесь на вкладку «Группы» и создайте новую группу, называемую TestGroup:

Как и в последний раз, вы будете возвращаться в стол, где вы можете отметить идентификатор группы:

Обратите внимание, что нам это понадобится на следующем шаге.

Создайте файл конфигурации

Чтобы облегчить нашу конфигурацию, создайте новый файл, называемый config.js и вставьте свои учетные данные:

export default {
  appId: "", //Enter your App ID
  apiKey: "", //Enter your API KEY
  GUID: "", // Enter your group UID
};

Теперь вы можете закрыть приборную панель. После настройки Comethat все взаимодействие происходит через код.

Создайте класс Cometchat Manager

Одно из прекрасных вещей о реагировании состоит в том, что он поддается отделению проблем. Наши компоненты могут сосредоточиться исключительно на презентации, в то время как мы можем создавать другие модули для обработки таких вещей, как данные для получения данных и управление государством.

Чтобы действительно воспользоваться этим, давайте создадим новую папку под названием «lib» и в этой новой папке, файл под названием Chat.js. Именно здесь все наше взаимодействие с CHETCHAT состоится:

import { CometChat } from "@cometchat-pro/chat";
import config from "../config";
export default class CCManager {
  static LISTENER_KEY_MESSAGE = "msglistener";
  static appId = config.appId;
  static apiKey = config.apiKey;
  static LISTENER_KEY_GROUP = "grouplistener";
  static init() {
    return CometChat.init(CCManager.appId);
  }
  static getTextMessage(uid, text, msgType) {
    if (msgType === "user") {
      return new CometChat.TextMessage(
        uid,
        text,
        CometChat.MESSAGE_TYPE.TEXT,
        CometChat.RECEIVER_TYPE.USER
      );
    } else {
      return new CometChat.TextMessage(
        uid,
        text,
        CometChat.MESSAGE_TYPE.TEXT,
        CometChat.RECEIVER_TYPE.GROUP
      );
    }
  }
  static getLoggedinUser() {
    return CometChat.getLoggedinUser();
  }
  static login(UID) {
    return CometChat.login(UID, this.apiKey);
  }
  static getGroupMessages(GUID, callback, limit = 30) {
    const messagesRequest = new CometChat.MessagesRequestBuilder()
      .setGUID(GUID)
      .setLimit(limit)
      .build();
    callback();
    return messagesRequest.fetchPrevious();
  }
  static sendGroupMessage(UID, message) {
    const textMessage = this.getTextMessage(UID, message, "group");
    return CometChat.sendMessage(textMessage);
  }
  static joinGroup(GUID) {
    return CometChat.joinGroup(GUID, CometChat.GROUP_TYPE.PUBLIC, "");
  }
  static addMessageListener(callback) {
    CometChat.addMessageListener(
      this.LISTENER_KEY_MESSAGE,
      new CometChat.MessageListener({
        onTextMessageReceived: textMessage => {
          callback(textMessage);
        }
      })
    );
  }
}

Помимо позволять нам создать разделение опасений, представляя код, как это, также облегчает переваривание.

Позвольте мне объяснить некоторые важные части этого модуля, начиная с вершины:

  • Lisker_key_message – Это требуется послушниму сообщению.
  • init () – Это необходимо вызывать только один раз в течение всего жизненного цикла приложения, он называет Comethat init Способ с помощью AppID.
  • getTextmessage (UID, текст, msgtype) – Это создает объект сообщения на основе Comethat. Текстура Метод, он принимает UID (GUID в нашем случае) и текстовое сообщение для отправки.
  • getLoggedinuser () – Это используется, чтобы получить в настоящее время вошедший в систему пользователем.
  • Войти () – Используется для входа пользователя на основе метода Comethat.Login, он принимает в UID (GUID в нашем случае) и Apikey.
  • GetGroupMessages (GUID, обратный вызов) – Это используется для получения предыдущих групповых сообщений от Checthat, используя Comethat. MessagesRequestBuilder () Метод, который принимает во внимание и ограничить в качестве параметров.
  • sendgroupmessage (UID, сообщение) – Это используется для отправки сообщений, использующих Comethat.sendmessage () Метод, и он принимает GUID и сообщение в качестве параметров.
  • Joingroup (GUID) – Он используется для присоединения к выбранной группе, используя GUID.
  • AddMessagelistener (обратный вызов) – использует Comethat.addmessageListener () Слушать сообщения (я упомянул, что это называется в режиме реального времени?), это требует Lisker_key_message в качестве параметра, а также обратный вызов, который называется при получении сообщения.

Здесь нет ничего конкретного для этого приложения. Вы также можете взять этот модуль, расширить его при необходимости и импортировать его в другой проект. Вообще, хотя это просто тонкая обертка вокруг SDK.

Обновите компонент входа

Со всей нашей нашей конфигурацией и кодом чата мы можем теперь быстро построить интернет-интерфейс, начиная с Вход составная часть.

Просто чтобы напомнить вам, это то, что будет выглядеть компонент входа в систему:

Как видите, его главная функция – спросить пользователя для их имени. Как только имя поставлено, мы оказываем GroupChat составная часть.

Заменить Login.js с участием:

import React from "react";
import { Redirect } from "react-router-dom";
import chat from "../lib/chat";
import spinner from "../logo.svg";
class Login extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      username: "",
      isAuthenticated: false,
      user: null,
      isSubmitting: false,
      errorMessage: ""
    };
  }
  onSubmit = e => {
    if (this.state.username !== "") {
      e.preventDefault();
      this.login();
    }
  };
  login = () => {
    this.toggleIsSubmitting();
    chat
    .login(this.state.username)
    .then(user => {
      this.setState({
        user,
        isAuthenticated: true
      });
    })
    .catch(error => {
      this.setState({
        errorMessage: "Please enter a valid username"
      });
      this.toggleIsSubmitting();
      console.log(error);
    });
  };
  toggleIsSubmitting = () => {
    this.setState(prevState => ({
      isSubmitting: !prevState.isSubmitting
    }));
  };
  handleInputChange = e => {
    this.setState({
      username: e.target.value
    });
  };
  render() {
    if (this.state.isAuthenticated) {
      return (
        
      );
    }
    return (
      

COMETCHAT

Create an account through your CometChat dashboard or login with one of our test users, superhero1, superhero2, etc.

{this.state.errorMessage} {this.state.isSubmitting ? ( Spinner component ) : ( )}
); } } export default Login;

Помимо презентационного HTML, большинство кода здесь посвящены обработке Реагистрационная форма .

Обновите компонент GroupChat

Компонент GroupChat имеет гораздо больше ответственности, чем компонент входа в систему. Как быстрое напоминание, это то, что он будет выглядеть:

По большей части GroupChat Работа компонента состоит в том, чтобы преодолеть модуль Chat Lib и UI, который мы представем пользователю. Например, когда пользователь отправляет сообщение, мы называем Chat.SendMessage И в качестве новых сообщений стиркается, функция обратного вызова называется:

import React from "react";
import { Redirect } from "react-router-dom";
import chat from "../lib/chat";
import config from "../config";
class Groupchat extends React.Component {
  constructor(props) {
    super(props);
this.state = {
      receiverID: "",
      messageText: null,
      groupMessage: [],
      user: {},
      isAuthenticated: true
    };
this.GUID = config.GUID;
  }
sendMessage = () => {
    chat.sendGroupMessage(this.GUID, this.state.messageText).then(
      message => {
        console.log("Message sent successfully:", message);
        this.setState({ messageText: null });
      },
      error => {
        if (error.code === "ERR_NOT_A_MEMBER") {
          chat.joinGroup(this.GUID).then(response => {
            this.sendMessage();
          });
        }
      }
    );
  };
scrollToBottom = () => {
    const chat = document.getElementById("chatList");
    chat.scrollTop = chat.scrollHeight;
  };
handleSubmit = event => {
    event.preventDefault();
    this.sendMessage();
    event.target.reset();
  };
handleChange = event => {
    this.setState({ messageText: event.target.value });
  };
getUser = () => {
    chat
      .getLoggedinUser()
      .then(user => {
        console.log("user details:", { user });
        this.setState({ user });
      })
      .catch(({ error }) => {
        if (error.code === "USER_NOT_LOGED_IN") {
          this.setState({
            isAuthenticated: false
          });
        }
      });
  };
messageListener = () => {
    chat.addMessageListener((data, error) => {
      if (error) return console.log(`error: ${error}`);
      this.setState(
        prevState => ({
          groupMessage: [...prevState.groupMessage, data]
        }),
        () => {
          this.scrollToBottom();
        }
      );
    });
  };
componentDidMount() {
    this.getUser();
    this.messageListener();
    // chat.joinGroup(this.GUID)
  }
render() {
    const { isAuthenticated } = this.state;
    if (!isAuthenticated) {
      return ;
    }
    return (
      
    {this.state.groupMessage.map(data => (
    {this.state.user.uid === data.sender.uid ? (
  • {data.sender.uid}

    {data.data.text}
  • ) : (
  • {data.sender.uid}

    {data.data.text}
  • )}
    ))}
); } } export default Groupchat;<

Здесь есть много, поэтому давайте сломаем важные части вниз:

  • sendmessage () – Эта функция обрабатывает отправку сообщения в группу, передавая GUID и текстовое сообщение, которое хранится, находится в состоянии компонента. Если пользователь не является частью группы, мы сделаем запрос, чтобы присоединиться к группе, а затем снова вызвать функцию SendMessage.
  • Scrolltobottom () – Эта функция будет использоваться в качестве функции обратного вызова для прослушивателя сообщений, он просто гарантирует, что последние сообщения отображаются в списке чата.
  • handlesubmit () – Это вызывает функцию SendMessage.
  • GetUser () – Это вызывает метод Chat.getLoggedinuser () и сохраняет объект пользователя в состоянии компонента.
  • Messagelistener () – Это вызывает функцию Chat.admessagelistener () и добавляет каждое новое сообщение, полученное на GroupMessage Массив, который хранится в состоянии компонента и отображается в приложении.
  • ComponentDidMount () – Это вызывает функции GetUser и Messagelistener.

Наконец, мы оказываем класс в зависимости от того, если сообщение наше или чужое. Таким образом, мы можем применить разные стили, которые являются темой следующего раздела.

Обновите стили

Если вы должны были запустить приложение сейчас, это будет работать, но без CSS не говорят о до сих пор, он будет выглядеть совсем нечетным.

Это не учебное пособие по поводу CSS, поэтому я не буду объяснять это ни в каких деталях, но, чтобы помочь вам выполнить, вы можете вставить следующие в файл App.css (у вас уже будет один, потому что он был сгенерирован Create-React-App ранее):

.App {
  text-align: center;
  display: flex;
  width: 100%;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 50vh;
}
.App p{
  font-size: 12px;
  width: 50%;
}
.App-logo {
  animation: App-logo-spin infinite 0.5s linear;
  height: 10vmin;
}
.form {
  display: flex;
  flex-direction: column;
}
.form input[type="text"] {
  width: 300px;
  height: 30px;
  margin-bottom: 10px;
}
.form input[type="submit"] {
  padding: 5px;
  height: 30px;
  border: none;
  background-color: #187dbc;
  color: #fff;
}
.form input[type="submit"]:hover {
  border: #fff;
  cursor: pointer;
  background-color: #000;
  color: #fff;
}
.error{
  color: red;
  font-size: 10px;
  text-align: center;
}
@keyframes App-logo-spin {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}
.message {
  font-size: 15px !important;
}
body {
  background-color: #f5f5f5;
  font: 600 18px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Lato,
    Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
  color: #4b4b4b;
}
.container {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: repeat(1, 50px);
  grid-gap: 3px;
  margin-top: 15px;
}
.group {
  background: #4eb5e5;
  grid-column-start: 1;
  grid-column-end: 2;
  grid-row-start: 1;
  grid-row-end: 190;
  border-radius: 5px;
}
.chatWindow {
  display: grid;
  grid-column-start: 2;
  grid-column-end: 9;
  grid-row-start: 1;
  grid-row-end: 190;
  background: rgb(233, 229, 229);
  border-radius: 5px;
}
.chatInputWrapper {
  display: grid;
  grid-row-start: 190;
  grid-row-end: 190;
}
::-webkit-scrollbar {
  display: none;
}
/* M E S S A G E S */
.chat {
  list-style: none;
  background: none;
  margin: 0;
  padding: 0 0 50px 0;
  margin-top: 60px;
  margin-bottom: 10px;
  max-height: 400px;
  overflow: scroll;
  scroll-behavior: smooth;
}
.chat li {
  padding: 0.5rem;
  overflow: hidden;
  display: flex;
}
.chat .avatar {
  position: relative;
  display: block;
  z-index: 2;
}
.chat .avatar img {
  background-color: rgba(255, 255, 255, 0.9);
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
}
.chat .uid img {
  background-color: rgba(255, 255, 255, 0.9);
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
}
.chat .day {
  position: relative;
  display: block;
  text-align: center;
  color: #c0c0c0;
  height: 20px;
  text-shadow: 7px 0px 0px #e5e5e5, 6px 0px 0px #e5e5e5, 5px 0px 0px #e5e5e5,
    4px 0px 0px #e5e5e5, 3px 0px 0px #e5e5e5, 2px 0px 0px #e5e5e5,
    1px 0px 0px #e5e5e5, 1px 0px 0px #e5e5e5, 0px 0px 0px #e5e5e5,
    -1px 0px 0px #e5e5e5, -2px 0px 0px #e5e5e5, -3px 0px 0px #e5e5e5,
    -4px 0px 0px #e5e5e5, -5px 0px 0px #e5e5e5, -6px 0px 0px #e5e5e5,
    -7px 0px 0px #e5e5e5;
  box-shadow: inset 20px 0px 0px #e5e5e5, inset -20px 0px 0px #e5e5e5,
    inset 0px -2px 0px #d7d7d7;
  line-height: 38px;
  margin-top: 5px;
  margin-bottom: 20px;
  cursor: default;
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
}
.other .msg {
  order: 1;
  border-top-left-radius: 0px;
  box-shadow: -1px 2px 0px #d4d4d4;
}
.other:before {
  content: "";
  position: relative;
  top: 0px;
  right: 0px;
  left: 40px;
  width: 0px;
  height: 0px;
  border: 5px solid #fff;
  border-left-color: transparent;
  border-bottom-color: transparent;
}
.self {
  justify-content: flex-end;
  align-items: flex-end;
}
.self .msg {
  order: 1;
  border-bottom-right-radius: 0px;
  box-shadow: 1px 2px 0px #d4d4d4;
}
.self .avatar {
  order: 2;
}
.self .avatar:after {
  content: "";
  position: relative;
  display: inline-block;
  bottom: 19px;
  right: 0px;
  width: 0px;
  height: 0px;
  border: 5px solid #fff;
  border-right-color: transparent;
  border-top-color: transparent;
  box-shadow: 0px 2px 0px #d4d4d4;
}
.msg {
  background: white;
  min-width: fit-content;
  padding: 10px;
  border-radius: 10px;
  box-shadow: 0px 2px 0px rgba(0, 0, 0, 0.07);
}
.msg p {
  font-size: 0.8rem;
  margin: 0 0 0.2rem 0;
  color: rgb(81, 84, 255);
}
.msg img {
  position: relative;
  display: block;
  width: 450px;
  border-radius: 5px;
  box-shadow: 0px 0px 3px #eee;
  transition: all 0.4s cubic-bezier(0.565, -0.26, 0.255, 1.41);
  cursor: default;
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
}
@media screen and (max-width: 800px) {
  .msg img {
    width: 300px;
  }
}
@media screen and (max-width: 550px) {
  .msg img {
    width: 200px;
  }
}
.msg time {
  font-size: 0.7rem;
  color: #ccc;
  margin-top: 3px;
  float: right;
  cursor: default;
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
}
.msg time:before {
  content: " ";
  color: #ddd;
  font-family: FontAwesome;
  display: inline-block;
  margin-right: 4px;
}
::-webkit-scrollbar {
  min-width: 12px;
  width: 12px;
  max-width: 12px;
  min-height: 12px;
  height: 12px;
  max-height: 12px;
  background: #e5e5e5;
}
::-webkit-scrollbar-thumb {
  background: rgb(48, 87, 158);
  border: none;
  border-radius: 100px;
  border: solid 3px #e5e5e5;
  box-shadow: inset 0px 0px 3px #999;
}
::-webkit-scrollbar-thumb:hover {
  background: #b0b0b0;
  box-shadow: inset 0px 0px 3px #888;
}
::-webkit-scrollbar-thumb:active {
  background: #aaa;
  box-shadow: inset 0px 0px 3px #7f7f7f;
}
::-webkit-scrollbar-button {
  display: block;
  height: 26px;
}
/* T Y P E */
input.textarea {
  width: 100%;
  height: 50px;
  background: #fafafa;
  border: none;
  outline: none;
  padding-left: 55px;
  padding-right: 55px;
  color: #666;
  font-weight: 400;
}

Заключение

Запустите приложение с NPM начать И низко и вот, ваше приложение чата завершено. По крайней мере, основная функциональность на месте. С COMPTHAT вы можете легко расширить приложение, чтобы включить «онлайн-список» Кто онлайн, прямые сообщения, медиа-сообщения и куча других функций.

Эта статья была первоначально опубликована на Chetchat’s блог .

Оригинал: “https://www.freecodecamp.org/news/building-a-modern-chat-application-with-react-js-558896622194/”