1import FontAwesome from '@expo/vector-icons/build/FontAwesome'; 2import * as MediaLibrary from 'expo-media-library'; 3import React from 'react'; 4import { 5 Image, 6 StyleProp, 7 StyleSheet, 8 Text, 9 TouchableOpacity, 10 View, 11 ViewStyle, 12} from 'react-native'; 13 14export default class MediaLibraryCell extends React.Component<{ 15 asset: MediaLibrary.Asset; 16 onPress: (asset: MediaLibrary.Asset) => void; 17 style?: StyleProp<ViewStyle>; 18}> { 19 onPress = () => { 20 const { asset } = this.props; 21 this.props.onPress(asset); 22 }; 23 24 getAssetData(asset: MediaLibrary.Asset) { 25 switch (asset.mediaType) { 26 case MediaLibrary.MediaType.photo: 27 return { 28 icon: 'photo', 29 description: `${asset.width}x${asset.height}`, 30 preview: <Image style={styles.preview} source={{ uri: asset.uri }} resizeMode="cover" />, 31 }; 32 case MediaLibrary.MediaType.video: 33 return { 34 icon: 'video-camera', 35 description: `${Math.round(asset.duration)}s`, 36 preview: <Image style={styles.preview} source={{ uri: asset.uri }} resizeMode="cover" />, 37 }; 38 case MediaLibrary.MediaType.audio: 39 return { 40 icon: 'music', 41 description: `${Math.round(asset.duration)}s`, 42 preview: ( 43 <View style={[styles.preview, styles.audioPreview]}> 44 <Text>Audio</Text> 45 </View> 46 ), 47 }; 48 default: 49 return null; 50 } 51 } 52 53 render() { 54 const { asset, style } = this.props; 55 const data = this.getAssetData(asset); 56 57 return ( 58 <TouchableOpacity style={[styles.container, style]} onPress={this.onPress}> 59 {data && data.preview} 60 {data && ( 61 <View style={styles.cellFooter}> 62 <FontAwesome name={data.icon as any} size={12} color="white" /> 63 <Text style={styles.description}>{data.description}</Text> 64 </View> 65 )} 66 </TouchableOpacity> 67 ); 68 } 69} 70 71const styles = StyleSheet.create({ 72 container: { 73 aspectRatio: 1, 74 padding: 1, 75 }, 76 preview: { 77 flex: 1, 78 }, 79 audioPreview: { 80 flexDirection: 'row', 81 alignItems: 'center', 82 justifyContent: 'center', 83 }, 84 cellFooter: { 85 height: 18, 86 paddingHorizontal: 5, 87 flexDirection: 'row', 88 alignItems: 'center', 89 backgroundColor: 'rgba(0, 0, 0, 0.5)', 90 position: 'absolute', 91 left: 1, 92 right: 1, 93 bottom: 1, 94 }, 95 description: { 96 paddingHorizontal: 5, 97 fontSize: 12, 98 color: 'white', 99 }, 100}); 101