Open the repository in your choice of code editor and run command npm install to install the dependencies. You can test out the original app by running the command npm run start.
2. Install DPAPI Packages
npm i @dpapi/server @dpapi/react
Remember to first uninstall React v16 and then re-install React v18
npm uninstall react react-dom
npm install react@18.2.0 react-dom@18.2.0
3. Create RoomProvider
Wrap the child elements with RoomProvider
src/index.js
import React from "react";
import ReactDOM from "react-dom";
import {RoomProvider} from "@dpapi/react";
import App from "./App";
import "./index.css";
const rootElement = document.getElementById("root");
ReactDOM.render(
<RoomProvider>
<App />
</RoomProvider>,
rootElement
);
4. Add Multiplayer Functionalities
useContext is used to create client socket connection.
joinRoom, roomCount and liveCursors are added to the React App which shall be rendered.
src/App.js
// Retain all app import statements ππΌ
import {useContext} from "react";
import "./App.css";
import {
clientSocket,
roomCount,
liveCursors,
joinRoom,
} from "@dpapi/react";
// Retain original calculator app code ππΌ
const App = () => {
const socket = useContext(clientSocket);
joinRoom("calcRoom", socket);
const usersCount = roomCount("calcRoom", socket);
const cursors = liveCursors("calcRoom", socket);
let [calc, setCalc] = useState({/* Retain code here */});
// Retain original calculator app code ππΌ
const resetClickHandler = () => {/* Retain code hereπΌ*/};
return (
<div className="App"> // β Remember to add a CSS file
<h1>Number of users in the room: {usersCount}</h1>
{cursors.map((cursor, index) => {
if (cursor.socketId !== socket.id) {
return (
<div
key={cursor.socketId || index}
className="other-cursor" // β Style your cursors with CSS
style={{
left: cursor.x,
top: cursor.y,
}}
/>
);
} else { return null; }
})}
<br />
<Wrapper>
// Retain original calculator app code ππΌ
</Wrapper>
</div>
);
};
export default App;
5. Cursor CSS Elements
Create a new file called App.css in the src directory.
In this section, we will assign random cursor icons to every client.
This is useful for providing a fun and dynamic user experience in a shared space.
We make use of React useState & useEffect hooks to assign and re-render cursor icons.
src/App.js
// Retain all app import statements ππΌ
import {useEffect} from "react";
// Retain original calculator app code ππΌ
const cursorUrlArray = [
"https://icons.iconarchive.com/icons/svengraph/daft-punk/256/Daft-Punk-Guyman-Off-icon.png",
"https://icons.iconarchive.com/icons/everaldo/starwars/128/Darth-Vader-icon.png",
"https://icons.iconarchive.com/icons/everaldo/starwars/128/clone-old-icon.png",
"https://icons.iconarchive.com/icons/svengraph/daft-punk/256/Daft-Punk-Thomas-On-icon.png",
];
const App = () => {
// Retain DPAPI functions ππΌ
const [cursorUrl, setCursorUrl] = useState("");
useEffect(() => {
setCursorUrl(
cursorUrlArray[Math.floor(Math.random() * cursorUrlArray.length)]
);
},[]);
let [calc, setCalc] = useState({/* Retain code here */});
// Retain original calculator app code ππΌ
const resetClickHandler = () => {/* Retain code hereπΌ*/};
return (
// Retain DPAPI code from above ππΌ
<div
key={cursor.socketId || index}
className="other-cursor" // β Style your cursors with CSS
style={{
left: cursor.x,
top: cursor.y,
backgroundImage: `url(${cursorUrl})`,
}}
// Retain all other code from above ππΌ
);
};
export default App;
Inside the useEffect hook, the setCursorUrl function is called to randomly select one of the cursorUrl values from the array and set it as the initial state of cursorUrl