Zoom Clone with React and 100ms SDK (part I)

benjaminbusari

Benjamin Busari

Posted on July 4, 2022

Zoom Clone with React and 100ms SDK (part I)

Video conferencing tools, like Zoom, and GoogleMeet allow individuals to meet and work together productively "face-to-face" when meeting in person isn't possible. This makes meeting remotely much more human, which is essential in order to help users feel and stay connected.

Zoom is a cloud-based video conferencing platform that can be used for video conferencing meetings, audio conferencing, webinars, meeting recordings, and live chat. You need a free account to start your own calls for up to 100 people; paid versions can support up to 1,000 people. You can make unlimited phone calls, hold unlimited meetings, and even record both.

Prerequisites and What You Will Learn

As a prerequisite to understanding and following this tutorial, you should have basic knowledge of React and CSS.

In this article, you will learn how to build this clone using the following concepts:

  • Creating a new React Application
  • Styling with CSS.
  • Setting up the Video Conference (This section is covered in detail here).

This tutorial will cover the following:

  • Creating a Zoom Clone layout.
  • Setting buttons for muting and unmuting the audio and video for both local and remote peers.
  • Setting buttons for sharing the screen for presentation for the host.
  • Setting buttons for recording the meeting
  • Creating a chat layout

Let’s Build Our Zoom Clone App

Developers Setup

For this tutorial, you will install packages with NPM, so you need to have Node installed on your system. Alternatively, you can use yarn if you prefer that.

For this tutorial, I used Node v16.15.0. I encourage you to use the same version if you are coding along.

  • Create a React App: Use npm for boilerplate to create react app.
npx create-react-app zoomclone
Enter fullscreen mode Exit fullscreen mode

The first thing to do now is to navigate into your public folder and open the index.html file, we need to import bootstrap in the index.html file for styling.


    <!-- Optional theme -->
        //This should be pasted in the <head> tag

    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap-theme.min.css"
        integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">

    <script defer src="https://unpkg.com/peerjs@1.3.1/dist/peerjs.min.js"></script>

        <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>

        <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>

    <link rel="stylesheet" href="style.css">
    <script src="https://kit.fontawesome.com/c939d0e917.js"></script>

   //While the bootstrap.min.js should be pasted in the <body> tag
  <body>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js"
    integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa"
    crossorigin="anonymous"></script>
  </body>
Enter fullscreen mode Exit fullscreen mode

The next thing to do is to navigate inside your SRC folder and create a folder naming it Components.

Inside the Component folder, let’s create a navBar.jsx file. It should look like this:

import React from 'react';
import './navBar.css';

const NavBar = () => {
    return(
        <nav className="navbar">
            <div className="container-fluid">
                <div className="navbar-header">
                    <button type="button" className="navbar-toggle collapsed" data-toggle="collapse"
                        data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
                        <span className="sr-only">Toggle navigation</span>
                        <span className="icon-bar"></span>
                        <span className="icon-bar"></span>
                        <span className="icon-bar"></span>
                    </button>
                    <a className="navbar-brand" href="https://google.com">
                        <img className="navbar-logo"
                            src="https://static.zoom.us/static/6.1.6656/image/new/ZoomLogo.png"
                            srcSet="https://static.zoom.us/static/6.1.6656/image/new/ZoomLogo.png 1x"
                            alt="Zoom logo" aria-hidden="true" data-iml="1243.5999999940395"
                            data-atf="true" />
                    </a>
                </div>
            <div className="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
                <ul className="nav navbar-nav navbar-right">
                    <li>
                        <a href="https://zoom.com" style={{fontSize: 15}}> Join</a>
                    </li>
                    <li>
                        <a href="https://zoom.com" style={{fontSize: 15}}>Host</a>
                    </li>
                    <li>
                        <a href="https://zoom.com" style={{fontSize: 15}}>Sign In</a>
                    </li>
                    <li>
                        <a className='signup'>SIGN UP IT'S FREE</a>
                    </li>
                </ul>
            </div>
        </div>
    </nav>
    )
}

export default NavBar;
Enter fullscreen mode Exit fullscreen mode

