UNPKG

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

270 lines (269 loc) 9.14 kB
import React from "react"; import { StyleProp, ViewStyle } from "react-native"; import { FontAwesome5 } from "@expo/vector-icons"; /** * Configuration for a single touch-optimized control button. * * @interface ButtonTouch * * @property {string} [name] - Button label/name * @property {keyof typeof FontAwesome5.glyphMap} [icon] - Icon name from FontAwesome5 glyphMap * @property {keyof typeof FontAwesome5.glyphMap} [alternateIcon] - Alternate icon name (shown when active) * @property {function} [onPress] - Click handler * @property {object} [backgroundColor] - Background colors with default and pressed states * @property {boolean} [active] - Whether button is in active state * @property {JSX.Element} [alternateIconComponent] - Custom alternate icon component * @property {JSX.Element} [iconComponent] - Custom icon component * @property {JSX.Element} [customComponent] - Completely custom button component * @property {string} [color] - Icon color * @property {string} [activeColor] - Icon color when active * @property {string} [inActiveColor] - Icon color when inactive * @property {boolean} [show] - Whether to show the button * @property {boolean} [disabled] - Whether button is disabled */ export interface ButtonTouch { name?: string; icon?: keyof typeof FontAwesome5.glyphMap; alternateIcon?: keyof typeof FontAwesome5.glyphMap; onPress?: () => void; backgroundColor?: { default?: string; pressed?: string; }; active?: boolean; alternateIconComponent?: JSX.Element; iconComponent?: JSX.Element; customComponent?: JSX.Element; color?: string; activeColor?: string; inActiveColor?: string; show?: boolean; disabled?: boolean; } /** * Configuration options for the ControlButtonsComponentTouch. * * @interface ControlButtonsComponentTouchOptions * * **Button Configuration:** * @property {ButtonTouch[]} buttons - Array of touch-optimized button configurations * * **Absolute Positioning:** * @property {'left' | 'right' | 'middle'} [position='left'] - Horizontal screen position * @property {'top' | 'bottom' | 'center'} [location='top'] - Vertical screen position * @property {'horizontal' | 'vertical'} [direction='horizontal'] - Button arrangement direction * * **Display Control:** * @property {boolean} [showAspect] - Whether to show the button group overlay * * **Styling:** * @property {StyleProp<ViewStyle>} [buttonsContainerStyle] - Custom styles for buttons container * @property {object} [style] - Additional custom styles for outer container * * **Custom Icons:** * @property {JSX.Element} [alternateIconComponent] - Global alternate icon component * @property {JSX.Element} [iconComponent] - Global icon component * * **Advanced Render Overrides:** * @property {function} [renderContent] - Optional custom renderer for button content (receives defaultContent and dimensions) * @property {function} [renderContainer] - Optional custom renderer for outer container (receives defaultContainer and dimensions) */ export interface ControlButtonsComponentTouchOptions { buttons: ButtonTouch[]; position?: "left" | "right" | "middle"; location?: "top" | "bottom" | "center"; direction?: "horizontal" | "vertical"; buttonsContainerStyle?: StyleProp<ViewStyle>; alternateIconComponent?: JSX.Element; iconComponent?: JSX.Element; showAspect?: boolean; style?: object; renderContent?: (options: { defaultContent: React.ReactNode; dimensions: { width: number; height: number; }; }) => React.ReactNode; renderContainer?: (options: { defaultContainer: React.ReactNode; dimensions: { width: number; height: number; }; }) => React.ReactNode; } export type ControlButtonsComponentTouchType = (options: ControlButtonsComponentTouchOptions) => JSX.Element; /** * ControlButtonsComponentTouch - Touch-optimized positioned overlay buttons * * ControlButtonsComponentTouch is a React Native component specifically optimized * for touch interfaces. It renders control buttons in an absolute positioned overlay * with enhanced touch targets and press feedback for mobile/tablet devices. * * **Key Features:** * - Touch-optimized button sizing and spacing * - Absolute positioning with 9 screen positions * - Horizontal or vertical button arrangement * - Active/inactive state visual feedback * - Disabled button support * - Enhanced press feedback for mobile * - Show/hide visibility control * - TypeScript-validated icon names * * **UI Customization:** * This component can be replaced via `uiOverrides.controlButtonsComponentTouch` to * provide a completely custom touch-optimized control overlay. * * @component * @param {ControlButtonsComponentTouchOptions} props - Configuration options for touch-optimized buttons * * @returns {JSX.Element} Rendered touch-optimized control button overlay * * @example * // Basic usage - Touch-optimized video controls * import React from 'react'; * import { ControlButtonsComponentTouch, ButtonTouch } from 'mediasfu-reactnative-expo'; * * function TouchVideoControls() { * const [isPlaying, setIsPlaying] = React.useState(false); * const [isMuted, setIsMuted] = React.useState(false); * * const touchButtons: ButtonTouch[] = [ * { * name: 'PlayPause', * icon: 'play', * alternateIcon: 'pause', * active: isPlaying, * onPress: () => setIsPlaying(!isPlaying), * activeColor: '#007bff', * inActiveColor: '#FFFFFF', * show: true, * }, * { * name: 'Mute', * icon: 'volume-up', * alternateIcon: 'volume-mute', * active: isMuted, * onPress: () => setIsMuted(!isMuted), * activeColor: '#FF0000', * inActiveColor: '#FFFFFF', * show: true, * }, * ]; * * return ( * <ControlButtonsComponentTouch * buttons={touchButtons} * position="middle" * location="bottom" * direction="horizontal" * showAspect={true} * buttonsContainerStyle={{ * backgroundColor: 'rgba(0,0,0,0.6)', * padding: 12, * borderRadius: 24, * gap: 16, * }} * /> * ); * } * * @example * // Side panel touch buttons * <ControlButtonsComponentTouch * buttons={sideButtons} * position="right" * location="center" * direction="vertical" * showAspect={true} * buttonsContainerStyle={{ * gap: 16, * padding: 12, * backgroundColor: 'rgba(0,0,0,0.7)', * }} * /> * * @example * // With disabled and conditional buttons * const buttons: ButtonTouch[] = [ * { * name: 'Record', * icon: 'circle', * onPress: startRecording, * disabled: isRecording, * color: '#FF0000', * show: canRecord, * }, * { * name: 'Stop', * icon: 'stop', * onPress: stopRecording, * disabled: !isRecording, * color: '#FFFFFF', * show: canRecord, * }, * ]; * * <ControlButtonsComponentTouch * buttons={buttons} * position="left" * location="top" * direction="horizontal" * showAspect={true} * /> * * @example * // Using uiOverrides for complete touch overlay replacement * import { MyCustomTouchButtons } from './MyCustomTouchButtons'; * * const sessionConfig = { * credentials: { apiKey: 'your-api-key' }, * uiOverrides: { * controlButtonsComponentTouch: { * component: MyCustomTouchButtons, * injectedProps: { * hapticFeedback: true, * minimumTouchSize: 48, * }, * }, * }, * }; * * // MyCustomTouchButtons.tsx * export const MyCustomTouchButtons = (props: ControlButtonsComponentTouchOptions & { hapticFeedback: boolean; minimumTouchSize: number }) => { * const handlePress = (button: ButtonTouch) => { * if (props.hapticFeedback && Platform.OS !== 'web') { * Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light); * } * button.onPress?.(); * }; * * return ( * <View style={{ flexDirection: props.direction === 'vertical' ? 'column' : 'row' }}> * {props.buttons.filter(btn => btn.show !== false).map((button, index) => ( * <Pressable * key={index} * onPress={() => handlePress(button)} * disabled={button.disabled} * style={{ * minWidth: props.minimumTouchSize, * minHeight: props.minimumTouchSize, * justifyContent: 'center', * alignItems: 'center', * opacity: button.disabled ? 0.5 : 1, * }} * > * <FontAwesome5 * name={button.active ? button.alternateIcon : button.icon} * size={28} * color={button.active ? button.activeColor : button.inActiveColor || button.color} * /> * </Pressable> * ))} * </View> * ); * }; */ declare const ControlButtonsComponentTouch: React.FC<ControlButtonsComponentTouchOptions>; export default ControlButtonsComponentTouch;