mediasfu-reactnative
Version:
MediaSFU Prebuilt React Native SDK
183 lines • 6.49 kB
JavaScript
import React, { useState, useEffect } from 'react';
import { View, Text, StyleSheet, Image, Animated, } from 'react-native';
import { getOverlayPosition } from '../../methods/utils/getOverlayPosition';
/**
* MiniCardAudio displays an audio card with optional waveform animation and custom styling options.
*
* This component supports showing an animated waveform, an image, and custom positioning for the overlay. It is designed
* for displaying audio-related information in a visually appealing, customizable way.
*
* @component
* @param {MiniCardAudioOptions} props - Configuration options for the MiniCardAudio component.
* @param {StyleProp<ViewStyle>} [props.customStyle] - Custom styles for the card container.
* @param {string} props.name - The name displayed on the audio card.
* @param {boolean} props.showWaveform - Toggles the waveform animation display.
* @param {OverlayPosition} [props.overlayPosition='topLeft'] - Position of the overlay on the card.
* @param {string} [props.barColor='white'] - Color of the waveform bars.
* @param {string} [props.textColor='white'] - Color of the displayed name text.
* @param {string} [props.imageSource] - URI for the background image.
* @param {boolean} [props.roundedImage=false] - Determines if the image should have rounded corners.
* @param {StyleProp<ImageStyle>} [props.imageStyle] - Custom styles for the background image.
*
* @returns {JSX.Element} The MiniCardAudio component.
*
* @example
* ```tsx
* import React from 'react';
* import { MiniCardAudio } from 'mediasfu-reactnative';
*
* function App() {
* return (
* <MiniCardAudio
* name="Alice Johnson"
* showWaveform={true}
* overlayPosition="bottomRight"
* barColor="blue"
* textColor="white"
* imageSource="https://example.com/profile.jpg"
* roundedImage={true}
* customStyle={{ width: 100, height: 100 }}
* />
* );
* }
*
* export default App;
* ```
*/
const MiniCardAudio = ({ customStyle, name, showWaveform, overlayPosition = 'topLeft', barColor = 'white', textColor = 'white', imageSource, roundedImage = false, imageStyle, }) => {
// Initialize waveform animation values
const [waveformAnimations] = useState(Array.from({ length: 9 }, () => new Animated.Value(0)));
// Reference to store interval IDs (if using setInterval)
// Not recommended in React Native; using Animated API instead
/**
* Animates the waveform bars using the Animated API.
*/
const animateWaveform = () => {
const animations = waveformAnimations.map((animation, index) => Animated.loop(Animated.sequence([
Animated.timing(animation, {
toValue: 1,
duration: getAnimationDuration(index),
useNativeDriver: false,
}),
Animated.timing(animation, {
toValue: 0,
duration: getAnimationDuration(index),
useNativeDriver: false,
}),
])));
Animated.parallel(animations).start();
};
/**
* Resets the waveform animations to their initial state.
*/
const resetWaveform = () => {
waveformAnimations.forEach((animation) => {
animation.setValue(0);
animation.stopAnimation();
});
};
/**
* Retrieves the animation duration for a specific bar.
* @param index - The index of the waveform bar.
* @returns number - The duration in milliseconds.
*/
const getAnimationDuration = (index) => {
const durations = [474, 433, 407, 458, 400, 427, 441, 419, 487];
return durations[index] || 400;
};
useEffect(() => {
if (showWaveform) {
animateWaveform();
}
else {
resetWaveform();
}
// Cleanup animations on component unmount or when showWaveform changes
return () => {
resetWaveform();
};
}, [showWaveform]);
return (<View style={[styles.card, customStyle]}>
{imageSource && (<Image source={{ uri: imageSource }} style={[
styles.backgroundImage,
roundedImage && styles.roundedImage,
imageStyle,
]} resizeMode="cover"/>)}
<View style={[getOverlayPosition({ position: overlayPosition }), styles.overlayContainer]}>
<View style={styles.nameColumn}>
<Text style={[styles.nameText, { color: textColor }]}>{name}</Text>
</View>
{showWaveform && (<View style={styles.waveformContainer}>
{waveformAnimations.map((animation, index) => (<Animated.View key={index} style={[
styles.bar,
{
height: animation.interpolate({
inputRange: [0, 1],
outputRange: [1, 16],
}),
backgroundColor: barColor,
},
]}/>))}
</View>)}
</View>
</View>);
};
export default MiniCardAudio;
/**
* Stylesheet for the MiniCardAudio component.
*/
const styles = StyleSheet.create({
card: {
width: '100%',
height: '100%',
margin: 0,
padding: 0,
backgroundColor: '#2c678f',
borderRadius: 10,
overflow: 'hidden',
},
overlayContainer: {
position: 'absolute',
// Additional positioning handled by getOverlayPositionStyle
},
nameColumn: {
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'rgba(0, 0, 0, 0.5)',
paddingVertical: 5,
paddingHorizontal: 10,
marginEnd: 2,
borderRadius: 5,
},
nameText: {
fontSize: 14,
color: 'white',
fontWeight: 'bold',
textAlign: 'center',
},
waveformContainer: {
flexDirection: 'row',
alignItems: 'flex-end',
backgroundColor: 'rgba(0, 0, 0, 0.05)',
paddingHorizontal: 5,
paddingVertical: 2,
borderRadius: 5,
marginTop: 5,
},
bar: {
width: 4,
marginHorizontal: 1,
borderRadius: 2,
},
backgroundImage: {
width: '60%',
height: '60%',
alignSelf: 'center',
justifyContent: 'center',
alignItems: 'center',
},
roundedImage: {
borderRadius: 50, // Fully rounded
},
});
//# sourceMappingURL=MiniCardAudio.js.map