Next, is to create a navBar.css file so we can style the Navbar.

.navbar {
    background-color: #fff;
}
.navbar-logo {
    width:50%;
    height:100%;
    margin-left: 30px;
}
#time_date {
    font-size: 17px;
    font-weight: 800;
    text-decoration: none;
    color: #000;
}
.signup {
    background-color: #F26D20;
    margin-top: 5px;
    border-radius: 30px;
    color: #fff;
}
Enter fullscreen mode Exit fullscreen mode

Inside the Component folder, let's create our landing page. This is what we see first when we open the application. This for us will be the foundation of our application.

Inside the Component folder, create a file and name it JoinForm.jsx.
Your JoinForm.jsx file should be like this:

import React from 'react';
import './style.css';
import NavBar from './navBar';

const JoinRoom = () => {
    return(
        <>
            <NavBar />
            <hr></hr>
            <div id="content_container" style={{minHeight: 872}}  className="zoom-newcontent ">
                <div id="content" className="main-content">
                    <div className="mini-layout" id="join-conf">
                        <div className="mini-layout-body">
                            <h1 style={{fontSize: 25}}>Join Meeting</h1>
                            <div className="box">
                                <form id="join-form" className="form-vertical">
                                    <div className="form-group confno" style={{marginBottom: 30}}>
                                        <div className="controls">
                                            <label htmlFor="join-confno" style={{color: 747486, fontSize: 15,marginBottom: 10}}>Meeting ID or Personal Link Name</label>
                                            <input aria-describedby="rule-tip" id="join-confno" 
                                                type="text" 
                                                className="form-control input-lg confno" 
                                                autoComplete="off" maxLength="100" 
                                                placeholder="Enter Meeting ID or Personal Link Name"
                                                name="userName"
                                                required
                                                />
                                            <div id="errorContainer" className="wc-new-syle">
                                                <div id="join-errormsg" className="error hideme"><i></i><span></span></div>
                                            </div>
                                        </div>
                                    </div>
                                    <div className="form-group" style={{marginBottom: 16}}>
                                        <div className="controls">
                                            By clicking "Join", you agree to our <a href="https://zoom.us/terms">Terms of Services</a> and <a href="https://zoom.us/privacy">Privacy Statement</a>
                                        </div>
                                    </div>
                                    <div className="form-group" style={{marginBottom: 72}}>
                                        <div className="controls wc-new-syle">
                                            <button id="btnSubmit" role="button" style={{ width: 200, padding: 5}} className="btn btn-primary user submit">Join</button>
                                        </div>
                                    </div>
                                    <div className="form-group">
                                        <div className="controls wc-new-syle">
                                            <a id="btnRoomSystemJoin" className="doc" href="https://zoom.us/meeting/rooms">Join a meeting from an H.323/SIP room system</a>
                                        </div>
                                    </div>
                                </form>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </>       
    )
}
export default JoinRoom;
Enter fullscreen mode Exit fullscreen mode

Let’s style the JoinForm, create a file, and name it styles.css

#content_container {
    min-height: 600px;
}
.form-control.input-lg.confno {
    font-size: 20px;
    height: 56px;
    text-align: center;
    width: 100%;
    margin-left: 0;
}
h1{
    text-align: center;
    margin-top: 100px;
}
#join-form {
    max-width: 360px;
    margin: 0 auto;
    margin-top: 50px;
}
#join-form .form-control, #join-form .btn {
    border-radius: 12px;
}
.links {
    font-size: 16px;
    color: #68687b;
}
.links a {
    color: #0E71EB;
    display: inline-block;
}
@media (max-width: 767px) {
    .form-horizontal .form-group {
        margin-left: 0;
        margin-right: 0;
    }
    #roomSystemDialog .modal-footer {
        padding-left: 20px;
        }
}
.form-control.input-lg.confno {
    font-size: 15px;
    text-align: left;
}
.form-control:focus {
    border: 2px solid #0E72ED;
}
.input-lg{
    height: 40px !important;
}
#join-conf .btn.user {
    height: 40px !important;
    font-size:16px;
    line-height:31px !important
}
.wc-new-syle{
    text-align: center;
}
Enter fullscreen mode Exit fullscreen mode

