Skip to content

Commit

Permalink
feat: implement big emoji messages and optimize emoji filtering (#1410)
Browse files Browse the repository at this point in the history
* Implement big emoji messages and optimize emoji filtering to account for emoji sequences connected by ZWJ characters

* Emoji detection fixes

* Emoji picker perf update by Thierry

* Revert "Emoji picker perf update by Thierry"

This reverts commit 326a14a.

* Simplify big emoji rendering

- Remove MessageBigEmoji component in favor of direct rendering in MessageSimpleText
- Remove optional props from bubble components (transparent, noPadding)
- Remove big emoji styling from reply messages
- Use VStack with Text directly for emoji-only messages
- Use xxl text size for big emojis (48/60)

* Revert more files

* Remove text color for emoji only rendering
  • Loading branch information
lourou authored Dec 31, 2024
1 parent 187d108 commit 089d602
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 0 deletions.
1 change: 1 addition & 0 deletions design-system/Text/Text.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Theme, ThemedStyle } from "@theme/useAppTheme";
import { IInvertedTextColors, ITextColors, IWeights } from "./Text.props";

export const textSizeStyles = {
xxl: { fontSize: 48, lineHeight: 60 } satisfies TextStyle,
xl: { fontSize: 32, lineHeight: 36 } satisfies TextStyle, // Made up, need to confirm with Andrew once we have the design
lg: { fontSize: 24, lineHeight: 28 } satisfies TextStyle, // Made up, need to confirm with Andrew once we have the design
md: { fontSize: 20, lineHeight: 20 } satisfies TextStyle,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,37 @@ import { useMessageContextStoreContext } from "@/features/conversation/conversat
import { useSelect } from "@/data/store/storeHelpers";
import { DecodedMessage, TextCodec } from "@xmtp/react-native-sdk";
import { memo } from "react";
import { shouldRenderBigEmoji } from "@/features/conversation/conversation-message/conversation-message.utils";
import { VStack } from "@design-system/VStack";
import { Text } from "@design-system/Text";
import { textSizeStyles } from "@design-system/Text/Text.styles";
import { useAppTheme } from "@theme/useAppTheme";

export const MessageSimpleText = memo(function MessageSimpleText(props: {
message: DecodedMessage<TextCodec>;
}) {
const { message } = props;

const { theme } = useAppTheme();

const textContent = message.content();

const { hasNextMessageInSeries, fromMe } = useMessageContextStoreContext(
useSelect(["hasNextMessageInSeries", "fromMe"])
);

if (shouldRenderBigEmoji(textContent)) {
return (
<VStack
style={{
alignItems: fromMe ? "flex-end" : "flex-start",
}}
>
<Text style={textSizeStyles.xxl}>{textContent}</Text>
</VStack>
);
}

return (
<BubbleContainer fromMe={fromMe}>
<BubbleContentContainer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import {
TextCodec,
} from "@xmtp/react-native-sdk";
import { useCurrentConversationTopic } from "../conversation.store-context";
import emojiRegex from "emoji-regex";

export function isAnActualMessage(
message: DecodedMessageWithCodecsType
Expand Down Expand Up @@ -257,3 +258,17 @@ export function getConvosMessageStatus(message: DecodedMessageWithCodecsType) {
throw new Error(`Unhandled delivery status: ${message.deliveryStatus}`);
}
}

// Compile emoji regex once
const compiledEmojiRegex = emojiRegex();

export const shouldRenderBigEmoji = (text: string) => {
const trimmedContent = text.trim();
const emojis = trimmedContent.match(compiledEmojiRegex) || [];

const hasEmojis = emojis.length > 0;
const hasFewerThanFourEmojis = emojis.length < 4;
const containsOnlyEmojis = emojis.join("") === trimmedContent;

return hasEmojis && hasFewerThanFourEmojis && containsOnlyEmojis;
};

0 comments on commit 089d602

Please sign in to comment.