În acest tutorial, vă voi ghida să creați propria aplicație de chat de grup folosind React, React Router și CometChat Pro. Da, mai degrabă decât să lansăm propriul server, vom folosi în schimb CometChat Pro pentru a gestiona trimiterea și primirea în timp real a mesajelor de chat.

Când ați terminat, ar trebui să aveți o aplicație de chat funcțională care să arate cam așa (desigur, sunteți binevenit să modificați și să experimentați lucrurile pe măsură ce mergeți mai departe):

Cum sa construiti o aplicatie de chat moderna cu Reactjs
1611319208 123 Cum sa construiti o aplicatie de chat moderna cu Reactjs

Am structurat acest tutorial ca o serie de pași pentru a face mai ușor de urmat. Dacă doriți doar să verificați codul, Click aici.

Configurarea proiectului

Înainte de a merge prea departe, trebuie mai întâi să ne configurăm proiectul React. Pentru a face acest lucru, vom folosi o bijuterie mai puțin cunoscută numită Creați aplicația React.

Cel mai bun lucru? Deoarece aveți npm instalat, puteți utiliza npx pentru a instala și rula create-react-app într-un singur pas:

npx create-react-app chatapp // note: npm v5.2+

După executarea acestei comenzi, va fi creat un nou folder numit „chatapp” cu următoarea structură:

1611319208 8 Cum sa construiti o aplicatie de chat moderna cu Reactjs

În plus, pentru a React, va trebui să instalăm și React Router și CometChat Pro SDK. Pentru a face acest lucru, mergeți la directorul chatapp și rulați:

npm install react-router-dom @cometchat-pro/chat --save

Adăugați React Router

În cele din urmă, aplicația noastră va avea două pagini – una numită Login unde utilizatorul se va conecta și altul sunat Groupchat unde vom reda camera de chat. Vom folosi React Router pentru a direcționa utilizatorii către pagina de care au nevoie.

Pentru a configura React Router, trebuie mai întâi să importăm Router împachetare componentă din fișierul index.js. Eu o numesc o componentă de împachetare pentru că noi ne înfășurăm App în interiorul Router componentă.

Înlocuiți index.js cu acest fragment:

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(
  <Router>
    <App />
  </Router>
  , document.getElementById('root'));

index.js este punctul de intrare pentru aplicația noastră. Singura sa sarcină reală este să ne redăm aplicația React. Majoritatea logicii noastre „reale” se întâmplă într-un fișier numit App.js, pe care îl vom modifica în continuare.

În App.js, trebuie să importăm dependențe suplimentare de React Router care ne vor permite să redăm diferite componente în funcție de ruta pe care a încărcat-o utilizatorul. De exemplu, dacă utilizatorul merge pe ruta „/ login”, ar trebui să redăm componenta Login. La fel, dacă utilizatorul merge pe ruta „/ chat”, ar trebui să redăm Groupchat componentă:

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 (
      <Switch>
        <Redirect exact from="/" to="/login" />
        <Route path="/login" component={Login} />
        <Route path="/chat" component={Groupchat} />
      </Switch>
    );
  }
}
export default App;

Dacă încercați să rulați acest cod, va genera cu siguranță unele erori, deoarece nu am făcut Login și Groupchat componente. Să facem asta acum.

Creați componenta Login

Pentru a menține proiectul frumos și ordonat, creați un folder numit components pentru a păstra componentele noastre personalizate.

Apoi, în acel folder nou creat, creați un fișier numit Login.js cu următorul cod:

import React from "react";
class Login extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
    };
  }
  render() {
    return ( 
      <div className="App">
        <h1>Login</h1>
      </div>
    );
  }
}
export default Login;

Tot ceea ce facem aici este să exportăm o componentă cu textul antetului „Conectare”. Vom rezolva această componentă în curând, dar, în acest moment, noi doar creăm un cazan.

Creați componenta Groupchat

În același folder de componente, creați o componentă nouă numită Groupchat.js:

import React from "react";
class Groupchat extends React.Component {
  constructor(props) {
    super(props);
  }
  render() {
    return <div className="chatWindow" />;
  }
}
export default Groupchat;

Pe măsură ce progresăm prin tutorial, vom dezvolta această componentă umilă în nucleul aplicației noastre de chat.

Cu Groupchat și Login componente la locul lor, ar trebui să puteți rula aplicația fără o eroare. Deschideți aplicația pe localhost și navigați la localhost: 3000 / login și apoi localhost: 3000 / chat pentru a vedea componentele în acțiune.

Creați ID-ul APP și cheia API CometChat

