From cbe86a97432907ce73aebb0c63febb292037e867 Mon Sep 17 00:00:00 2001 From: Hirbod <504909+hirbod@users.noreply.github.com> Date: Wed, 22 Nov 2023 00:30:23 +0100 Subject: [PATCH] Refactor/new channel message layout (#2549) * feat(wip): new channel message layout * Update AudioPlayer component styling * Fix consecutive message count bug in Messages component * Add animation to image preview component * Fix styling issues in MessageItem component * Update emoji button dimensions * Refactor message reactions component styles * Add useWindowDimensions hook to ReactionProvider * Fix key prop in MessageItem component * Fix translation bug in ReactionProvider component * Adjust styling and layout in MessageItem component * Fix null reference in Messages component * Add date display to message item * Fix display issue in MessageItem component --- .../components/audio-player/audio-player.tsx | 2 +- .../components/image-preview.web.tsx | 2 + .../components/message-item.tsx | 554 ++++++++++-------- .../components/creator-channels/messages.tsx | 47 +- .../app/components/creator-channels/types.ts | 1 + packages/app/components/reaction/constants.ts | 4 +- .../components/reaction/message-reactions.tsx | 15 +- .../components/reaction/reaction-provider.tsx | 16 +- 8 files changed, 378 insertions(+), 263 deletions(-) diff --git a/packages/app/components/audio-player/audio-player.tsx b/packages/app/components/audio-player/audio-player.tsx index 355322de14..bd28aa474b 100644 --- a/packages/app/components/audio-player/audio-player.tsx +++ b/packages/app/components/audio-player/audio-player.tsx @@ -123,7 +123,7 @@ export const AudioPlayer = memo( }, [id, prepare, url]); return ( - + diff --git a/packages/app/components/creator-channels/components/image-preview.web.tsx b/packages/app/components/creator-channels/components/image-preview.web.tsx index 21696ec29b..e0d1cedb3c 100644 --- a/packages/app/components/creator-channels/components/image-preview.web.tsx +++ b/packages/app/components/creator-channels/components/image-preview.web.tsx @@ -65,6 +65,8 @@ export const ImagePreview = ({ }} transition={{ type: "timing" }} draggable={false} + animate={{ transform: "translate3d(0,0,0) scale(1)" }} + initial={{ transform: "translate3d(0,0,0) scale(1)" }} /> (); const router = useRouter(); + const isByCreator = + channel_message?.sent_by?.profile.profile_id === channelOwnerProfileId; + const linkifiedMessage = useMemo( () => channel_message.body @@ -99,10 +104,12 @@ export const MessageItem = memo( cleanUserTextInput(removeTags(channel_message.body)), 10 ), - "!text-indigo-600 dark:!text-blue-400" + isByCreator + ? "text-base underline text-white font-medium" + : "text-underline text-base font-medium" ) : "", - [channel_message.body] + [channel_message.body, isByCreator] ); const style = useAnimatedStyle(() => { @@ -146,9 +153,6 @@ export const MessageItem = memo( return false; }, [channel_message.created_at]); - const isByCreator = - channel_message?.sent_by?.profile.profile_id === channelOwnerProfileId; - const loremText = useMemo( () => item.channel_message.body_text_length > 0 @@ -165,258 +169,160 @@ export const MessageItem = memo( return null; return ( - - - - - - - - - - - - - {channel_message?.sent_by?.profile.name ?? "Deleted User"} - - - - - - {formatDateRelativeWithIntl(channel_message.created_at)} - - {isByCreator ? ( - - - - ) : null} + + + + + + + + + + + + + {item?.channel_message?.sent_by?.profile.name ?? "Deleted User"} + + + + + + {formatDateRelativeWithIntl(channel_message.created_at)} + + + + 0 ? 25 : 0, + }} + > + + {isByCreator && !permissions?.can_view_creator_messages ? ( 0 + ? 48 * item.reaction_group.length : undefined, + backgroundColor: "#0074FE", }} > - { - enableLayoutAnimations(true); - requestAnimationFrame(async () => { - await reactOnMessage.trigger({ - messageId: item.channel_message.id, - reactionId: id, - }); - requestAnimationFrame(() => { - enableLayoutAnimations(false); - }); - }); - }} - /> - - - - - - - {item.channel_message?.sent_by?.profile.profile_id === - user?.user?.data.profile.profile_id || isUserAdmin ? ( - { - Alert.alert( - "Are you sure you want to delete this message?", - "", - [ - { - text: "Cancel", - }, - { - text: "Delete", - style: "destructive", - onPress: () => { - enableLayoutAnimations(true); - requestAnimationFrame(async () => { - listRef.current?.prepareForLayoutAnimationRender(); - await deleteMessage.trigger({ - messageId: item.channel_message.id, - }); - requestAnimationFrame(() => { - enableLayoutAnimations(false); - }); - }); - }, - }, - ] - ); - }} - key="delete" - > - - - Delete - - - ) : null} - - { - // edit message only if message is not older than 2 hours and it belongs to the user - item.channel_message?.sent_by?.profile.profile_id === - user?.user?.data.profile.profile_id && - allowMessageEditing ? ( - { - runOnUI(() => { - "worklet"; - const values = measure(animatedViewRef); - if (values) { - editMessageItemDimension.value = { - height: values.height, - pageY: values.pageY, - }; - } - runOnJS(setEditMessage)({ - text: item.channel_message.body, - id: item.channel_message.id, - }); - })(); - }} - key="edit" - > - - - Edit - - - ) : null - } - {item.channel_message?.sent_by?.profile.profile_id !== - user?.user?.data.profile.profile_id ? ( - { - router.push( - { - pathname: - Platform.OS === "web" - ? router.pathname - : "/report", - query: { - ...router.query, - reportModal: true, - channelMessageId: item.channel_message.id, - }, - }, - Platform.OS === "web" ? router.asPath : undefined - ); - }} - key="report" - > - - - Report - - - ) : null} - - - - - - {isByCreator && !permissions?.can_view_creator_messages ? ( - {Platform.OS === "web" ? ( // INFO: I had to do it like that because blur-sm would crash for no reason even with web prefix - - {loremText} - + {loremText} ) : item.channel_message.body_text_length > 0 ? ( - <> - + + {loremText} - + ) : null} ) : ( <> {item.channel_message.body_text_length > 0 ? ( - 0 + ? 48 * item.reaction_group.length + : undefined, + backgroundColor: isByCreator + ? "#0074FE" + : isDark + ? "#1F1F1F" + : "#ECECEC", + }} > - {linkifiedMessage} - {messageWasEdited && ( - - {` • edited`} - - )} - + + {linkifiedMessage} + {messageWasEdited && ( + + {` • edited`} + + )} + + ) : null} )} @@ -439,6 +345,7 @@ export const MessageItem = memo( Platform.OS === "web" ? ( <> @@ -447,6 +354,7 @@ export const MessageItem = memo( {({ animatedRef, animatedStyles }) => ( ) : null} + + + { + enableLayoutAnimations(true); + requestAnimationFrame(async () => { + await reactOnMessage.trigger({ + messageId: item.channel_message.id, + reactionId: id, + }); + requestAnimationFrame(() => { + enableLayoutAnimations(false); + }); + }); + }} + /> + + + + + + + {item.channel_message?.sent_by?.profile.profile_id === + user?.user?.data.profile.profile_id || isUserAdmin ? ( + { + Alert.alert( + "Are you sure you want to delete this message?", + "", + [ + { + text: "Cancel", + }, + { + text: "Delete", + style: "destructive", + onPress: () => { + enableLayoutAnimations(true); + requestAnimationFrame(async () => { + listRef.current?.prepareForLayoutAnimationRender(); + await deleteMessage.trigger({ + messageId: item.channel_message.id, + }); + requestAnimationFrame(() => { + enableLayoutAnimations(false); + }); + }); + }, + }, + ] + ); + }} + key="delete" + > + + + Delete + + + ) : null} + + { + // edit message only if message is not older than 2 hours and it belongs to the user + item.channel_message?.sent_by?.profile.profile_id === + user?.user?.data.profile.profile_id && + allowMessageEditing ? ( + { + runOnUI(() => { + "worklet"; + const values = measure(animatedViewRef); + if (values) { + editMessageItemDimension.value = { + height: values.height, + pageY: values.pageY, + }; + } + runOnJS(setEditMessage)({ + text: item.channel_message.body, + id: item.channel_message.id, + }); + })(); + }} + key="edit" + > + + + Edit + + + ) : null + } + {item.channel_message?.sent_by?.profile.profile_id !== + user?.user?.data.profile.profile_id ? ( + { + router.push( + { + pathname: + Platform.OS === "web" + ? router.pathname + : "/report", + query: { + ...router.query, + reportModal: true, + channelMessageId: item.channel_message.id, + }, + }, + Platform.OS === "web" ? router.asPath : undefined + ); + }} + key="report" + > + + + Report + + + ) : null} + + + + {item.reaction_group.length > 0 ? ( - - - + <> + + + + ) : null} diff --git a/packages/app/components/creator-channels/messages.tsx b/packages/app/components/creator-channels/messages.tsx index 770ad2436a..723f1a1249 100644 --- a/packages/app/components/creator-channels/messages.tsx +++ b/packages/app/components/creator-channels/messages.tsx @@ -323,11 +323,54 @@ export const Messages = memo(() => { } }, [channelDetail.data?.owner, error, router, fresh]); + const transformedData = useMemo(() => { + let consecutiveCount = 0; // Initialize the consecutive message count + + return data.map((item, index, array) => { + let isSameSenderAsNext = false; + + if (index < array.length - 1) { + const currentSenderId = + item?.channel_message?.sent_by?.profile?.profile_id; + const nextSenderId = + array[index + 1]?.channel_message?.sent_by?.profile?.profile_id; + + const currentDate = new Date( + item.channel_message?.created_at + ).getTime(); + const nextDate = new Date( + array[index + 1].channel_message?.created_at + ).getTime(); + const dayDifference = + Math.abs(currentDate - nextDate) / (1000 * 60 * 60 * 24); + + // Increment count or reset if sender changes + if (currentSenderId === nextSenderId) { + consecutiveCount++; + } else { + consecutiveCount = 0; // Reset count if sender changes + } + + // Check for same sender as next, less than a day's difference, and not the 5th message in a row + isSameSenderAsNext = + currentSenderId === nextSenderId && + dayDifference < 1 && + consecutiveCount % 10 !== 0; + } else { + // For the last item in the list, always show the sender + isSameSenderAsNext = false; + } + + return { ...item, isSameSenderAsNext }; + }); + }, [data]); + const renderItem: ListRenderItem = useCallback( - ({ item, extraData }) => { + ({ item, index, extraData }) => { return ( { ; diff --git a/packages/app/components/reaction/constants.ts b/packages/app/components/reaction/constants.ts index 7b622045b1..9605b4988a 100644 --- a/packages/app/components/reaction/constants.ts +++ b/packages/app/components/reaction/constants.ts @@ -1,5 +1,5 @@ -export const emojiButtonWidth = 54; -export const emojiButtonHeight = 37; +export const emojiButtonWidth = 50; +export const emojiButtonHeight = 36; export const reactionButtonSize = 18; export const reactionEmojis = ["😍", "🔥", "🤣", "🤯", "🙏"]; diff --git a/packages/app/components/reaction/message-reactions.tsx b/packages/app/components/reaction/message-reactions.tsx index f74a12db38..b5224d6933 100644 --- a/packages/app/components/reaction/message-reactions.tsx +++ b/packages/app/components/reaction/message-reactions.tsx @@ -57,7 +57,7 @@ export const MessageReactions = ({ ); return ( - + {channelReactions ? channelReactions.map((item, index) => { const userReaction = reactionGroup.find( @@ -67,7 +67,6 @@ export const MessageReactions = ({ return ( handleReactionPress(item.id)} tw={[ - "min-h-[25px] items-center justify-center px-2", + "min-h-[25px] items-center justify-center rounded-lg border-2 border-white px-1.5 dark:border-black", userReaction.self_reacted - ? "rounded-lg bg-gray-100 dark:bg-gray-900" - : "", + ? "bg-[#C4DFFF] dark:bg-[#102743]" + : "bg-[#F1F1F1] dark:bg-[#1C1C1C]", ]} > diff --git a/packages/app/components/reaction/reaction-provider.tsx b/packages/app/components/reaction/reaction-provider.tsx index c1e5070286..2da45f9c22 100644 --- a/packages/app/components/reaction/reaction-provider.tsx +++ b/packages/app/components/reaction/reaction-provider.tsx @@ -1,4 +1,5 @@ import { useState, useMemo, useCallback } from "react"; +import { useWindowDimensions } from "react-native"; import Animated, { useSharedValue, @@ -19,6 +20,7 @@ export const ReactionProvider = ({ children }: any) => { const [position, setPosition] = useState({ top: 0, left: 0 }); const [reactions, setReactions] = useState(null); const animatedV = useSharedValue(0); + const { width } = useWindowDimensions(); const close = () => { setVisible(false); }; @@ -52,27 +54,21 @@ export const ReactionProvider = ({ children }: any) => { willChange: "transform", // make it hardware accelerated on web transform: [ { - translateX: totalRectButtonWidth / 2 - 5, + translateX: width < 768 ? -18 : -totalRectButtonWidth / 2 + 60, }, { - translateY: -emojiButtonWidth / 2, + translateY: -emojiButtonWidth / 2 + 10, }, { scale: animatedV.value }, - { - translateX: -totalRectButtonWidth / 2 - 5, - }, - { - translateY: emojiButtonWidth / 2, - }, ], }; - }, [animatedV]); + }, [animatedV, width]); return ( {children} {visible && ( - + {reactions}