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