El código compartido es un aspecto esencial de la programación .
Con el auge del trabajo remoto y la colaboración virtual, los desarrolladores necesitan herramientas confiables para compartir código que ofrezcan comunicación en tiempo real, videoconferencias y audioconferencias, y una interfaz de usuario amigable. Codeshare.io es uno de esos ejemplos.
Pero hoy, vamos a arremangarnos y construir nuestro propio patio de recreo para compartir código usando Dyte.io. ¡Cinturón de seguridad! 🎢 Dyte es una plataforma amigable para desarrolladores que ofrece potentes SDK para crear experiencias en vivo dentro de nuestro producto. En este blog, lo guiaremos a través del proceso de creación de una plataforma de código compartido con Dyte.io y ReactJs. ¡Empecemos! 🏃
Antes que nada, necesitaríamos configurar una cuenta de Dyte. Para esto, primero visite Dyte.io y luego presione Comenzar a construir. En la página siguiente, inicie sesión con la cuenta de Google o GitHub para obtener su cuenta Dyte gratuita 🎉. Encontrará sus claves de API en la pestaña Claves de API en la barra lateral izquierda. Mantenga seguras sus claves API y no las comparta con nadie.
Llegando a un punto de control más antes de sumergirnos en la codificación.
Usaremos Node.js, un popular entorno de tiempo de ejecución de JavaScript, y create-react-app, una herramienta que genera un proyecto React con una configuración preconfigurada.
Para comenzar, crearemos tres carpetas client
, server
y plugin
.
Nota: 🧑💻 Si está en Mac, debe desactivar "AirPlay Receiver" en la configuración del sistema, ya que ocupaba el puerto 5000 de forma predeterminada.
Solo como referencia, así es como se vería nuestra final folder structure
al final de este blog.
Continuaremos e instalaremos Dyte
CLI usando el siguiente comando.
$ npm install -g @dytesdk/cli
Continuando con la parte de autorización y seleccionando la organización con los siguientes comandos.
$ dyte auth login $ dyte auth org
Para obtener más información, visite Dyte CLI Docs .
Para comenzar a crear un complemento Dyte personalizado, clonaremos Dyte Plugin Template
con el siguiente comando. La plantilla de complemento nos permite comenzar más rápido.
$ git clone https://github.com/dyte-in/react-plugin-template.git
Esta plantilla usa @dytesdk/plugin-sdk
y nos permite crear nuestros propios complementos en tiempo real que funcionan perfectamente con las reuniones de Dyte. Tiene muchas características interesantes para ayudarnos a resolver problemas complejos en minutos. Ahora, instalaremos las dependencias usando el comando "npm install".
$ npm install
A continuación, agregaremos un par de dependencias ejecutando el siguiente comando.
$ npm i @uiw/react-codemirror @codemirror/lang-javascript uuid
Aquí, agregamos react-codemirror
, que proporciona un editor de código preconstruido con soporte de idiomas. También estamos instalando UUID que nos ayudará a generar UUID con solo una llamada de función. Esto será útil pronto.
Ahora que tenemos todo configurado, podemos usar este comando para iniciar y probar nuestra configuración de complemento personalizado.
$ npm start
Para intentar usar nuestro nuevo complemento personalizado, tendremos que visitar http://staging.dyte.io
Aquí, se nos pedirá que creemos una nueva reunión. Es súper simple, solo agregue su nombre y el nombre de una reunión y presione Create
. En la página siguiente, le pedirá que se join
a la reunión. Haz clic en unirte y estás dentro.
Busque el botón Plugins
en la esquina inferior derecha y haga clic en él para revelar todos los complementos existentes. Estamos interesados en un complemento llamado, haga clic en launch
y revelará su complemento dentro de la reunión 🤯.
Tenemos todo listo con nosotros. ¡Ahora, podemos comenzar a escribir código real!
Comencemos con nuestro componente Editor de código.
Comencemos con la creación de nuestro propio editor de código 🧑💻.
Para esto, primero vamos a crear un componente y luego usaremos el paquete CodeMirror
que instalamos anteriormente. Primero, cree un nuevo React Functional Component
en un archivo llamado CodeEditor.js
dentro de src/containers
y pegue el siguiente código.
<CodeMirror style={{ fontSize: "32px", textAlign: "left" }} value={code} onChange={handleCodeChange} height="100vh" width="100vw" theme={'dark'} extensions={[javascript({ jsx: true })]}/>
El componente CodeMirror proporciona un editor de código preconstruido. Viene con varias funciones de resaltado de sintaxis.
Para trabajar en el manejo de los cambios de código en vivo, primero creemos un nuevo code
con nombre de estado
import { useEffect, useState, useRef } from "react"; const [code, setCode] = useState("function add(a, b) { return a + b;}");
Ahora, crearemos una función handleCodeChange
que emitirá eventos cada vez que haya un cambio en nuestro código en CodeMirror
usando la función plugin.emit()
.
Aquí, estamos emitiendo un objeto que tiene dos propiedades. El primero es una user id
generada aleatoriamente y el segundo es nuestro código completo.
import { useEffect, useState, useRef } from "react"; import CodeMirror from '@uiw/react-codemirror'; import { javascript } from '@codemirror/lang-javascript'; const CodeEditor = ({ plugin }) => { const [code, setCode] = useState("function add(a, b) {return a + b;}"); const [userId, setUserId] = useState() const handleCodeChange = async (code) => { plugin.emit(`CODE_CHANGE`, { code, user }) } return ( <> <CodeMirror style={{ fontSize: "32px", textAlign: "left" }} value={code} onChange={handleCodeChange} height="100vh" width="100vw" theme={'dark'} extensions={[javascript({ jsx: true })]} /> </> ); } export default CodeEditor;
Necesitamos escuchar el evento cuando otras personas cambian el código. Para esto, usaremos la función plugin.on()
como se muestra a continuación. La función acepta event name
como parámetro y recibe los cambios de código.
Una cosa más a tener en cuenta aquí es que tenemos que actualizar nuestro código actual solo si lo envían otros usuarios. Para esto necesitamos poner una declaración condicional simple if(data.user != userId){}
import { useEffect, useState, useRef } from "react"; import CodeMirror from '@uiw/react-codemirror'; import { javascript } from '@codemirror/lang-javascript'; import {v4} from 'uuid'; const user = v4() const CodeEditor = ({ plugin }) => { const [code, setCode] = useState("function add(a, b) {\n return a + b;\n}"); const [userId, setUserId] = useState() useEffect(() => { if (plugin) { const startListening = async () => { plugin.on(`CODE_CHANGE`, (data) => { if(data.user != user) { setCode(data.code) } }); } startListening() } }, [plugin]) const handleCodeChange = async (code) => { plugin.emit(`CODE_CHANGE`, { code, user }) } return ( <> <CodeMirror style={{ fontSize: "32px", textAlign: "left" }} value={code} onChange={handleCodeChange} height="100vh" width="100vw" theme={'dark'} extensions={[javascript({ jsx: true })]} /> </> ); } export default CodeEditor;
En este componente, estamos creando un editor de código usando CodeMirror. Cualquier cambio en el editor emite un evento CODE_CHANGE
para todos los usuarios de la reunión, mediante la llamada a la función plugin.emit()
. La función emit
toma eventName
y data
como argumentos.
En el siguiente paso, debemos importar el componente CodeEditor al archivo Main.tsx
. Su archivo debería verse así. 👇
import { useDytePlugin } from '../context' import CodeEditor from './CodeEditor'; const Main = () => { const plugin = useDytePlugin(); return ( <div style={{ height: "100%" }}> <CodeEditor plugin={plugin} /> </div> ) } export default Main
El código para nuestro "Complemento de editor de código colaborativo" 😉 ya está listo. ¿Cómo alguien escribió el primer editor de código sin un editor de código 😂? Bromas aparte, ya estamos listos con nuestro Plugin 🎉.
Para pagar, abre staging.dyte.io y síguelo. Ingrese su nombre y el título de la reunión para ingresar. Haga clic en Unirse a la reunión. Abra el complemento Localhost Dev
y estará listo para comenzar.
🧑💻 Ahora es el momento de publicar nuestro contenido, este es un proceso simple con Dyte CLI
. Para esto, primero tenemos que construir nuestro complemento y luego ejecutar el comando dyte plugins publish
.
$ dyte plugins create $ npm run build $ cp dyte-config.json ./build/dyte-config.json $ cd build $ dyte plugins publish
Ahora que hemos creado el complemento que nos ayudará a colaborar en el código, podemos comenzar a crear la plataforma para usar este complemento.
Comencemos con el lado del cliente. Dentro de la carpeta client
, configuraremos un nuevo proyecto ReactJS
usando create-react-app
y crearemos nuestra aplicación de reacción usando el siguiente comando.
$ npx create-react-app .
A continuación, instalemos las dependencias de Dyte
y code-editor
ejecutando el siguiente comando:
$ npm i @dytesdk/react-ui-kit @dytesdk/react-web-core react-simple-code-editor
🎬 Ahora, comencemos nuestro servidor de desarrollo con npm start:
$ npm start
Abramos el archivo app.js
dentro de la carpeta src
. Eliminaremos el contenido de este archivo y agregaremos el siguiente fragmento de código 👇.
import Layout from './components/Layout' function App() { return ( <Layout /> ); } export default App;
A continuación, escribiremos el componente Layout
, crearemos un diseño con nuestro logotipo, título y IU de reunión.
Usaremos varias bibliotecas, incluidas DyteMeeting
y PrismJS, para crear un editor de código colaborativo y una interfaz de usuario para reuniones.
import Meet from "./Meeting" const Layout = () => { return ( <> <div style={{ padding: "30px", display: "flex", justifyContent: "space-between", alignItems: "center" }}> <img src="https://dyte.io/blog/content/images/2021/09/Dyte-Logo.svg" height={"70px"}/> <span style={{ fontSize: "30px", color: "#3e75fd" }}>Collaborative Code Editor</span> <img style={{ opacity: "0"}} src="https://dyte.io/blog/content/images/2021/09/Dyte-Logo.svg" height={"80px"}/> </div> <div style={{ height: "88vh" }} ><Meet /></div> </> ) } export default Layout
🧑💻 Primero, necesitamos crear algunas funciones de utilidad en un archivo client/src/utils/api.js
const createMeeting = async () => { const resp = await fetch("http://localhost:3000/meetings", { method: "POST", body: JSON.stringify({ title: "New Code pair" }), headers: { "Content-Type": "application/json" } }) const data = await resp.json() console.log(data) return data.data.id; } const joinMeeting = async (id) => { const resp = await fetch(`http://localhost:3000/meetings/${id}/participants`, { method: "POST", body: JSON.stringify({ name: "new user", preset_name: "group_call_host" }), headers: { "Content-Type": "application/json" } }) const data = await resp.json() console.log(data) return data.data.token; } export { createMeeting, joinMeeting }
Estas funciones se comunican con nuestro backend para crear reuniones y agregar participantes. Para la creación de reuniones, pasamos title
como un parámetro opcional.
Y para agregar participantes, pasamos el parámetro name
(opcional), el parámetro picture
(opcional) y el parámetro preset_name
(obligatorio) junto con meetingId
.
Hora de nuestro componente Reunión. Para esto, usaremos el kit Dyte UI ✨ que hace que sea muy fácil integrar el uso compartido de audio/video en vivo en su aplicación. Sí, estas 10-15 líneas de código hacen todo el trabajo pesado 🏋🏼♂️.
import { useState, useEffect, useRef } from "react"; import { DyteMeeting, provideDyteDesignSystem } from "@dytesdk/react-ui-kit"; import { useDyteClient } from "@dytesdk/react-web-core"; import { createMeeting, joinMeeting } from "../utils/api"; const Meet = () => { const meetingEl = useRef(); const [meeting, initMeeting] = useDyteClient(); const [userToken, setUserToken] = useState(); const [meetingId, setMeetingId] = useState(); const createMeetingId = async () => { const newMeetingId = await createMeeting(); setMeetingId(newMeetingId); }; useEffect(() => { const id = window.location.pathname.split("/")[2]; if (!id) { createMeetingId(); } else { setMeetingId(id); } }, []); const joinMeetingId = async () => { if (meetingId) { const authToken = await joinMeeting(meetingId); await initMeeting({ authToken, modules: { plugin: true, devTools: { logs: true, plugins: [ { name: "Collaborative-code-editor", port: "5000", id: "<your-plugin-id>", }, ], }, }, }); setUserToken(authToken); } }; useEffect(() => { if (meetingId && !userToken) joinMeetingId(); }, [meetingId]); useEffect(() => { if (userToken) { provideDyteDesignSystem(meetingEl.current, { theme: "dark", }); } }, [userToken]); return ( <> {userToken && meetingId ? ( <DyteMeeting mode="fill" meeting={meeting} ref={meetingEl} /> ) : ( <div>Loading...</div> )} </> ); }; export default Meet;
Ya estamos listos con la interfaz de usuario de nuestra plataforma de código compartido 🎉
🧑💻 Dyte proporciona una variedad de potentes API que mejoran la experiencia del desarrollador y cumplen con una amplia gama de requisitos del desarrollador.
Podemos administrar las organizaciones, sesiones, reuniones, grabaciones, webhooks, transmisión en vivo, análisis y mucho más de Dyte.
Para simplificar el proceso, usaremos Express con Node para crear un backend que ayudará con la autenticación, la creación de reuniones y la adición de participantes. ✨
Para comenzar en la carpeta del proyecto, siga los siguientes pasos:
$ mkdir server && cd server
Comenzaremos con la instalación de un par de dependencias, cd en el directorio 'servidor' y usaremos el siguiente comando.
$ npm init -y $ npm install express cors axios dotenv $ npm install -g nodemon
Primero, creemos un archivo .env
para almacenar nuestra clave API en server/src
. Puede encontrar estas claves en Dyte Dashboard.
DYTE_ORG_ID=<ID> DYTE_API_KEY=<KEY>
Agreguemos también algunos scripts ✍️ que nos ayudarán a ejecutar nuestra aplicación server
. Agregue las siguientes líneas en su archivo package.json
dentro de scripts
de la etiqueta.
"start": "node dist/index.js", "dev": "nodemon src/index.js"
Vamos a crear nuestros archivos y carpetas ahora. Todo nuestro código vivirá dentro de la carpeta server/src
. Dentro src
crea otra carpeta utils
.
Inicialice un archivo index.js
dentro de src
y dyte-api.js
dentro de utils
. Ahora agreguemos nuestro archivo .env
en src
, que contendrá nuestros secretos API.
Abra el archivo src/.env
y agréguele las siguientes líneas. Reemplace los valores de marcador de posición con los secretos de API del panel de Dyte.
DYTE_ORG_ID=<YOUR-DYTE-ORG-ID> DYTE_API_KEY=<YOUR-DYTE-API-KEY>
Podemos empezar a escribir código ahora. Comencemos con la creación de la configuración axios
para acceder a las API de Dyte.
Abra utils/dyte-api.js
e ingrese el siguiente código.
Este código ayudará a comunicarse con las API y la autenticación de Dyte.
const axios = require('axios'); require('dotenv').config(); const DYTE_API_KEY = process.env.DYTE_API_KEY; const DYTE_ORG_ID = process.env.DYTE_ORG_ID; const API_HASH = Buffer.from( `${DYTE_ORG_ID}:${DYTE_API_KEY}`, 'utf-8' ).toString('base64'); const DyteAPI = axios.create({ baseURL: 'https://api.cluster.dyte.in/v2', headers: { Authorization: `Basic ${API_HASH}`, }, }); module.exports = DyteAPI;
A continuación, escribiremos las rutas.
Nuestro front-end se comunicará en estas rutas para crear reuniones y agregar participantes a las reuniones.
Abramos index.js
y agreguemos el siguiente fragmento de código.👇
const express = require('express'); const cors = require('cors'); const DyteAPI = require('./utils/dyte-api') const PORT = process.env.PORT || 3000; const app = express(); app.use(cors("http://localhost:3001")); app.use(express.json()); app.post('/meetings', async (req, res) => { const { title } = req.body const response = await DyteAPI.post('/meetings', { title, }); return res.status(response.status).json(response.data); }); app.post('/meetings/:meetingId/participants', async (req, res) => { const meetingId = req.params.meetingId const { name, picture, preset_name } = req.body const client_specific_id = `react-samples::${name.replaceAll(' ', '-')}-${Math.random().toString(36).substring(2, 7)}`; const response = await DyteAPI.post(`/meetings/${meetingId}/participants`, { name, picture, preset_name, client_specific_id, }); return res.status(response.status).json(response.data); }); app.listen(PORT, () => { console.log(`Started listening on ${PORT}...`) });
Ta-da! 🎩✨ ¡Lo logramos!
Ahora, finalmente probaremos nuestra plataforma de código compartido para colaborar mientras programamos con nuestros amigos y compañeros de equipo.
Con nuestro nuevo y brillante editor de código y Dyte reuniendo toda la configuración, ¡finalmente probaremos nuestra plataforma!
Dentro del tipo de cliente PORT=3001 npm start
Tipo de complemento interno npm start
Tipo de servidor interno PORT=3000 npm run dev
Y ahí lo tiene, videoconferencia en la aplicación y colaboración con nuestro propio "Complemento de colaboración de código".
🧑💻 Puedes probar la plataforma de código compartido
🎉 ¡Guau! ¡Llegaste hasta el final, amigo mío! Espero que hayas aprendido un par de cosas hoy y te hayas divertido siguiendo el camino.
Juntos, hemos construido una elegante plataforma de código compartido y programación en vivo, completa con reuniones en la aplicación, todo con solo una pizca de React y una cucharada de Dyte. Hable acerca de una receta para el éxito!
Te respaldamos con nuestras plantillas de complementos y potentes SDK, lo que hace que sea muy fácil comenzar y crear tus propias obras maestras colaborativas, como la que cocinamos juntos hoy.
¿Entonces, Qué esperas? ¡Dirígete a Dyte.io y deja fluir tu creatividad! ¡Comience a crear sus propias aplicaciones de colaboración y puede que cree la próxima gran novedad! 🚀