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