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