UNPKG

mediasfu-reactnative

Version:
183 lines 6.49 kB
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