The JoinForm page should look like this:

JoinForm

The upper part is the navBar we imported in the JoinForm.js file.

Now, let’s create a ControlBar, this is where we set the control buttons for our zoom application, this is an integral part of the application we are building.

import React from "react";

const ControlBar = () => 
  return (
    <div class="main__controls">
        <div className="main__controls__block">
            <div className="main__controls__button main__mute_button">
               <i className="fas fa-microphone"></i>
               <span>Mute</span>
            </div>
            <div className="main__controls__button main__video_button" >
               <i className="fas fa-video"></i>
               <span>Stop Video</span>
            </div>
            <div className="main__controls__button">
                <i className="fas fa-shield-alt"></i>
                <span>Security</span>
            </div>
            <div className="main__controls__button">
                <i className="fas fa-user-friends"></i>
                <span>Participants</span>
            </div>
            <div className="main__controls__button">
                <i className="fas fa-comment-alt"></i>
                <span>Chat</span>
            </div>
            <div className="main__controls__button main__video_button" >
                <i className="fas fa-desktop"></i>
                <span>Share Screen</span>
            </div>
            <div className="main__controls__button">
                <i className="fas fa-record-vinyl"></i>
                <span>Record </span>
            </div>
            <div className="main__controls__button">
                <i className="fas fa-laugh"></i>
                <span>Reactions</span>
            </div>
            <div className="main__controls__button">
                <i className="fas fa-retweet"></i>
                <span>Apps</span>
            </div>
            <div className="main__controls__button">
                <i className="fas fa-clipboard"></i>
                <span>Whiteboard</span>
            </div>
        </div>
        <div className="main__controls__block">
          <div className="main__controls__button">
            <span className="leave_meeting">Leave Meeting</span>
          </div>
        </div>
    </div>
  );
};

export default ControlBar;
Enter fullscreen mode Exit fullscreen mode

💥The control buttons are ready but not functional yet, in the next series to this article, you would see how the buttons work.

Now, let’s create our room, this is where the video tile displays.

Create a file and name it Room.js, the room.js file should look like this:

import React from "react";
import ControlBar from "./Control/ControlBar";

import './view.css';

const Room = () => {

  return (
    <div class="main"> 
      <div class="main__left">
        <div class="main__videos">
          <div id="video-grid">
            <div className="flex flex-col mt-20">
              <div className="flex bg-gray-900 w-screen min-h-screen p-2 flex-wrap">
                <h3>VIDEO</h3>
              </div>
            </div> 
          </div>
        </div>
        <ControlBar />
      </div>
      <div className="main__right">
          <div className="main__header">
              <h6>Chat</h6>
          </div>
          <div className="main__chat_window">
              <ul className="messages">

              </ul>
          </div>
          <div className="main__message_container">
              <input id="chat_message" type="text" placeholder="Type message here..." />
          </div>
      </div>
    </div>
  );
};

export default Room;
Enter fullscreen mode Exit fullscreen mode

The room should look like this with the control bar below it.

RoomJs Image

Finally! that's the end of this section, I hope you really found it interesting and easy to follow through.

In the next article, we will be making use of 100ms SDK for video conferencing and also assign functions to our controlBar.

100ms is a cloud-based platform that lets you integrate video and audio conferencing into your application. It provides APIs and SDKs through which you can set up and manage telecommunication services on the client and server-side applications.

Conclusion

In this tutorial, you have successfully created a zoom clone layout and styled its buttons. What the Zoom App lacks now are the functionalities of each buttons (audio, participants, share screen), the video displayed, reactions (emojis and stickers), chat, and how to copy, share links and add another user to the video conference. I'll walk you through implementing this in Part 2.

This piece is a first step towards the main goal of us building a zoom app clone with react js and 100ms. Click on the link to continue the tutorial.

You might also be interested in other guides using React and 100ms SDK:

Building a Google Classroom Clone with React and 100ms SDK

Building a Twitch Clone with React

Building a Discord Stage Channel

💖 💪 🙅 🚩
benjaminbusari
Benjamin Busari

Posted on July 4, 2022

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related