mediasfu-reactnative-expo
Version:
mediasfu-reactnative-expo – Expo-managed React Native WebRTC SDK for video conferencing, webinars, live streaming, broadcast, screen sharing, whiteboard, chat, recording, live subtitles, translation, and AI agent rooms on iOS, Android, and web. Prebuilt r
332 lines (331 loc) • 13.1 kB
TypeScript
import React from 'react';
import { StyleProp, ViewStyle, ImageStyle } from 'react-native';
import { Socket } from 'socket.io-client';
import { ControlsPosition, InfoPosition, Participant, ControlMediaOptions, AudioDecibels, CoHostResponsibility, ShowAlert, CustomAudioCardType } from '../../@types/types';
/**
* Interface defining the parameters required by the AudioCard component.
*
* These parameters provide the context and state needed for audio display,
* participant management, and media controls.
*
* @interface AudioCardParameters
* @property {AudioDecibels[]} audioDecibels - Array of audio level data for all participants (used for waveform visualization)
* @property {Participant[]} participants - Array of all participants in the session
* @property {Socket} socket - Socket.io client instance for real-time communication
* @property {CoHostResponsibility[]} coHostResponsibility - Array of responsibilities assigned to co-hosts
* @property {string} roomName - Name/ID of the current room session
* @property {ShowAlert} [showAlert] - Optional function to display alerts/notifications
* @property {string} coHost - User ID of the co-host
* @property {string} islevel - Current user's level/role (e.g., '0', '1', '2')
* @property {string} member - Current user's member ID
* @property {string} eventType - Type of event ('conference', 'webinar', 'broadcast', etc.)
* @property {() => AudioCardParameters} getUpdatedAllParams - Function to retrieve latest parameter state
*/
export interface AudioCardParameters {
audioDecibels: AudioDecibels[];
participants: Participant[];
socket: Socket;
coHostResponsibility: CoHostResponsibility[];
roomName: string;
showAlert?: ShowAlert;
coHost: string;
islevel: string;
member: string;
eventType: string;
getUpdatedAllParams(): AudioCardParameters;
}
/**
* Interface defining the options for the AudioCard component.
*
* AudioCard displays a participant in audio-only mode with waveform visualization,
* participant info, and optional media controls.
*
* @interface AudioCardOptions
*
* **Core Display Properties:**
* @property {string} name - Participant's display name
* @property {Participant} participant - Complete participant object with metadata
* @property {AudioDecibels} [audioDecibels] - Audio level data for this participant's waveform
*
* **Styling Properties:**
* @property {StyleProp<ViewStyle>} [customStyle] - Custom styles for the card container
* @property {object} [style] - Additional style object for the container
* @property {string} [backgroundColor] - Background color (default: '#2c678f')
* @property {string} [barColor] - Color of the audio waveform bars (default: 'red')
* @property {string} [textColor] - Color of text overlays (default: 'white')
*
* **Image/Avatar Properties:**
* @property {string} [imageSource] - URI for participant's avatar image
* @property {boolean} [roundedImage] - Whether to display avatar with rounded corners (default: false)
* @property {StyleProp<ImageStyle>} [imageStyle] - Custom styles for the avatar image
*
* **Controls & Info Properties:**
* @property {boolean} [showControls] - Whether to show media control buttons (default: true)
* @property {boolean} [showInfo] - Whether to show participant info overlay (default: true)
* @property {React.ReactNode} [videoInfoComponent] - Custom component for info overlay
* @property {React.ReactNode} [videoControlsComponent] - Custom component for controls
* @property {ControlsPosition} [controlsPosition] - Position of controls overlay (default: 'topLeft')
* @property {InfoPosition} [infoPosition] - Position of info overlay (default: 'bottomLeft')
*
* **Media Control:**
* @property {(options: ControlMediaOptions) => Promise<void>} [controlUserMedia] - Function to control user media settings (default: controlMedia)
*
* **State Parameters:**
* @property {AudioCardParameters} parameters - State and context parameters for the card
*
* **Custom UI Override:**
* @property {CustomAudioCardType} [customAudioCard] - Custom render function for complete card replacement.
* When provided, this function receives all AudioCardOptions and returns custom JSX.Element.
* This allows full control over the audio card's appearance and behavior.
*
* **Advanced Render Overrides:**
* @property {(options: { defaultContent: React.ReactNode; dimensions: { width: number; height: number }}) => React.ReactNode} [renderContent]
* Function to wrap or replace the default card content while preserving container
* @property {(options: { defaultContainer: React.ReactNode; dimensions: { width: number; height: number }}) => React.ReactNode} [renderContainer]
* Function to wrap or replace the entire card container
*/
export interface AudioCardOptions {
controlUserMedia?: (options: ControlMediaOptions) => Promise<void>;
customStyle?: StyleProp<ViewStyle>;
name: string;
barColor?: string;
textColor?: string;
imageSource?: string;
roundedImage?: boolean;
imageStyle?: StyleProp<ImageStyle>;
showControls?: boolean;
showInfo?: boolean;
videoInfoComponent?: React.ReactNode;
videoControlsComponent?: React.ReactNode;
controlsPosition?: ControlsPosition;
infoPosition?: InfoPosition;
participant: Participant;
backgroundColor?: string;
audioDecibels?: AudioDecibels;
liveSubtitleText?: string;
showSubtitles?: boolean;
parameters: AudioCardParameters;
customAudioCard?: CustomAudioCardType;
/**
* Optional custom style to apply to the container.
*/
style?: object;
/**
* Optional function to render custom content, receiving the default content and dimensions.
*/
renderContent?: (options: {
defaultContent: React.ReactNode;
dimensions: {
width: number;
height: number;
};
}) => React.ReactNode;
/**
* Optional function to render a custom container, receiving the default container and dimensions.
*/
renderContainer?: (options: {
defaultContainer: React.ReactNode;
dimensions: {
width: number;
height: number;
};
}) => React.ReactNode;
}
export type AudioCardType = (options: AudioCardOptions) => JSX.Element;
/**
* AudioCard - Displays a participant in audio-only mode with waveform and controls
*
* AudioCard is a specialized React Native component for displaying participants in
* audio-only scenarios. It renders an avatar/image with an animated audio waveform,
* participant info overlay, and optional media control buttons. The component is ideal
* for audio-focused events, participants with video off, or compact grid layouts.
*
* **Key Features:**
* - Animated audio waveform visualization based on real-time decibel levels
* - Avatar/image display with optional rounded corners
* - Optional control buttons for muting/video toggling
* - Participant info overlay with customizable positioning
* - Fallback to MiniCard for compact display
* - Responsive layout with custom styling support
*
* **UI Customization - Two-Tier Override System:**
*
* 1. **Custom Render Function** (via `customAudioCard` prop):
* Pass a function that receives all AudioCardOptions and returns custom JSX.
* Provides complete control over rendering logic and appearance.
*
* 2. **Component Override** (via `uiOverrides.audioCardComponent`):
* Replace the entire AudioCard component while preserving MediaSFU's orchestration.
* Useful when you want a different component implementation.
*
* **Advanced Render Overrides:**
* - `renderContent`: Wrap/modify the card's inner content while keeping container
* - `renderContainer`: Wrap/modify the entire card container
*
* @component
* @param {AudioCardOptions} props - Configuration options for the AudioCard component
*
* @returns {JSX.Element} Rendered audio card with waveform, avatar, and controls
*
* @example
* // Basic usage - Display participant audio card with default styling
* import React from 'react';
* import { AudioCard } from 'mediasfu-reactnative-expo';
* import { Socket } from 'socket.io-client';
*
* const socket = Socket('https://example.com');
*
* function AudioParticipantGrid() {
* return (
* <AudioCard
* name="Alice Johnson"
* participant={{
* name: 'Alice Johnson',
* id: '456',
* videoOn: false,
* muted: false,
* audioID: 'audio_123',
* }}
* audioDecibels={{ name: 'Alice Johnson', averageLoudness: 50 }}
* parameters={{
* audioDecibels: [{ name: 'Alice Johnson', averageLoudness: 50 }],
* participants: [{ name: 'Alice Johnson', id: '456', videoOn: false, muted: false }],
* socket,
* coHostResponsibility: [],
* roomName: 'room1',
* coHost: 'coHostId',
* islevel: '1',
* member: '456',
* eventType: 'conference',
* getUpdatedAllParams: () => ({ ...params }),
* }}
* backgroundColor="#2c678f"
* barColor="red"
* textColor="white"
* showControls={true}
* showInfo={true}
* />
* );
* }
*
* @example
* // Custom styled audio card with avatar and custom colors
* <AudioCard
* name="Bob Wilson"
* participant={currentParticipant}
* audioDecibels={{ name: 'Bob Wilson', averageLoudness: 65 }}
* parameters={sessionParams}
* backgroundColor="#1a1a2e"
* barColor="#0f3460"
* textColor="#e94560"
* imageSource="https://example.com/avatar/bob.jpg"
* roundedImage={true}
* showControls={true}
* showInfo={true}
* controlsPosition="bottomRight"
* infoPosition="topLeft"
* customStyle={{ borderRadius: 12, margin: 8, borderWidth: 2, borderColor: '#e94560' }}
* />
*
* @example
* // Custom audio card with custom render function
* import { View, Text, Animated } from 'react-native';
*
* const customAudioCard = (options: AudioCardOptions) => {
* const { name, participant, audioDecibels } = options;
* const volume = audioDecibels?.averageLoudness || 0;
*
* return (
* <View style={{ backgroundColor: '#000', padding: 15, borderRadius: 10 }}>
* <Text style={{ color: '#fff', fontSize: 16, fontWeight: 'bold' }}>{name}</Text>
* <View style={{ marginTop: 10, flexDirection: 'row', alignItems: 'center' }}>
* <Text style={{ color: '#888' }}>Volume: </Text>
* <View style={{ width: volume * 2, height: 5, backgroundColor: volume > 50 ? 'green' : 'yellow' }} />
* </View>
* {participant.muted && (
* <Text style={{ color: 'red', marginTop: 5 }}>🔇 Muted</Text>
* )}
* </View>
* );
* };
*
* <AudioCard
* name="Custom Audio Participant"
* participant={participant}
* audioDecibels={audioData}
* parameters={params}
* customAudioCard={customAudioCard}
* />
*
* @example
* // Using uiOverrides for component-level customization
* import { MyCustomAudioCard } from './MyCustomAudioCard';
*
* const sessionConfig = {
* credentials: { apiKey: 'your-api-key' },
* uiOverrides: {
* audioCardComponent: {
* component: MyCustomAudioCard,
* injectedProps: {
* theme: 'neon',
* showWaveform: true,
* animationSpeed: 'fast',
* },
* },
* },
* };
*
* // MyCustomAudioCard.tsx
* export const MyCustomAudioCard = (props: AudioCardOptions & { theme: string; showWaveform: boolean; animationSpeed: string }) => {
* const waveformColor = props.theme === 'neon' ? '#00ff00' : '#ff0000';
*
* return (
* <View style={{ padding: 10 }}>
* <Text style={{ color: waveformColor }}>{props.name}</Text>
* {props.showWaveform && (
* <Text>Audio Level: {props.audioDecibels?.averageLoudness || 0}</Text>
* )}
* </View>
* );
* };
*
* @example
* ```tsx
* import React from 'react';
* import { AudioCard } from 'mediasfu-reactnative-expo';
* import { io } from 'socket.io-client';
*
* function App() {
* const socket = io('http://localhost:3000');
*
* return (
* <AudioCard
* name="John Doe"
* barColor="blue"
* textColor="white"
* imageSource="https://example.com/image.jpg"
* showControls={true}
* showInfo={true}
* participant={{ name: "John Doe", muted: false, videoOn: true }}
* parameters={{
* audioDecibels: [{ name: "John Doe", averageLoudness: 128 }],
* participants: [{ name: "John Doe" }],
* socket,
* coHostResponsibility: [],
* roomName: "Room 1",
* coHost: "Admin",
* islevel: "1",
* member: "12345",
* eventType: "meeting",
* showAlert: ({ message, type }) => console.log(message, type),
* getUpdatedAllParams: () => ({}),
* }}
* />
* );
* }
*
* export default App;
* ```
*/
declare const AudioCard: React.FC<AudioCardOptions>;
export default AudioCard;