Așa cum am menționat la începutul tutorialului, nu vom lansa propriul server în acest tutorial. În schimb, vom folosi un serviciu găzduit de CometChat Pro.

Înainte de a ne putea conecta la CometChat, trebuie mai întâi să creăm o aplicație CometChat din tabloul de bord:

1611319208 876 Cum sa construiti o aplicatie de chat moderna cu Reactjs

Odată ce aplicația dvs. a fost creată, apăsați „Explorați”, apoi accesați fila „Chei API”:

1611319208 264 Cum sa construiti o aplicatie de chat moderna cu Reactjs

Faceți clic pe „Creați cheia API” și completați formularul, alegând domeniul de aplicare Numai autentificare. Din tabel, puteți nota ID-ul aplicației și cheia aplicației, vom avea nevoie de acestea în scurt timp.

Creați ID-ul grupului CometChat

În timp ce avem tabloul de bord deschis, să creăm și un grup. În mod normal, veți face acest lucru cu codul (de exemplu, puteți permite utilizatorului să creeze un grup de chat personalizat pentru echipa sau proiectul său prin aplicația dvs.), dar pentru învățare și testare, tabloul de bord este în regulă.

Mergeți la fila „Grupuri” și creați un grup nou numit testgroup:

1611319209 812 Cum sa construiti o aplicatie de chat moderna cu Reactjs

Ca și ultima dată, veți fi readus la un tabel unde puteți nota ID-ul grupului:

1611319209 686 Cum sa construiti o aplicatie de chat moderna cu Reactjs

Rețineți că vom avea nevoie de acest lucru în pasul următor.

Creați fișierul de configurare

Pentru a face mai ușoară referirea la configurația noastră, creați un nou fișier numit config.js și lipiți acreditările:

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

Acum puteți închide tabloul de bord. Odată ce ați configurat CometChat, toată interacțiunea are loc prin cod.

Creați o clasă CometChat Manager

Unul dintre lucrurile frumoase despre React este că se pretează la o separare a preocupărilor. Componentele noastre se pot concentra exclusiv pe prezentare, în timp ce putem crea alte module pentru a gestiona lucruri precum preluarea datelor și gestionarea stării.

Pentru a profita cu adevărat de acest lucru, să creăm un folder nou numit „lib” și în acel folder nou, un fișier numit chat.js. Aici va avea loc toată interacțiunea noastră cu CometChat:

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);
        }
      })
    );
  }
}

În afară de a ne permite să creăm o separare a preocupărilor, prezentarea codului astfel face, de asemenea, mai ușor de digerat.

Permiteți-mi să explic câteva părți importante ale acestui modul, începând de sus:

  • LISTENER_KEY_MESSAGE – Acest lucru este cerut de ascultătorul de mesaje.
  • init() – Este necesar să fie apelat o singură dată pe tot parcursul ciclului de viață al aplicației, se numește CometChat init metoda cu appID.
  • getTextMessage(uid, text, msgType) – creează obiectul mesaj pe baza CometChat.TextMessage, acceptă UID (GUID în cazul nostru) și mesajul text de trimis.
  • getLoggedInUser() – este folosit pentru a obține utilizatorul conectat în prezent.
  • login() – este folosit pentru a vă conecta la un utilizator pe baza metodei CometChat.login, ia UID (GUID în cazul nostru) și apiKey.
  • getGroupMessages(GUID, callback, limit = 30) – aceasta este utilizată pentru a obține mesajele de grup anterioare de la CometChat folosind CometChat.MessagesRequestBuilder() metoda care ia GUID și limitează ca parametri.
  • sendGroupMessage(UID, message)– aceasta este utilizată pentru a trimite mesaje folosind CometChat.sendMessage() metoda și acceptă GUID și mesajul ca parametri.
  • joinGroup(GUID) – Este folosit pentru a vă alătura unui grup ales folosind un GUID.
  • addMessageListener(callback) – Folosește CometChat.addMessageListener() pentru a asculta mesaje (am menționat că acest lucru este apelat în timp real?), necesită LISTENER_KEY_MESSAGE ca parametru și, de asemenea, un apel invers care este apelat la primirea unui mesaj.

Aici nu este nimic specific acestei aplicații. S-ar putea să luați acest modul, să îl extindeți dacă este necesar și să îl importați într-un alt proiect. În general, totuși, acesta este doar un înveliș subțire în jurul SDK-ului.

Actualizați componenta de conectare

Cu toate configurația și codul de chat la locul nostru, putem acum să construim rapid interfața de utilizare începând cu Login componentă.

Doar pentru a vă reaminti, așa va arăta componenta Login:

1611319209 203 Cum sa construiti o aplicatie de chat moderna cu Reactjs

