Facebook Like Chat Application using React JS, PHP and jQuery

  Reading Time:

This is similar to the previous chat application i have created except this uses React for the UI instead of jQuery. React JS is really amazing in creating UI. React uses Virtual DOM instead of the real DOM to find the difference between an UI update and hits the original DOM with a very minial update. React Components provide a convenient way to express the UI design constructed.

Facebook Like Chat Application using ReactJS

Database Design

Database Schema

The database design is pretty much same as that is used in the previous chat application.

The FbChatMock class is same as the one previously used, so there is no change in that.

Chat/Index Page

This is where the chat is loaded. Remeber to pass the user_id in the url for setting the current chat user id.

<!DOCTYPE html>
  <html>
    <head>
      <meta charset="UTF-8">
      <title>Facebook Chat application using React JS, PHP and MySQL</title>
      <link href="style/core.css" rel="stylesheet" type="text/css" />
    </head>
    <body>
      <?php
      @session_start();
      
      $_SESSION['user_id'] = isset($_GET['user_id']) ? (int) $_GET['user_id'] : 0;
      
      // Load the messages initially
      require_once __DIR__ . '/../core/FbChatMock.php';
      $chat = new FbChatMock();
      $messages = $chat->getMessages();
      ?>
      <!-- This is the React main render container -->
      <div id="container"></div>
      <!-- Load JS at bottom for performance -->
      <script type="text/javascript" src="scripts/jquery-1.11.0.min.js"></script>
      <script type="text/javascript" src="scripts/react.js"></script>
      <script type="text/javascript" src="scripts/JSXTransformer.js"></script>
      <script type="text/jsx" src="scripts/react-chat.js"></script>
    </body>
  </html>

The HTML is pretty much simple, because React will take care of the rest.

Ajax Components

There are two ajax components.

  1. get_messages.php – Get’s the messages from the database and sends it in JSON format.
  2. add_msg.php – Add’s a messsage to the database, fetches the messsages and sends it back as a JSON

get_messages.php

<?php
  require_once __DIR__ . '/../../core/FbChatMock.php';
  
  $chat = new FbChatMock();
  $messages = $chat->getMessages();
  $chat_converstaion = array();
  
  if (!empty($messages)) {
    foreach ($messages as $message) {
      $chat_id = (int) $message['chat_id'];
      $msg = htmlentities($message['message'], ENT_NOQUOTES);
      $user_name = ucfirst($message['username']);
      $sent = date('F j, Y, g:i a', $message['sent_on']);
      $chat_converstaion[] = array (
          'username' => $user_name,
          'message' => $msg,
          'time' => $sent,
          'id' => $chat_id
      );
    }
    $response = json_encode($chat_converstaion);
  } else {
    echo '<span style="margin-left: 25px;">No chat messages available!</span>';
  }
  
  header('Content-type: application/json');
  echo $response;
  ?>

add_msg.php

<?php
  session_start();
  
  if (isset($_POST['msg'])) {
    require_once __DIR__ . '/../../core/FbChatMock.php';
    
    $userId = (int) $_SESSION['user_id'];
    // Escape the message string
    $msg = htmlentities($_POST['msg'],  ENT_NOQUOTES);
    
    $chat = new FbChatMock();
    $result = $chat->addMessage($userId, $msg);
    // Send back the updated messages
    $messages = $chat->getMessages();
    $chat_converstaion = array();
  
    if (!empty($messages)) {
      foreach ($messages as $message) {
        $chat_id = (int) $message['chat_id'];
        $msg = htmlentities($message['message'], ENT_NOQUOTES);
        $user_name = ucfirst($message['username']);
        $sent = date('F j, Y, g:i a', $message['sent_on']);
        $chat_converstaion[] = array (
            'username' => $user_name,
            'message' => $msg,
            'time' => $sent,
            'id' => $chat_id
        );
      }
      $response = json_encode($chat_converstaion);
    } else {
      echo '<span style="margin-left: 25px;">No chat messages available!</span>';
    }
  
    header('Content-type: application/json');
    echo $response;
  }
  ?>

React JS

This the main React js script where all the rendering of the Chat components takes place. React allows us to express the design that we make and convert them to components that is finally rendered as a web component. Below is the component structure of the Chat application.

React Components Structure
-ChatContainer
      -ChatHeader
      -Messages
          -Row(Loop)
      -ChatFooter
