import CustomText from '@components/Text' import { useAccessibility } from '@utils/accessibility/AccessibilityManager' import { StyleConstants } from '@utils/styles/constants' import { useTheme } from '@utils/styles/ThemeManager' import React, { useContext } from 'react' import { useTranslation } from 'react-i18next' import { Dimensions, Image, View } from 'react-native' import { Gesture, GestureDetector } from 'react-native-gesture-handler' import Animated, { Extrapolate, interpolate, runOnJS, useAnimatedStyle, useSharedValue } from 'react-native-reanimated' import ComposeContext from '../utils/createContext' export interface Props { index: number } const ComposeEditAttachmentImage: React.FC = ({ index }) => { const { t } = useTranslation('screenCompose') const { colors } = useTheme() const { screenReaderEnabled } = useAccessibility() const { composeState, composeDispatch } = useContext(ComposeContext) const theAttachmentRemote = composeState.attachments.uploads[index].remote! const theAttachmentLocal = composeState.attachments.uploads[index].local const windowWidth = Dimensions.get('window').width const imageWidthBase = theAttachmentRemote?.meta?.original?.aspect < 1 ? windowWidth * theAttachmentRemote?.meta?.original?.aspect : windowWidth const imageDimensionis = { width: imageWidthBase, height: imageWidthBase / ((theAttachmentRemote as Mastodon.AttachmentImage)?.meta?.original?.aspect || 1) } const updateFocus = ({ x, y }: { x: number; y: number }) => { composeDispatch({ type: 'attachment/edit', payload: { ...theAttachmentRemote, meta: { ...theAttachmentRemote.meta, focus: { x: x > 1 ? 1 : x, y: y > 1 ? 1 : y } } } }) } const pan = useSharedValue({ x: (((theAttachmentRemote as Mastodon.AttachmentImage)?.meta?.focus?.x || 0) * imageDimensionis.width) / 2, y: (((theAttachmentRemote as Mastodon.AttachmentImage)?.meta?.focus?.y || 0) * imageDimensionis.height) / 2 }) const start = useSharedValue({ x: 0, y: 0 }) const gesture = Gesture.Pan() .onBegin(() => { start.value = pan.value }) .onUpdate(e => { pan.value = { x: e.translationX + start.value.x, y: e.translationY + start.value.y } }) .onEnd(() => { runOnJS(updateFocus)({ x: pan.value.x / (imageDimensionis.width / 2), y: pan.value.y / (imageDimensionis.height / 2) }) }) .onFinalize(() => { start.value = pan.value }) const styleTransform = useAnimatedStyle(() => { return { transform: [ { translateX: interpolate( pan.value.x, [-imageDimensionis.width / 2, imageDimensionis.width / 2], [-imageDimensionis.width / 2, imageDimensionis.width / 2], Extrapolate.CLAMP ) }, { translateY: interpolate( pan.value.y, [-imageDimensionis.height / 2, imageDimensionis.height / 2], [-imageDimensionis.height / 2, imageDimensionis.height / 2], Extrapolate.CLAMP ) } ] } }) return ( <> } /> {screenReaderEnabled ? null : ( {t('content.editAttachment.content.imageFocus')} )} ) } export default ComposeEditAttachmentImage