După cum puteți vedea, funcția sa principală este de a cere utilizatorului numele acestuia. Odată furnizat un nume, redăm Groupchat componentă.

A inlocui Login.js cu:

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 (
        <Redirect
          to={{
            pathname: "/chat",
            state: { user: this.state.user }
          }}
        />
      );
    }
    return (
      <div className="App">
        <h1>COMETCHAT</h1>
        <p>Create an account through your CometChat dashboard or login with one of our test users, superhero1, superhero2, etc.</p>
        <form className="form" onSubmit={this.onSubmit}>
          <input onChange={this.handleInputChange} type="text" />
          <span className="error">{this.state.errorMessage}</span>
          {this.state.isSubmitting ? (
            <img src={spinner} alt="Spinner component" className="App-logo" />
          ) : (
            <input
              type="submit"
              disabled={this.state.username === ""}
              value="LOGIN"
            />
          )}
        </form>
      </div>
    );
  }
}
export default Login;

În afară de HTML-ul de prezentare, majoritatea codului de aici este dedicat manipulării unui Reacționează forma.

Actualizați componenta Groupchat

Componenta Groupchat are mult mai multă responsabilitate decât componenta Login. Ca un memento rapid, așa va arăta:

1611319209 965 Cum sa construiti o aplicatie de chat moderna cu Reactjs

În cea mai mare parte, Groupchat sarcina componentei este de a conecta modulul de chat lib și interfața de utilizare pe care o vom prezenta utilizatorului. De exemplu, atunci când un utilizator trimite un mesaj, apelăm chat.sendMessage și pe măsură ce mesajele noi intră, o funcție de apel invers este numită:

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 <Redirect to="/" />;
    }
    return (
      <div className="chatWindow">
        <ul className="chat" id="chatList">
          {this.state.groupMessage.map(data => (
            <div key={data.id}>
              {this.state.user.uid === data.sender.uid ? (
                <li className="self">
                  <div className="msg">
                    <p>{data.sender.uid}</p>
                    <div className="message"> {data.data.text}</div>
                  </div>
                </li>
              ) : (
                <li className="other">
                  <div className="msg">
                    <p>{data.sender.uid}</p>
                   <div className="message"> {data.data.text} </div>
                  </div>
                </li>
              )}
            </div>
          ))}
        </ul>
        <div className="chatInputWrapper">
          <form onSubmit={this.handleSubmit}>
            <input
              className="textarea input"
              type="text"
              placeholder="Enter your message..."
              onChange={this.handleChange}
            />
          </form>
        </div>
      </div>
    );
  }
}
export default Groupchat;<

Există multe de digerat aici, așa că haideți să descompunem părțile importante:

  • sendMessage() – Această funcție gestionează trimiterea unui mesaj către grup, trecerea GUID-ului, iar mesajul text stocat se află în starea componentei. Dacă utilizatorul nu face parte din grup, vom face o cerere de aderare la grup și apoi vom apela din nou funcția sendMessage.
  • scrollToBottom() – Această funcție va fi utilizată ca funcție de apel invers pentru ascultătorul de mesaje, ci doar se asigură că ultimele mesaje sunt afișate în lista de chat.
  • handleSubmit() – Aceasta apelează funcția sendMessage.
  • getUser() – Aceasta apelează metoda chat.getLoggedInUser () și stochează obiectul utilizator în starea componentei.
  • messageListener() – Aceasta apelează funcția chat.addMessageListener () și adaugă fiecare mesaj nou primit la groupMessage matrice care este stocată în starea componentei și redată în aplicație.
  • componentDidMount() – Aceasta apelează funcțiile getUser și messageListener.

În cele din urmă, redăm o clasă în funcție de dacă mesajul este al nostru sau al altuia. În acest fel, putem aplica diferite stiluri, care este subiectul secțiunii următoare.

Actualizați stilurile

Dacă ar fi să rulați aplicația acum, ar funcționa, dar fără CSS de care să vorbiți până acum, ar părea destul de uh, ciudat.

Acesta nu este un tutorial despre CSS, așa că nu îl voi explica în detaliu, dar pentru a vă ajuta să urmăriți, puteți lipi următoarele în fișierul App.css (veți avea deja unul deoarece a fost generat de create-react-app mai devreme):

.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;
}

Concluzie

Rulați aplicația cu npm start și jos și iată, aplicația dvs. de chat este completă. Cel puțin, funcționalitatea de bază este la locul său. Cu CometChat, puteți extinde cu ușurință aplicația pentru a include o „listă online cine este”, mesaje directe, mesaje media și o grămadă de alte caracteristici.

Acest articol a fost publicat inițial pe Cometchat blog.