tooot/src/screens/Compose/DraftsList/Root.tsx

264 lines
8.2 KiB
TypeScript
Raw Normal View History

2021-02-20 19:12:44 +01:00
import apiInstance from '@api/instance'
2021-02-07 00:39:11 +01:00
import Icon from '@components/Icon'
import ComponentSeparator from '@components/Separator'
import CustomText from '@components/Text'
2021-02-08 23:47:20 +01:00
import HeaderSharedCreated from '@components/Timeline/Shared/HeaderShared/Created'
2021-02-07 00:39:11 +01:00
import { useNavigation } from '@react-navigation/native'
2022-04-30 23:47:52 +02:00
import { useAppDispatch } from '@root/store'
2021-02-20 19:12:44 +01:00
import {
getInstanceDrafts,
removeInstanceDraft
} from '@utils/slices/instancesSlice'
2021-02-07 00:39:11 +01:00
import { StyleConstants } from '@utils/styles/constants'
import { useTheme } from '@utils/styles/ThemeManager'
2021-03-18 22:34:54 +01:00
import React, { useCallback, useContext, useState } from 'react'
2021-02-07 00:39:11 +01:00
import { useTranslation } from 'react-i18next'
import {
Dimensions,
2021-03-19 21:44:52 +01:00
Image,
2021-02-07 00:39:11 +01:00
Modal,
2021-03-11 23:12:17 +01:00
Platform,
2021-02-07 00:39:11 +01:00
Pressable,
View
} from 'react-native'
import { PanGestureHandler } from 'react-native-gesture-handler'
2021-02-07 00:39:11 +01:00
import { SwipeListView } from 'react-native-swipe-list-view'
2022-04-30 23:47:52 +02:00
import { useSelector } from 'react-redux'
2021-02-07 00:39:11 +01:00
import formatText from '../formatText'
import ComposeContext from '../utils/createContext'
import { ComposeStateDraft, ExtendedAttachment } from '../utils/types'
export interface Props {
timestamp: number
}
const ComposeDraftsListRoot: React.FC<Props> = ({ timestamp }) => {
const { composeDispatch } = useContext(ComposeContext)
2021-03-28 23:31:10 +02:00
const { t } = useTranslation('screenCompose')
2021-02-07 00:39:11 +01:00
const navigation = useNavigation()
2022-04-30 23:47:52 +02:00
const dispatch = useAppDispatch()
2022-02-12 14:51:01 +01:00
const { colors, theme } = useTheme()
2021-02-20 19:12:44 +01:00
const instanceDrafts = useSelector(getInstanceDrafts)?.filter(
2021-02-07 00:39:11 +01:00
draft => draft.timestamp !== timestamp
)
const actionWidth =
StyleConstants.Font.Size.L + StyleConstants.Spacing.Global.PagePadding * 4
const [checkingAttachments, setCheckingAttachments] = useState(false)
const removeDraft = useCallback(ts => {
2021-02-20 19:12:44 +01:00
dispatch(removeInstanceDraft(ts))
2021-02-07 00:39:11 +01:00
}, [])
const renderItem = useCallback(
({ item }: { item: ComposeStateDraft }) => {
return (
<Pressable
2021-04-09 21:43:12 +02:00
accessibilityHint={t('content.draftsList.content.accessibilityHint')}
style={{
flex: 1,
padding: StyleConstants.Spacing.Global.PagePadding,
backgroundColor: colors.backgroundDefault
}}
2021-02-07 00:39:11 +01:00
onPress={async () => {
setCheckingAttachments(true)
let tempDraft = item
let tempUploads: ExtendedAttachment[] = []
if (item.attachments && item.attachments.uploads.length) {
for (const attachment of item.attachments.uploads) {
2021-02-20 19:12:44 +01:00
await apiInstance<Mastodon.Attachment>({
2021-02-07 00:39:11 +01:00
method: 'get',
url: `media/${attachment.remote?.id}`
})
.then(res => {
2021-02-11 01:33:31 +01:00
if (res.body.id === attachment.remote?.id) {
2021-02-07 00:39:11 +01:00
tempUploads.push(attachment)
}
})
.catch(() => {})
}
tempDraft = {
...tempDraft,
attachments: { ...item.attachments, uploads: tempUploads }
}
}
tempDraft.spoiler?.length &&
formatText({
textInput: 'text',
composeDispatch,
content: tempDraft.spoiler
})
tempDraft.text?.length &&
formatText({
textInput: 'text',
composeDispatch,
content: tempDraft.text
})
composeDispatch({
type: 'loadDraft',
payload: tempDraft
})
2021-02-20 19:12:44 +01:00
dispatch(removeInstanceDraft(item.timestamp))
2021-02-07 00:39:11 +01:00
navigation.goBack()
}}
>
<View style={{ flex: 1 }}>
<HeaderSharedCreated created_at={item.timestamp} />
<CustomText
fontStyle='M'
2021-02-07 00:39:11 +01:00
numberOfLines={2}
style={{
marginTop: StyleConstants.Spacing.XS,
color: colors.primaryDefault
}}
2021-02-07 00:39:11 +01:00
>
{item.text ||
item.spoiler ||
t('content.draftsList.content.textEmpty')}
</CustomText>
2021-02-07 00:39:11 +01:00
{item.attachments?.uploads.length ? (
<View
style={{
flex: 1,
flexDirection: 'row',
marginTop: StyleConstants.Spacing.S
}}
>
2021-02-07 00:39:11 +01:00
{item.attachments.uploads.map((attachment, index) => (
2021-03-19 21:44:52 +01:00
<Image
2021-02-07 00:39:11 +01:00
key={index}
style={{
width:
(Dimensions.get('screen').width -
StyleConstants.Spacing.Global.PagePadding * 2 -
StyleConstants.Spacing.S * 3) /
4,
height:
(Dimensions.get('screen').width -
StyleConstants.Spacing.Global.PagePadding * 2 -
StyleConstants.Spacing.S * 3) /
4,
marginLeft: index !== 0 ? StyleConstants.Spacing.S : 0
}}
2021-02-07 00:39:11 +01:00
source={{
uri:
attachment.local?.local_thumbnail ||
attachment.remote?.preview_url
}}
/>
))}
</View>
) : null}
</View>
</Pressable>
)
},
2022-02-12 14:51:01 +01:00
[theme]
2021-02-07 00:39:11 +01:00
)
const renderHiddenItem = useCallback(
({ item }) => (
<View
style={{
flex: 1,
flexDirection: 'row',
justifyContent: 'flex-end',
backgroundColor: colors.red
}}
2021-02-07 00:39:11 +01:00
children={
<Pressable
style={{
flexBasis:
StyleConstants.Font.Size.L +
StyleConstants.Spacing.Global.PagePadding * 4,
justifyContent: 'center',
alignItems: 'center'
}}
2021-02-07 00:39:11 +01:00
onPress={() => removeDraft(item.timestamp)}
children={
<Icon
name='Trash'
size={StyleConstants.Font.Size.L}
2022-02-12 14:51:01 +01:00
color={colors.primaryOverlay}
2021-02-07 00:39:11 +01:00
/>
}
/>
}
/>
),
2022-02-12 14:51:01 +01:00
[theme]
2021-02-07 00:39:11 +01:00
)
return (
<>
2022-05-29 17:45:53 +02:00
<View
style={{
flexDirection: 'row',
alignItems: 'center',
marginHorizontal: StyleConstants.Spacing.Global.PagePadding,
padding: StyleConstants.Spacing.S,
borderColor: colors.border,
borderWidth: 1,
borderRadius: StyleConstants.Spacing.S
}}
>
<Icon
name='AlertTriangle'
color={colors.secondary}
size={StyleConstants.Font.Size.M}
style={{ marginRight: StyleConstants.Spacing.S }}
/>
<CustomText
fontStyle='S'
style={{ flexShrink: 1, color: colors.secondary }}
>
{t('content.draftsList.warning')}
</CustomText>
</View>
2021-03-11 23:12:17 +01:00
<PanGestureHandler enabled={Platform.OS === 'ios'}>
<SwipeListView
2021-02-20 19:12:44 +01:00
data={instanceDrafts}
renderItem={renderItem}
renderHiddenItem={renderHiddenItem}
disableRightSwipe={true}
rightOpenValue={-actionWidth}
2021-03-11 23:12:17 +01:00
// previewRowKey={
// instanceDrafts?.length
// ? instanceDrafts[0].timestamp.toString()
// : undefined
// }
// previewDuration={350}
previewOpenValue={-actionWidth / 2}
ItemSeparatorComponent={ComponentSeparator}
keyExtractor={item => item.timestamp.toString()}
/>
</PanGestureHandler>
2021-02-07 00:39:11 +01:00
<Modal
transparent
animationType='fade'
visible={checkingAttachments}
children={
<View
style={{
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: colors.backgroundOverlayInvert
}}
2021-02-07 00:39:11 +01:00
children={
<CustomText
fontStyle='M'
children={t('content.draftsList.checkAttachment')}
style={{ color: colors.primaryOverlay }}
2021-02-07 00:39:11 +01:00
/>
}
/>
}
/>
</>
)
}
export default ComposeDraftsListRoot