@planningcenter/chat-react-native 3.12.0-rc.2 → 3.12.0-rc.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -456,8 +456,8 @@ const LightboxModal = ({ visible, setModalVisible, imageAttachments, initialImag
456
456
  {formatDatePreview(createdAt)}
457
457
  </Text>
458
458
  </View>
459
- <IconButton onPress={handleOpenInBrowser} name="general.newWindow" accessibilityRole="link" accessibilityLabel="Open image in browser" accessibilityHint="Image can be downloaded and shared through the browser." style={styles.actionButton} iconStyle={styles.actionButtonIcon} size="lg"/>
460
- <IconButton onPress={handleCloseModal} name="general.x" accessibilityLabel="Close image" style={styles.actionButton} iconStyle={styles.actionButtonIcon} size="lg"/>
459
+ <IconButton onPress={handleOpenInBrowser} disabled={isStatusBarHidden} name="general.newWindow" accessibilityRole="link" accessibilityLabel="Open image in browser" accessibilityHint="Image can be downloaded and shared through the browser." style={styles.actionButton} iconStyle={styles.actionButtonIcon} size="lg"/>
460
+ <IconButton onPress={handleCloseModal} disabled={isStatusBarHidden} name="general.x" accessibilityLabel="Close image" style={styles.actionButton} iconStyle={styles.actionButtonIcon} size="lg"/>
461
461
  </Animated.View>
462
462
  </Modal>);
463
463
  };
