mediasfu-reactjs
Version:
MediaSFU Prebuilt ReactJS SDK - Compatible with React 18 & 19, TypeScript & JavaScript
285 lines • 11.7 kB
TypeScript
import React from "react";
import { Producer } from "mediasoup-client/lib/types";
import { ConnectSendTransportScreenType, CreateSendTransportType, DisconnectSendTransportScreenType, PrepopulateUserMediaType, StopShareScreenType, SleepType, ConnectSendTransportScreenParameters, CreateSendTransportParameters, DisconnectSendTransportScreenParameters, PrepopulateUserMediaParameters, StopShareScreenParameters } from "../../@types/types";
export interface ScreenboardModalParameters extends ConnectSendTransportScreenParameters, CreateSendTransportParameters, DisconnectSendTransportScreenParameters, PrepopulateUserMediaParameters, StopShareScreenParameters {
localStreamScreen: MediaStream | null;
shared: boolean;
hostLabel: string;
annotateScreenStream: boolean;
processedScreenStream: MediaStream | null;
mainScreenCanvas: HTMLCanvasElement | null;
canvasScreenboard: HTMLCanvasElement | null;
transportCreated: boolean;
screenProducer: Producer | null;
updateLocalStreamScreen: (stream: MediaStream | null) => void;
updateProcessedScreenStream: (stream: MediaStream | null) => void;
updateMainScreenCanvas: (canvas: HTMLCanvasElement | null) => void;
sleep: SleepType;
createSendTransport: CreateSendTransportType;
disconnectSendTransportScreen: DisconnectSendTransportScreenType;
connectSendTransportScreen: ConnectSendTransportScreenType;
stopShareScreen: StopShareScreenType;
prepopulateUserMedia: PrepopulateUserMediaType;
getUpdatedAllParams: () => ScreenboardModalParameters;
[key: string]: any;
}
export interface ScreenboardModalOptions {
parameters: ScreenboardModalParameters;
isVisible: boolean;
onClose: () => void;
position?: string;
backgroundColor?: string;
}
export type ScreenboardModalType = (options: ScreenboardModalOptions) => React.JSX.Element;
/**
* ScreenboardModal - A modal component for managing screen annotation and drawing overlays.
*
* This component provides an interactive interface for controlling screen annotation features during
* screen sharing sessions. It manages the annotation stream lifecycle, canvas handling, transport
* creation, and synchronization with the screen sharing infrastructure.
*
* **Key Features:**
* - **Annotation Toggle**: Enable/disable drawing annotations on shared screen with real-time updates
* - **Stream Management**: Handles local screen stream, processed stream, and annotation canvas streams
* - **Canvas Integration**: Manages mainScreenCanvas and canvasScreenboard for annotation rendering
* - **Transport Lifecycle**: Creates, connects, and disconnects WebRTC transport for annotation streams
* - **Screen Producer Control**: Manages screen producer for annotation stream broadcasting
* - **Async Operations**: Proper sleep/delay handling for stream transitions
* - **User Media Sync**: Prepopulates user media when annotation state changes
* - **Host Indicators**: Displays host label for session context
* - **Shared State Awareness**: Tracks shared/unshared states for proper annotation behavior
* - **Modal Controls**: Close button with automatic canvas cleanup and transport disconnection
* - **Flexible Positioning**: Configurable modal position (topRight, topLeft, bottomRight, bottomLeft)
* - **Responsive Design**: Auto-sizing based on content with overlay behavior
*
* @component
*
* @param {ScreenboardModalOptions} props - Configuration options for ScreenboardModal
* @param {ScreenboardModalParameters} props.parameters - Comprehensive parameters object containing:
* - **Stream State**: localStreamScreen, processedScreenStream
* - **Canvas State**: mainScreenCanvas, canvasScreenboard
* - **Session State**: shared, hostLabel, annotateScreenStream, transportCreated, screenProducer
* - **Update Functions**: updateLocalStreamScreen, updateProcessedScreenStream, updateMainScreenCanvas
* - **MediaSFU Functions**: sleep, createSendTransport, disconnectSendTransportScreen, connectSendTransportScreen, stopShareScreen, prepopulateUserMedia
* - **Context**: getUpdatedAllParams (returns current state)
* @param {boolean} props.isVisible - Controls modal visibility
* @param {() => void} props.onClose - Callback function invoked when modal is closed
* @param {string} [props.position="topRight"] - Modal screen position (topRight, topLeft, bottomRight, bottomLeft)
* @param {string} [props.backgroundColor="#83c0e9"] - Background color for modal content
*
* @returns {React.JSX.Element} The rendered ScreenboardModal component
*
* @example
* // Basic usage for screen annotation
* ```tsx
* import React, { useState } from 'react';
* import { ScreenboardModal } from 'mediasfu-reactjs';
*
* const BasicScreenAnnotation = () => {
* const [showModal, setShowModal] = useState(true);
* const [annotateEnabled, setAnnotateEnabled] = useState(false);
*
* const parameters = {
* localStreamScreen: new MediaStream(),
* shared: true,
* hostLabel: 'John (Host)',
* annotateScreenStream: annotateEnabled,
* processedScreenStream: null,
* mainScreenCanvas: null,
* canvasScreenboard: null,
* transportCreated: true,
* screenProducer: null,
* updateLocalStreamScreen: (stream) => console.log('Local stream updated'),
* updateProcessedScreenStream: (stream) => console.log('Processed stream updated'),
* updateMainScreenCanvas: (canvas) => console.log('Canvas updated'),
* sleep: async ({ ms }) => new Promise(resolve => setTimeout(resolve, ms)),
* createSendTransport: async (options) => console.log('Transport created'),
* disconnectSendTransportScreen: async (options) => console.log('Transport disconnected'),
* connectSendTransportScreen: async (options) => console.log('Transport connected'),
* stopShareScreen: async (options) => console.log('Screen share stopped'),
* prepopulateUserMedia: async (options) => console.log('User media prepopulated'),
* getUpdatedAllParams: () => parameters
* };
*
* return (
* <ScreenboardModal
* parameters={parameters}
* isVisible={showModal}
* onClose={() => setShowModal(false)}
* />
* );
* };
* ```
*
* @example
* // Custom styled with position control
* ```tsx
* import React, { useState, useRef } from 'react';
* import { ScreenboardModal } from 'mediasfu-reactjs';
*
* const CustomStyledAnnotation = () => {
* const [showModal, setShowModal] = useState(true);
* const canvasRef = useRef<HTMLCanvasElement>(null);
*
* const handleAnnotationToggle = async () => {
* const canvas = canvasRef.current;
* if (!canvas) return;
*
* // Initialize canvas for annotation
* const ctx = canvas.getContext('2d');
* if (ctx) {
* ctx.strokeStyle = '#ff0000';
* ctx.lineWidth = 3;
* }
* };
*
* const parameters = {
* localStreamScreen: new MediaStream(),
* shared: true,
* hostLabel: 'Presenter',
* annotateScreenStream: false,
* processedScreenStream: null,
* mainScreenCanvas: null,
* canvasScreenboard: canvasRef.current,
* transportCreated: true,
* screenProducer: null,
* updateLocalStreamScreen: (stream) => {},
* updateProcessedScreenStream: (stream) => {},
* updateMainScreenCanvas: (canvas) => {},
* sleep: async ({ ms }) => new Promise(resolve => setTimeout(resolve, ms)),
* createSendTransport: async (options) => {},
* disconnectSendTransportScreen: async (options) => {},
* connectSendTransportScreen: async (options) => {},
* stopShareScreen: async (options) => {},
* prepopulateUserMedia: async (options) => {},
* getUpdatedAllParams: () => parameters
* };
*
* return (
* <>
* <canvas ref={canvasRef} style={{ display: 'none' }} />
* <ScreenboardModal
* parameters={parameters}
* isVisible={showModal}
* onClose={() => setShowModal(false)}
* position="bottomLeft"
* backgroundColor="#34495e"
* />
* </>
* );
* };
* ```
*
* @example
* // Analytics tracking for annotation usage
* ```tsx
* import React, { useState, useEffect } from 'react';
* import { ScreenboardModal } from 'mediasfu-reactjs';
*
* const AnalyticsScreenAnnotation = () => {
* const [showModal, setShowModal] = useState(true);
* const [annotateEnabled, setAnnotateEnabled] = useState(false);
*
* useEffect(() => {
* if (annotateEnabled) {
* analytics.track('Screen Annotation Enabled', {
* timestamp: new Date(),
* hostLabel: 'Presenter'
* });
* } else {
* analytics.track('Screen Annotation Disabled');
* }
* }, [annotateEnabled]);
*
* const parameters = {
* localStreamScreen: new MediaStream(),
* shared: true,
* hostLabel: 'Presenter',
* annotateScreenStream: annotateEnabled,
* processedScreenStream: null,
* mainScreenCanvas: null,
* canvasScreenboard: null,
* transportCreated: true,
* screenProducer: null,
* updateLocalStreamScreen: (stream) => {
* analytics.track('Local Stream Updated', { hasStream: !!stream });
* },
* updateProcessedScreenStream: (stream) => {
* analytics.track('Processed Stream Updated', { hasStream: !!stream });
* },
* updateMainScreenCanvas: (canvas) => {
* analytics.track('Canvas Updated', { hasCanvas: !!canvas });
* },
* sleep: async ({ ms }) => new Promise(resolve => setTimeout(resolve, ms)),
* createSendTransport: async (options) => {},
* disconnectSendTransportScreen: async (options) => {},
* connectSendTransportScreen: async (options) => {},
* stopShareScreen: async (options) => {},
* prepopulateUserMedia: async (options) => {},
* getUpdatedAllParams: () => parameters
* };
*
* return (
* <ScreenboardModal
* parameters={parameters}
* isVisible={showModal}
* onClose={() => {
* analytics.track('Screenboard Modal Closed');
* setShowModal(false);
* }}
* />
* );
* };
* ```
*
* @example
* // Integration with MediasfuGeneric using uiOverrides
* ```tsx
* import React, { useState } from 'react';
* import { MediasfuGeneric, ScreenboardModal } from 'mediasfu-reactjs';
*
* const CustomScreenboardComponent = (props) => {
* const [annotationColor, setAnnotationColor] = useState('#ff0000');
*
* return (
* <div className="custom-screenboard-wrapper">
* <div className="annotation-controls">
* <label>Annotation Color:</label>
* <input
* type="color"
* value={annotationColor}
* onChange={(e) => setAnnotationColor(e.target.value)}
* />
* <div className="annotation-status">
* {props.parameters.annotateScreenStream ? '🎨 Drawing Active' : '⏸️ Drawing Paused'}
* </div>
* </div>
* <ScreenboardModal
* {...props}
* position="topLeft"
* backgroundColor={annotationColor + '33'} // Add transparency
* />
* </div>
* );
* };
*
* const App = () => {
* const [credentials] = useState({
* apiUserName: 'user123',
* apiKey: 'your-api-key'
* });
*
* return (
* <MediasfuGeneric
* credentials={credentials}
* uiOverrides={{
* ScreenboardModal: CustomScreenboardComponent
* }}
* />
* );
* };
* ```
*/
declare const ScreenboardModal: React.FC<ScreenboardModalOptions>;
export default ScreenboardModal;
//# sourceMappingURL=ScreenboardModal.d.ts.map