tooot/src/screens/Shared/Compose/Attachments.tsx

159 lines
4.0 KiB
TypeScript
Raw Normal View History

import React, { Dispatch, useCallback } from 'react'
2020-12-06 12:52:29 +01:00
import { FlatList, Image, Pressable, StyleSheet, View } from 'react-native'
import { Feather } from '@expo/vector-icons'
2020-11-21 13:19:05 +01:00
import { PostAction, PostState } from '../Compose'
import { StyleConstants } from 'src/utils/styles/constants'
2020-12-06 12:52:29 +01:00
import { useTheme } from 'src/utils/styles/ThemeManager'
import { useNavigation } from '@react-navigation/native'
import ShimmerPlaceholder from 'react-native-shimmer-placeholder'
const DEFAULT_HEIGHT = 200
export interface Props {
postState: PostState
postDispatch: Dispatch<PostAction>
}
2020-12-03 22:03:06 +01:00
const ComposeAttachments: React.FC<Props> = ({ postState, postDispatch }) => {
2020-12-06 12:52:29 +01:00
const { theme } = useTheme()
const navigation = useNavigation()
const imageActions = ({
type,
icon,
onPress
}: {
type: 'edit' | 'delete'
icon: string
onPress: () => void
}) => {
return (
2020-12-06 12:52:29 +01:00
<Pressable
style={[
styles.actions,
styles[type],
{ backgroundColor: theme.backgroundOverlay }
]}
onPress={onPress}
>
<Feather
2020-12-06 12:52:29 +01:00
name={icon}
size={StyleConstants.Font.Size.L}
color={theme.primaryOverlay}
/>
2020-12-06 12:52:29 +01:00
</Pressable>
)
2020-12-06 12:52:29 +01:00
}
2020-12-06 12:52:29 +01:00
const renderImage = useCallback(
({
item,
index
}: {
item: Mastodon.Attachment & { local_url?: string }
index: number
}) => {
return (
<View key={index}>
<Image
style={[
styles.image,
{
width: (item.meta?.original?.aspect || 1) * DEFAULT_HEIGHT
}
]}
source={{
uri:
item.type === 'image'
? item.local_url || item.preview_url
: item.preview_url
}}
/>
{imageActions({
type: 'delete',
icon: 'x',
onPress: () =>
postDispatch({
type: 'attachments',
payload: postState.attachments.filter(e => e.id !== item.id)
})
})}
{imageActions({
type: 'edit',
icon: 'edit',
onPress: () =>
navigation.navigate('Screen-Shared-Compose-EditAttachment', {
2020-12-06 16:06:38 +01:00
attachment: item,
postDispatch
2020-12-06 12:52:29 +01:00
})
})}
</View>
)
},
[]
)
return (
<View style={styles.base}>
<FlatList
horizontal
data={postState.attachments}
renderItem={renderImage}
2020-12-06 12:52:29 +01:00
ListFooterComponent={
<ShimmerPlaceholder
style={styles.progressContainer}
visible={postState.attachmentUploadProgress === undefined}
width={
(postState.attachmentUploadProgress?.aspect || 16 / 9) *
DEFAULT_HEIGHT
}
height={200}
/>
}
showsHorizontalScrollIndicator={false}
/>
</View>
)
}
const styles = StyleSheet.create({
base: {
flex: 1,
flexDirection: 'row',
marginRight: StyleConstants.Spacing.Global.PagePadding,
2020-12-06 12:52:29 +01:00
height: DEFAULT_HEIGHT
},
image: {
flex: 1,
marginLeft: StyleConstants.Spacing.Global.PagePadding,
marginTop: StyleConstants.Spacing.Global.PagePadding,
marginBottom: StyleConstants.Spacing.Global.PagePadding
},
2020-12-06 12:52:29 +01:00
actions: {
position: 'absolute',
2020-12-06 12:52:29 +01:00
padding: StyleConstants.Spacing.S * 1.5,
borderRadius: StyleConstants.Spacing.XL
},
2020-12-06 12:52:29 +01:00
edit: {
bottom:
StyleConstants.Spacing.Global.PagePadding + StyleConstants.Spacing.S,
right: StyleConstants.Spacing.S
},
delete: {
top: StyleConstants.Spacing.Global.PagePadding + StyleConstants.Spacing.S,
right: StyleConstants.Spacing.S
},
progressContainer: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
height: DEFAULT_HEIGHT,
marginLeft: StyleConstants.Spacing.Global.PagePadding,
marginTop: StyleConstants.Spacing.Global.PagePadding,
marginBottom: StyleConstants.Spacing.Global.PagePadding
}
})
2020-12-03 22:03:06 +01:00
export default ComposeAttachments