@@ -1 +1 @@
1
- {"version":3,"file":"image_attachment.js","sourceRoot":"","sources":["../../../../src/components/conversation/attachments/image_attachment.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { useMemo, useState, Dispatch, SetStateAction, useCallback } from 'react'\nimport {\n StatusBar,\n StyleSheet,\n Modal,\n View,\n Linking,\n Dimensions,\n Platform,\n NativeSyntheticEvent,\n NativeScrollEvent,\n ViewToken,\n} from 'react-native'\nimport { useSafeAreaInsets } from 'react-native-safe-area-context'\nimport {\n FlatList,\n Gesture,\n GestureDetector,\n GestureHandlerRootView,\n Pressable,\n} from 'react-native-gesture-handler'\nimport Animated, {\n runOnJS,\n useAnimatedStyle,\n useAnimatedReaction,\n useSharedValue,\n withSpring,\n withDecay,\n SharedValue,\n} from 'react-native-reanimated'\nimport { tokens } from '../../../vendor/tapestry/tokens'\nimport { IconButton, Image, Heading, Text } from '../../display'\nimport colorFunction from 'color'\nimport { formatDatePreview } from '../../../utils/date'\nimport { DenormalizedMessageAttachmentResource } from '../../../types/resources/denormalized_attachment_resource'\nimport { PlatformPressable } from '@react-navigation/elements'\nimport { useTheme } from '../../../hooks'\n\nconst { width: WINDOW_WIDTH, height: WINDOW_HEIGHT } = Dimensions.get('window')\nconst DISMISS_PAN_THRESHOLD = 300\nconst MIN_DISTANCE_PAN_FOR_PLATFORM = Platform.OS === 'android' ? 5 : 0 // Android requires a higher threshold to give pinching priority\nconst POINTER_FOR_SINGLE_FINGER_PAN = 1 // Single-finger panning helps to avoid conflicts with pinching\nconst DEFAULT_OPACITY = 1\nconst DEFAULT_TRANSLATE_X = 0\nconst DEFAULT_TRANSLATE_Y = 0\nconst DEFAULT_SCALE = 1\nconst MIN_SCALE = 0.5\nconst MAX_SCALE = 5\nconst MAX_SCALE_OVERSHOOT = 5\nconst DOUBLE_TAP_ZOOM_SCALE = 2\nconst DECAY_VELOCITY_FACTOR = 0.4\nconst RESET_SPRING_CONFIG = {\n damping: 20,\n stiffness: 150,\n}\n\nexport type MetaProps = {\n authorName: string\n createdAt: string\n}\n\nexport function ImageAttachment({\n attachment,\n imageAttachments,\n currentImageIndex,\n metaProps,\n onMessageAttachmentLongPress,\n}: {\n attachment: DenormalizedMessageAttachmentResource\n imageAttachments: DenormalizedMessageAttachmentResource[]\n currentImageIndex: number\n metaProps: MetaProps\n onMessageAttachmentLongPress: (attachment: DenormalizedMessageAttachmentResource) => void\n}) {\n const { attributes } = attachment\n const { url, urlMedium, filename, metadata = {} } = attributes\n const { colors } = useTheme()\n\n const styles = useStyles({ imageWidth: metadata.width, imageHeight: metadata.height })\n const [visible, setVisible] = useState(false)\n\n return (\n <>\n <PlatformPressable\n style={styles.container}\n onPress={() => setVisible(true)}\n onLongPress={() => onMessageAttachmentLongPress(attachment)}\n android_ripple={{ color: colors.androidRippleNeutral, foreground: true }}\n accessibilityHint=\"Long press for more options\"\n >\n <Image\n source={{ uri: urlMedium || url }}\n style={styles.image}\n wrapperStyle={styles.attachmentImageWrapper}\n alt={filename}\n />\n </PlatformPressable>\n <LightboxModal\n visible={visible}\n setModalVisible={setVisible}\n imageAttachments={imageAttachments}\n initialImageIndex={currentImageIndex}\n metaProps={metaProps}\n />\n </>\n )\n}\n\ninterface LightboxModalProps {\n visible: boolean\n setModalVisible: Dispatch<SetStateAction<boolean>>\n imageAttachments: DenormalizedMessageAttachmentResource[]\n initialImageIndex: number\n metaProps: MetaProps\n}\n\nconst LightboxModal = ({\n visible,\n setModalVisible,\n imageAttachments,\n initialImageIndex,\n metaProps,\n}: LightboxModalProps) => {\n const styles = useStyles()\n const insets = useSafeAreaInsets()\n const [currentImageIndex, setCurrentImageIndex] = useState(initialImageIndex)\n\n const { authorName, createdAt } = metaProps\n\n // Get current image data\n const currentImage = imageAttachments[currentImageIndex]\n const { url, urlMedium, metadata = {} } = currentImage.attributes\n const imageWidth = metadata.width\n const imageHeight = metadata.height\n\n // Calculate available space for image display\n const availableWindowWidth = WINDOW_WIDTH\n const availableWindowHeight = WINDOW_HEIGHT - insets.top - insets.bottom\n\n /* ============================\n ANIMATION VALUES\n ============================ */\n // Native State:\n const dismissY = useSharedValue(0) // vertical distance to dismiss modal\n const opacity = useSharedValue(DEFAULT_OPACITY) // opacity of modal\n const scale = useSharedValue(DEFAULT_SCALE) // zoom level of image\n const focalX = useSharedValue(0) // focal point of image between fingers\n const focalY = useSharedValue(0) // focal point of image between fingers\n const translateX = useSharedValue(DEFAULT_TRANSLATE_X) // horizontal distance to pan image\n const translateY = useSharedValue(DEFAULT_TRANSLATE_Y) // vertical distance to pan image\n const savedScale = useSharedValue(DEFAULT_SCALE) // previous zoom level\n const savedTranslateX = useSharedValue(DEFAULT_TRANSLATE_X) // previous horizontal position\n const savedTranslateY = useSharedValue(DEFAULT_TRANSLATE_Y) // previous vertical position\n const toolbarVisible = useSharedValue(1) // toolbar visibility state\n\n // React (JS) State:\n const [isStatusBarHidden, setIsStatusBarHidden] = useState(false)\n const [flatListScrollEnabled, setFlatListScrollEnabled] = useState(true)\n const [panGestureEnabled, setPanGestureEnabled] = useState(false)\n\n // Syncs toolbar useSharedValue state with React's state so that the status bar can be hidden/shown based on the toolbar's animation\n useAnimatedReaction(\n () => toolbarVisible.value,\n value => {\n runOnJS(setIsStatusBarHidden)(value === 0)\n }\n )\n\n // Syncs FlatList scroll state with scale changes\n // When image is at default scale, enable scroll and disable pan gesture\n // When image is zoomed in, disable scroll and enable pan gesture\n useAnimatedReaction(\n () => scale.value,\n value => {\n const enableFlatListScroll = value === DEFAULT_SCALE\n runOnJS(setFlatListScrollEnabled)(enableFlatListScroll)\n runOnJS(setPanGestureEnabled)(!enableFlatListScroll)\n }\n )\n\n /* ============================\n HANDLERS\n ============================ */\n const handleOpenInBrowser = useCallback(() => {\n Linking.openURL(urlMedium || url)\n }, [urlMedium, url])\n\n const resetDismissGestures = useCallback(() => {\n dismissY.value = withSpring(0, RESET_SPRING_CONFIG)\n opacity.value = withSpring(DEFAULT_OPACITY, RESET_SPRING_CONFIG)\n }, [dismissY, opacity])\n\n const resetAllGestures = useCallback(() => {\n resetDismissGestures()\n scale.value = withSpring(DEFAULT_SCALE, RESET_SPRING_CONFIG)\n translateX.value = withSpring(DEFAULT_TRANSLATE_X, RESET_SPRING_CONFIG)\n translateY.value = withSpring(DEFAULT_TRANSLATE_Y, RESET_SPRING_CONFIG)\n savedScale.value = DEFAULT_SCALE\n savedTranslateX.value = DEFAULT_TRANSLATE_X\n savedTranslateY.value = DEFAULT_TRANSLATE_Y\n toolbarVisible.value = withSpring(1, RESET_SPRING_CONFIG)\n }, [\n resetDismissGestures,\n scale,\n translateX,\n translateY,\n savedScale,\n savedTranslateX,\n savedTranslateY,\n toolbarVisible,\n ])\n\n const handleCloseModal = useCallback(() => {\n setModalVisible(false)\n resetAllGestures()\n }, [setModalVisible, resetAllGestures])\n\n /* ============================\n UTILITY WORKLET FUNCTIONS\n 'worklet' runs functions on the UI thread, instead of the JS thread for better performance.\n ============================ */\n const getImageContainedToWindowDimensions = () => {\n 'worklet'\n\n if (!imageWidth || !imageHeight) {\n return { width: availableWindowWidth, height: availableWindowHeight }\n }\n\n const imageAspectRatio = imageWidth / imageHeight\n const windowAspectRatio = availableWindowWidth / availableWindowHeight\n\n // Constrain image width if its wider than window\n if (imageAspectRatio > windowAspectRatio) {\n return {\n width: availableWindowWidth,\n height: availableWindowWidth / imageAspectRatio,\n }\n }\n\n // Constrain image height if its taller than window\n return {\n width: availableWindowHeight * imageAspectRatio,\n height: availableWindowHeight,\n }\n }\n\n const zoomToFocalPoint = ({\n focalPointX,\n focalPointY,\n targetScale,\n currentSavedScale,\n currentSavedTranslateX,\n currentSavedTranslateY,\n }: {\n focalPointX: number\n focalPointY: number\n targetScale: number\n currentSavedScale: number\n currentSavedTranslateX: number\n currentSavedTranslateY: number\n }) => {\n 'worklet'\n\n // How far the focal point is from the center of the window\n const windowCenterX = WINDOW_WIDTH / 2\n const windowCenterY = WINDOW_HEIGHT / 2\n\n // Position of focal point relative to current image position\n const focalRelativeX = focalPointX - windowCenterX - currentSavedTranslateX\n const focalRelativeY = focalPointY - windowCenterY - currentSavedTranslateY\n\n // Calculate new translation to keep focal point under fingers\n const scaleRatio = targetScale / currentSavedScale\n const newTranslateX = currentSavedTranslateX + focalRelativeX * (1 - scaleRatio)\n const newTranslateY = currentSavedTranslateY + focalRelativeY * (1 - scaleRatio)\n\n return {\n translateX: newTranslateX,\n translateY: newTranslateY,\n }\n }\n\n const getMaxTranslationLimits = (currentScale: number) => {\n 'worklet'\n\n const { width: containedImageWidth, height: containedImageHeight } =\n getImageContainedToWindowDimensions()\n\n // Image dimensions after scaling/zooming\n const scaledWidth = containedImageWidth * currentScale\n const scaledHeight = containedImageHeight * currentScale\n\n // How much the scaled image exceeds the window container\n const excessWidth = scaledWidth - availableWindowWidth\n const excessHeight = scaledHeight - availableWindowHeight\n\n // How far the image can move in each direction before hitting window edges\n const maxTranslateX = Math.max(DEFAULT_TRANSLATE_X, excessWidth / 2)\n const maxTranslateY = Math.max(DEFAULT_TRANSLATE_Y, excessHeight / 2)\n\n return { maxTranslateX, maxTranslateY }\n }\n\n const clampDecay = (currentScale: number): { x: [number, number]; y: [number, number] } => {\n 'worklet'\n\n const { maxTranslateX, maxTranslateY } = getMaxTranslationLimits(currentScale)\n\n return {\n x: [-maxTranslateX, maxTranslateX],\n y: [-maxTranslateY, maxTranslateY],\n }\n }\n\n const clampTranslation = ({\n x,\n y,\n currentScale,\n }: {\n x: number\n y: number\n currentScale: number\n }) => {\n 'worklet'\n\n const { maxTranslateX, maxTranslateY } = getMaxTranslationLimits(currentScale)\n\n return {\n x: Math.min(maxTranslateX, Math.max(-maxTranslateX, x)),\n y: Math.min(maxTranslateY, Math.max(-maxTranslateY, y)),\n }\n }\n\n const isImageAtVerticalBoundry = (currentScale: number) => {\n 'worklet'\n\n const { height: containedImageHeight } = getImageContainedToWindowDimensions()\n\n // Calculate how much the image can exceed the window container\n const scaledHeight = containedImageHeight * currentScale\n const excessHeight = scaledHeight - availableWindowHeight\n const maxTranslateY = Math.max(DEFAULT_TRANSLATE_Y, excessHeight / 2)\n\n const currentTranslateY = translateY.value\n const panPositionTolerance = 1 // buffer to account for translateY being at a subpixel position\n\n const atTopBoundry = currentTranslateY >= maxTranslateY - panPositionTolerance\n const atBottomBoundry = currentTranslateY <= -maxTranslateY + panPositionTolerance\n\n return atTopBoundry || atBottomBoundry\n }\n\n /* ============================\n UTILITY FLATLIST FUNCTIONS\n Supports the image gallery layout and swipe functionality.\n ============================ */\n\n // Used in tandem with FlatList's initialScrollIndex to quickly calculate the position and size of each image before they load.\n const getItemLayout = useCallback(\n (_: unknown, index: number) => ({\n length: WINDOW_WIDTH,\n offset: WINDOW_WIDTH * index,\n index,\n }),\n []\n )\n\n // Captures the current image's index after the FlatList finishes its scroll animation.\n // Used in tandem with onViewableItemsChanged to ensure the final value for currentImageIndex is set.\n const onMomentumScrollEnd = useCallback(\n (event: NativeSyntheticEvent<NativeScrollEvent>) => {\n // Calculate the index of the image that is currently visible\n const imageOffsetX = event.nativeEvent.contentOffset.x\n const newImageIndex = Math.round(imageOffsetX / WINDOW_WIDTH)\n\n // Check if the image index has changed and the FlatList didn't scroll past the first or last image\n const didImageIndexChange = newImageIndex !== currentImageIndex\n const isImageIndexWithinBounds = newImageIndex >= 0 && newImageIndex < imageAttachments.length\n\n if (didImageIndexChange && isImageIndexWithinBounds) {\n setCurrentImageIndex(newImageIndex)\n }\n },\n [currentImageIndex, imageAttachments.length]\n )\n\n // Supplements onMomentumScrollEnd by capturing the current image's index while the FlatList is actively scrolling.\n // Used in tandem with viewabilityConfig to trigger when the image is 50% visible in the window.\n const onViewableItemsChanged = useCallback(\n ({ viewableItems }: { viewableItems: ViewToken<DenormalizedMessageAttachmentResource>[] }) => {\n if (viewableItems.length === 0) return\n\n // Use the first viewable item which is enforced by the FlatList's pagingEnabled prop that allows only two images to be visible at a time when scrolling.\n const firstViewableItem = viewableItems[0]\n const newIndex = firstViewableItem.index\n\n if (newIndex !== null && newIndex !== currentImageIndex) {\n setCurrentImageIndex(newIndex)\n }\n },\n [currentImageIndex]\n )\n\n /* ============================\n GESTURES\n ============================ */\n const singleTapGesture = Gesture.Tap()\n .numberOfTaps(1)\n .onStart(() => {\n toolbarVisible.value = withSpring(toolbarVisible.value > 0.5 ? 0 : 1, RESET_SPRING_CONFIG)\n })\n\n const doubleTapGesture = Gesture.Tap()\n .numberOfTaps(2)\n .onStart(e => {\n const isZoomedIn = scale.value > DEFAULT_SCALE\n if (isZoomedIn) {\n runOnJS(resetAllGestures)()\n } else {\n // Hide toolbar when starting to zoom\n toolbarVisible.value = withSpring(0, RESET_SPRING_CONFIG)\n\n // Zoom to 2x at tap location\n const newTranslation = zoomToFocalPoint({\n focalPointX: e.x,\n focalPointY: e.y,\n targetScale: DOUBLE_TAP_ZOOM_SCALE,\n currentSavedScale: savedScale.value,\n currentSavedTranslateX: savedTranslateX.value,\n currentSavedTranslateY: savedTranslateY.value,\n })\n\n // Apply clamping to ensure image edges remain within window boundaries\n const clampedTranslate = clampTranslation({\n x: newTranslation.translateX,\n y: newTranslation.translateY,\n currentScale: DOUBLE_TAP_ZOOM_SCALE,\n })\n\n // Animate to new scale and translation\n scale.value = withSpring(DOUBLE_TAP_ZOOM_SCALE, RESET_SPRING_CONFIG)\n translateX.value = withSpring(clampedTranslate.x, RESET_SPRING_CONFIG)\n translateY.value = withSpring(clampedTranslate.y, RESET_SPRING_CONFIG)\n\n // Update saved state for next gesture\n savedScale.value = DOUBLE_TAP_ZOOM_SCALE\n savedTranslateX.value = clampedTranslate.x\n savedTranslateY.value = clampedTranslate.y\n }\n })\n\n const pinchGesture = Gesture.Pinch()\n .onStart(e => {\n focalX.value = e.focalX\n focalY.value = e.focalY\n\n // Hide toolbar when starting to zoom\n toolbarVisible.value = withSpring(0, RESET_SPRING_CONFIG)\n\n // Ensure that pinch accounts for the decay animation and starts from the true current position.\n savedTranslateX.value = translateX.value\n savedTranslateY.value = translateY.value\n })\n .onUpdate(e => {\n // Zoom image in/out within scale limits\n const newScale = savedScale.value * e.scale\n const newScaleClamped = Math.min(\n MAX_SCALE + MAX_SCALE_OVERSHOOT,\n Math.max(MIN_SCALE, newScale)\n )\n scale.value = newScaleClamped\n\n // Calculate new translation to keep focal point under fingers\n const newTranslation = zoomToFocalPoint({\n focalPointX: focalX.value,\n focalPointY: focalY.value,\n targetScale: newScaleClamped,\n currentSavedScale: savedScale.value,\n currentSavedTranslateX: savedTranslateX.value,\n currentSavedTranslateY: savedTranslateY.value,\n })\n\n // Apply translation without clamping to ensure focal point doesn't jump during gesture\n translateX.value = newTranslation.translateX\n translateY.value = newTranslation.translateY\n })\n .onEnd(() => {\n const currentScale = scale.value\n\n // Dismiss modal if fully zoomed out\n if (currentScale <= MIN_SCALE) {\n runOnJS(handleCloseModal)()\n return\n }\n\n // Reset all gestures if image is near default scale\n const isNearDefaultScale = currentScale <= DEFAULT_SCALE + 0.1\n if (isNearDefaultScale) {\n runOnJS(resetAllGestures)()\n return\n }\n\n // Check if overshooting the max scale and clamp it\n const finalScale = currentScale > MAX_SCALE ? MAX_SCALE : currentScale\n\n // Recalculate translation using focal point to always return to the same position when image is overshooting the max scale\n const newTranslation = zoomToFocalPoint({\n focalPointX: focalX.value,\n focalPointY: focalY.value,\n targetScale: finalScale,\n currentSavedScale: savedScale.value,\n currentSavedTranslateX: savedTranslateX.value,\n currentSavedTranslateY: savedTranslateY.value,\n })\n\n // Ensure image edges remain within window boundaries\n const clampedTranslate = clampTranslation({\n x: newTranslation.translateX,\n y: newTranslation.translateY,\n currentScale: finalScale,\n })\n\n // Animate to position and scale limits with a spring\n scale.value = withSpring(finalScale, RESET_SPRING_CONFIG)\n translateX.value = withSpring(clampedTranslate.x, RESET_SPRING_CONFIG)\n translateY.value = withSpring(clampedTranslate.y, RESET_SPRING_CONFIG)\n\n // Save state for next gesture\n savedScale.value = finalScale\n savedTranslateX.value = clampedTranslate.x\n savedTranslateY.value = clampedTranslate.y\n })\n\n const panGesture = Gesture.Pan()\n .minDistance(MIN_DISTANCE_PAN_FOR_PLATFORM)\n .minPointers(POINTER_FOR_SINGLE_FINGER_PAN)\n .maxPointers(POINTER_FOR_SINGLE_FINGER_PAN)\n .enabled(panGestureEnabled)\n .onStart(() => {\n // Update saved position to current animated position\n // This ensures smooth continuation if decay is running\n savedTranslateX.value = translateX.value\n savedTranslateY.value = translateY.value\n })\n .onUpdate(e => {\n // Only pan if image is zoomed in\n if (scale.value <= DEFAULT_SCALE) return\n\n const newTranslateX = savedTranslateX.value + e.translationX\n const newTranslateY = savedTranslateY.value + e.translationY\n\n // Ensure image edges remain within window boundaries\n const clampedTranslate = clampTranslation({\n x: newTranslateX,\n y: newTranslateY,\n currentScale: scale.value,\n })\n translateX.value = clampedTranslate.x\n translateY.value = clampedTranslate.y\n })\n .onEnd(e => {\n // Prevents saving pan position if image is zoomed out while panning\n if (scale.value <= DEFAULT_SCALE) return\n\n const clampDecayBounds = clampDecay(scale.value)\n\n translateX.value = withDecay(\n {\n velocity: e.velocityX * DECAY_VELOCITY_FACTOR,\n clamp: clampDecayBounds.x,\n deceleration: 0.996,\n },\n finished => {\n if (finished) {\n savedTranslateX.value = translateX.value\n }\n }\n )\n\n translateY.value = withDecay(\n {\n velocity: e.velocityY * DECAY_VELOCITY_FACTOR,\n clamp: clampDecayBounds.y,\n deceleration: 0.996,\n },\n finished => {\n if (finished) {\n savedTranslateY.value = translateY.value\n }\n }\n )\n })\n\n const panToDismissModalGesture = Gesture.Pan()\n .onUpdate(e => {\n const atDefaultScale = scale.value === DEFAULT_SCALE\n\n // Calculate zoom conditions for dismissing modal\n const atVerticalBoundry = isImageAtVerticalBoundry(scale.value)\n const panDirectionIsPrimarilyVertical = Math.abs(e.translationY) > Math.abs(e.translationX)\n const canDismissWhileZoomed = atVerticalBoundry && panDirectionIsPrimarilyVertical\n\n if (atDefaultScale || canDismissWhileZoomed) {\n const panDistance = Math.abs(e.translationY)\n const fadeProgress = panDistance / DISMISS_PAN_THRESHOLD\n\n opacity.value = Math.max(0, DEFAULT_OPACITY - fadeProgress)\n dismissY.value = e.translationY\n }\n })\n .onEnd(() => {\n const exceededDismissThreshold = Math.abs(dismissY.value) > DISMISS_PAN_THRESHOLD\n\n if (exceededDismissThreshold) {\n runOnJS(handleCloseModal)()\n } else {\n runOnJS(resetDismissGestures)()\n }\n })\n\n /* ==============================\n IMPLEMENT GESTURES & ANIMATIONS\n ================================= */\n // Race between pinch and pan ensures only one is active at a time, preserving focal point logic\n const pinchOrPanGestures = Gesture.Race(pinchGesture, panGesture)\n\n // Exclusive race ensures single tap doesn't interfere with double tap\n const tapGestures = Gesture.Exclusive(doubleTapGesture, singleTapGesture)\n\n // Race between tap gestures and pinch/pan\n const transformImageGestures = Gesture.Race(tapGestures, pinchOrPanGestures)\n\n // Dismiss can work simultaneously with all gestures\n const composedGesture = Gesture.Simultaneous(transformImageGestures, panToDismissModalGesture)\n\n const animatedToolbarStyles = useAnimatedStyle(() => ({\n opacity: toolbarVisible.value,\n transform: [\n { translateY: (1 - toolbarVisible.value) * -20 }, // slide up when hiding\n ],\n }))\n\n return (\n <Modal visible={visible} transparent animationType=\"fade\" onRequestClose={handleCloseModal}>\n <StatusBar\n barStyle=\"light-content\"\n hidden={isStatusBarHidden}\n animated\n showHideTransition=\"slide\"\n />\n <GestureHandlerRootView>\n <GestureDetector gesture={composedGesture}>\n <PreventPressEventsBubbling>\n <FlatList\n data={imageAttachments}\n renderItem={({ item, index }) => (\n <GestureImage\n item={item}\n gesturesEnabled={index === currentImageIndex}\n scale={scale}\n translateX={translateX}\n translateY={translateY}\n dismissY={dismissY}\n opacity={opacity}\n />\n )}\n keyExtractor={(item, index) => `${item.id}-${index}`}\n horizontal\n pagingEnabled\n scrollEnabled={flatListScrollEnabled}\n showsHorizontalScrollIndicator={false}\n initialScrollIndex={initialImageIndex}\n getItemLayout={getItemLayout}\n onMomentumScrollEnd={onMomentumScrollEnd}\n onViewableItemsChanged={onViewableItemsChanged}\n viewabilityConfig={{\n itemVisiblePercentThreshold: 50, // 50% of the image must be visible in the window to be considered viewable\n }}\n style={styles.gallery}\n contentContainerStyle={styles.galleryContentContainer}\n />\n </PreventPressEventsBubbling>\n </GestureDetector>\n </GestureHandlerRootView>\n\n <Animated.View\n style={[styles.actionToolbar, animatedToolbarStyles]}\n accessibilityRole=\"toolbar\"\n >\n <View style={styles.actionToolbarTextMeta}>\n <Heading variant=\"h3\" style={styles.actionToolbarTitle} numberOfLines={1}>\n {authorName}\n </Heading>\n <Text variant=\"tertiary\" style={styles.actionToolbarSubtitle}>\n {formatDatePreview(createdAt)}\n </Text>\n </View>\n <IconButton\n onPress={handleOpenInBrowser}\n name=\"general.newWindow\"\n accessibilityRole=\"link\"\n accessibilityLabel=\"Open image in browser\"\n accessibilityHint=\"Image can be downloaded and shared through the browser.\"\n style={styles.actionButton}\n iconStyle={styles.actionButtonIcon}\n size=\"lg\"\n />\n <IconButton\n onPress={handleCloseModal}\n name=\"general.x\"\n accessibilityLabel=\"Close image\"\n style={styles.actionButton}\n iconStyle={styles.actionButtonIcon}\n size=\"lg\"\n />\n </Animated.View>\n </Modal>\n )\n}\n\nconst PreventPressEventsBubbling = ({ children }: { children: React.ReactNode }) => {\n return (\n <Pressable onLongPress={() => {}} onPress={() => {}}>\n {children}\n </Pressable>\n )\n}\n\ninterface GestureImageProps {\n item: DenormalizedMessageAttachmentResource\n gesturesEnabled: boolean\n scale: SharedValue<number>\n translateX: SharedValue<number>\n translateY: SharedValue<number>\n dismissY: SharedValue<number>\n opacity: SharedValue<number>\n}\n\nconst GestureImage = ({\n item,\n gesturesEnabled,\n scale,\n translateX,\n translateY,\n dismissY,\n opacity,\n}: GestureImageProps) => {\n const styles = useStyles()\n const { url: itemUrl, urlMedium: itemUrlMedium } = item.attributes\n\n const animatedImageStyles = useAnimatedStyle(() => {\n return {\n transform: [\n { translateX: gesturesEnabled ? translateX.value : DEFAULT_TRANSLATE_X },\n { translateY: gesturesEnabled ? translateY.value + dismissY.value : DEFAULT_TRANSLATE_Y },\n { scale: gesturesEnabled ? scale.value : DEFAULT_SCALE },\n ],\n opacity: opacity.value,\n }\n })\n\n return (\n <Image\n source={{ uri: itemUrlMedium || itemUrl }}\n style={styles.gestureImage}\n animatedImageStyle={animatedImageStyles}\n loadingBackgroundStyles={styles.gestureImageLoading}\n resizeMode=\"contain\"\n alt=\"\"\n />\n )\n}\n\ninterface UseStylesProps {\n imageWidth?: number\n imageHeight?: number\n}\n\nconst useStyles = ({ imageWidth = 100, imageHeight = 100 }: UseStylesProps = {}) => {\n const { top, bottom } = useSafeAreaInsets()\n const backgroundColor = tokens.colorNeutral7\n const transparentBackgroundColor = useMemo(\n () => colorFunction(backgroundColor).alpha(0.8).toString(),\n [backgroundColor]\n )\n\n return StyleSheet.create({\n container: {\n maxWidth: '100%',\n },\n attachmentImageWrapper: {\n width: '100%',\n minWidth: 200,\n aspectRatio: imageWidth / imageHeight,\n },\n image: {\n borderRadius: 8,\n },\n gallery: {\n backgroundColor,\n },\n galleryContentContainer: {\n paddingTop: top,\n paddingBottom: bottom,\n },\n gestureImage: {\n height: '100%',\n width: WINDOW_WIDTH,\n backgroundColor: 'transparent',\n },\n gestureImageLoading: {\n backgroundColor,\n },\n actionToolbar: {\n width: '100%',\n position: 'absolute',\n top: 0,\n flexDirection: 'row',\n alignItems: 'center',\n gap: 20,\n paddingHorizontal: 16,\n paddingTop: top + 16,\n paddingBottom: 8,\n backgroundColor: transparentBackgroundColor,\n },\n actionToolbarTextMeta: {\n flex: 1,\n },\n actionToolbarTitle: {\n marginRight: 'auto',\n flexShrink: 1,\n color: tokens.colorNeutral88,\n },\n actionToolbarSubtitle: {\n color: tokens.colorNeutral68,\n },\n actionButton: {\n backgroundColor,\n height: 40,\n width: 40,\n borderRadius: 50,\n borderWidth: 1,\n borderColor: tokens.colorNeutral24,\n },\n actionButtonIcon: {\n color: tokens.colorNeutral88,\n },\n })\n}\n"]}
1
+ {"version":3,"file":"image_attachment.js","sourceRoot":"","sources":["../../../../src/components/conversation/attachments/image_attachment.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,OAAO,EAAE,QAAQ,EAA4B,WAAW,EAAE,MAAM,OAAO,CAAA;AACvF,OAAO,EACL,SAAS,EACT,UAAU,EACV,KAAK,EACL,IAAI,EACJ,OAAO,EACP,UAAU,EACV,QAAQ,GAIT,MAAM,cAAc,CAAA;AACrB,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAA;AAClE,OAAO,EACL,QAAQ,EACR,OAAO,EACP,eAAe,EACf,sBAAsB,EACtB,SAAS,GACV,MAAM,8BAA8B,CAAA;AACrC,OAAO,QAAQ,EAAE,EACf,OAAO,EACP,gBAAgB,EAChB,mBAAmB,EACnB,cAAc,EACd,UAAU,EACV,SAAS,GAEV,MAAM,yBAAyB,CAAA;AAChC,OAAO,EAAE,MAAM,EAAE,MAAM,iCAAiC,CAAA;AACxD,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAA;AAChE,OAAO,aAAa,MAAM,OAAO,CAAA;AACjC,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AAEvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAA;AAC9D,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAEzC,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,aAAa,EAAE,GAAG,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;AAC/E,MAAM,qBAAqB,GAAG,GAAG,CAAA;AACjC,MAAM,6BAA6B,GAAG,QAAQ,CAAC,EAAE,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA,CAAC,gEAAgE;AACxI,MAAM,6BAA6B,GAAG,CAAC,CAAA,CAAC,+DAA+D;AACvG,MAAM,eAAe,GAAG,CAAC,CAAA;AACzB,MAAM,mBAAmB,GAAG,CAAC,CAAA;AAC7B,MAAM,mBAAmB,GAAG,CAAC,CAAA;AAC7B,MAAM,aAAa,GAAG,CAAC,CAAA;AACvB,MAAM,SAAS,GAAG,GAAG,CAAA;AACrB,MAAM,SAAS,GAAG,CAAC,CAAA;AACnB,MAAM,mBAAmB,GAAG,CAAC,CAAA;AAC7B,MAAM,qBAAqB,GAAG,CAAC,CAAA;AAC/B,MAAM,qBAAqB,GAAG,GAAG,CAAA;AACjC,MAAM,mBAAmB,GAAG;IAC1B,OAAO,EAAE,EAAE;IACX,SAAS,EAAE,GAAG;CACf,CAAA;AAOD,MAAM,UAAU,eAAe,CAAC,EAC9B,UAAU,EACV,gBAAgB,EAChB,iBAAiB,EACjB,SAAS,EACT,4BAA4B,GAO7B;IACC,MAAM,EAAE,UAAU,EAAE,GAAG,UAAU,CAAA;IACjC,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,GAAG,EAAE,EAAE,GAAG,UAAU,CAAA;IAC9D,MAAM,EAAE,MAAM,EAAE,GAAG,QAAQ,EAAE,CAAA;IAE7B,MAAM,MAAM,GAAG,SAAS,CAAC,EAAE,UAAU,EAAE,QAAQ,CAAC,KAAK,EAAE,WAAW,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAA;IACtF,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;IAE7C,OAAO,CACL,EACE;MAAA,CAAC,iBAAiB,CAChB,KAAK,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CACxB,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAChC,WAAW,CAAC,CAAC,GAAG,EAAE,CAAC,4BAA4B,CAAC,UAAU,CAAC,CAAC,CAC5D,cAAc,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,oBAAoB,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CACzE,iBAAiB,CAAC,6BAA6B,CAE/C;QAAA,CAAC,KAAK,CACJ,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE,SAAS,IAAI,GAAG,EAAE,CAAC,CAClC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CACpB,YAAY,CAAC,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAC5C,GAAG,CAAC,CAAC,QAAQ,CAAC,EAElB;MAAA,EAAE,iBAAiB,CACnB;MAAA,CAAC,aAAa,CACZ,OAAO,CAAC,CAAC,OAAO,CAAC,CACjB,eAAe,CAAC,CAAC,UAAU,CAAC,CAC5B,gBAAgB,CAAC,CAAC,gBAAgB,CAAC,CACnC,iBAAiB,CAAC,CAAC,iBAAiB,CAAC,CACrC,SAAS,CAAC,CAAC,SAAS,CAAC,EAEzB;IAAA,GAAG,CACJ,CAAA;AACH,CAAC;AAUD,MAAM,aAAa,GAAG,CAAC,EACrB,OAAO,EACP,eAAe,EACf,gBAAgB,EAChB,iBAAiB,EACjB,SAAS,GACU,EAAE,EAAE;IACvB,MAAM,MAAM,GAAG,SAAS,EAAE,CAAA;IAC1B,MAAM,MAAM,GAAG,iBAAiB,EAAE,CAAA;IAClC,MAAM,CAAC,iBAAiB,EAAE,oBAAoB,CAAC,GAAG,QAAQ,CAAC,iBAAiB,CAAC,CAAA;IAE7E,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,SAAS,CAAA;IAE3C,yBAAyB;IACzB,MAAM,YAAY,GAAG,gBAAgB,CAAC,iBAAiB,CAAC,CAAA;IACxD,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,QAAQ,GAAG,EAAE,EAAE,GAAG,YAAY,CAAC,UAAU,CAAA;IACjE,MAAM,UAAU,GAAG,QAAQ,CAAC,KAAK,CAAA;IACjC,MAAM,WAAW,GAAG,QAAQ,CAAC,MAAM,CAAA;IAEnC,8CAA8C;IAC9C,MAAM,oBAAoB,GAAG,YAAY,CAAA;IACzC,MAAM,qBAAqB,GAAG,aAAa,GAAG,MAAM,CAAC,GAAG,GAAG,MAAM,CAAC,MAAM,CAAA;IAExE;;mCAE+B;IAC/B,gBAAgB;IAChB,MAAM,QAAQ,GAAG,cAAc,CAAC,CAAC,CAAC,CAAA,CAAC,qCAAqC;IACxE,MAAM,OAAO,GAAG,cAAc,CAAC,eAAe,CAAC,CAAA,CAAC,mBAAmB;IACnE,MAAM,KAAK,GAAG,cAAc,CAAC,aAAa,CAAC,CAAA,CAAC,sBAAsB;IAClE,MAAM,MAAM,GAAG,cAAc,CAAC,CAAC,CAAC,CAAA,CAAC,uCAAuC;IACxE,MAAM,MAAM,GAAG,cAAc,CAAC,CAAC,CAAC,CAAA,CAAC,uCAAuC;IACxE,MAAM,UAAU,GAAG,cAAc,CAAC,mBAAmB,CAAC,CAAA,CAAC,mCAAmC;IAC1F,MAAM,UAAU,GAAG,cAAc,CAAC,mBAAmB,CAAC,CAAA,CAAC,iCAAiC;IACxF,MAAM,UAAU,GAAG,cAAc,CAAC,aAAa,CAAC,CAAA,CAAC,sBAAsB;IACvE,MAAM,eAAe,GAAG,cAAc,CAAC,mBAAmB,CAAC,CAAA,CAAC,+BAA+B;IAC3F,MAAM,eAAe,GAAG,cAAc,CAAC,mBAAmB,CAAC,CAAA,CAAC,6BAA6B;IACzF,MAAM,cAAc,GAAG,cAAc,CAAC,CAAC,CAAC,CAAA,CAAC,2BAA2B;IAEpE,oBAAoB;IACpB,MAAM,CAAC,iBAAiB,EAAE,oBAAoB,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;IACjE,MAAM,CAAC,qBAAqB,EAAE,wBAAwB,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAA;IACxE,MAAM,CAAC,iBAAiB,EAAE,oBAAoB,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;IAEjE,oIAAoI;IACpI,mBAAmB,CACjB,GAAG,EAAE,CAAC,cAAc,CAAC,KAAK,EAC1B,KAAK,CAAC,EAAE;QACN,OAAO,CAAC,oBAAoB,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAA;IAC5C,CAAC,CACF,CAAA;IAED,iDAAiD;IACjD,wEAAwE;IACxE,iEAAiE;IACjE,mBAAmB,CACjB,GAAG,EAAE,CAAC,KAAK,CAAC,KAAK,EACjB,KAAK,CAAC,EAAE;QACN,MAAM,oBAAoB,GAAG,KAAK,KAAK,aAAa,CAAA;QACpD,OAAO,CAAC,wBAAwB,CAAC,CAAC,oBAAoB,CAAC,CAAA;QACvD,OAAO,CAAC,oBAAoB,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAA;IACtD,CAAC,CACF,CAAA;IAED;;mCAE+B;IAC/B,MAAM,mBAAmB,GAAG,WAAW,CAAC,GAAG,EAAE;QAC3C,OAAO,CAAC,OAAO,CAAC,SAAS,IAAI,GAAG,CAAC,CAAA;IACnC,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,CAAA;IAEpB,MAAM,oBAAoB,GAAG,WAAW,CAAC,GAAG,EAAE;QAC5C,QAAQ,CAAC,KAAK,GAAG,UAAU,CAAC,CAAC,EAAE,mBAAmB,CAAC,CAAA;QACnD,OAAO,CAAC,KAAK,GAAG,UAAU,CAAC,eAAe,EAAE,mBAAmB,CAAC,CAAA;IAClE,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAA;IAEvB,MAAM,gBAAgB,GAAG,WAAW,CAAC,GAAG,EAAE;QACxC,oBAAoB,EAAE,CAAA;QACtB,KAAK,CAAC,KAAK,GAAG,UAAU,CAAC,aAAa,EAAE,mBAAmB,CAAC,CAAA;QAC5D,UAAU,CAAC,KAAK,GAAG,UAAU,CAAC,mBAAmB,EAAE,mBAAmB,CAAC,CAAA;QACvE,UAAU,CAAC,KAAK,GAAG,UAAU,CAAC,mBAAmB,EAAE,mBAAmB,CAAC,CAAA;QACvE,UAAU,CAAC,KAAK,GAAG,aAAa,CAAA;QAChC,eAAe,CAAC,KAAK,GAAG,mBAAmB,CAAA;QAC3C,eAAe,CAAC,KAAK,GAAG,mBAAmB,CAAA;QAC3C,cAAc,CAAC,KAAK,GAAG,UAAU,CAAC,CAAC,EAAE,mBAAmB,CAAC,CAAA;IAC3D,CAAC,EAAE;QACD,oBAAoB;QACpB,KAAK;QACL,UAAU;QACV,UAAU;QACV,UAAU;QACV,eAAe;QACf,eAAe;QACf,cAAc;KACf,CAAC,CAAA;IAEF,MAAM,gBAAgB,GAAG,WAAW,CAAC,GAAG,EAAE;QACxC,eAAe,CAAC,KAAK,CAAC,CAAA;QACtB,gBAAgB,EAAE,CAAA;IACpB,CAAC,EAAE,CAAC,eAAe,EAAE,gBAAgB,CAAC,CAAC,CAAA;IAEvC;;;mCAG+B;IAC/B,MAAM,mCAAmC,GAAG,GAAG,EAAE;QAC/C,SAAS,CAAA;QAET,IAAI,CAAC,UAAU,IAAI,CAAC,WAAW,EAAE,CAAC;YAChC,OAAO,EAAE,KAAK,EAAE,oBAAoB,EAAE,MAAM,EAAE,qBAAqB,EAAE,CAAA;QACvE,CAAC;QAED,MAAM,gBAAgB,GAAG,UAAU,GAAG,WAAW,CAAA;QACjD,MAAM,iBAAiB,GAAG,oBAAoB,GAAG,qBAAqB,CAAA;QAEtE,iDAAiD;QACjD,IAAI,gBAAgB,GAAG,iBAAiB,EAAE,CAAC;YACzC,OAAO;gBACL,KAAK,EAAE,oBAAoB;gBAC3B,MAAM,EAAE,oBAAoB,GAAG,gBAAgB;aAChD,CAAA;QACH,CAAC;QAED,mDAAmD;QACnD,OAAO;YACL,KAAK,EAAE,qBAAqB,GAAG,gBAAgB;YAC/C,MAAM,EAAE,qBAAqB;SAC9B,CAAA;IACH,CAAC,CAAA;IAED,MAAM,gBAAgB,GAAG,CAAC,EACxB,WAAW,EACX,WAAW,EACX,WAAW,EACX,iBAAiB,EACjB,sBAAsB,EACtB,sBAAsB,GAQvB,EAAE,EAAE;QACH,SAAS,CAAA;QAET,2DAA2D;QAC3D,MAAM,aAAa,GAAG,YAAY,GAAG,CAAC,CAAA;QACtC,MAAM,aAAa,GAAG,aAAa,GAAG,CAAC,CAAA;QAEvC,6DAA6D;QAC7D,MAAM,cAAc,GAAG,WAAW,GAAG,aAAa,GAAG,sBAAsB,CAAA;QAC3E,MAAM,cAAc,GAAG,WAAW,GAAG,aAAa,GAAG,sBAAsB,CAAA;QAE3E,8DAA8D;QAC9D,MAAM,UAAU,GAAG,WAAW,GAAG,iBAAiB,CAAA;QAClD,MAAM,aAAa,GAAG,sBAAsB,GAAG,cAAc,GAAG,CAAC,CAAC,GAAG,UAAU,CAAC,CAAA;QAChF,MAAM,aAAa,GAAG,sBAAsB,GAAG,cAAc,GAAG,CAAC,CAAC,GAAG,UAAU,CAAC,CAAA;QAEhF,OAAO;YACL,UAAU,EAAE,aAAa;YACzB,UAAU,EAAE,aAAa;SAC1B,CAAA;IACH,CAAC,CAAA;IAED,MAAM,uBAAuB,GAAG,CAAC,YAAoB,EAAE,EAAE;QACvD,SAAS,CAAA;QAET,MAAM,EAAE,KAAK,EAAE,mBAAmB,EAAE,MAAM,EAAE,oBAAoB,EAAE,GAChE,mCAAmC,EAAE,CAAA;QAEvC,yCAAyC;QACzC,MAAM,WAAW,GAAG,mBAAmB,GAAG,YAAY,CAAA;QACtD,MAAM,YAAY,GAAG,oBAAoB,GAAG,YAAY,CAAA;QAExD,yDAAyD;QACzD,MAAM,WAAW,GAAG,WAAW,GAAG,oBAAoB,CAAA;QACtD,MAAM,YAAY,GAAG,YAAY,GAAG,qBAAqB,CAAA;QAEzD,2EAA2E;QAC3E,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,mBAAmB,EAAE,WAAW,GAAG,CAAC,CAAC,CAAA;QACpE,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,mBAAmB,EAAE,YAAY,GAAG,CAAC,CAAC,CAAA;QAErE,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,CAAA;IACzC,CAAC,CAAA;IAED,MAAM,UAAU,GAAG,CAAC,YAAoB,EAAgD,EAAE;QACxF,SAAS,CAAA;QAET,MAAM,EAAE,aAAa,EAAE,aAAa,EAAE,GAAG,uBAAuB,CAAC,YAAY,CAAC,CAAA;QAE9E,OAAO;YACL,CAAC,EAAE,CAAC,CAAC,aAAa,EAAE,aAAa,CAAC;YAClC,CAAC,EAAE,CAAC,CAAC,aAAa,EAAE,aAAa,CAAC;SACnC,CAAA;IACH,CAAC,CAAA;IAED,MAAM,gBAAgB,GAAG,CAAC,EACxB,CAAC,EACD,CAAC,EACD,YAAY,GAKb,EAAE,EAAE;QACH,SAAS,CAAA;QAET,MAAM,EAAE,aAAa,EAAE,aAAa,EAAE,GAAG,uBAAuB,CAAC,YAAY,CAAC,CAAA;QAE9E,OAAO;YACL,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC;YACvD,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC;SACxD,CAAA;IACH,CAAC,CAAA;IAED,MAAM,wBAAwB,GAAG,CAAC,YAAoB,EAAE,EAAE;QACxD,SAAS,CAAA;QAET,MAAM,EAAE,MAAM,EAAE,oBAAoB,EAAE,GAAG,mCAAmC,EAAE,CAAA;QAE9E,+DAA+D;QAC/D,MAAM,YAAY,GAAG,oBAAoB,GAAG,YAAY,CAAA;QACxD,MAAM,YAAY,GAAG,YAAY,GAAG,qBAAqB,CAAA;QACzD,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,mBAAmB,EAAE,YAAY,GAAG,CAAC,CAAC,CAAA;QAErE,MAAM,iBAAiB,GAAG,UAAU,CAAC,KAAK,CAAA;QAC1C,MAAM,oBAAoB,GAAG,CAAC,CAAA,CAAC,gEAAgE;QAE/F,MAAM,YAAY,GAAG,iBAAiB,IAAI,aAAa,GAAG,oBAAoB,CAAA;QAC9E,MAAM,eAAe,GAAG,iBAAiB,IAAI,CAAC,aAAa,GAAG,oBAAoB,CAAA;QAElF,OAAO,YAAY,IAAI,eAAe,CAAA;IACxC,CAAC,CAAA;IAED;;;mCAG+B;IAE/B,+HAA+H;IAC/H,MAAM,aAAa,GAAG,WAAW,CAC/B,CAAC,CAAU,EAAE,KAAa,EAAE,EAAE,CAAC,CAAC;QAC9B,MAAM,EAAE,YAAY;QACpB,MAAM,EAAE,YAAY,GAAG,KAAK;QAC5B,KAAK;KACN,CAAC,EACF,EAAE,CACH,CAAA;IAED,uFAAuF;IACvF,qGAAqG;IACrG,MAAM,mBAAmB,GAAG,WAAW,CACrC,CAAC,KAA8C,EAAE,EAAE;QACjD,6DAA6D;QAC7D,MAAM,YAAY,GAAG,KAAK,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC,CAAA;QACtD,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,YAAY,CAAC,CAAA;QAE7D,mGAAmG;QACnG,MAAM,mBAAmB,GAAG,aAAa,KAAK,iBAAiB,CAAA;QAC/D,MAAM,wBAAwB,GAAG,aAAa,IAAI,CAAC,IAAI,aAAa,GAAG,gBAAgB,CAAC,MAAM,CAAA;QAE9F,IAAI,mBAAmB,IAAI,wBAAwB,EAAE,CAAC;YACpD,oBAAoB,CAAC,aAAa,CAAC,CAAA;QACrC,CAAC;IACH,CAAC,EACD,CAAC,iBAAiB,EAAE,gBAAgB,CAAC,MAAM,CAAC,CAC7C,CAAA;IAED,mHAAmH;IACnH,gGAAgG;IAChG,MAAM,sBAAsB,GAAG,WAAW,CACxC,CAAC,EAAE,aAAa,EAAyE,EAAE,EAAE;QAC3F,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC;YAAE,OAAM;QAEtC,yJAAyJ;QACzJ,MAAM,iBAAiB,GAAG,aAAa,CAAC,CAAC,CAAC,CAAA;QAC1C,MAAM,QAAQ,GAAG,iBAAiB,CAAC,KAAK,CAAA;QAExC,IAAI,QAAQ,KAAK,IAAI,IAAI,QAAQ,KAAK,iBAAiB,EAAE,CAAC;YACxD,oBAAoB,CAAC,QAAQ,CAAC,CAAA;QAChC,CAAC;IACH,CAAC,EACD,CAAC,iBAAiB,CAAC,CACpB,CAAA;IAED;;mCAE+B;IAC/B,MAAM,gBAAgB,GAAG,OAAO,CAAC,GAAG,EAAE;SACnC,YAAY,CAAC,CAAC,CAAC;SACf,OAAO,CAAC,GAAG,EAAE;QACZ,cAAc,CAAC,KAAK,GAAG,UAAU,CAAC,cAAc,CAAC,KAAK,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,mBAAmB,CAAC,CAAA;IAC5F,CAAC,CAAC,CAAA;IAEJ,MAAM,gBAAgB,GAAG,OAAO,CAAC,GAAG,EAAE;SACnC,YAAY,CAAC,CAAC,CAAC;SACf,OAAO,CAAC,CAAC,CAAC,EAAE;QACX,MAAM,UAAU,GAAG,KAAK,CAAC,KAAK,GAAG,aAAa,CAAA;QAC9C,IAAI,UAAU,EAAE,CAAC;YACf,OAAO,CAAC,gBAAgB,CAAC,EAAE,CAAA;QAC7B,CAAC;aAAM,CAAC;YACN,qCAAqC;YACrC,cAAc,CAAC,KAAK,GAAG,UAAU,CAAC,CAAC,EAAE,mBAAmB,CAAC,CAAA;YAEzD,6BAA6B;YAC7B,MAAM,cAAc,GAAG,gBAAgB,CAAC;gBACtC,WAAW,EAAE,CAAC,CAAC,CAAC;gBAChB,WAAW,EAAE,CAAC,CAAC,CAAC;gBAChB,WAAW,EAAE,qBAAqB;gBAClC,iBAAiB,EAAE,UAAU,CAAC,KAAK;gBACnC,sBAAsB,EAAE,eAAe,CAAC,KAAK;gBAC7C,sBAAsB,EAAE,eAAe,CAAC,KAAK;aAC9C,CAAC,CAAA;YAEF,uEAAuE;YACvE,MAAM,gBAAgB,GAAG,gBAAgB,CAAC;gBACxC,CAAC,EAAE,cAAc,CAAC,UAAU;gBAC5B,CAAC,EAAE,cAAc,CAAC,UAAU;gBAC5B,YAAY,EAAE,qBAAqB;aACpC,CAAC,CAAA;YAEF,uCAAuC;YACvC,KAAK,CAAC,KAAK,GAAG,UAAU,CAAC,qBAAqB,EAAE,mBAAmB,CAAC,CAAA;YACpE,UAAU,CAAC,KAAK,GAAG,UAAU,CAAC,gBAAgB,CAAC,CAAC,EAAE,mBAAmB,CAAC,CAAA;YACtE,UAAU,CAAC,KAAK,GAAG,UAAU,CAAC,gBAAgB,CAAC,CAAC,EAAE,mBAAmB,CAAC,CAAA;YAEtE,sCAAsC;YACtC,UAAU,CAAC,KAAK,GAAG,qBAAqB,CAAA;YACxC,eAAe,CAAC,KAAK,GAAG,gBAAgB,CAAC,CAAC,CAAA;YAC1C,eAAe,CAAC,KAAK,GAAG,gBAAgB,CAAC,CAAC,CAAA;QAC5C,CAAC;IACH,CAAC,CAAC,CAAA;IAEJ,MAAM,YAAY,GAAG,OAAO,CAAC,KAAK,EAAE;SACjC,OAAO,CAAC,CAAC,CAAC,EAAE;QACX,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,MAAM,CAAA;QACvB,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,MAAM,CAAA;QAEvB,qCAAqC;QACrC,cAAc,CAAC,KAAK,GAAG,UAAU,CAAC,CAAC,EAAE,mBAAmB,CAAC,CAAA;QAEzD,gGAAgG;QAChG,eAAe,CAAC,KAAK,GAAG,UAAU,CAAC,KAAK,CAAA;QACxC,eAAe,CAAC,KAAK,GAAG,UAAU,CAAC,KAAK,CAAA;IAC1C,CAAC,CAAC;SACD,QAAQ,CAAC,CAAC,CAAC,EAAE;QACZ,wCAAwC;QACxC,MAAM,QAAQ,GAAG,UAAU,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAA;QAC3C,MAAM,eAAe,GAAG,IAAI,CAAC,GAAG,CAC9B,SAAS,GAAG,mBAAmB,EAC/B,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,QAAQ,CAAC,CAC9B,CAAA;QACD,KAAK,CAAC,KAAK,GAAG,eAAe,CAAA;QAE7B,8DAA8D;QAC9D,MAAM,cAAc,GAAG,gBAAgB,CAAC;YACtC,WAAW,EAAE,MAAM,CAAC,KAAK;YACzB,WAAW,EAAE,MAAM,CAAC,KAAK;YACzB,WAAW,EAAE,eAAe;YAC5B,iBAAiB,EAAE,UAAU,CAAC,KAAK;YACnC,sBAAsB,EAAE,eAAe,CAAC,KAAK;YAC7C,sBAAsB,EAAE,eAAe,CAAC,KAAK;SAC9C,CAAC,CAAA;QAEF,uFAAuF;QACvF,UAAU,CAAC,KAAK,GAAG,cAAc,CAAC,UAAU,CAAA;QAC5C,UAAU,CAAC,KAAK,GAAG,cAAc,CAAC,UAAU,CAAA;IAC9C,CAAC,CAAC;SACD,KAAK,CAAC,GAAG,EAAE;QACV,MAAM,YAAY,GAAG,KAAK,CAAC,KAAK,CAAA;QAEhC,oCAAoC;QACpC,IAAI,YAAY,IAAI,SAAS,EAAE,CAAC;YAC9B,OAAO,CAAC,gBAAgB,CAAC,EAAE,CAAA;YAC3B,OAAM;QACR,CAAC;QAED,oDAAoD;QACpD,MAAM,kBAAkB,GAAG,YAAY,IAAI,aAAa,GAAG,GAAG,CAAA;QAC9D,IAAI,kBAAkB,EAAE,CAAC;YACvB,OAAO,CAAC,gBAAgB,CAAC,EAAE,CAAA;YAC3B,OAAM;QACR,CAAC;QAED,mDAAmD;QACnD,MAAM,UAAU,GAAG,YAAY,GAAG,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,YAAY,CAAA;QAEtE,2HAA2H;QAC3H,MAAM,cAAc,GAAG,gBAAgB,CAAC;YACtC,WAAW,EAAE,MAAM,CAAC,KAAK;YACzB,WAAW,EAAE,MAAM,CAAC,KAAK;YACzB,WAAW,EAAE,UAAU;YACvB,iBAAiB,EAAE,UAAU,CAAC,KAAK;YACnC,sBAAsB,EAAE,eAAe,CAAC,KAAK;YAC7C,sBAAsB,EAAE,eAAe,CAAC,KAAK;SAC9C,CAAC,CAAA;QAEF,qDAAqD;QACrD,MAAM,gBAAgB,GAAG,gBAAgB,CAAC;YACxC,CAAC,EAAE,cAAc,CAAC,UAAU;YAC5B,CAAC,EAAE,cAAc,CAAC,UAAU;YAC5B,YAAY,EAAE,UAAU;SACzB,CAAC,CAAA;QAEF,qDAAqD;QACrD,KAAK,CAAC,KAAK,GAAG,UAAU,CAAC,UAAU,EAAE,mBAAmB,CAAC,CAAA;QACzD,UAAU,CAAC,KAAK,GAAG,UAAU,CAAC,gBAAgB,CAAC,CAAC,EAAE,mBAAmB,CAAC,CAAA;QACtE,UAAU,CAAC,KAAK,GAAG,UAAU,CAAC,gBAAgB,CAAC,CAAC,EAAE,mBAAmB,CAAC,CAAA;QAEtE,8BAA8B;QAC9B,UAAU,CAAC,KAAK,GAAG,UAAU,CAAA;QAC7B,eAAe,CAAC,KAAK,GAAG,gBAAgB,CAAC,CAAC,CAAA;QAC1C,eAAe,CAAC,KAAK,GAAG,gBAAgB,CAAC,CAAC,CAAA;IAC5C,CAAC,CAAC,CAAA;IAEJ,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,EAAE;SAC7B,WAAW,CAAC,6BAA6B,CAAC;SAC1C,WAAW,CAAC,6BAA6B,CAAC;SAC1C,WAAW,CAAC,6BAA6B,CAAC;SAC1C,OAAO,CAAC,iBAAiB,CAAC;SAC1B,OAAO,CAAC,GAAG,EAAE;QACZ,qDAAqD;QACrD,uDAAuD;QACvD,eAAe,CAAC,KAAK,GAAG,UAAU,CAAC,KAAK,CAAA;QACxC,eAAe,CAAC,KAAK,GAAG,UAAU,CAAC,KAAK,CAAA;IAC1C,CAAC,CAAC;SACD,QAAQ,CAAC,CAAC,CAAC,EAAE;QACZ,iCAAiC;QACjC,IAAI,KAAK,CAAC,KAAK,IAAI,aAAa;YAAE,OAAM;QAExC,MAAM,aAAa,GAAG,eAAe,CAAC,KAAK,GAAG,CAAC,CAAC,YAAY,CAAA;QAC5D,MAAM,aAAa,GAAG,eAAe,CAAC,KAAK,GAAG,CAAC,CAAC,YAAY,CAAA;QAE5D,qDAAqD;QACrD,MAAM,gBAAgB,GAAG,gBAAgB,CAAC;YACxC,CAAC,EAAE,aAAa;YAChB,CAAC,EAAE,aAAa;YAChB,YAAY,EAAE,KAAK,CAAC,KAAK;SAC1B,CAAC,CAAA;QACF,UAAU,CAAC,KAAK,GAAG,gBAAgB,CAAC,CAAC,CAAA;QACrC,UAAU,CAAC,KAAK,GAAG,gBAAgB,CAAC,CAAC,CAAA;IACvC,CAAC,CAAC;SACD,KAAK,CAAC,CAAC,CAAC,EAAE;QACT,oEAAoE;QACpE,IAAI,KAAK,CAAC,KAAK,IAAI,aAAa;YAAE,OAAM;QAExC,MAAM,gBAAgB,GAAG,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;QAEhD,UAAU,CAAC,KAAK,GAAG,SAAS,CAC1B;YACE,QAAQ,EAAE,CAAC,CAAC,SAAS,GAAG,qBAAqB;YAC7C,KAAK,EAAE,gBAAgB,CAAC,CAAC;YACzB,YAAY,EAAE,KAAK;SACpB,EACD,QAAQ,CAAC,EAAE;YACT,IAAI,QAAQ,EAAE,CAAC;gBACb,eAAe,CAAC,KAAK,GAAG,UAAU,CAAC,KAAK,CAAA;YAC1C,CAAC;QACH,CAAC,CACF,CAAA;QAED,UAAU,CAAC,KAAK,GAAG,SAAS,CAC1B;YACE,QAAQ,EAAE,CAAC,CAAC,SAAS,GAAG,qBAAqB;YAC7C,KAAK,EAAE,gBAAgB,CAAC,CAAC;YACzB,YAAY,EAAE,KAAK;SACpB,EACD,QAAQ,CAAC,EAAE;YACT,IAAI,QAAQ,EAAE,CAAC;gBACb,eAAe,CAAC,KAAK,GAAG,UAAU,CAAC,KAAK,CAAA;YAC1C,CAAC;QACH,CAAC,CACF,CAAA;IACH,CAAC,CAAC,CAAA;IAEJ,MAAM,wBAAwB,GAAG,OAAO,CAAC,GAAG,EAAE;SAC3C,QAAQ,CAAC,CAAC,CAAC,EAAE;QACZ,MAAM,cAAc,GAAG,KAAK,CAAC,KAAK,KAAK,aAAa,CAAA;QAEpD,iDAAiD;QACjD,MAAM,iBAAiB,GAAG,wBAAwB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;QAC/D,MAAM,+BAA+B,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,YAAY,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,YAAY,CAAC,CAAA;QAC3F,MAAM,qBAAqB,GAAG,iBAAiB,IAAI,+BAA+B,CAAA;QAElF,IAAI,cAAc,IAAI,qBAAqB,EAAE,CAAC;YAC5C,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,YAAY,CAAC,CAAA;YAC5C,MAAM,YAAY,GAAG,WAAW,GAAG,qBAAqB,CAAA;YAExD,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,eAAe,GAAG,YAAY,CAAC,CAAA;YAC3D,QAAQ,CAAC,KAAK,GAAG,CAAC,CAAC,YAAY,CAAA;QACjC,CAAC;IACH,CAAC,CAAC;SACD,KAAK,CAAC,GAAG,EAAE;QACV,MAAM,wBAAwB,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,qBAAqB,CAAA;QAEjF,IAAI,wBAAwB,EAAE,CAAC;YAC7B,OAAO,CAAC,gBAAgB,CAAC,EAAE,CAAA;QAC7B,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,oBAAoB,CAAC,EAAE,CAAA;QACjC,CAAC;IACH,CAAC,CAAC,CAAA;IAEJ;;wCAEoC;IACpC,gGAAgG;IAChG,MAAM,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,UAAU,CAAC,CAAA;IAEjE,sEAAsE;IACtE,MAAM,WAAW,GAAG,OAAO,CAAC,SAAS,CAAC,gBAAgB,EAAE,gBAAgB,CAAC,CAAA;IAEzE,0CAA0C;IAC1C,MAAM,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,kBAAkB,CAAC,CAAA;IAE5E,oDAAoD;IACpD,MAAM,eAAe,GAAG,OAAO,CAAC,YAAY,CAAC,sBAAsB,EAAE,wBAAwB,CAAC,CAAA;IAE9F,MAAM,qBAAqB,GAAG,gBAAgB,CAAC,GAAG,EAAE,CAAC,CAAC;QACpD,OAAO,EAAE,cAAc,CAAC,KAAK;QAC7B,SAAS,EAAE;YACT,EAAE,UAAU,EAAE,CAAC,CAAC,GAAG,cAAc,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,uBAAuB;SAC1E;KACF,CAAC,CAAC,CAAA;IAEH,OAAO,CACL,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,WAAW,CAAC,aAAa,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,gBAAgB,CAAC,CACzF;MAAA,CAAC,SAAS,CACR,QAAQ,CAAC,eAAe,CACxB,MAAM,CAAC,CAAC,iBAAiB,CAAC,CAC1B,QAAQ,CACR,kBAAkB,CAAC,OAAO,EAE5B;MAAA,CAAC,sBAAsB,CACrB;QAAA,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,eAAe,CAAC,CACxC;UAAA,CAAC,0BAA0B,CACzB;YAAA,CAAC,QAAQ,CACP,IAAI,CAAC,CAAC,gBAAgB,CAAC,CACvB,UAAU,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAC/B,CAAC,YAAY,CACX,IAAI,CAAC,CAAC,IAAI,CAAC,CACX,eAAe,CAAC,CAAC,KAAK,KAAK,iBAAiB,CAAC,CAC7C,KAAK,CAAC,CAAC,KAAK,CAAC,CACb,UAAU,CAAC,CAAC,UAAU,CAAC,CACvB,UAAU,CAAC,CAAC,UAAU,CAAC,CACvB,QAAQ,CAAC,CAAC,QAAQ,CAAC,CACnB,OAAO,CAAC,CAAC,OAAO,CAAC,EACjB,CACH,CAAC,CACF,YAAY,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,EAAE,IAAI,KAAK,EAAE,CAAC,CACrD,UAAU,CACV,aAAa,CACb,aAAa,CAAC,CAAC,qBAAqB,CAAC,CACrC,8BAA8B,CAAC,CAAC,KAAK,CAAC,CACtC,kBAAkB,CAAC,CAAC,iBAAiB,CAAC,CACtC,aAAa,CAAC,CAAC,aAAa,CAAC,CAC7B,mBAAmB,CAAC,CAAC,mBAAmB,CAAC,CACzC,sBAAsB,CAAC,CAAC,sBAAsB,CAAC,CAC/C,iBAAiB,CAAC,CAAC;YACjB,2BAA2B,EAAE,EAAE,EAAE,2EAA2E;SAC7G,CAAC,CACF,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CACtB,qBAAqB,CAAC,CAAC,MAAM,CAAC,uBAAuB,CAAC,EAE1D;UAAA,EAAE,0BAA0B,CAC9B;QAAA,EAAE,eAAe,CACnB;MAAA,EAAE,sBAAsB,CAExB;;MAAA,CAAC,QAAQ,CAAC,IAAI,CACZ,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,EAAE,qBAAqB,CAAC,CAAC,CACrD,iBAAiB,CAAC,SAAS,CAE3B;QAAA,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,qBAAqB,CAAC,CACxC;UAAA,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CACvE;YAAA,CAAC,UAAU,CACb;UAAA,EAAE,OAAO,CACT;UAAA,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAC3D;YAAA,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAC/B;UAAA,EAAE,IAAI,CACR;QAAA,EAAE,IAAI,CACN;QAAA,CAAC,UAAU,CACT,OAAO,CAAC,CAAC,mBAAmB,CAAC,CAC7B,QAAQ,CAAC,CAAC,iBAAiB,CAAC,CAC5B,IAAI,CAAC,mBAAmB,CACxB,iBAAiB,CAAC,MAAM,CACxB,kBAAkB,CAAC,uBAAuB,CAC1C,iBAAiB,CAAC,yDAAyD,CAC3E,KAAK,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,CAC3B,SAAS,CAAC,CAAC,MAAM,CAAC,gBAAgB,CAAC,CACnC,IAAI,CAAC,IAAI,EAEX;QAAA,CAAC,UAAU,CACT,OAAO,CAAC,CAAC,gBAAgB,CAAC,CAC1B,QAAQ,CAAC,CAAC,iBAAiB,CAAC,CAC5B,IAAI,CAAC,WAAW,CAChB,kBAAkB,CAAC,aAAa,CAChC,KAAK,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,CAC3B,SAAS,CAAC,CAAC,MAAM,CAAC,gBAAgB,CAAC,CACnC,IAAI,CAAC,IAAI,EAEb;MAAA,EAAE,QAAQ,CAAC,IAAI,CACjB;IAAA,EAAE,KAAK,CAAC,CACT,CAAA;AACH,CAAC,CAAA;AAED,MAAM,0BAA0B,GAAG,CAAC,EAAE,QAAQ,EAAiC,EAAE,EAAE;IACjF,OAAO,CACL,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAClD;MAAA,CAAC,QAAQ,CACX;IAAA,EAAE,SAAS,CAAC,CACb,CAAA;AACH,CAAC,CAAA;AAYD,MAAM,YAAY,GAAG,CAAC,EACpB,IAAI,EACJ,eAAe,EACf,KAAK,EACL,UAAU,EACV,UAAU,EACV,QAAQ,EACR,OAAO,GACW,EAAE,EAAE;IACtB,MAAM,MAAM,GAAG,SAAS,EAAE,CAAA;IAC1B,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,GAAG,IAAI,CAAC,UAAU,CAAA;IAElE,MAAM,mBAAmB,GAAG,gBAAgB,CAAC,GAAG,EAAE;QAChD,OAAO;YACL,SAAS,EAAE;gBACT,EAAE,UAAU,EAAE,eAAe,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,mBAAmB,EAAE;gBACxE,EAAE,UAAU,EAAE,eAAe,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,mBAAmB,EAAE;gBACzF,EAAE,KAAK,EAAE,eAAe,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,aAAa,EAAE;aACzD;YACD,OAAO,EAAE,OAAO,CAAC,KAAK;SACvB,CAAA;IACH,CAAC,CAAC,CAAA;IAEF,OAAO,CACL,CAAC,KAAK,CACJ,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE,aAAa,IAAI,OAAO,EAAE,CAAC,CAC1C,KAAK,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,CAC3B,kBAAkB,CAAC,CAAC,mBAAmB,CAAC,CACxC,uBAAuB,CAAC,CAAC,MAAM,CAAC,mBAAmB,CAAC,CACpD,UAAU,CAAC,SAAS,CACpB,GAAG,CAAC,EAAE,EACN,CACH,CAAA;AACH,CAAC,CAAA;AAOD,MAAM,SAAS,GAAG,CAAC,EAAE,UAAU,GAAG,GAAG,EAAE,WAAW,GAAG,GAAG,KAAqB,EAAE,EAAE,EAAE;IACjF,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,iBAAiB,EAAE,CAAA;IAC3C,MAAM,eAAe,GAAG,MAAM,CAAC,aAAa,CAAA;IAC5C,MAAM,0BAA0B,GAAG,OAAO,CACxC,GAAG,EAAE,CAAC,aAAa,CAAC,eAAe,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAC1D,CAAC,eAAe,CAAC,CAClB,CAAA;IAED,OAAO,UAAU,CAAC,MAAM,CAAC;QACvB,SAAS,EAAE;YACT,QAAQ,EAAE,MAAM;SACjB;QACD,sBAAsB,EAAE;YACtB,KAAK,EAAE,MAAM;YACb,QAAQ,EAAE,GAAG;YACb,WAAW,EAAE,UAAU,GAAG,WAAW;SACtC;QACD,KAAK,EAAE;YACL,YAAY,EAAE,CAAC;SAChB;QACD,OAAO,EAAE;YACP,eAAe;SAChB;QACD,uBAAuB,EAAE;YACvB,UAAU,EAAE,GAAG;YACf,aAAa,EAAE,MAAM;SACtB;QACD,YAAY,EAAE;YACZ,MAAM,EAAE,MAAM;YACd,KAAK,EAAE,YAAY;YACnB,eAAe,EAAE,aAAa;SAC/B;QACD,mBAAmB,EAAE;YACnB,eAAe;SAChB;QACD,aAAa,EAAE;YACb,KAAK,EAAE,MAAM;YACb,QAAQ,EAAE,UAAU;YACpB,GAAG,EAAE,CAAC;YACN,aAAa,EAAE,KAAK;YACpB,UAAU,EAAE,QAAQ;YACpB,GAAG,EAAE,EAAE;YACP,iBAAiB,EAAE,EAAE;YACrB,UAAU,EAAE,GAAG,GAAG,EAAE;YACpB,aAAa,EAAE,CAAC;YAChB,eAAe,EAAE,0BAA0B;SAC5C;QACD,qBAAqB,EAAE;YACrB,IAAI,EAAE,CAAC;SACR;QACD,kBAAkB,EAAE;YAClB,WAAW,EAAE,MAAM;YACnB,UAAU,EAAE,CAAC;YACb,KAAK,EAAE,MAAM,CAAC,cAAc;SAC7B;QACD,qBAAqB,EAAE;YACrB,KAAK,EAAE,MAAM,CAAC,cAAc;SAC7B;QACD,YAAY,EAAE;YACZ,eAAe;YACf,MAAM,EAAE,EAAE;YACV,KAAK,EAAE,EAAE;YACT,YAAY,EAAE,EAAE;YAChB,WAAW,EAAE,CAAC;YACd,WAAW,EAAE,MAAM,CAAC,cAAc;SACnC;QACD,gBAAgB,EAAE;YAChB,KAAK,EAAE,MAAM,CAAC,cAAc;SAC7B;KACF,CAAC,CAAA;AACJ,CAAC,CAAA","sourcesContent":["import React, { useMemo, useState, Dispatch, SetStateAction, useCallback } from 'react'\nimport {\n StatusBar,\n StyleSheet,\n Modal,\n View,\n Linking,\n Dimensions,\n Platform,\n NativeSyntheticEvent,\n NativeScrollEvent,\n ViewToken,\n} from 'react-native'\nimport { useSafeAreaInsets } from 'react-native-safe-area-context'\nimport {\n FlatList,\n Gesture,\n GestureDetector,\n GestureHandlerRootView,\n Pressable,\n} from 'react-native-gesture-handler'\nimport Animated, {\n runOnJS,\n useAnimatedStyle,\n useAnimatedReaction,\n useSharedValue,\n withSpring,\n withDecay,\n SharedValue,\n} from 'react-native-reanimated'\nimport { tokens } from '../../../vendor/tapestry/tokens'\nimport { IconButton, Image, Heading, Text } from '../../display'\nimport colorFunction from 'color'\nimport { formatDatePreview } from '../../../utils/date'\nimport { DenormalizedMessageAttachmentResource } from '../../../types/resources/denormalized_attachment_resource'\nimport { PlatformPressable } from '@react-navigation/elements'\nimport { useTheme } from '../../../hooks'\n\nconst { width: WINDOW_WIDTH, height: WINDOW_HEIGHT } = Dimensions.get('window')\nconst DISMISS_PAN_THRESHOLD = 300\nconst MIN_DISTANCE_PAN_FOR_PLATFORM = Platform.OS === 'android' ? 5 : 0 // Android requires a higher threshold to give pinching priority\nconst POINTER_FOR_SINGLE_FINGER_PAN = 1 // Single-finger panning helps to avoid conflicts with pinching\nconst DEFAULT_OPACITY = 1\nconst DEFAULT_TRANSLATE_X = 0\nconst DEFAULT_TRANSLATE_Y = 0\nconst DEFAULT_SCALE = 1\nconst MIN_SCALE = 0.5\nconst MAX_SCALE = 5\nconst MAX_SCALE_OVERSHOOT = 5\nconst DOUBLE_TAP_ZOOM_SCALE = 2\nconst DECAY_VELOCITY_FACTOR = 0.4\nconst RESET_SPRING_CONFIG = {\n damping: 20,\n stiffness: 150,\n}\n\nexport type MetaProps = {\n authorName: string\n createdAt: string\n}\n\nexport function ImageAttachment({\n attachment,\n imageAttachments,\n currentImageIndex,\n metaProps,\n onMessageAttachmentLongPress,\n}: {\n attachment: DenormalizedMessageAttachmentResource\n imageAttachments: DenormalizedMessageAttachmentResource[]\n currentImageIndex: number\n metaProps: MetaProps\n onMessageAttachmentLongPress: (attachment: DenormalizedMessageAttachmentResource) => void\n}) {\n const { attributes } = attachment\n const { url, urlMedium, filename, metadata = {} } = attributes\n const { colors } = useTheme()\n\n const styles = useStyles({ imageWidth: metadata.width, imageHeight: metadata.height })\n const [visible, setVisible] = useState(false)\n\n return (\n <>\n <PlatformPressable\n style={styles.container}\n onPress={() => setVisible(true)}\n onLongPress={() => onMessageAttachmentLongPress(attachment)}\n android_ripple={{ color: colors.androidRippleNeutral, foreground: true }}\n accessibilityHint=\"Long press for more options\"\n >\n <Image\n source={{ uri: urlMedium || url }}\n style={styles.image}\n wrapperStyle={styles.attachmentImageWrapper}\n alt={filename}\n />\n </PlatformPressable>\n <LightboxModal\n visible={visible}\n setModalVisible={setVisible}\n imageAttachments={imageAttachments}\n initialImageIndex={currentImageIndex}\n metaProps={metaProps}\n />\n </>\n )\n}\n\ninterface LightboxModalProps {\n visible: boolean\n setModalVisible: Dispatch<SetStateAction<boolean>>\n imageAttachments: DenormalizedMessageAttachmentResource[]\n initialImageIndex: number\n metaProps: MetaProps\n}\n\nconst LightboxModal = ({\n visible,\n setModalVisible,\n imageAttachments,\n initialImageIndex,\n metaProps,\n}: LightboxModalProps) => {\n const styles = useStyles()\n const insets = useSafeAreaInsets()\n const [currentImageIndex, setCurrentImageIndex] = useState(initialImageIndex)\n\n const { authorName, createdAt } = metaProps\n\n // Get current image data\n const currentImage = imageAttachments[currentImageIndex]\n const { url, urlMedium, metadata = {} } = currentImage.attributes\n const imageWidth = metadata.width\n const imageHeight = metadata.height\n\n // Calculate available space for image display\n const availableWindowWidth = WINDOW_WIDTH\n const availableWindowHeight = WINDOW_HEIGHT - insets.top - insets.bottom\n\n /* ============================\n ANIMATION VALUES\n ============================ */\n // Native State:\n const dismissY = useSharedValue(0) // vertical distance to dismiss modal\n const opacity = useSharedValue(DEFAULT_OPACITY) // opacity of modal\n const scale = useSharedValue(DEFAULT_SCALE) // zoom level of image\n const focalX = useSharedValue(0) // focal point of image between fingers\n const focalY = useSharedValue(0) // focal point of image between fingers\n const translateX = useSharedValue(DEFAULT_TRANSLATE_X) // horizontal distance to pan image\n const translateY = useSharedValue(DEFAULT_TRANSLATE_Y) // vertical distance to pan image\n const savedScale = useSharedValue(DEFAULT_SCALE) // previous zoom level\n const savedTranslateX = useSharedValue(DEFAULT_TRANSLATE_X) // previous horizontal position\n const savedTranslateY = useSharedValue(DEFAULT_TRANSLATE_Y) // previous vertical position\n const toolbarVisible = useSharedValue(1) // toolbar visibility state\n\n // React (JS) State:\n const [isStatusBarHidden, setIsStatusBarHidden] = useState(false)\n const [flatListScrollEnabled, setFlatListScrollEnabled] = useState(true)\n const [panGestureEnabled, setPanGestureEnabled] = useState(false)\n\n // Syncs toolbar useSharedValue state with React's state so that the status bar can be hidden/shown based on the toolbar's animation\n useAnimatedReaction(\n () => toolbarVisible.value,\n value => {\n runOnJS(setIsStatusBarHidden)(value === 0)\n }\n )\n\n // Syncs FlatList scroll state with scale changes\n // When image is at default scale, enable scroll and disable pan gesture\n // When image is zoomed in, disable scroll and enable pan gesture\n useAnimatedReaction(\n () => scale.value,\n value => {\n const enableFlatListScroll = value === DEFAULT_SCALE\n runOnJS(setFlatListScrollEnabled)(enableFlatListScroll)\n runOnJS(setPanGestureEnabled)(!enableFlatListScroll)\n }\n )\n\n /* ============================\n HANDLERS\n ============================ */\n const handleOpenInBrowser = useCallback(() => {\n Linking.openURL(urlMedium || url)\n }, [urlMedium, url])\n\n const resetDismissGestures = useCallback(() => {\n dismissY.value = withSpring(0, RESET_SPRING_CONFIG)\n opacity.value = withSpring(DEFAULT_OPACITY, RESET_SPRING_CONFIG)\n }, [dismissY, opacity])\n\n const resetAllGestures = useCallback(() => {\n resetDismissGestures()\n scale.value = withSpring(DEFAULT_SCALE, RESET_SPRING_CONFIG)\n translateX.value = withSpring(DEFAULT_TRANSLATE_X, RESET_SPRING_CONFIG)\n translateY.value = withSpring(DEFAULT_TRANSLATE_Y, RESET_SPRING_CONFIG)\n savedScale.value = DEFAULT_SCALE\n savedTranslateX.value = DEFAULT_TRANSLATE_X\n savedTranslateY.value = DEFAULT_TRANSLATE_Y\n toolbarVisible.value = withSpring(1, RESET_SPRING_CONFIG)\n }, [\n resetDismissGestures,\n scale,\n translateX,\n translateY,\n savedScale,\n savedTranslateX,\n savedTranslateY,\n toolbarVisible,\n ])\n\n const handleCloseModal = useCallback(() => {\n setModalVisible(false)\n resetAllGestures()\n }, [setModalVisible, resetAllGestures])\n\n /* ============================\n UTILITY WORKLET FUNCTIONS\n 'worklet' runs functions on the UI thread, instead of the JS thread for better performance.\n ============================ */\n const getImageContainedToWindowDimensions = () => {\n 'worklet'\n\n if (!imageWidth || !imageHeight) {\n return { width: availableWindowWidth, height: availableWindowHeight }\n }\n\n const imageAspectRatio = imageWidth / imageHeight\n const windowAspectRatio = availableWindowWidth / availableWindowHeight\n\n // Constrain image width if its wider than window\n if (imageAspectRatio > windowAspectRatio) {\n return {\n width: availableWindowWidth,\n height: availableWindowWidth / imageAspectRatio,\n }\n }\n\n // Constrain image height if its taller than window\n return {\n width: availableWindowHeight * imageAspectRatio,\n height: availableWindowHeight,\n }\n }\n\n const zoomToFocalPoint = ({\n focalPointX,\n focalPointY,\n targetScale,\n currentSavedScale,\n currentSavedTranslateX,\n currentSavedTranslateY,\n }: {\n focalPointX: number\n focalPointY: number\n targetScale: number\n currentSavedScale: number\n currentSavedTranslateX: number\n currentSavedTranslateY: number\n }) => {\n 'worklet'\n\n // How far the focal point is from the center of the window\n const windowCenterX = WINDOW_WIDTH / 2\n const windowCenterY = WINDOW_HEIGHT / 2\n\n // Position of focal point relative to current image position\n const focalRelativeX = focalPointX - windowCenterX - currentSavedTranslateX\n const focalRelativeY = focalPointY - windowCenterY - currentSavedTranslateY\n\n // Calculate new translation to keep focal point under fingers\n const scaleRatio = targetScale / currentSavedScale\n const newTranslateX = currentSavedTranslateX + focalRelativeX * (1 - scaleRatio)\n const newTranslateY = currentSavedTranslateY + focalRelativeY * (1 - scaleRatio)\n\n return {\n translateX: newTranslateX,\n translateY: newTranslateY,\n }\n }\n\n const getMaxTranslationLimits = (currentScale: number) => {\n 'worklet'\n\n const { width: containedImageWidth, height: containedImageHeight } =\n getImageContainedToWindowDimensions()\n\n // Image dimensions after scaling/zooming\n const scaledWidth = containedImageWidth * currentScale\n const scaledHeight = containedImageHeight * currentScale\n\n // How much the scaled image exceeds the window container\n const excessWidth = scaledWidth - availableWindowWidth\n const excessHeight = scaledHeight - availableWindowHeight\n\n // How far the image can move in each direction before hitting window edges\n const maxTranslateX = Math.max(DEFAULT_TRANSLATE_X, excessWidth / 2)\n const maxTranslateY = Math.max(DEFAULT_TRANSLATE_Y, excessHeight / 2)\n\n return { maxTranslateX, maxTranslateY }\n }\n\n const clampDecay = (currentScale: number): { x: [number, number]; y: [number, number] } => {\n 'worklet'\n\n const { maxTranslateX, maxTranslateY } = getMaxTranslationLimits(currentScale)\n\n return {\n x: [-maxTranslateX, maxTranslateX],\n y: [-maxTranslateY, maxTranslateY],\n }\n }\n\n const clampTranslation = ({\n x,\n y,\n currentScale,\n }: {\n x: number\n y: number\n currentScale: number\n }) => {\n 'worklet'\n\n const { maxTranslateX, maxTranslateY } = getMaxTranslationLimits(currentScale)\n\n return {\n x: Math.min(maxTranslateX, Math.max(-maxTranslateX, x)),\n y: Math.min(maxTranslateY, Math.max(-maxTranslateY, y)),\n }\n }\n\n const isImageAtVerticalBoundry = (currentScale: number) => {\n 'worklet'\n\n const { height: containedImageHeight } = getImageContainedToWindowDimensions()\n\n // Calculate how much the image can exceed the window container\n const scaledHeight = containedImageHeight * currentScale\n const excessHeight = scaledHeight - availableWindowHeight\n const maxTranslateY = Math.max(DEFAULT_TRANSLATE_Y, excessHeight / 2)\n\n const currentTranslateY = translateY.value\n const panPositionTolerance = 1 // buffer to account for translateY being at a subpixel position\n\n const atTopBoundry = currentTranslateY >= maxTranslateY - panPositionTolerance\n const atBottomBoundry = currentTranslateY <= -maxTranslateY + panPositionTolerance\n\n return atTopBoundry || atBottomBoundry\n }\n\n /* ============================\n UTILITY FLATLIST FUNCTIONS\n Supports the image gallery layout and swipe functionality.\n ============================ */\n\n // Used in tandem with FlatList's initialScrollIndex to quickly calculate the position and size of each image before they load.\n const getItemLayout = useCallback(\n (_: unknown, index: number) => ({\n length: WINDOW_WIDTH,\n offset: WINDOW_WIDTH * index,\n index,\n }),\n []\n )\n\n // Captures the current image's index after the FlatList finishes its scroll animation.\n // Used in tandem with onViewableItemsChanged to ensure the final value for currentImageIndex is set.\n const onMomentumScrollEnd = useCallback(\n (event: NativeSyntheticEvent<NativeScrollEvent>) => {\n // Calculate the index of the image that is currently visible\n const imageOffsetX = event.nativeEvent.contentOffset.x\n const newImageIndex = Math.round(imageOffsetX / WINDOW_WIDTH)\n\n // Check if the image index has changed and the FlatList didn't scroll past the first or last image\n const didImageIndexChange = newImageIndex !== currentImageIndex\n const isImageIndexWithinBounds = newImageIndex >= 0 && newImageIndex < imageAttachments.length\n\n if (didImageIndexChange && isImageIndexWithinBounds) {\n setCurrentImageIndex(newImageIndex)\n }\n },\n [currentImageIndex, imageAttachments.length]\n )\n\n // Supplements onMomentumScrollEnd by capturing the current image's index while the FlatList is actively scrolling.\n // Used in tandem with viewabilityConfig to trigger when the image is 50% visible in the window.\n const onViewableItemsChanged = useCallback(\n ({ viewableItems }: { viewableItems: ViewToken<DenormalizedMessageAttachmentResource>[] }) => {\n if (viewableItems.length === 0) return\n\n // Use the first viewable item which is enforced by the FlatList's pagingEnabled prop that allows only two images to be visible at a time when scrolling.\n const firstViewableItem = viewableItems[0]\n const newIndex = firstViewableItem.index\n\n if (newIndex !== null && newIndex !== currentImageIndex) {\n setCurrentImageIndex(newIndex)\n }\n },\n [currentImageIndex]\n )\n\n /* ============================\n GESTURES\n ============================ */\n const singleTapGesture = Gesture.Tap()\n .numberOfTaps(1)\n .onStart(() => {\n toolbarVisible.value = withSpring(toolbarVisible.value > 0.5 ? 0 : 1, RESET_SPRING_CONFIG)\n })\n\n const doubleTapGesture = Gesture.Tap()\n .numberOfTaps(2)\n .onStart(e => {\n const isZoomedIn = scale.value > DEFAULT_SCALE\n if (isZoomedIn) {\n runOnJS(resetAllGestures)()\n } else {\n // Hide toolbar when starting to zoom\n toolbarVisible.value = withSpring(0, RESET_SPRING_CONFIG)\n\n // Zoom to 2x at tap location\n const newTranslation = zoomToFocalPoint({\n focalPointX: e.x,\n focalPointY: e.y,\n targetScale: DOUBLE_TAP_ZOOM_SCALE,\n currentSavedScale: savedScale.value,\n currentSavedTranslateX: savedTranslateX.value,\n currentSavedTranslateY: savedTranslateY.value,\n })\n\n // Apply clamping to ensure image edges remain within window boundaries\n const clampedTranslate = clampTranslation({\n x: newTranslation.translateX,\n y: newTranslation.translateY,\n currentScale: DOUBLE_TAP_ZOOM_SCALE,\n })\n\n // Animate to new scale and translation\n scale.value = withSpring(DOUBLE_TAP_ZOOM_SCALE, RESET_SPRING_CONFIG)\n translateX.value = withSpring(clampedTranslate.x, RESET_SPRING_CONFIG)\n translateY.value = withSpring(clampedTranslate.y, RESET_SPRING_CONFIG)\n\n // Update saved state for next gesture\n savedScale.value = DOUBLE_TAP_ZOOM_SCALE\n savedTranslateX.value = clampedTranslate.x\n savedTranslateY.value = clampedTranslate.y\n }\n })\n\n const pinchGesture = Gesture.Pinch()\n .onStart(e => {\n focalX.value = e.focalX\n focalY.value = e.focalY\n\n // Hide toolbar when starting to zoom\n toolbarVisible.value = withSpring(0, RESET_SPRING_CONFIG)\n\n // Ensure that pinch accounts for the decay animation and starts from the true current position.\n savedTranslateX.value = translateX.value\n savedTranslateY.value = translateY.value\n })\n .onUpdate(e => {\n // Zoom image in/out within scale limits\n const newScale = savedScale.value * e.scale\n const newScaleClamped = Math.min(\n MAX_SCALE + MAX_SCALE_OVERSHOOT,\n Math.max(MIN_SCALE, newScale)\n )\n scale.value = newScaleClamped\n\n // Calculate new translation to keep focal point under fingers\n const newTranslation = zoomToFocalPoint({\n focalPointX: focalX.value,\n focalPointY: focalY.value,\n targetScale: newScaleClamped,\n currentSavedScale: savedScale.value,\n currentSavedTranslateX: savedTranslateX.value,\n currentSavedTranslateY: savedTranslateY.value,\n })\n\n // Apply translation without clamping to ensure focal point doesn't jump during gesture\n translateX.value = newTranslation.translateX\n translateY.value = newTranslation.translateY\n })\n .onEnd(() => {\n const currentScale = scale.value\n\n // Dismiss modal if fully zoomed out\n if (currentScale <= MIN_SCALE) {\n runOnJS(handleCloseModal)()\n return\n }\n\n // Reset all gestures if image is near default scale\n const isNearDefaultScale = currentScale <= DEFAULT_SCALE + 0.1\n if (isNearDefaultScale) {\n runOnJS(resetAllGestures)()\n return\n }\n\n // Check if overshooting the max scale and clamp it\n const finalScale = currentScale > MAX_SCALE ? MAX_SCALE : currentScale\n\n // Recalculate translation using focal point to always return to the same position when image is overshooting the max scale\n const newTranslation = zoomToFocalPoint({\n focalPointX: focalX.value,\n focalPointY: focalY.value,\n targetScale: finalScale,\n currentSavedScale: savedScale.value,\n currentSavedTranslateX: savedTranslateX.value,\n currentSavedTranslateY: savedTranslateY.value,\n })\n\n // Ensure image edges remain within window boundaries\n const clampedTranslate = clampTranslation({\n x: newTranslation.translateX,\n y: newTranslation.translateY,\n currentScale: finalScale,\n })\n\n // Animate to position and scale limits with a spring\n scale.value = withSpring(finalScale, RESET_SPRING_CONFIG)\n translateX.value = withSpring(clampedTranslate.x, RESET_SPRING_CONFIG)\n translateY.value = withSpring(clampedTranslate.y, RESET_SPRING_CONFIG)\n\n // Save state for next gesture\n savedScale.value = finalScale\n savedTranslateX.value = clampedTranslate.x\n savedTranslateY.value = clampedTranslate.y\n })\n\n const panGesture = Gesture.Pan()\n .minDistance(MIN_DISTANCE_PAN_FOR_PLATFORM)\n .minPointers(POINTER_FOR_SINGLE_FINGER_PAN)\n .maxPointers(POINTER_FOR_SINGLE_FINGER_PAN)\n .enabled(panGestureEnabled)\n .onStart(() => {\n // Update saved position to current animated position\n // This ensures smooth continuation if decay is running\n savedTranslateX.value = translateX.value\n savedTranslateY.value = translateY.value\n })\n .onUpdate(e => {\n // Only pan if image is zoomed in\n if (scale.value <= DEFAULT_SCALE) return\n\n const newTranslateX = savedTranslateX.value + e.translationX\n const newTranslateY = savedTranslateY.value + e.translationY\n\n // Ensure image edges remain within window boundaries\n const clampedTranslate = clampTranslation({\n x: newTranslateX,\n y: newTranslateY,\n currentScale: scale.value,\n })\n translateX.value = clampedTranslate.x\n translateY.value = clampedTranslate.y\n })\n .onEnd(e => {\n // Prevents saving pan position if image is zoomed out while panning\n if (scale.value <= DEFAULT_SCALE) return\n\n const clampDecayBounds = clampDecay(scale.value)\n\n translateX.value = withDecay(\n {\n velocity: e.velocityX * DECAY_VELOCITY_FACTOR,\n clamp: clampDecayBounds.x,\n deceleration: 0.996,\n },\n finished => {\n if (finished) {\n savedTranslateX.value = translateX.value\n }\n }\n )\n\n translateY.value = withDecay(\n {\n velocity: e.velocityY * DECAY_VELOCITY_FACTOR,\n clamp: clampDecayBounds.y,\n deceleration: 0.996,\n },\n finished => {\n if (finished) {\n savedTranslateY.value = translateY.value\n }\n }\n )\n })\n\n const panToDismissModalGesture = Gesture.Pan()\n .onUpdate(e => {\n const atDefaultScale = scale.value === DEFAULT_SCALE\n\n // Calculate zoom conditions for dismissing modal\n const atVerticalBoundry = isImageAtVerticalBoundry(scale.value)\n const panDirectionIsPrimarilyVertical = Math.abs(e.translationY) > Math.abs(e.translationX)\n const canDismissWhileZoomed = atVerticalBoundry && panDirectionIsPrimarilyVertical\n\n if (atDefaultScale || canDismissWhileZoomed) {\n const panDistance = Math.abs(e.translationY)\n const fadeProgress = panDistance / DISMISS_PAN_THRESHOLD\n\n opacity.value = Math.max(0, DEFAULT_OPACITY - fadeProgress)\n dismissY.value = e.translationY\n }\n })\n .onEnd(() => {\n const exceededDismissThreshold = Math.abs(dismissY.value) > DISMISS_PAN_THRESHOLD\n\n if (exceededDismissThreshold) {\n runOnJS(handleCloseModal)()\n } else {\n runOnJS(resetDismissGestures)()\n }\n })\n\n /* ==============================\n IMPLEMENT GESTURES & ANIMATIONS\n ================================= */\n // Race between pinch and pan ensures only one is active at a time, preserving focal point logic\n const pinchOrPanGestures = Gesture.Race(pinchGesture, panGesture)\n\n // Exclusive race ensures single tap doesn't interfere with double tap\n const tapGestures = Gesture.Exclusive(doubleTapGesture, singleTapGesture)\n\n // Race between tap gestures and pinch/pan\n const transformImageGestures = Gesture.Race(tapGestures, pinchOrPanGestures)\n\n // Dismiss can work simultaneously with all gestures\n const composedGesture = Gesture.Simultaneous(transformImageGestures, panToDismissModalGesture)\n\n const animatedToolbarStyles = useAnimatedStyle(() => ({\n opacity: toolbarVisible.value,\n transform: [\n { translateY: (1 - toolbarVisible.value) * -20 }, // slide up when hiding\n ],\n }))\n\n return (\n <Modal visible={visible} transparent animationType=\"fade\" onRequestClose={handleCloseModal}>\n <StatusBar\n barStyle=\"light-content\"\n hidden={isStatusBarHidden}\n animated\n showHideTransition=\"slide\"\n />\n <GestureHandlerRootView>\n <GestureDetector gesture={composedGesture}>\n <PreventPressEventsBubbling>\n <FlatList\n data={imageAttachments}\n renderItem={({ item, index }) => (\n <GestureImage\n item={item}\n gesturesEnabled={index === currentImageIndex}\n scale={scale}\n translateX={translateX}\n translateY={translateY}\n dismissY={dismissY}\n opacity={opacity}\n />\n )}\n keyExtractor={(item, index) => `${item.id}-${index}`}\n horizontal\n pagingEnabled\n scrollEnabled={flatListScrollEnabled}\n showsHorizontalScrollIndicator={false}\n initialScrollIndex={initialImageIndex}\n getItemLayout={getItemLayout}\n onMomentumScrollEnd={onMomentumScrollEnd}\n onViewableItemsChanged={onViewableItemsChanged}\n viewabilityConfig={{\n itemVisiblePercentThreshold: 50, // 50% of the image must be visible in the window to be considered viewable\n }}\n style={styles.gallery}\n contentContainerStyle={styles.galleryContentContainer}\n />\n </PreventPressEventsBubbling>\n </GestureDetector>\n </GestureHandlerRootView>\n\n <Animated.View\n style={[styles.actionToolbar, animatedToolbarStyles]}\n accessibilityRole=\"toolbar\"\n >\n <View style={styles.actionToolbarTextMeta}>\n <Heading variant=\"h3\" style={styles.actionToolbarTitle} numberOfLines={1}>\n {authorName}\n </Heading>\n <Text variant=\"tertiary\" style={styles.actionToolbarSubtitle}>\n {formatDatePreview(createdAt)}\n </Text>\n </View>\n <IconButton\n onPress={handleOpenInBrowser}\n disabled={isStatusBarHidden}\n name=\"general.newWindow\"\n accessibilityRole=\"link\"\n accessibilityLabel=\"Open image in browser\"\n accessibilityHint=\"Image can be downloaded and shared through the browser.\"\n style={styles.actionButton}\n iconStyle={styles.actionButtonIcon}\n size=\"lg\"\n />\n <IconButton\n onPress={handleCloseModal}\n disabled={isStatusBarHidden}\n name=\"general.x\"\n accessibilityLabel=\"Close image\"\n style={styles.actionButton}\n iconStyle={styles.actionButtonIcon}\n size=\"lg\"\n />\n </Animated.View>\n </Modal>\n )\n}\n\nconst PreventPressEventsBubbling = ({ children }: { children: React.ReactNode }) => {\n return (\n <Pressable onLongPress={() => {}} onPress={() => {}}>\n {children}\n </Pressable>\n )\n}\n\ninterface GestureImageProps {\n item: DenormalizedMessageAttachmentResource\n gesturesEnabled: boolean\n scale: SharedValue<number>\n translateX: SharedValue<number>\n translateY: SharedValue<number>\n dismissY: SharedValue<number>\n opacity: SharedValue<number>\n}\n\nconst GestureImage = ({\n item,\n gesturesEnabled,\n scale,\n translateX,\n translateY,\n dismissY,\n opacity,\n}: GestureImageProps) => {\n const styles = useStyles()\n const { url: itemUrl, urlMedium: itemUrlMedium } = item.attributes\n\n const animatedImageStyles = useAnimatedStyle(() => {\n return {\n transform: [\n { translateX: gesturesEnabled ? translateX.value : DEFAULT_TRANSLATE_X },\n { translateY: gesturesEnabled ? translateY.value + dismissY.value : DEFAULT_TRANSLATE_Y },\n { scale: gesturesEnabled ? scale.value : DEFAULT_SCALE },\n ],\n opacity: opacity.value,\n }\n })\n\n return (\n <Image\n source={{ uri: itemUrlMedium || itemUrl }}\n style={styles.gestureImage}\n animatedImageStyle={animatedImageStyles}\n loadingBackgroundStyles={styles.gestureImageLoading}\n resizeMode=\"contain\"\n alt=\"\"\n />\n )\n}\n\ninterface UseStylesProps {\n imageWidth?: number\n imageHeight?: number\n}\n\nconst useStyles = ({ imageWidth = 100, imageHeight = 100 }: UseStylesProps = {}) => {\n const { top, bottom } = useSafeAreaInsets()\n const backgroundColor = tokens.colorNeutral7\n const transparentBackgroundColor = useMemo(\n () => colorFunction(backgroundColor).alpha(0.8).toString(),\n [backgroundColor]\n )\n\n return StyleSheet.create({\n container: {\n maxWidth: '100%',\n },\n attachmentImageWrapper: {\n width: '100%',\n minWidth: 200,\n aspectRatio: imageWidth / imageHeight,\n },\n image: {\n borderRadius: 8,\n },\n gallery: {\n backgroundColor,\n },\n galleryContentContainer: {\n paddingTop: top,\n paddingBottom: bottom,\n },\n gestureImage: {\n height: '100%',\n width: WINDOW_WIDTH,\n backgroundColor: 'transparent',\n },\n gestureImageLoading: {\n backgroundColor,\n },\n actionToolbar: {\n width: '100%',\n position: 'absolute',\n top: 0,\n flexDirection: 'row',\n alignItems: 'center',\n gap: 20,\n paddingHorizontal: 16,\n paddingTop: top + 16,\n paddingBottom: 8,\n backgroundColor: transparentBackgroundColor,\n },\n actionToolbarTextMeta: {\n flex: 1,\n },\n actionToolbarTitle: {\n marginRight: 'auto',\n flexShrink: 1,\n color: tokens.colorNeutral88,\n },\n actionToolbarSubtitle: {\n color: tokens.colorNeutral68,\n },\n actionButton: {\n backgroundColor,\n height: 40,\n width: 40,\n borderRadius: 50,\n borderWidth: 1,\n borderColor: tokens.colorNeutral24,\n },\n actionButtonIcon: {\n color: tokens.colorNeutral88,\n },\n })\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@planningcenter/chat-react-native",
3
- "version": "3.12.0-rc.2",
3
+ "version": "3.12.0-rc.3",
4
4
  "description": "",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -55,5 +55,5 @@
55
55
  "prettier": "^3.4.2",
56
56
  "typescript": "<5.6.0"
57
57
  },
58
- "gitHead": "ca633e8e42c62de56a0776dd856879ad6440de9e"
58
+ "gitHead": "ac4297d751da7aaba10e7ef15a627ded35b17252"
59
59
  }
@@ -697,6 +697,7 @@ const LightboxModal = ({
697
697
  </View>
698
698
  <IconButton
699
699
  onPress={handleOpenInBrowser}
700
+ disabled={isStatusBarHidden}
700
701
  name="general.newWindow"
701
702
  accessibilityRole="link"
702
703
  accessibilityLabel="Open image in browser"
@@ -707,6 +708,7 @@ const LightboxModal = ({
707
708
  />
708
709
  <IconButton
709
710
  onPress={handleCloseModal}
711
+ disabled={isStatusBarHidden}
710
712
  name="general.x"
711
713
  accessibilityLabel="Close image"
712
714
  style={styles.actionButton}