2020-12-11 00:29:22 +01:00
|
|
|
import React, { useCallback, useContext } from 'react'
|
2020-12-06 21:42:19 +01:00
|
|
|
import {
|
|
|
|
FlatList,
|
|
|
|
Image,
|
|
|
|
Pressable,
|
|
|
|
StyleSheet,
|
|
|
|
Text,
|
|
|
|
View
|
|
|
|
} from 'react-native'
|
2020-11-19 22:45:26 +01:00
|
|
|
|
2020-12-13 14:04:25 +01:00
|
|
|
import { ComposeContext } from '@screens/Shared/Compose'
|
|
|
|
import { StyleConstants } from '@utils/styles/constants'
|
|
|
|
import { useTheme } from '@utils/styles/ThemeManager'
|
2020-12-06 12:52:29 +01:00
|
|
|
import { useNavigation } from '@react-navigation/native'
|
2020-12-17 09:44:03 +01:00
|
|
|
import { createShimmerPlaceholder } from 'react-native-shimmer-placeholder'
|
2020-12-26 23:05:17 +01:00
|
|
|
import Button from '@components/Button'
|
2020-12-13 14:04:25 +01:00
|
|
|
import addAttachments from '@screens/Shared/Compose/addAttachments'
|
2020-12-07 00:23:26 +01:00
|
|
|
import { Feather } from '@expo/vector-icons'
|
2020-12-17 09:44:03 +01:00
|
|
|
import { LinearGradient } from 'expo-linear-gradient'
|
2020-12-06 12:52:29 +01:00
|
|
|
|
|
|
|
const DEFAULT_HEIGHT = 200
|
2020-11-19 22:45:26 +01:00
|
|
|
|
2020-12-11 00:29:22 +01:00
|
|
|
const ComposeAttachments: React.FC = () => {
|
|
|
|
const { composeState, composeDispatch } = useContext(ComposeContext)
|
2020-12-06 12:52:29 +01:00
|
|
|
const { theme } = useTheme()
|
|
|
|
const navigation = useNavigation()
|
|
|
|
|
2020-12-06 21:42:19 +01:00
|
|
|
const renderAttachment = useCallback(
|
2020-12-06 12:52:29 +01:00
|
|
|
({
|
|
|
|
item,
|
|
|
|
index
|
|
|
|
}: {
|
|
|
|
item: Mastodon.Attachment & { local_url?: string }
|
|
|
|
index: number
|
|
|
|
}) => {
|
|
|
|
return (
|
|
|
|
<View key={index}>
|
|
|
|
<Image
|
|
|
|
style={[
|
|
|
|
styles.image,
|
|
|
|
{
|
2020-12-06 21:42:19 +01:00
|
|
|
width:
|
|
|
|
((item as Mastodon.AttachmentImage).meta?.original?.aspect ||
|
|
|
|
(item as Mastodon.AttachmentVideo).meta?.original.width! /
|
|
|
|
(item as Mastodon.AttachmentVideo).meta?.original
|
|
|
|
.height! ||
|
|
|
|
1) * DEFAULT_HEIGHT
|
2020-12-06 12:52:29 +01:00
|
|
|
}
|
|
|
|
]}
|
|
|
|
source={{
|
|
|
|
uri:
|
|
|
|
item.type === 'image'
|
|
|
|
? item.local_url || item.preview_url
|
|
|
|
: item.preview_url
|
|
|
|
}}
|
|
|
|
/>
|
2020-12-06 21:42:19 +01:00
|
|
|
{(item as Mastodon.AttachmentVideo).meta?.original?.duration && (
|
|
|
|
<Text
|
|
|
|
style={[
|
|
|
|
styles.duration,
|
|
|
|
{
|
|
|
|
color: theme.background,
|
|
|
|
backgroundColor: theme.backgroundOverlay
|
|
|
|
}
|
|
|
|
]}
|
|
|
|
>
|
|
|
|
{(item as Mastodon.AttachmentVideo).meta?.original.duration}
|
|
|
|
</Text>
|
|
|
|
)}
|
2020-12-26 23:05:17 +01:00
|
|
|
<Button
|
|
|
|
type='icon'
|
|
|
|
content='x'
|
|
|
|
spacing='M'
|
|
|
|
round
|
|
|
|
overlay
|
|
|
|
style={styles.delete}
|
2020-12-06 21:42:19 +01:00
|
|
|
onPress={() =>
|
2020-12-07 12:31:40 +01:00
|
|
|
composeDispatch({
|
2020-12-06 12:52:29 +01:00
|
|
|
type: 'attachments',
|
2020-12-07 00:23:26 +01:00
|
|
|
payload: {
|
2020-12-07 12:31:40 +01:00
|
|
|
uploads: composeState.attachments.uploads.filter(
|
2020-12-07 00:23:26 +01:00
|
|
|
e => e.id !== item.id
|
|
|
|
)
|
|
|
|
}
|
2020-12-06 12:52:29 +01:00
|
|
|
})
|
2020-12-06 21:42:19 +01:00
|
|
|
}
|
|
|
|
/>
|
2020-12-26 23:05:17 +01:00
|
|
|
<Button
|
|
|
|
type='icon'
|
|
|
|
content='edit'
|
|
|
|
spacing='M'
|
|
|
|
round
|
|
|
|
overlay
|
|
|
|
style={styles.edit}
|
2020-12-06 21:42:19 +01:00
|
|
|
onPress={() =>
|
2020-12-06 12:52:29 +01:00
|
|
|
navigation.navigate('Screen-Shared-Compose-EditAttachment', {
|
2020-12-06 16:06:38 +01:00
|
|
|
attachment: item,
|
2020-12-07 12:31:40 +01:00
|
|
|
composeDispatch
|
2020-12-06 12:52:29 +01:00
|
|
|
})
|
2020-12-06 21:42:19 +01:00
|
|
|
}
|
|
|
|
/>
|
2020-12-06 12:52:29 +01:00
|
|
|
</View>
|
|
|
|
)
|
|
|
|
},
|
|
|
|
[]
|
|
|
|
)
|
2020-12-05 01:55:53 +01:00
|
|
|
|
2020-12-06 21:42:19 +01:00
|
|
|
const listFooter = useCallback(() => {
|
2020-12-17 09:44:03 +01:00
|
|
|
const ShimmerPlaceholder = createShimmerPlaceholder(LinearGradient)
|
|
|
|
|
2020-12-06 21:42:19 +01:00
|
|
|
return (
|
|
|
|
<ShimmerPlaceholder
|
|
|
|
style={styles.progressContainer}
|
2020-12-07 12:31:40 +01:00
|
|
|
visible={composeState.attachmentUploadProgress === undefined}
|
2020-12-06 21:42:19 +01:00
|
|
|
width={
|
2020-12-11 00:29:22 +01:00
|
|
|
(composeState.attachmentUploadProgress?.aspect || 3 / 2) *
|
|
|
|
DEFAULT_HEIGHT
|
2020-12-06 21:42:19 +01:00
|
|
|
}
|
|
|
|
height={200}
|
2020-12-27 16:25:29 +01:00
|
|
|
shimmerColors={theme.shimmer}
|
2020-12-06 21:42:19 +01:00
|
|
|
>
|
2020-12-07 12:31:40 +01:00
|
|
|
{composeState.attachments.uploads.length > 0 &&
|
|
|
|
composeState.attachments.uploads[0].type === 'image' &&
|
|
|
|
composeState.attachments.uploads.length < 4 && (
|
2020-12-06 21:42:19 +01:00
|
|
|
<Pressable
|
|
|
|
style={{
|
|
|
|
width: DEFAULT_HEIGHT,
|
|
|
|
height: DEFAULT_HEIGHT,
|
|
|
|
backgroundColor: theme.border
|
|
|
|
}}
|
|
|
|
onPress={async () =>
|
2020-12-07 12:31:40 +01:00
|
|
|
await addAttachments({ composeState, composeDispatch })
|
2020-12-06 21:42:19 +01:00
|
|
|
}
|
|
|
|
>
|
2020-12-26 23:05:17 +01:00
|
|
|
<Button
|
|
|
|
type='icon'
|
|
|
|
content='upload-cloud'
|
|
|
|
spacing='M'
|
|
|
|
round
|
|
|
|
overlay
|
2020-12-06 21:42:19 +01:00
|
|
|
onPress={async () =>
|
2020-12-07 12:31:40 +01:00
|
|
|
await addAttachments({ composeState, composeDispatch })
|
2020-12-06 21:42:19 +01:00
|
|
|
}
|
2020-12-26 23:05:17 +01:00
|
|
|
style={{
|
|
|
|
position: 'absolute',
|
2020-12-06 21:42:19 +01:00
|
|
|
top:
|
|
|
|
(DEFAULT_HEIGHT -
|
2020-12-26 23:05:17 +01:00
|
|
|
StyleConstants.Spacing.M * 2 -
|
|
|
|
StyleConstants.Font.Size.M) /
|
2020-12-06 21:42:19 +01:00
|
|
|
2,
|
|
|
|
left:
|
|
|
|
(DEFAULT_HEIGHT -
|
2020-12-26 23:05:17 +01:00
|
|
|
StyleConstants.Spacing.M * 2 -
|
|
|
|
StyleConstants.Font.Size.M) /
|
2020-12-06 21:42:19 +01:00
|
|
|
2
|
|
|
|
}}
|
|
|
|
/>
|
|
|
|
</Pressable>
|
|
|
|
)}
|
|
|
|
</ShimmerPlaceholder>
|
|
|
|
)
|
2020-12-07 12:31:40 +01:00
|
|
|
}, [composeState.attachmentUploadProgress, composeState.attachments.uploads])
|
2020-12-06 21:42:19 +01:00
|
|
|
|
2020-11-19 22:45:26 +01:00
|
|
|
return (
|
|
|
|
<View style={styles.base}>
|
2020-12-07 00:23:26 +01:00
|
|
|
<Pressable
|
|
|
|
style={styles.sensitive}
|
|
|
|
onPress={() =>
|
2020-12-07 12:31:40 +01:00
|
|
|
composeDispatch({
|
2020-12-07 00:23:26 +01:00
|
|
|
type: 'attachments',
|
2020-12-07 12:31:40 +01:00
|
|
|
payload: { sensitive: !composeState.attachments.sensitive }
|
2020-12-07 00:23:26 +01:00
|
|
|
})
|
|
|
|
}
|
|
|
|
>
|
|
|
|
<Feather
|
2020-12-07 12:31:40 +01:00
|
|
|
name={composeState.attachments.sensitive ? 'check-circle' : 'circle'}
|
2020-12-07 00:23:26 +01:00
|
|
|
size={StyleConstants.Font.Size.L}
|
|
|
|
color={theme.primary}
|
|
|
|
/>
|
|
|
|
<Text style={[styles.sensitiveText, { color: theme.primary }]}>
|
|
|
|
标记媒体为敏感内容
|
|
|
|
</Text>
|
|
|
|
</Pressable>
|
|
|
|
<View style={styles.imageContainer}>
|
|
|
|
<FlatList
|
|
|
|
horizontal
|
2020-12-07 12:31:40 +01:00
|
|
|
extraData={composeState.attachments.uploads.length}
|
|
|
|
data={composeState.attachments.uploads}
|
2020-12-07 00:23:26 +01:00
|
|
|
renderItem={renderAttachment}
|
|
|
|
ListFooterComponent={listFooter}
|
|
|
|
showsHorizontalScrollIndicator={false}
|
|
|
|
keyboardShouldPersistTaps='handled'
|
|
|
|
/>
|
|
|
|
</View>
|
2020-11-19 22:45:26 +01:00
|
|
|
</View>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
const styles = StyleSheet.create({
|
|
|
|
base: {
|
|
|
|
flex: 1,
|
2020-12-05 01:55:53 +01:00
|
|
|
marginRight: StyleConstants.Spacing.Global.PagePadding,
|
2020-12-07 00:23:26 +01:00
|
|
|
marginTop: StyleConstants.Spacing.M
|
|
|
|
},
|
|
|
|
sensitive: {
|
|
|
|
flex: 1,
|
|
|
|
flexDirection: 'row',
|
|
|
|
alignItems: 'center',
|
|
|
|
marginLeft: StyleConstants.Spacing.Global.PagePadding
|
|
|
|
},
|
|
|
|
sensitiveText: {
|
2020-12-29 00:21:05 +01:00
|
|
|
...StyleConstants.FontStyle.M,
|
2020-12-07 00:23:26 +01:00
|
|
|
marginLeft: StyleConstants.Spacing.S
|
|
|
|
},
|
|
|
|
imageContainer: {
|
2020-12-06 12:52:29 +01:00
|
|
|
height: DEFAULT_HEIGHT
|
2020-11-19 22:45:26 +01:00
|
|
|
},
|
|
|
|
image: {
|
2020-12-05 01:55:53 +01:00
|
|
|
flex: 1,
|
|
|
|
marginLeft: StyleConstants.Spacing.Global.PagePadding,
|
|
|
|
marginTop: StyleConstants.Spacing.Global.PagePadding,
|
|
|
|
marginBottom: StyleConstants.Spacing.Global.PagePadding
|
2020-11-19 22:45:26 +01:00
|
|
|
},
|
2020-12-06 21:42:19 +01:00
|
|
|
duration: {
|
2020-11-19 22:45:26 +01:00
|
|
|
position: 'absolute',
|
2020-12-06 21:42:19 +01:00
|
|
|
bottom:
|
|
|
|
StyleConstants.Spacing.Global.PagePadding + StyleConstants.Spacing.S,
|
|
|
|
left: StyleConstants.Spacing.Global.PagePadding + StyleConstants.Spacing.S,
|
2020-12-29 00:21:05 +01:00
|
|
|
...StyleConstants.FontStyle.S,
|
2020-12-06 21:42:19 +01:00
|
|
|
paddingLeft: StyleConstants.Spacing.S,
|
|
|
|
paddingRight: StyleConstants.Spacing.S,
|
|
|
|
paddingTop: StyleConstants.Spacing.XS,
|
|
|
|
paddingBottom: StyleConstants.Spacing.XS
|
2020-11-19 22:45:26 +01:00
|
|
|
},
|
2020-12-26 23:05:17 +01:00
|
|
|
delete: {
|
|
|
|
position: 'absolute',
|
|
|
|
top: StyleConstants.Spacing.Global.PagePadding + StyleConstants.Spacing.S,
|
|
|
|
right: StyleConstants.Spacing.S
|
|
|
|
},
|
2020-12-06 12:52:29 +01:00
|
|
|
edit: {
|
2020-12-26 23:05:17 +01:00
|
|
|
position: 'absolute',
|
2020-12-06 12:52:29 +01:00
|
|
|
bottom:
|
|
|
|
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-11-19 22:45:26 +01:00
|
|
|
}
|
|
|
|
})
|
|
|
|
|
2020-12-07 00:23:26 +01:00
|
|
|
export default ComposeAttachments
|