1
0
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:
Zhiyuan Zheng 2021-03-09 14:43:31 +01:00
parent fa3c298b8a
commit 7d797bb401
No known key found for this signature in database
GPG Key ID: 078A93AB607D85E0
4 changed files with 115 additions and 130 deletions

View File

@ -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: () => (

View File

@ -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

View File

@ -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>

View 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