mirror of
https://github.com/tooot-app/app
synced 2025-02-10 00:40:51 +01:00
Fix attachment editing image
This commit is contained in:
parent
fa3c298b8a
commit
7d797bb401
@ -1,16 +1,12 @@
|
||||
import apiInstance from '@api/instance'
|
||||
import analytics from '@components/analytics'
|
||||
import haptics from '@components/haptics'
|
||||
import { HeaderCenter, HeaderLeft, HeaderRight } from '@components/Header'
|
||||
import { HeaderCenter, HeaderLeft } from '@components/Header'
|
||||
import { StackScreenProps } from '@react-navigation/stack'
|
||||
import React, { useCallback, useContext, useEffect, useState } from 'react'
|
||||
import React, { useCallback } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Alert, KeyboardAvoidingView, Platform } from 'react-native'
|
||||
import { useSharedValue } from 'react-native-reanimated'
|
||||
import { KeyboardAvoidingView, Platform } from 'react-native'
|
||||
import { SafeAreaView } from 'react-native-safe-area-context'
|
||||
import { createNativeStackNavigator } from 'react-native-screens/native-stack'
|
||||
import ComposeEditAttachmentRoot from './EditAttachment/Root'
|
||||
import ComposeContext from './utils/createContext'
|
||||
import ComposeEditAttachmentSubmit from './EditAttachment/Submit'
|
||||
|
||||
const Stack = createNativeStackNavigator()
|
||||
|
||||
@ -25,40 +21,8 @@ const ComposeEditAttachment: React.FC<ScreenComposeEditAttachmentProp> = ({
|
||||
},
|
||||
navigation
|
||||
}) => {
|
||||
const { composeState, composeDispatch } = useContext(ComposeContext)
|
||||
console.log('rendering')
|
||||
const { t } = useTranslation('sharedCompose')
|
||||
const theAttachment = composeState.attachments.uploads[index].remote!
|
||||
|
||||
const [isSubmitting, setIsSubmitting] = useState(false)
|
||||
|
||||
const [altText, setAltText] = useState<string | undefined>(
|
||||
theAttachment.description
|
||||
)
|
||||
const focus = useSharedValue({
|
||||
x: theAttachment.meta?.focus?.x,
|
||||
y: theAttachment.meta?.focus?.y
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
const unsubscribe = navigation.addListener('beforeRemove', () => {
|
||||
composeDispatch({
|
||||
type: 'attachment/edit',
|
||||
payload: {
|
||||
...theAttachment,
|
||||
description: altText,
|
||||
meta: {
|
||||
...theAttachment.meta,
|
||||
focus: {
|
||||
x: focus.value.x > 1 ? 1 : focus.value.x,
|
||||
y: focus.value.y > 1 ? 1 : focus.value.y
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
return unsubscribe
|
||||
}, [focus.value.x, focus.value.y, altText])
|
||||
|
||||
const headerLeft = useCallback(
|
||||
() => (
|
||||
@ -70,68 +34,9 @@ const ComposeEditAttachment: React.FC<ScreenComposeEditAttachmentProp> = ({
|
||||
),
|
||||
[]
|
||||
)
|
||||
const headerRight = useCallback(
|
||||
() => (
|
||||
<HeaderRight
|
||||
type='icon'
|
||||
content='Save'
|
||||
loading={isSubmitting}
|
||||
onPress={() => {
|
||||
analytics('editattachment_confirm_press')
|
||||
if (!altText && focus.value.x === 0 && focus.value.y === 0) {
|
||||
navigation.goBack()
|
||||
return
|
||||
}
|
||||
setIsSubmitting(true)
|
||||
const formData = new FormData()
|
||||
if (altText) {
|
||||
formData.append('description', altText)
|
||||
}
|
||||
if (focus.value.x !== 0 || focus.value.y !== 0) {
|
||||
formData.append('focus', `${focus.value.x},${focus.value.y}`)
|
||||
}
|
||||
|
||||
apiInstance<Mastodon.Attachment>({
|
||||
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'
|
||||
}
|
||||
]
|
||||
)
|
||||
})
|
||||
}}
|
||||
/>
|
||||
),
|
||||
|
||||
[isSubmitting, altText, focus.value.x, focus.value.y]
|
||||
)
|
||||
|
||||
const children = useCallback(
|
||||
() => (
|
||||
<ComposeEditAttachmentRoot
|
||||
index={index}
|
||||
focus={focus}
|
||||
altText={altText}
|
||||
setAltText={setAltText}
|
||||
/>
|
||||
),
|
||||
() => <ComposeEditAttachmentRoot index={index} />,
|
||||
[]
|
||||
)
|
||||
|
||||
@ -147,7 +52,7 @@ const ComposeEditAttachment: React.FC<ScreenComposeEditAttachmentProp> = ({
|
||||
children={children}
|
||||
options={{
|
||||
headerLeft,
|
||||
headerRight,
|
||||
headerRight: () => <ComposeEditAttachmentSubmit index={index} />,
|
||||
headerTitle: t('content.editAttachment.header.title'),
|
||||
...(Platform.OS === 'android' && {
|
||||
headerCenter: () => (
|
||||
|
@ -18,18 +18,14 @@ import ComposeContext from '../utils/createContext'
|
||||
|
||||
export interface Props {
|
||||
index: number
|
||||
focus: Animated.SharedValue<{
|
||||
x: number
|
||||
y: number
|
||||
}>
|
||||
}
|
||||
|
||||
const ComposeEditAttachmentImage: React.FC<Props> = ({ index, focus }) => {
|
||||
const ComposeEditAttachmentImage: React.FC<Props> = ({ index }) => {
|
||||
const { t } = useTranslation('sharedCompose')
|
||||
const { theme } = useTheme()
|
||||
|
||||
const { composeState } = useContext(ComposeContext)
|
||||
const theAttachmentRemote = composeState.attachments.uploads[index].remote
|
||||
const { composeState, composeDispatch } = useContext(ComposeContext)
|
||||
const theAttachmentRemote = composeState.attachments.uploads[index].remote!
|
||||
const theAttachmentLocal = composeState.attachments.uploads[index].local
|
||||
|
||||
const imageWidthBase =
|
||||
@ -57,8 +53,21 @@ const ComposeEditAttachmentImage: React.FC<Props> = ({ index, focus }) => {
|
||||
2
|
||||
)
|
||||
const updateFocus = ({ x, y }: { x: number; y: number }) => {
|
||||
focus.value = { x, y }
|
||||
composeDispatch({
|
||||
type: 'attachment/edit',
|
||||
payload: {
|
||||
...theAttachmentRemote,
|
||||
meta: {
|
||||
...theAttachmentRemote.meta,
|
||||
focus: {
|
||||
x: x > 1 ? 1 : x,
|
||||
y: y > 1 ? 1 : y
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
type PanContext = {
|
||||
startX: number
|
||||
startY: number
|
||||
|
@ -1,39 +1,27 @@
|
||||
import AttachmentVideo from '@components/Timeline/Shared/Attachment/Video'
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import React, { Dispatch, SetStateAction, useContext, useMemo } from 'react'
|
||||
import React, { useContext, useMemo } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { ScrollView, StyleSheet, Text, TextInput, View } from 'react-native'
|
||||
import Animated from 'react-native-reanimated'
|
||||
import ComposeContext from '../utils/createContext'
|
||||
import ComposeEditAttachmentImage from './Image'
|
||||
|
||||
export interface Props {
|
||||
index: number
|
||||
focus: Animated.SharedValue<{
|
||||
x: number
|
||||
y: number
|
||||
}>
|
||||
altText: string | undefined
|
||||
setAltText: Dispatch<SetStateAction<string | undefined>>
|
||||
}
|
||||
|
||||
const ComposeEditAttachmentRoot: React.FC<Props> = ({
|
||||
index,
|
||||
focus,
|
||||
altText,
|
||||
setAltText
|
||||
}) => {
|
||||
const ComposeEditAttachmentRoot: React.FC<Props> = ({ index }) => {
|
||||
const { t } = useTranslation('sharedCompose')
|
||||
const { mode, theme } = useTheme()
|
||||
const { composeState } = useContext(ComposeContext)
|
||||
const theAttachment = composeState.attachments.uploads[index].remote
|
||||
const { composeState, composeDispatch } = useContext(ComposeContext)
|
||||
const theAttachment = composeState.attachments.uploads[index].remote!
|
||||
|
||||
const mediaDisplay = useMemo(() => {
|
||||
if (theAttachment) {
|
||||
switch (theAttachment.type) {
|
||||
case 'image':
|
||||
return <ComposeEditAttachmentImage index={index} focus={focus} />
|
||||
return <ComposeEditAttachmentImage index={index} />
|
||||
case 'video':
|
||||
case 'gifv':
|
||||
const video = composeState.attachments.uploads[index]
|
||||
@ -58,6 +46,15 @@ const ComposeEditAttachmentRoot: React.FC<Props> = ({
|
||||
return null
|
||||
}, [])
|
||||
|
||||
const onChangeText = (e: any) =>
|
||||
composeDispatch({
|
||||
type: 'attachment/edit',
|
||||
payload: {
|
||||
...theAttachment,
|
||||
description: e
|
||||
}
|
||||
})
|
||||
|
||||
return (
|
||||
<ScrollView>
|
||||
{mediaDisplay}
|
||||
@ -74,15 +71,15 @@ const ComposeEditAttachmentRoot: React.FC<Props> = ({
|
||||
autoCorrect={false}
|
||||
maxLength={1500}
|
||||
multiline
|
||||
onChangeText={e => setAltText(e)}
|
||||
onChangeText={onChangeText}
|
||||
placeholder={t('content.editAttachment.content.altText.placeholder')}
|
||||
placeholderTextColor={theme.secondary}
|
||||
scrollEnabled
|
||||
value={altText}
|
||||
value={theAttachment.description}
|
||||
keyboardAppearance={mode}
|
||||
/>
|
||||
<Text style={[styles.altTextLength, { color: theme.secondary }]}>
|
||||
{altText?.length || 0} / 1500
|
||||
{theAttachment.description?.length || 0} / 1500
|
||||
</Text>
|
||||
</View>
|
||||
</ScrollView>
|
||||
|
74
src/screens/Compose/EditAttachment/Submit.tsx
Normal file
74
src/screens/Compose/EditAttachment/Submit.tsx
Normal file
@ -0,0 +1,74 @@
|
||||
import apiInstance from '@api/instance'
|
||||
import analytics from '@components/analytics'
|
||||
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<Props> = ({ index }) => {
|
||||
const { composeState } = useContext(ComposeContext)
|
||||
const navigation = useNavigation()
|
||||
const [isSubmitting, setIsSubmitting] = useState(false)
|
||||
const { t } = useTranslation('sharedCompose')
|
||||
|
||||
const theAttachment = composeState.attachments.uploads[index].remote!
|
||||
|
||||
return (
|
||||
<HeaderRight
|
||||
type='icon'
|
||||
content='Save'
|
||||
loading={isSubmitting}
|
||||
onPress={() => {
|
||||
analytics('editattachment_confirm_press')
|
||||
|
||||
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},${-theAttachment.meta.focus.y}`
|
||||
)
|
||||
}
|
||||
|
||||
apiInstance<Mastodon.Attachment>({
|
||||
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
|
Loading…
x
Reference in New Issue
Block a user