UNPKG

mediasfu-reactjs

Version:

MediaSFU Prebuilt ReactJS SDK - Compatible with React 18 & 19, TypeScript & JavaScript

249 lines 8.35 kB
import React from "react"; import { Socket } from "socket.io-client"; import { ConnectSocketType, ConnectLocalSocketType } from "../../sockets/SocketManager"; import { ShowAlert, CreateMediaSFURoomOptions, JoinMediaSFURoomOptions, JoinRoomOnMediaSFUType, CreateRoomOnMediaSFUType } from "../../@types/types"; export interface WelcomePageParameters { imgSrc?: string; showAlert?: ShowAlert; updateIsLoadingModalVisible: (visible: boolean) => void; connectSocket: ConnectSocketType; connectLocalSocket?: ConnectLocalSocketType; updateSocket: (socket: Socket) => void; updateLocalSocket?: (socket: Socket) => void; updateValidated: (validated: boolean) => void; updateApiUserName: (apiUserName: string) => void; updateApiToken: (apiToken: string) => void; updateLink: (link: string) => void; updateRoomName: (roomName: string) => void; updateMember: (userName: string) => void; } export interface WelcomePageOptions { parameters: WelcomePageParameters; localLink?: string; connectMediaSFU?: boolean; credentials?: { apiUserName: string; apiKey: string; }; returnUI?: boolean; noUIPreJoinOptions?: CreateMediaSFURoomOptions | JoinMediaSFURoomOptions; createMediaSFURoom?: CreateRoomOnMediaSFUType; joinMediaSFURoom?: JoinRoomOnMediaSFUType; } export type WelcomePageType = (options: WelcomePageOptions) => React.JSX.Element; /** * WelcomePage - Event entry interface with manual input and QR code scanning * * The default pre-join page that allows users to enter event credentials manually * or scan a QR code. Handles validation, rate limiting, and socket connection * establishment before entering the main event room. * * Features: * - Manual event detail entry (name, event ID, secret/passcode) * - QR code scanning support (optional) * - Rate limiting (max 10 failed attempts, 3-hour cooldown) * - Socket connection establishment * - Credential validation and error handling * - Persistent attempt tracking via cookies * - MediaSFU logo branding * - Responsive form layout * * @component * @param {WelcomePageOptions} options - Configuration options * @param {WelcomePageParameters} options.parameters - MediaSFU parameters object * @param {string} [options.parameters.imgSrc] - Custom logo image source * @param {ShowAlert} [options.parameters.showAlert] - Alert display function * @param {Function} options.parameters.updateIsLoadingModalVisible - Loading state updater * @param {ConnectSocketType} options.parameters.connectSocket - Socket connection function * @param {Function} options.parameters.updateSocket - Socket instance updater * @param {Function} options.parameters.updateValidated - Validation state updater * @param {Function} options.parameters.updateApiUserName - API username updater * @param {Function} options.parameters.updateApiToken - API token updater * @param {Function} options.parameters.updateLink - Event link updater * @param {Function} options.parameters.updateRoomName - Room name updater * @param {Function} options.parameters.updateMember - Member name updater * * @returns {React.JSX.Element} Rendered welcome page * * @example * // Basic usage as default pre-join page * ```tsx * import React from 'react'; * import { MediasfuGeneric, WelcomePage } from 'mediasfu-reactjs'; * * function App() { * return ( * <MediasfuGeneric * PrejoinPage={WelcomePage} * credentials={{ apiUserName: '', apiKey: '' }} * /> * ); * } * ``` * * @example * // Custom branded welcome page * ```tsx * import { MediasfuGeneric, WelcomePage } from 'mediasfu-reactjs'; * import brandLogo from './assets/brand-logo.png'; * * function App() { * const customParameters = { * imgSrc: brandLogo, * showAlert: ({ message, type }) => { * // Custom alert implementation * toast[type](message); * }, * updateIsLoadingModalVisible: (visible) => setLoading(visible), * connectSocket: connectSocket, * updateSocket: setSocket, * updateValidated: setValidated, * updateApiUserName: setApiUserName, * updateApiToken: setApiToken, * updateLink: setLink, * updateRoomName: setRoomName, * updateMember: setMember, * }; * * return ( * <MediasfuGeneric * PrejoinPage={(props) => <WelcomePage parameters={customParameters} />} * /> * ); * } * ``` * * @example * // Completely custom pre-join page replacing WelcomePage * ```tsx * import React, { useState } from 'react'; * import { MediasfuGeneric } from 'mediasfu-reactjs'; * * function CustomWelcome({ parameters }) { * const [eventCode, setEventCode] = useState(''); * const [userName, setUserName] = useState(''); * * const handleJoin = async () => { * // Parse event code format: username_eventid_secret * const [apiUserName, eventID, apiToken] = eventCode.split('_'); * * parameters.updateIsLoadingModalVisible(true); * * try { * const socket = await parameters.connectSocket({ * apiUserName, * apiKey: apiToken, * apiToken, * link: 'https://mediasfu.com', * }); * * parameters.updateSocket(socket); * parameters.updateApiUserName(apiUserName); * parameters.updateApiToken(apiToken); * parameters.updateRoomName(eventID); * parameters.updateMember(userName); * parameters.updateValidated(true); * } catch (error) { * parameters.showAlert?.({ * message: 'Failed to join event', * type: 'danger', * duration: 3000, * }); * } finally { * parameters.updateIsLoadingModalVisible(false); * } * }; * * return ( * <div style={{ * display: 'flex', * flexDirection: 'column', * alignItems: 'center', * justifyContent: 'center', * minHeight: '100vh', * background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)', * padding: 20, * }}> * <div style={{ * background: 'white', * padding: 40, * borderRadius: 20, * boxShadow: '0 20px 60px rgba(0,0,0,0.3)', * maxWidth: 400, * width: '100%', * }}> * <h1 style={{ marginBottom: 24, textAlign: 'center' }}>Join Event</h1> * <input * type="text" * placeholder="Your Name" * value={userName} * onChange={(e) => setUserName(e.target.value)} * style={{ * width: '100%', * padding: 12, * marginBottom: 16, * borderRadius: 8, * border: '1px solid #e2e8f0', * }} * /> * <input * type="text" * placeholder="Event Code (username_eventid_secret)" * value={eventCode} * onChange={(e) => setEventCode(e.target.value)} * style={{ * width: '100%', * padding: 12, * marginBottom: 20, * borderRadius: 8, * border: '1px solid #e2e8f0', * }} * /> * <button * onClick={handleJoin} * disabled={!userName || !eventCode} * style={{ * width: '100%', * padding: 14, * background: '#667eea', * color: 'white', * border: 'none', * borderRadius: 8, * fontWeight: 600, * cursor: userName && eventCode ? 'pointer' : 'not-allowed', * opacity: userName && eventCode ? 1 : 0.5, * }} * > * Join Now * </button> * </div> * </div> * ); * } * * function App() { * return <MediasfuGeneric PrejoinPage={CustomWelcome} />; * } * ``` * * @example * // Override via uiOverrides * ```tsx * import { MediasfuGeneric, WelcomePage } from 'mediasfu-reactjs'; * * const uiOverrides = { * welcomePage: { * component: (props) => ( * <div style={{ background: '#0f172a' }}> * <WelcomePage {...props} /> * </div> * ), * }, * }; * * <MediasfuGeneric uiOverrides={uiOverrides} />; * ``` */ declare const WelcomePage: React.FC<WelcomePageOptions>; export default WelcomePage; //# sourceMappingURL=WelcomePage.d.ts.map