/**
   * This is the chat header component,
   * Data inside this is static based on the browser url
   */
  var ChatHeader = React.createClass({
    render: function() {
      // To display the username
      if (/user_id=1/i.test(window.location.search)) {
        name = 'John';
      } else {
        name = 'Scott';
      }
      
      return (
        <div className="msg-wgt-header">
          <a href="#">{name}</a>
        </div>
      );
    }
  });
  
  // This is the chat row component
  var Row = React.createClass({
    render: function() {
      return (
        <div className="msg-row-container">
          <div className="msg-row">
            <div className="avatar"></div>
            <span className="user-label">
              <a href="#" className="chat-username">{this.props.username}</a> <span className="msg-time">{this.props.time}</span>
            </span><br/>
            {this.props.message}
          </div>
        </div>
      );
    }
  });
  
  /**
   * Messages component
   */
  var Messages = React.createClass({
    render: function() {
      // This is how you set inline styles in React
      var inlineStyles = {
        height: '300px',
        overflowY: 'scroll'
      };
    
      // Loop through the list of chats and create array of Row components
      var Rows = this.props.datas.map(function(data) {
        return (
          <Row key={data.id} username={data.username} time={data.time} message={data.message} />
        )
      });
      
      return (
        <div style={inlineStyles}>
          {Rows}
        </div>
      );
    }
  });
  
  /**
   * This component contains the chat textarea
   */
  var ChatFooter = React.createClass({
    // Message send event handler
    handleUserMessage: function(event) {
      // When shift and enter key is pressed
      if (event.shiftKey && event.keyCode === 13) {
        var msg = this.refs.textArea.getDOMNode().value.trim();
        if (msg !== '') {
          // call the sendmessages of ChatContainer throught the props
          this.props.sendMessage(msg);
        }
        // Prevent default and clear the textarea
        event.preventDefault();
        this.refs.textArea.getDOMNode().value = null;
      }
    },
    
    render: function() {
      return (
        <div className="msg-wgt-footer">
          <textarea id="chatMsg" ref="textArea" onKeyDown={this.handleUserMessage} placeholder="Type your message. Press shift + Enter to send" />
        </div>
      );
    }
  });
  
  var ChatContainer = React.createClass({
    // Load the initial chats
    getInitialState: function() {
      return {datas: []};
    },
    
    // Get's the list of messages from the server and set's the state,
    // so that it re-renders the Messages
    getMessages: function() {
      $.ajax({
        url: 'ajax/get_messages.php',
        dataType: 'json',
        success: function(data) {
          this.setState({datas: data});
        }.bind(this)
      });
    },
    
    // Will add a new message and update the messages list
    sendMessage: function(message) {
      var that = this;
      $.ajax({
        url: 'ajax/add_msg.php',
        method: 'post',
        dataType: 'json',
        data: {msg: message},
        success: function(data) {
          this.setState({datas: data});
        }.bind(this)
      });
    },
    
    componentDidMount: function() {
      // get the list of messages
      this.getMessages();
      // set the poll interval
      setInterval(this.getMessages, 5000);
    },
    
    render: function() {
      return (
        <div className="chat-container">
          <ChatHeader />
          <Messages datas={this.state.datas} />
          <ChatFooter sendMessage={this.sendMessage} />
        </div>
      );
    }
  });
  
  // React entry point
  React.render(
    <ChatContainer />,
    document.getElementById('container')
  );

CSS Style

core.css

.chat-container {
    bottom: 0px;
    width: 250px;
    position: fixed;
    z-index: 300;
    right: 50px;
    border-top-right-radius: 3px;
    border-top-left-radius: 3px;
    font-family: 'tahoma';
    font-size: 12px;
    border: 1px solid lightgray;
  }
  
  /* message box header styles*/
  
  .msg-wgt-header {
    background-color: #6D84B4;
    border: 1px solid rgba(67, 106, 187, 0.76);
    border-top-right-radius: 3px;
    border-top-left-radius: 3px;
    color: white;
    text-align: center;
    height: 28px;
  }
  
  .msg-wgt-header a {
    text-decoration: none;
    font-weight: bold;
    color: white;
    vertical-align: middle;
  }
  
  /* message box body styles*/
  
  .msg-row-container {
    border-bottom: 1px solid lightgray;
  }
  
  .msg-row {
    width: 100%;
    display: inline-block;
  }
  
  .message {
    margin-left: 40px;
  }
  
  /* Message box footer styles*/
  
  .msg-wgt-footer {
    height: 42px;
  }
  
  .msg-wgt-footer textarea {
    width: 95%;
    font-family: 'tahoma';
    font-size: 13px;
    padding: 5px;
  }
  
  .user-label {
    font-size: 11px;
  }
  
  .chat-username {
    color: '#6D84B4';
  }
  
  .msg-time {
    font-size: 10px;
    float: right;
    color: gray;
  }
  
  .avatar {
    width: 30px;
    height: 30px;
    float: left;
    background: url('/chat/public/assets/chat_avatar.png');
    border: 1px solid lightgray;
  }

If you have any queries leave a comment and subscribe to get more of updates like this.

Linux chmod Command Clearly Explained

In the Linux environment not all the users have permission to modify files and have access to directories. There are a set of user access permissions...

Implementing Enum Using Late Static Binding in PHP

It has been a while since i programmed in Java. One of the type features of Java that can be implemented in PHP is Enum, which...