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, StyleSheet, Text, View } from 'react-native' import { PanGestureHandler } from 'react-native-gesture-handler' import Animated, { Extrapolate, interpolate, runOnJS, useAnimatedGestureHandler, useAnimatedStyle, useSharedValue } from 'react-native-reanimated' import Svg, { Circle, G, Path } from 'react-native-svg' import ComposeContext from '../utils/createContext' export interface Props { index: number } const ComposeEditAttachmentImage: React.FC = ({ index }) => { const { t } = useTranslation('sharedCompose') const { theme } = useTheme() const { composeState, composeDispatch } = useContext(ComposeContext) const theAttachmentRemote = composeState.attachments.uploads[index].remote! const theAttachmentLocal = composeState.attachments.uploads[index].local const imageWidthBase = theAttachmentRemote?.meta?.original?.aspect < 1 ? Dimensions.get('screen').width * theAttachmentRemote?.meta?.original?.aspect : Dimensions.get('screen').width const padding = (Dimensions.get('screen').width - imageWidthBase) / 2 const imageDimensionis = { width: imageWidthBase, height: imageWidthBase / ((theAttachmentRemote as Mastodon.AttachmentImage)?.meta?.original ?.aspect || 1) } const panX = useSharedValue( (((theAttachmentRemote as Mastodon.AttachmentImage)?.meta?.focus?.x || 0) * imageDimensionis.width) / 2 ) const panY = useSharedValue( (((theAttachmentRemote as Mastodon.AttachmentImage)?.meta?.focus?.y || 0) * imageDimensionis.height) / 2 ) 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 } } } }) } type PanContext = { startX: number startY: number } const onGestureEvent = useAnimatedGestureHandler({ onStart: (_, context: PanContext) => { context.startX = panX.value context.startY = panY.value }, onActive: ({ translationX, translationY }, context: PanContext) => { panX.value = context.startX + translationX panY.value = context.startY + translationY }, onEnd: ({ translationX, translationY }, context: PanContext) => { runOnJS(updateFocus)({ x: (context.startX + translationX) / (imageDimensionis.width / 2), y: (context.startY + translationY) / (imageDimensionis.height / 2) }) } }) const styleTransform = useAnimatedStyle(() => { return { transform: [ { translateX: interpolate( panX.value, [ -imageDimensionis.width / 2 + padding, imageDimensionis.width / 2 + padding ], [ -imageDimensionis.width / 2 + padding, imageDimensionis.width / 2 + padding ], Extrapolate.CLAMP ) }, { translateY: interpolate( panY.value, [-imageDimensionis.height / 2, imageDimensionis.height / 2], [-imageDimensionis.height / 2, imageDimensionis.height / 2], Extrapolate.CLAMP ) } ] } }) return ( <> {t('content.editAttachment.content.imageFocus')} ) } const styles = StyleSheet.create({ base: { overflow: 'hidden', flex: 1, alignItems: 'center' }, imageFocusText: { ...StyleConstants.FontStyle.M, padding: StyleConstants.Spacing.Global.PagePadding } }) export default ComposeEditAttachmentImage