From ff05c7c9d1aaf8e25dd2758e2921321b6bc2c088 Mon Sep 17 00:00:00 2001 From: alantoa Date: Wed, 27 Sep 2023 21:02:44 +0800 Subject: [PATCH] fix lightbox size --- .../components/message-item.tsx | 30 ++- .../components/creator-channels/messages.tsx | 37 ++++ .../light-box/light-box-modal.tsx | 4 +- .../design-system/light-box/light-box.tsx | 184 ++++++++++-------- 4 files changed, 158 insertions(+), 97 deletions(-) diff --git a/packages/app/components/creator-channels/components/message-item.tsx b/packages/app/components/creator-channels/components/message-item.tsx index e3f907c18c..399b1f6880 100644 --- a/packages/app/components/creator-channels/components/message-item.tsx +++ b/packages/app/components/creator-channels/components/message-item.tsx @@ -74,6 +74,8 @@ export const MessageItem = memo( editMessageItemDimension, edition, isUserAdmin, + imageAttachmentWidth, + imageAttachmentHeight, }: MessageItemProps & { edition?: CreatorEditionResponse; isUserAdmin?: boolean; @@ -83,6 +85,8 @@ export const MessageItem = memo( height: number; pageY: number; }>; + imageAttachmentWidth: number; + imageAttachmentHeight: number; }) => { const { channel_message } = item; const reactOnMessage = useReactOnMessage(channelId); @@ -160,22 +164,6 @@ export const MessageItem = memo( : "", [item.channel_message.body_text_length, messageNotViewable] ); - const imageAttachmentHeight = useMemo(() => { - const theFirstAttachment = item.channel_message.attachments[0]; - - if ( - !item.channel_message?.attachments?.length || - !theFirstAttachment || - !theFirstAttachment.height || - !theFirstAttachment.width - ) { - return 0; - } - return Math.min( - 320 * (theFirstAttachment.height / theFirstAttachment.width), - 320 - ); - }, [item.channel_message.attachments]); // TODO: remove and support video if ( @@ -453,9 +441,15 @@ export const MessageItem = memo( {item.channel_message?.attachments?.length > 0 && item.channel_message?.attachments[0].mime.includes("image") ? ( - + { + const theFirstAttachment = item.channel_message?.attachments[0]; + if ( + !theFirstAttachment || + !theFirstAttachment.height || + !theFirstAttachment.width + ) { + return 0; + } + if (theFirstAttachment.height > theFirstAttachment.width) { + return 160; + } else if (theFirstAttachment.height < theFirstAttachment.width) { + return 320; + } else { + return 320; + } +}; +const getImageAttachmentHeight = (item: ChannelMessageItem) => { + const theFirstAttachment = item.channel_message?.attachments[0]; + + if ( + !theFirstAttachment || + !theFirstAttachment.height || + !theFirstAttachment.width + ) { + return 0; + } + if (theFirstAttachment.height > theFirstAttachment.width) { + return 284; + } else if (theFirstAttachment.height < theFirstAttachment.width) { + return 180; + } else { + return 320; + } +}; const keyExtractor = (item: ChannelMessageItem) => item.channel_message.id.toString(); @@ -348,6 +383,8 @@ export const Messages = memo(() => { { return { opacity: backdropOpacity.value, }; - }); + }, []); const closeModal = useCallback(() => { "worklet"; animationProgress.value = withTiming(0, timingConfig, () => { diff --git a/packages/design-system/light-box/light-box.tsx b/packages/design-system/light-box/light-box.tsx index cf760d4cf8..b5bd5c07c0 100644 --- a/packages/design-system/light-box/light-box.tsx +++ b/packages/design-system/light-box/light-box.tsx @@ -1,4 +1,4 @@ -import React, { useState } from "react"; +import React, { useState, useCallback, useMemo, memo } from "react"; import { Dimensions, StyleProp, ViewStyle } from "react-native"; import { Gesture, GestureDetector } from "react-native-gesture-handler"; @@ -8,16 +8,17 @@ import Animated, { useAnimatedRef, useAnimatedStyle, useSharedValue, + SharedValue, } from "react-native-reanimated"; import { AnimationParams, useLightBox } from "./provider"; export type ImageBoundingClientRect = { - x: Animated.SharedValue; - y: Animated.SharedValue; - width: Animated.SharedValue; - height: Animated.SharedValue; - imageOpacity: Animated.SharedValue; + x: SharedValue; + y: SharedValue; + width: SharedValue; + height: SharedValue; + imageOpacity: SharedValue; }; export type TargetImageInfo = { width: number | string; @@ -41,81 +42,110 @@ export type LightBoxProps = TargetImageInfo & { nativeHeaderHeight?: number; }; -export const LightBox: React.FC = ({ - width: imgWidth, - height: imgHeight, - containerStyle, - imgLayout, - children, - onLongPress, - tapToClose = true, - onTap, - nativeHeaderHeight = 0, - borderRadius, -}) => { - // Todo: add lightboxImage component. - const [targetLayout] = useState(null); +export const LightBox = memo( + ({ + width: imgWidth, + height: imgHeight, + containerStyle, + imgLayout, + children, + onLongPress, + tapToClose = true, + onTap, + nativeHeaderHeight = 0, + borderRadius, + }) => { + // Todo: add lightboxImage component. + const [targetLayout] = useState(null); - const animatedRef = useAnimatedRef(); - const opacity = useSharedValue(1); - const lightBox = useLightBox(); + const animatedRef = useAnimatedRef(); + const opacity = useSharedValue(1); + const lightBox = useLightBox(); - const styles = useAnimatedStyle(() => { - return { - width: typeof imgWidth === "number" ? imgWidth : "100%", - height: typeof imgHeight === "number" ? imgHeight : "100%", - opacity: opacity.value, - }; - }); - const width = useSharedValue(0); - const height = useSharedValue(0); - const x = useSharedValue(0); - const y = useSharedValue(0); + const styles = useAnimatedStyle(() => { + return { + width: typeof imgWidth === "number" ? imgWidth : "100%", + height: typeof imgHeight === "number" ? imgHeight : "100%", + opacity: opacity.value, + }; + }, []); + const width = useSharedValue(0); + const height = useSharedValue(0); + const x = useSharedValue(0); + const y = useSharedValue(0); - const handlePress = () => { - if (!targetLayout && !imgLayout) return; - const position = { imageOpacity: opacity, width, height, x, y }; + const handlePress = useCallback(() => { + if (!targetLayout && !imgLayout) return; + const position = { imageOpacity: opacity, width, height, x, y }; - lightBox?.show({ - position, - layout: targetLayout ?? - imgLayout ?? { - width: Dimensions.get("window").width, - height: Dimensions.get("window").width, - }, - imageElement: children, - tapToClose, - onTap, + lightBox?.show({ + position, + layout: targetLayout ?? + imgLayout ?? { + width: Dimensions.get("window").width, + height: Dimensions.get("window").width, + }, + imageElement: children, + tapToClose, + onTap, + borderRadius, + }); + }, [ borderRadius, - }); - }; + children, + height, + imgLayout, + lightBox, + onTap, + opacity, + tapToClose, + targetLayout, + width, + x, + y, + ]); + + const tapGesture = useMemo( + () => + Gesture.Tap().onEnd((_, success) => { + if (!success) return; + const measurements = measure(animatedRef); + width.value = measurements!.width; + height.value = measurements!.height; + x.value = measurements!.pageX; + y.value = measurements!.pageY - nativeHeaderHeight; + runOnJS(handlePress)(); + }), + [animatedRef, handlePress, height, nativeHeaderHeight, width, x, y] + ); + const longPressGesture = useMemo( + () => + Gesture.LongPress() + .enabled(!!onLongPress) + .maxDistance(10) + .onStart(() => { + "worklet"; + if (onLongPress) { + runOnJS(onLongPress)(); + } + }), + [onLongPress] + ); + const gesture = useMemo( + () => Gesture.Race(longPressGesture, tapGesture), + [longPressGesture, tapGesture] + ); - const tapGesture = Gesture.Tap().onEnd((_, success) => { - if (!success) return; - const measurements = measure(animatedRef); - width.value = measurements!.width; - height.value = measurements!.height; - x.value = measurements!.pageX; - y.value = measurements!.pageY - nativeHeaderHeight; - runOnJS(handlePress)(); - }); - const longPressGesture = Gesture.LongPress() - .enabled(!!onLongPress) - .maxDistance(10) - .onStart(() => { - "worklet"; - if (onLongPress) { - runOnJS(onLongPress)(); - } - }); - return ( - //@ts-ignore - - - - {children} + return ( + //@ts-ignore + + + + {children} + - - - ); -}; + + ); + } +); +LightBox.displayName = "LightBox";