diff --git a/src/screens/Compose.tsx b/src/screens/Compose.tsx index cdb599a6..82ed08c6 100644 --- a/src/screens/Compose.tsx +++ b/src/screens/Compose.tsx @@ -407,12 +407,12 @@ const ScreenCompose: React.FC> = ({ diff --git a/src/screens/Compose/DraftsList.tsx b/src/screens/Compose/DraftsList.tsx index 642bc41d..c0e75001 100644 --- a/src/screens/Compose/DraftsList.tsx +++ b/src/screens/Compose/DraftsList.tsx @@ -1,49 +1,227 @@ +import apiInstance from '@api/instance' import { HeaderLeft } from '@components/Header' -import { createNativeStackNavigator } from '@react-navigation/native-stack' +import Icon from '@components/Icon' +import ComponentSeparator from '@components/Separator' +import CustomText from '@components/Text' +import HeaderSharedCreated from '@components/Timeline/Shared/HeaderShared/Created' +import { useAppDispatch } from '@root/store' import { ScreenComposeStackScreenProps } from '@utils/navigation/navigators' -import React, { useCallback } from 'react' +import { getInstanceDrafts, removeInstanceDraft } from '@utils/slices/instancesSlice' +import { StyleConstants } from '@utils/styles/constants' +import { useTheme } from '@utils/styles/ThemeManager' +import React, { useContext, useEffect, useState } from 'react' import { useTranslation } from 'react-i18next' -import ComposeDraftsListRoot from './DraftsList/Root' +import { Dimensions, Modal, Platform, Pressable, View } from 'react-native' +import FastImage from 'react-native-fast-image' +import { PanGestureHandler } from 'react-native-gesture-handler' +import { SwipeListView } from 'react-native-swipe-list-view' +import { useSelector } from 'react-redux' +import ComposeContext from './utils/createContext' +import { formatText } from './utils/processText' +import { ComposeStateDraft, ExtendedAttachment } from './utils/types' -const Stack = createNativeStackNavigator() - -const ComposeDraftsList: React.FC< - ScreenComposeStackScreenProps<'Screen-Compose-DraftsList'> -> = ({ +const ComposeDraftsList: React.FC> = ({ + navigation, route: { params: { timestamp } - }, - navigation + } }) => { + const { colors } = useTheme() const { t } = useTranslation('screenCompose') - const children = useCallback( - () => , - [] - ) - const headerLeft = useCallback( - () => ( - navigation.goBack()} - /> - ), - [] + useEffect(() => { + navigation.setOptions({ + title: t('content.draftsList.header.title'), + headerLeft: () => ( + navigation.goBack()} /> + ) + }) + }, []) + + const { composeDispatch } = useContext(ComposeContext) + const instanceDrafts = useSelector(getInstanceDrafts)?.filter( + draft => draft.timestamp !== timestamp ) + const [checkingAttachments, setCheckingAttachments] = useState(false) + const dispatch = useAppDispatch() + + const actionWidth = StyleConstants.Font.Size.L + StyleConstants.Spacing.Global.PagePadding * 4 return ( - - + + + + {t('content.draftsList.warning')} + + + + { + return ( + { + setCheckingAttachments(true) + let tempDraft = item + let tempUploads: ExtendedAttachment[] = [] + if (item.attachments && item.attachments.uploads.length) { + for (const attachment of item.attachments.uploads) { + await apiInstance({ + method: 'get', + url: `media/${attachment.remote?.id}` + }) + .then(res => { + if (res.body.id === attachment.remote?.id) { + 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 + }) + dispatch(removeInstanceDraft(item.timestamp)) + navigation.goBack() + }} + > + + + + {item.text || item.spoiler || t('content.draftsList.content.textEmpty')} + + {item.attachments?.uploads.length ? ( + + {item.attachments.uploads.map((attachment, index) => ( + + ))} + + ) : null} + + + ) + }} + renderHiddenItem={({ item }) => ( + dispatch(removeInstanceDraft(item.timestamp))} + children={ + + } + /> + } + /> + )} + disableRightSwipe={true} + rightOpenValue={-actionWidth} + previewOpenValue={-actionWidth / 2} + ItemSeparatorComponent={ComponentSeparator} + keyExtractor={item => item.timestamp.toString()} + /> + + + } + /> + } /> - + ) } diff --git a/src/screens/Compose/DraftsList/Root.tsx b/src/screens/Compose/DraftsList/Root.tsx deleted file mode 100644 index 7b3e870f..00000000 --- a/src/screens/Compose/DraftsList/Root.tsx +++ /dev/null @@ -1,223 +0,0 @@ -import apiInstance from '@api/instance' -import Icon from '@components/Icon' -import ComponentSeparator from '@components/Separator' -import CustomText from '@components/Text' -import HeaderSharedCreated from '@components/Timeline/Shared/HeaderShared/Created' -import { useNavigation } from '@react-navigation/native' -import { useAppDispatch } from '@root/store' -import { getInstanceDrafts, removeInstanceDraft } from '@utils/slices/instancesSlice' -import { StyleConstants } from '@utils/styles/constants' -import { useTheme } from '@utils/styles/ThemeManager' -import React, { useCallback, useContext, useState } from 'react' -import { useTranslation } from 'react-i18next' -import { Dimensions, Image, Modal, Platform, Pressable, View } from 'react-native' -import { PanGestureHandler } from 'react-native-gesture-handler' -import { SwipeListView } from 'react-native-swipe-list-view' -import { useSelector } from 'react-redux' -import ComposeContext from '../utils/createContext' -import { formatText } from '../utils/processText' -import { ComposeStateDraft, ExtendedAttachment } from '../utils/types' - -export interface Props { - timestamp: number -} - -const ComposeDraftsListRoot: React.FC = ({ timestamp }) => { - const { composeDispatch } = useContext(ComposeContext) - const { t } = useTranslation('screenCompose') - const navigation = useNavigation() - const dispatch = useAppDispatch() - const { colors, theme } = useTheme() - const instanceDrafts = useSelector(getInstanceDrafts)?.filter( - draft => draft.timestamp !== timestamp - ) - - const actionWidth = StyleConstants.Font.Size.L + StyleConstants.Spacing.Global.PagePadding * 4 - - const [checkingAttachments, setCheckingAttachments] = useState(false) - - const renderItem = useCallback( - ({ item }: { item: ComposeStateDraft }) => { - return ( - { - setCheckingAttachments(true) - let tempDraft = item - let tempUploads: ExtendedAttachment[] = [] - if (item.attachments && item.attachments.uploads.length) { - for (const attachment of item.attachments.uploads) { - await apiInstance({ - method: 'get', - url: `media/${attachment.remote?.id}` - }) - .then(res => { - if (res.body.id === attachment.remote?.id) { - 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 - }) - dispatch(removeInstanceDraft(item.timestamp)) - navigation.goBack() - }} - > - - - - {item.text || item.spoiler || t('content.draftsList.content.textEmpty')} - - {item.attachments?.uploads.length ? ( - - {item.attachments.uploads.map((attachment, index) => ( - - ))} - - ) : null} - - - ) - }, - [theme] - ) - - return ( - <> - - - - {t('content.draftsList.warning')} - - - - ( - dispatch(removeInstanceDraft(item.timestamp))} - children={ - - } - /> - } - /> - )} - disableRightSwipe={true} - rightOpenValue={-actionWidth} - previewOpenValue={-actionWidth / 2} - ItemSeparatorComponent={ComponentSeparator} - keyExtractor={item => item.timestamp.toString()} - /> - - - } - /> - } - /> - - ) -} - -export default ComposeDraftsListRoot diff --git a/src/screens/Compose/EditAttachment.tsx b/src/screens/Compose/EditAttachment.tsx index fd9b6967..5aea5eff 100644 --- a/src/screens/Compose/EditAttachment.tsx +++ b/src/screens/Compose/EditAttachment.tsx @@ -1,49 +1,90 @@ -import { HeaderLeft } from '@components/Header' -import { createNativeStackNavigator } from '@react-navigation/native-stack' +import apiInstance from '@api/instance' +import haptics from '@components/haptics' +import { HeaderLeft, HeaderRight } from '@components/Header' import { ScreenComposeStackScreenProps } from '@utils/navigation/navigators' -import React from 'react' +import React, { useContext, useEffect, useState } from 'react' import { useTranslation } from 'react-i18next' -import { KeyboardAvoidingView, Platform } from 'react-native' +import { Alert, KeyboardAvoidingView, Platform } from 'react-native' import { SafeAreaView } from 'react-native-safe-area-context' import ComposeEditAttachmentRoot from './EditAttachment/Root' -import ComposeEditAttachmentSubmit from './EditAttachment/Submit' +import ComposeContext from './utils/createContext' -const Stack = createNativeStackNavigator() - -const ComposeEditAttachment: React.FC> = ({ +const ComposeEditAttachment: React.FC< + ScreenComposeStackScreenProps<'Screen-Compose-EditAttachment'> +> = ({ + navigation, route: { params: { index } - }, - navigation -}) => { - const { t } = useTranslation('screenCompose') - - return ( - - - - } - options={{ - headerLeft: () => navigation.goBack()} - />, - headerRight: () => , - title: t('content.editAttachment.header.title') - }} - /> - - - - ) } +}) => { + const { t } = useTranslation('screenCompose') + + const { composeState } = useContext(ComposeContext) + const [isSubmitting, setIsSubmitting] = useState(false) + + const theAttachment = composeState.attachments.uploads[index].remote! + + useEffect(() => { + navigation.setOptions({ + title: t('content.editAttachment.header.title'), + headerLeft: () => ( + navigation.goBack()} /> + ), + headerRight: () => ( + { + setIsSubmitting(true) + const formData = new FormData() + if (theAttachment.description) { + formData.append('description', theAttachment.description) + } + if (theAttachment.meta?.focus?.x !== 0 || theAttachment.meta.focus.y !== 0) { + formData.append( + 'focus', + `${theAttachment.meta?.focus?.x || 0},${-theAttachment.meta?.focus?.y || 0}` + ) + } + + theAttachment?.id && + apiInstance({ + method: 'put', + url: `media/${theAttachment.id}`, + body: formData + }) + .then(() => { + haptics('Success') + navigation.goBack() + }) + .catch(() => { + setIsSubmitting(false) + haptics('Error') + Alert.alert(t('content.editAttachment.header.right.failed.title'), undefined, [ + { + text: t('content.editAttachment.header.right.failed.button'), + style: 'cancel' + } + ]) + }) + }} + /> + ) + }) + }, [theAttachment]) + + return ( + + + + + + ) +} export default ComposeEditAttachment diff --git a/src/screens/Compose/EditAttachment/Submit.tsx b/src/screens/Compose/EditAttachment/Submit.tsx deleted file mode 100644 index c4ee0e39..00000000 --- a/src/screens/Compose/EditAttachment/Submit.tsx +++ /dev/null @@ -1,79 +0,0 @@ -import apiInstance from '@api/instance' -import haptics from '@components/haptics' -import { HeaderRight } from '@components/Header' -import { useNavigation } from '@react-navigation/native' -import React, { useContext, useState } from 'react' -import { useTranslation } from 'react-i18next' -import { Alert } from 'react-native' -import ComposeContext from '../utils/createContext' - -export interface Props { - index: number -} - -const ComposeEditAttachmentSubmit: React.FC = ({ index }) => { - const { composeState } = useContext(ComposeContext) - const navigation = useNavigation() - const [isSubmitting, setIsSubmitting] = useState(false) - const { t } = useTranslation('screenCompose') - - const theAttachment = composeState.attachments.uploads[index].remote! - - return ( - { - setIsSubmitting(true) - const formData = new FormData() - if (theAttachment.description) { - formData.append('description', theAttachment.description) - } - if ( - theAttachment.meta?.focus?.x !== 0 || - theAttachment.meta.focus.y !== 0 - ) { - formData.append( - 'focus', - `${theAttachment.meta?.focus?.x || 0},${ - -theAttachment.meta?.focus?.y || 0 - }` - ) - } - - theAttachment?.id && - apiInstance({ - method: 'put', - url: `media/${theAttachment.id}`, - body: formData - }) - .then(() => { - haptics('Success') - navigation.goBack() - }) - .catch(() => { - setIsSubmitting(false) - haptics('Error') - Alert.alert( - t('content.editAttachment.header.right.failed.title'), - undefined, - [ - { - text: t( - 'content.editAttachment.header.right.failed.button' - ), - style: 'cancel' - } - ] - ) - }) - }} - /> - ) -} - -export default ComposeEditAttachmentSubmit diff --git a/src/screens/Compose/Root/Footer/Attachments.tsx b/src/screens/Compose/Root/Footer/Attachments.tsx index ec71b0a5..8c7ff50f 100644 --- a/src/screens/Compose/Root/Footer/Attachments.tsx +++ b/src/screens/Compose/Root/Footer/Attachments.tsx @@ -171,21 +171,23 @@ const ComposeAttachments: React.FC = ({ accessibleRefAttachments }) => { haptics('Success') }} /> -