Skip to content

Instantly share code, notes, and snippets.

@efstathiosntonas
Created February 1, 2023 15:57
Show Gist options
  • Save efstathiosntonas/a4d077de5bc5315b4f0371383a4aa807 to your computer and use it in GitHub Desktop.
Save efstathiosntonas/a4d077de5bc5315b4f0371383a4aa807 to your computer and use it in GitHub Desktop.
BubbleArrow for react native
import React, { memo, useMemo } from "react";
import { Platform, StyleSheet, View } from "react-native";
import Svg, { Path } from "react-native-svg";
import { moderateScale } from "react-native-size-matters";
import { useStyle } from "react-native-style-utilities";
import useThemeContext from "@themes/themeContext";
import { Chat_Message } from "@generated/graphql";
import { currentUser } from "@functions/auth";
type MessageArrowTypes = {
alignment: string;
isTargetedMessage: boolean;
message: Chat_Message;
nextMessage: Chat_Message | undefined;
previousMessage: Chat_Message | undefined;
};
const MessageArrow = ({
alignment,
isTargetedMessage,
message,
nextMessage,
previousMessage
}: MessageArrowTypes) => {
const themeContext = useThemeContext();
const containerStyle = useStyle(
() => [
styles.arrowContainer,
alignment === "left" ? styles.arrowLeftContainer : styles.arrowRightContainer
],
[alignment]
);
const fill = useMemo(
() =>
alignment === "left" && message.audio
? themeContext.chatScreen.audioPlayer.left.leftBubble
: alignment === "right" && message.audio
? themeContext.chatScreen.audioPlayer.right.rightBubble
: alignment === "left" && isTargetedMessage
? themeContext.chatChannel.highlightedMessage
: alignment === "left"
? themeContext.chatChannel.leftBubble.background
: alignment === "right" && isTargetedMessage
? themeContext.chatChannel.highlightedMessage
: themeContext.chatChannel.rightBubble.background,
[
alignment,
isTargetedMessage,
message.audio,
themeContext.chatChannel.highlightedMessage,
themeContext.chatChannel.leftBubble.background,
themeContext.chatChannel.rightBubble.background,
themeContext.chatScreen.audioPlayer.left.leftBubble,
themeContext.chatScreen.audioPlayer.right.rightBubble
]
);
const svgStyle = useStyle(
() =>
alignment === "left"
? [
styles.arrowLeft,
{
top: 1,
opacity:
previousMessage?.author_id === message.author_id &&
nextMessage?.author_id !== message.author_id
? 1
: nextMessage?.author_id !== message.author_id
? 1
: 0
}
]
: [
styles.arrowRight,
{
top: message.channel_type !== "GROUP" ? moderateScale(-16, 0.6) : 0,
opacity: nextMessage?.author_id === currentUser().uid ? 0 : 1
}
],
[
alignment,
message.author_id,
message.channel_type,
nextMessage?.author_id,
previousMessage?.author_id
]
);
return (
<View style={containerStyle}>
<Svg
enable-background="new 32.485 17.5 15.515 17.5"
height={moderateScale(17.5, 0.6)}
style={svgStyle}
viewBox="32.484 17.5 15.515 17.5"
width={moderateScale(15, 0.6)}
>
<Path
d={
alignment === "left"
? "M38.484,17.5c0,8.75,1,13.5-6,17.5C51.484,35,52.484,17.5,38.484,17.5z"
: "M48,35c-7-4-6-8.75-6-17.5C28,17.5,29,35,48,35z"
}
x="0"
y="0"
fill={fill}
/>
</Svg>
</View>
);
};
const styles = StyleSheet.create({
arrowLeft: {
left: moderateScale(4, 0.5)
},
arrowRight: {
left: moderateScale(Platform.OS === "ios" ? -3 : -4, 0.5)
},
arrowContainer: {
bottom: 1,
flex: 1,
left: 0,
position: "absolute",
right: 0,
top: 0,
zIndex: -1
},
arrowLeftContainer: {
alignItems: "flex-start",
justifyContent: "flex-end"
},
arrowRightContainer: {
alignItems: "flex-end",
justifyContent: "flex-end"
}
});
export default memo(MessageArrow);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment