@planningcenter/chat-react-native 3.44.1-rc.1 → 3.44.1
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.
- package/build/components/conversation/message.d.ts.map +1 -1
- package/build/components/conversation/message.js +3 -1
- package/build/components/conversation/message.js.map +1 -1
- package/build/components/conversation/message_form.d.ts.map +1 -1
- package/build/components/conversation/message_form.js +5 -3
- package/build/components/conversation/message_form.js.map +1 -1
- package/build/components/conversation/reply_shadow_message.d.ts.map +1 -1
- package/build/components/conversation/reply_shadow_message.js +3 -1
- package/build/components/conversation/reply_shadow_message.js.map +1 -1
- package/build/utils/message_text.d.ts +3 -0
- package/build/utils/message_text.d.ts.map +1 -0
- package/build/utils/message_text.js +8 -0
- package/build/utils/message_text.js.map +1 -0
- package/package.json +3 -3
- package/src/components/conversation/message.tsx +3 -1
- package/src/components/conversation/message_form.tsx +6 -3
- package/src/components/conversation/reply_shadow_message.tsx +3 -1
- package/src/utils/__tests__/message_text.test.ts +45 -0
- package/src/utils/message_text.ts +9 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"message.d.ts","sourceRoot":"","sources":["../../../src/components/conversation/message.tsx"],"names":[],"mappings":"AAsBA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"message.d.ts","sourceRoot":"","sources":["../../../src/components/conversation/message.tsx"],"names":[],"mappings":"AAsBA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAkB7C;;GAEG;AACH,UAAU,YAAa,SAAQ,eAAe;IAC5C,4BAA4B,EAAE,OAAO,CAAA;IACrC,eAAe,EAAE,MAAM,CAAA;IACvB,wBAAwB,CAAC,EAAE,MAAM,CAAA;IACjC,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB;AAED,wBAAgB,OAAO,CAAC,EACtB,4BAA4B,EAC5B,eAAe,EACf,wBAAwB,EACxB,aAAa,EACb,GAAG,OAAO,EACX,EAAE,YAAY,2CA2Rd"}
|
|
@@ -13,6 +13,7 @@ import { useLiveRelativeTime } from '../../hooks/use_live_relative_time';
|
|
|
13
13
|
import { useMessageCreateOrUpdate } from '../../hooks/use_message_create_or_update';
|
|
14
14
|
import { pluralize } from '../../utils';
|
|
15
15
|
import { isNewMessage } from '../../utils/cache/messages_cache';
|
|
16
|
+
import { stripEmptyTextCharacters } from '../../utils/message_text';
|
|
16
17
|
import { Haptic } from '../../utils/native_adapters';
|
|
17
18
|
import { CONVERSATION_MESSAGE_LIST_PADDING_HORIZONTAL, MESSAGE_AUTHOR_AVATAR_COLUMN_WIDTH, platformFontWeightMedium, } from '../../utils/styles';
|
|
18
19
|
import { ComponentErrorBoundary } from '../page/component_error_boundary';
|
|
@@ -21,7 +22,8 @@ import { MessageMarkdown } from './message_markdown';
|
|
|
21
22
|
import { MessageReadReceipts } from './message_read_receipts';
|
|
22
23
|
import { TheirReplyConnector, MyReplyConnector, AVATAR_CONNECTOR_SPACING } from './reply_connectors';
|
|
23
24
|
export function Message({ canDeleteNonAuthoredMessages, conversation_id, latestReadMessageSortKey, inReplyScreen, ...message }) {
|
|
24
|
-
const {
|
|
25
|
+
const { reactionCounts, pending, error, attachments, author } = message;
|
|
26
|
+
const text = stripEmptyTextCharacters(message.text ?? '');
|
|
25
27
|
const deletingMessageIds = useDeletingIds('deleteMessage');
|
|
26
28
|
const isDeleting = deletingMessageIds.has(message.id);
|
|
27
29
|
const styles = useMessageStyles(message.mine, isDeleting);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"message.js","sourceRoot":"","sources":["../../../src/components/conversation/message.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useNavigation } from '@react-navigation/native'\nimport { some } from 'lodash'\nimport React, { useEffect } from 'react'\nimport {\n AccessibilityActionEvent,\n Pressable,\n StyleSheet,\n useWindowDimensions,\n View,\n} from 'react-native'\nimport Animated from 'react-native-reanimated'\nimport { MessageReaction } from '../../components/conversation/message_reaction'\nimport { Avatar, Icon, Spinner, Text, TextButton, TextInlineButton } from '../../components/display'\nimport {\n useAnimatedMessageBackgroundColor,\n useInteractionGhostBackgroundColor,\n useTheme,\n} from '../../hooks'\nimport { useDeletingIds } from '../../hooks'\nimport { useConversationMessage } from '../../hooks/use_conversation_message'\nimport { useLiveRelativeTime } from '../../hooks/use_live_relative_time'\nimport { useMessageCreateOrUpdate } from '../../hooks/use_message_create_or_update'\nimport { MessageResource } from '../../types'\nimport { DenormalizedMessageAttachmentResource } from '../../types/resources/denormalized_attachment_resource'\nimport { ReactionCountResource } from '../../types/resources/reaction'\nimport { pluralize } from '../../utils'\nimport { isNewMessage } from '../../utils/cache/messages_cache'\nimport { Haptic } from '../../utils/native_adapters'\nimport {\n CONVERSATION_MESSAGE_LIST_PADDING_HORIZONTAL,\n MESSAGE_AUTHOR_AVATAR_COLUMN_WIDTH,\n platformFontWeightMedium,\n} from '../../utils/styles'\nimport { ComponentErrorBoundary } from '../page/component_error_boundary'\nimport { MessageAttachments } from './message_attachments'\nimport { MessageMarkdown } from './message_markdown'\nimport { MessageReadReceipts } from './message_read_receipts'\nimport { TheirReplyConnector, MyReplyConnector, AVATAR_CONNECTOR_SPACING } from './reply_connectors'\n\n/** Message\n * Component for display of a message within a conversation list\n */\ninterface MessageProps extends MessageResource {\n canDeleteNonAuthoredMessages: boolean\n conversation_id: number\n latestReadMessageSortKey?: string\n inReplyScreen?: boolean\n}\n\nexport function Message({\n canDeleteNonAuthoredMessages,\n conversation_id,\n latestReadMessageSortKey,\n inReplyScreen,\n ...message\n}: MessageProps) {\n const { text, reactionCounts, pending, error, attachments, author } = message\n const deletingMessageIds = useDeletingIds('deleteMessage')\n const isDeleting = deletingMessageIds.has(message.id)\n const styles = useMessageStyles(message.mine, isDeleting)\n const navigation = useNavigation()\n const { colors } = useTheme()\n const hasReactions = reactionCounts.length > 0\n const [showMessageMetaToggle, setShowMessageMetaToggle] = React.useState(false)\n const showMessageMeta =\n showMessageMetaToggle || message.myLatestInConversation || !!pending || !!error || false\n const timestamp = useLiveRelativeTime(message.createdAt)\n const wasEdited = Boolean(message.textEditedAt)\n const isPersisted = !isNewMessage(message)\n const [temporarilyHidePendingState, setTemporarilyHidePendingState] = React.useState(true)\n const [messageBubbleHeight, setMessageBubbleHeight] = React.useState(0)\n const { animatedBackgroundColor, handleMessagePressIn, handleMessagePressOut } =\n useAnimatedMessageBackgroundColor()\n const { message: replyRootMessage } = useConversationMessage({\n conversation_id,\n messageId: message.replyRootId || '',\n enabled: !!message.replyRootId,\n })\n\n const metaProps = {\n authorName: author.name,\n createdAt: message.createdAt,\n }\n\n const renderAuthor = (!message.mine && message.renderAuthor) || false\n const showReplyCountButton = !inReplyScreen && message.replyRootId === message.id\n const isReplyRootMessage = message.replyRootId === message.id\n const isDeletedReplyRootMessage = isReplyRootMessage && !!message.deletedAt\n const replyToReplyRootMessage = !isReplyRootMessage && !!message.replyRootId\n\n const replyCountText = pluralize(message.replyCount, 'reply')\n const messagePendingLabel = isPersisted ? 'Saving' : 'Sending'\n const replyRootAuthorName = message.replyRootId ? replyRootMessage?.author.name : author.name\n const messageText = isDeletedReplyRootMessage ? 'Message deleted' : text\n\n const messageBottomMargin =\n message.lastInGroup || message.nextIsReplyShadowMessage\n ? 16\n : hasReactions || showMessageMeta || showReplyCountButton\n ? 8\n : 4\n\n const messageIsReplyLabel = replyToReplyRootMessage ? 'Reply' : ''\n const attachmentLabel = some(attachments) ? pluralize(attachments.length, 'attachment') : ''\n const replyCountLabel = isReplyRootMessage ? replyCountText : ''\n const accessibilityLabel = `${author?.name || ''} ${messageIsReplyLabel} ${attachmentLabel} ${\n messageText || ''\n } ${timestamp} ${replyCountLabel}`\n\n useEffect(() => {\n if (pending) {\n const timer = setTimeout(() => {\n setTemporarilyHidePendingState(false)\n }, 2000)\n return () => clearTimeout(timer)\n }\n return () => {}\n }, [pending])\n\n const retryFailedSaveMutation = useMessageCreateOrUpdate({\n conversationId: conversation_id,\n message,\n })\n\n const handleRetry = () => {\n if (text && error) {\n retryFailedSaveMutation.mutateAsync({\n text,\n attachments: message.attachmentsForCreate,\n })\n }\n }\n\n const handleMessagePress = () => {\n setShowMessageMetaToggle(!showMessageMetaToggle)\n }\n\n const handleMessageLongPress = () => {\n if (!isPersisted) return\n\n Haptic.impactLight()\n navigation.navigate('MessageActions', {\n message_id: message.id,\n conversation_id,\n canDeleteNonAuthoredMessages,\n inReplyScreen,\n reply_root_author_name: replyRootAuthorName,\n })\n }\n\n const handleReactionLongPress = (reaction: ReactionCountResource) => {\n Haptic.impactLight()\n navigation.navigate('Reactions', {\n message_id: message.id,\n conversation_id,\n reaction_value: reaction.value,\n })\n }\n\n const handleMessageAttachmentLongPress = (attachment: DenormalizedMessageAttachmentResource) => {\n Haptic.impactLight()\n navigation.navigate('AttachmentActions', {\n attachmentId: attachment?.id,\n attachmentContentType: attachment?.attributes.contentType,\n attachmentUrl: attachment?.attributes.url,\n conversation_id,\n canDeleteNonAuthoredMessages,\n myMessage: message.mine,\n })\n }\n\n const handleNavigateToReplyPress = () => {\n navigation.navigate('ConversationReply', {\n conversation_id,\n reply_root_id: message.id,\n reply_root_author_name: author.name,\n })\n }\n\n const accessibilityActions = [\n {\n name: 'navigateToReplies',\n label: 'Navigate to replies',\n },\n ]\n\n const handleAccessibilityAction = (event: AccessibilityActionEvent) => {\n if (event.nativeEvent.actionName === 'navigateToReplies') {\n handleNavigateToReplyPress()\n }\n }\n\n return (\n <Pressable\n onLongPress={isDeleting ? undefined : handleMessageLongPress}\n onPress={isDeleting ? undefined : handleMessagePress}\n onPressIn={isDeleting ? undefined : handleMessagePressIn}\n onPressOut={isDeleting ? undefined : handleMessagePressOut}\n android_ripple={{ color: colors.androidRippleNeutral, borderless: false, foreground: true }}\n accessibilityRole=\"button\"\n accessibilityLabel={accessibilityLabel}\n accessibilityHint=\"Long press to view message actions like reacting and copying.\"\n accessibilityActions={isReplyRootMessage ? accessibilityActions : undefined}\n onAccessibilityAction={isReplyRootMessage ? handleAccessibilityAction : undefined}\n disabled={isDeletedReplyRootMessage || isDeleting}\n >\n <Animated.View style={[styles.message, animatedBackgroundColor]}>\n {!message.mine && (\n <View>\n {renderAuthor ? (\n <Avatar\n size={'md'}\n sourceUri={author.avatar}\n style={styles.avatar}\n maxFontSizeMultiplier={1}\n minFontSizeMultiplier={1}\n fallbackIconName={isDeletedReplyRootMessage ? 'publishing.trash' : 'general.person'}\n showFallback={isDeletedReplyRootMessage}\n />\n ) : (\n <View style={styles.avatarPlaceholder} />\n )}\n <TheirReplyConnector message={message} messageBubbleHeight={messageBubbleHeight} />\n </View>\n )}\n <View style={[styles.messageContent, { marginBottom: messageBottomMargin }]}>\n {renderAuthor && !isDeletedReplyRootMessage && (\n <Text variant=\"footnote\" style={styles.authorName}>\n {author.name}\n </Text>\n )}\n <View\n style={styles.messageBubble}\n onLayout={e => setMessageBubbleHeight(e.nativeEvent.layout.height)}\n >\n {isDeletedReplyRootMessage ? (\n <View style={styles.messageText}>\n <Text style={styles.replyRootDeletedText}>{messageText}</Text>\n </View>\n ) : (\n <>\n <ComponentErrorBoundary>\n <MessageAttachments\n attachments={attachments}\n metaProps={metaProps}\n onMessageAttachmentLongPress={handleMessageAttachmentLongPress}\n onMessageLongPress={handleMessageLongPress}\n />\n </ComponentErrorBoundary>\n {text && (\n <View style={styles.messageText}>\n <MessageMarkdown text={text} />\n </View>\n )}\n </>\n )}\n </View>\n {showReplyCountButton && (\n <TextButton\n variant=\"footnote\"\n onPress={handleNavigateToReplyPress}\n style={styles.messageReplyCount}\n accessibilityHint=\"Navigates to reply screen for this message\"\n accessibilityRole=\"link\"\n >\n {replyCountText}\n </TextButton>\n )}\n {hasReactions && !isDeletedReplyRootMessage && (\n <View style={styles.messageReactions}>\n {reactionCounts.map(reaction => (\n <MessageReaction\n key={reaction.value}\n reaction={reaction}\n onLongPress={handleReactionLongPress}\n message={message}\n conversationId={conversation_id}\n />\n ))}\n </View>\n )}\n {showMessageMeta && !isDeletedReplyRootMessage && (\n <View style={styles.messageMeta}>\n {message.mine && !pending && !error && (\n <MessageReadReceipts\n message={message}\n latestReadMessageSortKey={latestReadMessageSortKey}\n />\n )}\n {error ? (\n <View style={styles.errorContainer}>\n {retryFailedSaveMutation.isPending ? (\n <Spinner size={12} />\n ) : (\n <Icon name=\"general.exclamationTriangle\" size={12} style={styles.errorIcon} />\n )}\n <Text variant=\"footnote\" style={styles.errorText}>\n Failed to {isPersisted ? 'edit' : 'send'} |{' '}\n <TextInlineButton\n onPress={handleRetry}\n variant=\"footnote\"\n appearance=\"danger\"\n disabled={retryFailedSaveMutation.isPending}\n >\n Try again\n </TextInlineButton>\n </Text>\n </View>\n ) : pending && (!temporarilyHidePendingState || isPersisted) ? (\n <View style={styles.pendingIndicatorContainer}>\n <Icon\n name=\"general.outlinedClock\"\n size={12}\n color={colors.iconColorDefaultSecondary}\n />\n <Text variant=\"footnote\">{messagePendingLabel}</Text>\n </View>\n ) : isPersisted ? (\n <Text variant=\"footnote\">{timestamp}</Text>\n ) : null}\n {!pending && !error && wasEdited && (\n <Text variant=\"footnote\">\n |{' '}\n <Text variant=\"footnote\" style={styles.editedText}>\n Edited\n </Text>\n </Text>\n )}\n </View>\n )}\n </View>\n {message.mine && (\n <MyReplyConnector message={message} messageBubbleHeight={messageBubbleHeight} />\n )}\n </Animated.View>\n </Pressable>\n )\n}\n\nconst useMessageStyles = (mine: boolean, isDeleting: boolean) => {\n const { colors } = useTheme()\n const myMessageBackgroundColor = useInteractionGhostBackgroundColor()\n const { width } = useWindowDimensions()\n const tabletWidth = width >= 744 // Smallest iPad Mini's width\n\n const messageBubbleBackgroundColor = mine ? myMessageBackgroundColor : colors.fillColorNeutral070\n\n return StyleSheet.create({\n message: {\n gap: 8,\n flexDirection: mine ? 'row-reverse' : 'row',\n paddingHorizontal: CONVERSATION_MESSAGE_LIST_PADDING_HORIZONTAL,\n opacity: isDeleting ? 0.5 : 1,\n },\n messageContent: {\n flex: 1,\n gap: 4,\n },\n avatar: {\n marginBottom: AVATAR_CONNECTOR_SPACING,\n },\n avatarPlaceholder: {\n width: MESSAGE_AUTHOR_AVATAR_COLUMN_WIDTH, // Same width as avatar\n },\n authorName: {\n fontWeight: platformFontWeightMedium,\n },\n messageBubble: {\n backgroundColor: messageBubbleBackgroundColor,\n borderRadius: 8,\n maxWidth: tabletWidth ? 360 : '80%',\n alignSelf: mine ? 'flex-end' : 'flex-start',\n },\n messageText: {\n paddingVertical: 6,\n paddingHorizontal: 8,\n },\n messageReactions: {\n flexDirection: 'row',\n gap: 4,\n justifyContent: mine ? 'flex-end' : 'flex-start',\n },\n messageReplyCount: {\n alignSelf: mine ? 'flex-end' : 'flex-start',\n },\n messageMeta: {\n flexDirection: 'row',\n alignItems: 'center',\n justifyContent: mine ? 'flex-end' : 'flex-start',\n gap: 4,\n },\n editedText: {\n fontWeight: platformFontWeightMedium,\n },\n pendingIndicatorContainer: {\n flexDirection: 'row',\n alignItems: 'center',\n gap: 4,\n },\n errorContainer: {\n flexDirection: 'row',\n alignItems: 'center',\n gap: 4,\n },\n errorIcon: {\n color: colors.statusErrorIcon,\n },\n errorText: {\n color: colors.statusErrorText,\n },\n replyRootDeletedText: {\n color: colors.textColorDefaultSecondary,\n fontStyle: 'italic',\n },\n })\n}\n"]}
|
|
1
|
+
{"version":3,"file":"message.js","sourceRoot":"","sources":["../../../src/components/conversation/message.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AACxD,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAC7B,OAAO,KAAK,EAAE,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AACxC,OAAO,EAEL,SAAS,EACT,UAAU,EACV,mBAAmB,EACnB,IAAI,GACL,MAAM,cAAc,CAAA;AACrB,OAAO,QAAQ,MAAM,yBAAyB,CAAA;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,gDAAgD,CAAA;AAChF,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAA;AACpG,OAAO,EACL,iCAAiC,EACjC,kCAAkC,EAClC,QAAQ,GACT,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAC5C,OAAO,EAAE,sBAAsB,EAAE,MAAM,sCAAsC,CAAA;AAC7E,OAAO,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAA;AACxE,OAAO,EAAE,wBAAwB,EAAE,MAAM,0CAA0C,CAAA;AAInF,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AACvC,OAAO,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAA;AAC/D,OAAO,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAA;AACnE,OAAO,EAAE,MAAM,EAAE,MAAM,6BAA6B,CAAA;AACpD,OAAO,EACL,4CAA4C,EAC5C,kCAAkC,EAClC,wBAAwB,GACzB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EAAE,sBAAsB,EAAE,MAAM,kCAAkC,CAAA;AACzE,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAA;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAA;AAC7D,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAA;AAYpG,MAAM,UAAU,OAAO,CAAC,EACtB,4BAA4B,EAC5B,eAAe,EACf,wBAAwB,EACxB,aAAa,EACb,GAAG,OAAO,EACG;IACb,MAAM,EAAE,cAAc,EAAE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,OAAO,CAAA;IACvE,MAAM,IAAI,GAAG,wBAAwB,CAAC,OAAO,CAAC,IAAI,IAAI,EAAE,CAAC,CAAA;IACzD,MAAM,kBAAkB,GAAG,cAAc,CAAC,eAAe,CAAC,CAAA;IAC1D,MAAM,UAAU,GAAG,kBAAkB,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;IACrD,MAAM,MAAM,GAAG,gBAAgB,CAAC,OAAO,CAAC,IAAI,EAAE,UAAU,CAAC,CAAA;IACzD,MAAM,UAAU,GAAG,aAAa,EAAE,CAAA;IAClC,MAAM,EAAE,MAAM,EAAE,GAAG,QAAQ,EAAE,CAAA;IAC7B,MAAM,YAAY,GAAG,cAAc,CAAC,MAAM,GAAG,CAAC,CAAA;IAC9C,MAAM,CAAC,qBAAqB,EAAE,wBAAwB,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;IAC/E,MAAM,eAAe,GACnB,qBAAqB,IAAI,OAAO,CAAC,sBAAsB,IAAI,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,KAAK,IAAI,KAAK,CAAA;IAC1F,MAAM,SAAS,GAAG,mBAAmB,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;IACxD,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,CAAA;IAC/C,MAAM,WAAW,GAAG,CAAC,YAAY,CAAC,OAAO,CAAC,CAAA;IAC1C,MAAM,CAAC,2BAA2B,EAAE,8BAA8B,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAA;IAC1F,MAAM,CAAC,mBAAmB,EAAE,sBAAsB,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAA;IACvE,MAAM,EAAE,uBAAuB,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,GAC5E,iCAAiC,EAAE,CAAA;IACrC,MAAM,EAAE,OAAO,EAAE,gBAAgB,EAAE,GAAG,sBAAsB,CAAC;QAC3D,eAAe;QACf,SAAS,EAAE,OAAO,CAAC,WAAW,IAAI,EAAE;QACpC,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,WAAW;KAC/B,CAAC,CAAA;IAEF,MAAM,SAAS,GAAG;QAChB,UAAU,EAAE,MAAM,CAAC,IAAI;QACvB,SAAS,EAAE,OAAO,CAAC,SAAS;KAC7B,CAAA;IAED,MAAM,YAAY,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,YAAY,CAAC,IAAI,KAAK,CAAA;IACrE,MAAM,oBAAoB,GAAG,CAAC,aAAa,IAAI,OAAO,CAAC,WAAW,KAAK,OAAO,CAAC,EAAE,CAAA;IACjF,MAAM,kBAAkB,GAAG,OAAO,CAAC,WAAW,KAAK,OAAO,CAAC,EAAE,CAAA;IAC7D,MAAM,yBAAyB,GAAG,kBAAkB,IAAI,CAAC,CAAC,OAAO,CAAC,SAAS,CAAA;IAC3E,MAAM,uBAAuB,GAAG,CAAC,kBAAkB,IAAI,CAAC,CAAC,OAAO,CAAC,WAAW,CAAA;IAE5E,MAAM,cAAc,GAAG,SAAS,CAAC,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC,CAAA;IAC7D,MAAM,mBAAmB,GAAG,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAA;IAC9D,MAAM,mBAAmB,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,gBAAgB,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAA;IAC7F,MAAM,WAAW,GAAG,yBAAyB,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAA;IAExE,MAAM,mBAAmB,GACvB,OAAO,CAAC,WAAW,IAAI,OAAO,CAAC,wBAAwB;QACrD,CAAC,CAAC,EAAE;QACJ,CAAC,CAAC,YAAY,IAAI,eAAe,IAAI,oBAAoB;YACvD,CAAC,CAAC,CAAC;YACH,CAAC,CAAC,CAAC,CAAA;IAET,MAAM,mBAAmB,GAAG,uBAAuB,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAA;IAClE,MAAM,eAAe,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;IAC5F,MAAM,eAAe,GAAG,kBAAkB,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,CAAA;IAChE,MAAM,kBAAkB,GAAG,GAAG,MAAM,EAAE,IAAI,IAAI,EAAE,IAAI,mBAAmB,IAAI,eAAe,IACxF,WAAW,IAAI,EACjB,IAAI,SAAS,IAAI,eAAe,EAAE,CAAA;IAElC,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,OAAO,EAAE,CAAC;YACZ,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;gBAC5B,8BAA8B,CAAC,KAAK,CAAC,CAAA;YACvC,CAAC,EAAE,IAAI,CAAC,CAAA;YACR,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,CAAA;QAClC,CAAC;QACD,OAAO,GAAG,EAAE,GAAE,CAAC,CAAA;IACjB,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAA;IAEb,MAAM,uBAAuB,GAAG,wBAAwB,CAAC;QACvD,cAAc,EAAE,eAAe;QAC/B,OAAO;KACR,CAAC,CAAA;IAEF,MAAM,WAAW,GAAG,GAAG,EAAE;QACvB,IAAI,IAAI,IAAI,KAAK,EAAE,CAAC;YAClB,uBAAuB,CAAC,WAAW,CAAC;gBAClC,IAAI;gBACJ,WAAW,EAAE,OAAO,CAAC,oBAAoB;aAC1C,CAAC,CAAA;QACJ,CAAC;IACH,CAAC,CAAA;IAED,MAAM,kBAAkB,GAAG,GAAG,EAAE;QAC9B,wBAAwB,CAAC,CAAC,qBAAqB,CAAC,CAAA;IAClD,CAAC,CAAA;IAED,MAAM,sBAAsB,GAAG,GAAG,EAAE;QAClC,IAAI,CAAC,WAAW;YAAE,OAAM;QAExB,MAAM,CAAC,WAAW,EAAE,CAAA;QACpB,UAAU,CAAC,QAAQ,CAAC,gBAAgB,EAAE;YACpC,UAAU,EAAE,OAAO,CAAC,EAAE;YACtB,eAAe;YACf,4BAA4B;YAC5B,aAAa;YACb,sBAAsB,EAAE,mBAAmB;SAC5C,CAAC,CAAA;IACJ,CAAC,CAAA;IAED,MAAM,uBAAuB,GAAG,CAAC,QAA+B,EAAE,EAAE;QAClE,MAAM,CAAC,WAAW,EAAE,CAAA;QACpB,UAAU,CAAC,QAAQ,CAAC,WAAW,EAAE;YAC/B,UAAU,EAAE,OAAO,CAAC,EAAE;YACtB,eAAe;YACf,cAAc,EAAE,QAAQ,CAAC,KAAK;SAC/B,CAAC,CAAA;IACJ,CAAC,CAAA;IAED,MAAM,gCAAgC,GAAG,CAAC,UAAiD,EAAE,EAAE;QAC7F,MAAM,CAAC,WAAW,EAAE,CAAA;QACpB,UAAU,CAAC,QAAQ,CAAC,mBAAmB,EAAE;YACvC,YAAY,EAAE,UAAU,EAAE,EAAE;YAC5B,qBAAqB,EAAE,UAAU,EAAE,UAAU,CAAC,WAAW;YACzD,aAAa,EAAE,UAAU,EAAE,UAAU,CAAC,GAAG;YACzC,eAAe;YACf,4BAA4B;YAC5B,SAAS,EAAE,OAAO,CAAC,IAAI;SACxB,CAAC,CAAA;IACJ,CAAC,CAAA;IAED,MAAM,0BAA0B,GAAG,GAAG,EAAE;QACtC,UAAU,CAAC,QAAQ,CAAC,mBAAmB,EAAE;YACvC,eAAe;YACf,aAAa,EAAE,OAAO,CAAC,EAAE;YACzB,sBAAsB,EAAE,MAAM,CAAC,IAAI;SACpC,CAAC,CAAA;IACJ,CAAC,CAAA;IAED,MAAM,oBAAoB,GAAG;QAC3B;YACE,IAAI,EAAE,mBAAmB;YACzB,KAAK,EAAE,qBAAqB;SAC7B;KACF,CAAA;IAED,MAAM,yBAAyB,GAAG,CAAC,KAA+B,EAAE,EAAE;QACpE,IAAI,KAAK,CAAC,WAAW,CAAC,UAAU,KAAK,mBAAmB,EAAE,CAAC;YACzD,0BAA0B,EAAE,CAAA;QAC9B,CAAC;IACH,CAAC,CAAA;IAED,OAAO,CACL,KAAC,SAAS,IACR,WAAW,EAAE,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,sBAAsB,EAC5D,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,kBAAkB,EACpD,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,oBAAoB,EACxD,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,qBAAqB,EAC1D,cAAc,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,oBAAoB,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,EAC3F,iBAAiB,EAAC,QAAQ,EAC1B,kBAAkB,EAAE,kBAAkB,EACtC,iBAAiB,EAAC,+DAA+D,EACjF,oBAAoB,EAAE,kBAAkB,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,SAAS,EAC3E,qBAAqB,EAAE,kBAAkB,CAAC,CAAC,CAAC,yBAAyB,CAAC,CAAC,CAAC,SAAS,EACjF,QAAQ,EAAE,yBAAyB,IAAI,UAAU,YAEjD,MAAC,QAAQ,CAAC,IAAI,IAAC,KAAK,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,uBAAuB,CAAC,aAC5D,CAAC,OAAO,CAAC,IAAI,IAAI,CAChB,MAAC,IAAI,eACF,YAAY,CAAC,CAAC,CAAC,CACd,KAAC,MAAM,IACL,IAAI,EAAE,IAAI,EACV,SAAS,EAAE,MAAM,CAAC,MAAM,EACxB,KAAK,EAAE,MAAM,CAAC,MAAM,EACpB,qBAAqB,EAAE,CAAC,EACxB,qBAAqB,EAAE,CAAC,EACxB,gBAAgB,EAAE,yBAAyB,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,gBAAgB,EACnF,YAAY,EAAE,yBAAyB,GACvC,CACH,CAAC,CAAC,CAAC,CACF,KAAC,IAAI,IAAC,KAAK,EAAE,MAAM,CAAC,iBAAiB,GAAI,CAC1C,EACD,KAAC,mBAAmB,IAAC,OAAO,EAAE,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,GAAI,IAC9E,CACR,EACD,MAAC,IAAI,IAAC,KAAK,EAAE,CAAC,MAAM,CAAC,cAAc,EAAE,EAAE,YAAY,EAAE,mBAAmB,EAAE,CAAC,aACxE,YAAY,IAAI,CAAC,yBAAyB,IAAI,CAC7C,KAAC,IAAI,IAAC,OAAO,EAAC,UAAU,EAAC,KAAK,EAAE,MAAM,CAAC,UAAU,YAC9C,MAAM,CAAC,IAAI,GACP,CACR,EACD,KAAC,IAAI,IACH,KAAK,EAAE,MAAM,CAAC,aAAa,EAC3B,QAAQ,EAAE,CAAC,CAAC,EAAE,CAAC,sBAAsB,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,YAEjE,yBAAyB,CAAC,CAAC,CAAC,CAC3B,KAAC,IAAI,IAAC,KAAK,EAAE,MAAM,CAAC,WAAW,YAC7B,KAAC,IAAI,IAAC,KAAK,EAAE,MAAM,CAAC,oBAAoB,YAAG,WAAW,GAAQ,GACzD,CACR,CAAC,CAAC,CAAC,CACF,8BACE,KAAC,sBAAsB,cACrB,KAAC,kBAAkB,IACjB,WAAW,EAAE,WAAW,EACxB,SAAS,EAAE,SAAS,EACpB,4BAA4B,EAAE,gCAAgC,EAC9D,kBAAkB,EAAE,sBAAsB,GAC1C,GACqB,EACxB,IAAI,IAAI,CACP,KAAC,IAAI,IAAC,KAAK,EAAE,MAAM,CAAC,WAAW,YAC7B,KAAC,eAAe,IAAC,IAAI,EAAE,IAAI,GAAI,GAC1B,CACR,IACA,CACJ,GACI,EACN,oBAAoB,IAAI,CACvB,KAAC,UAAU,IACT,OAAO,EAAC,UAAU,EAClB,OAAO,EAAE,0BAA0B,EACnC,KAAK,EAAE,MAAM,CAAC,iBAAiB,EAC/B,iBAAiB,EAAC,4CAA4C,EAC9D,iBAAiB,EAAC,MAAM,YAEvB,cAAc,GACJ,CACd,EACA,YAAY,IAAI,CAAC,yBAAyB,IAAI,CAC7C,KAAC,IAAI,IAAC,KAAK,EAAE,MAAM,CAAC,gBAAgB,YACjC,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,CAC9B,KAAC,eAAe,IAEd,QAAQ,EAAE,QAAQ,EAClB,WAAW,EAAE,uBAAuB,EACpC,OAAO,EAAE,OAAO,EAChB,cAAc,EAAE,eAAe,IAJ1B,QAAQ,CAAC,KAAK,CAKnB,CACH,CAAC,GACG,CACR,EACA,eAAe,IAAI,CAAC,yBAAyB,IAAI,CAChD,MAAC,IAAI,IAAC,KAAK,EAAE,MAAM,CAAC,WAAW,aAC5B,OAAO,CAAC,IAAI,IAAI,CAAC,OAAO,IAAI,CAAC,KAAK,IAAI,CACrC,KAAC,mBAAmB,IAClB,OAAO,EAAE,OAAO,EAChB,wBAAwB,EAAE,wBAAwB,GAClD,CACH,EACA,KAAK,CAAC,CAAC,CAAC,CACP,MAAC,IAAI,IAAC,KAAK,EAAE,MAAM,CAAC,cAAc,aAC/B,uBAAuB,CAAC,SAAS,CAAC,CAAC,CAAC,CACnC,KAAC,OAAO,IAAC,IAAI,EAAE,EAAE,GAAI,CACtB,CAAC,CAAC,CAAC,CACF,KAAC,IAAI,IAAC,IAAI,EAAC,6BAA6B,EAAC,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,SAAS,GAAI,CAC/E,EACD,MAAC,IAAI,IAAC,OAAO,EAAC,UAAU,EAAC,KAAK,EAAE,MAAM,CAAC,SAAS,2BACnC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,QAAI,GAAG,EAC/C,KAAC,gBAAgB,IACf,OAAO,EAAE,WAAW,EACpB,OAAO,EAAC,UAAU,EAClB,UAAU,EAAC,QAAQ,EACnB,QAAQ,EAAE,uBAAuB,CAAC,SAAS,0BAG1B,IACd,IACF,CACR,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,2BAA2B,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC,CAC7D,MAAC,IAAI,IAAC,KAAK,EAAE,MAAM,CAAC,yBAAyB,aAC3C,KAAC,IAAI,IACH,IAAI,EAAC,uBAAuB,EAC5B,IAAI,EAAE,EAAE,EACR,KAAK,EAAE,MAAM,CAAC,yBAAyB,GACvC,EACF,KAAC,IAAI,IAAC,OAAO,EAAC,UAAU,YAAE,mBAAmB,GAAQ,IAChD,CACR,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAChB,KAAC,IAAI,IAAC,OAAO,EAAC,UAAU,YAAE,SAAS,GAAQ,CAC5C,CAAC,CAAC,CAAC,IAAI,EACP,CAAC,OAAO,IAAI,CAAC,KAAK,IAAI,SAAS,IAAI,CAClC,MAAC,IAAI,IAAC,OAAO,EAAC,UAAU,kBACpB,GAAG,EACL,KAAC,IAAI,IAAC,OAAO,EAAC,UAAU,EAAC,KAAK,EAAE,MAAM,CAAC,UAAU,uBAE1C,IACF,CACR,IACI,CACR,IACI,EACN,OAAO,CAAC,IAAI,IAAI,CACf,KAAC,gBAAgB,IAAC,OAAO,EAAE,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,GAAI,CACjF,IACa,GACN,CACb,CAAA;AACH,CAAC;AAED,MAAM,gBAAgB,GAAG,CAAC,IAAa,EAAE,UAAmB,EAAE,EAAE;IAC9D,MAAM,EAAE,MAAM,EAAE,GAAG,QAAQ,EAAE,CAAA;IAC7B,MAAM,wBAAwB,GAAG,kCAAkC,EAAE,CAAA;IACrE,MAAM,EAAE,KAAK,EAAE,GAAG,mBAAmB,EAAE,CAAA;IACvC,MAAM,WAAW,GAAG,KAAK,IAAI,GAAG,CAAA,CAAC,6BAA6B;IAE9D,MAAM,4BAA4B,GAAG,IAAI,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAC,MAAM,CAAC,mBAAmB,CAAA;IAEjG,OAAO,UAAU,CAAC,MAAM,CAAC;QACvB,OAAO,EAAE;YACP,GAAG,EAAE,CAAC;YACN,aAAa,EAAE,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,KAAK;YAC3C,iBAAiB,EAAE,4CAA4C;YAC/D,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;SAC9B;QACD,cAAc,EAAE;YACd,IAAI,EAAE,CAAC;YACP,GAAG,EAAE,CAAC;SACP;QACD,MAAM,EAAE;YACN,YAAY,EAAE,wBAAwB;SACvC;QACD,iBAAiB,EAAE;YACjB,KAAK,EAAE,kCAAkC,EAAE,uBAAuB;SACnE;QACD,UAAU,EAAE;YACV,UAAU,EAAE,wBAAwB;SACrC;QACD,aAAa,EAAE;YACb,eAAe,EAAE,4BAA4B;YAC7C,YAAY,EAAE,CAAC;YACf,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK;YACnC,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,YAAY;SAC5C;QACD,WAAW,EAAE;YACX,eAAe,EAAE,CAAC;YAClB,iBAAiB,EAAE,CAAC;SACrB;QACD,gBAAgB,EAAE;YAChB,aAAa,EAAE,KAAK;YACpB,GAAG,EAAE,CAAC;YACN,cAAc,EAAE,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,YAAY;SACjD;QACD,iBAAiB,EAAE;YACjB,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,YAAY;SAC5C;QACD,WAAW,EAAE;YACX,aAAa,EAAE,KAAK;YACpB,UAAU,EAAE,QAAQ;YACpB,cAAc,EAAE,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,YAAY;YAChD,GAAG,EAAE,CAAC;SACP;QACD,UAAU,EAAE;YACV,UAAU,EAAE,wBAAwB;SACrC;QACD,yBAAyB,EAAE;YACzB,aAAa,EAAE,KAAK;YACpB,UAAU,EAAE,QAAQ;YACpB,GAAG,EAAE,CAAC;SACP;QACD,cAAc,EAAE;YACd,aAAa,EAAE,KAAK;YACpB,UAAU,EAAE,QAAQ;YACpB,GAAG,EAAE,CAAC;SACP;QACD,SAAS,EAAE;YACT,KAAK,EAAE,MAAM,CAAC,eAAe;SAC9B;QACD,SAAS,EAAE;YACT,KAAK,EAAE,MAAM,CAAC,eAAe;SAC9B;QACD,oBAAoB,EAAE;YACpB,KAAK,EAAE,MAAM,CAAC,yBAAyB;YACvC,SAAS,EAAE,QAAQ;SACpB;KACF,CAAC,CAAA;AACJ,CAAC,CAAA","sourcesContent":["import { useNavigation } from '@react-navigation/native'\nimport { some } from 'lodash'\nimport React, { useEffect } from 'react'\nimport {\n AccessibilityActionEvent,\n Pressable,\n StyleSheet,\n useWindowDimensions,\n View,\n} from 'react-native'\nimport Animated from 'react-native-reanimated'\nimport { MessageReaction } from '../../components/conversation/message_reaction'\nimport { Avatar, Icon, Spinner, Text, TextButton, TextInlineButton } from '../../components/display'\nimport {\n useAnimatedMessageBackgroundColor,\n useInteractionGhostBackgroundColor,\n useTheme,\n} from '../../hooks'\nimport { useDeletingIds } from '../../hooks'\nimport { useConversationMessage } from '../../hooks/use_conversation_message'\nimport { useLiveRelativeTime } from '../../hooks/use_live_relative_time'\nimport { useMessageCreateOrUpdate } from '../../hooks/use_message_create_or_update'\nimport { MessageResource } from '../../types'\nimport { DenormalizedMessageAttachmentResource } from '../../types/resources/denormalized_attachment_resource'\nimport { ReactionCountResource } from '../../types/resources/reaction'\nimport { pluralize } from '../../utils'\nimport { isNewMessage } from '../../utils/cache/messages_cache'\nimport { stripEmptyTextCharacters } from '../../utils/message_text'\nimport { Haptic } from '../../utils/native_adapters'\nimport {\n CONVERSATION_MESSAGE_LIST_PADDING_HORIZONTAL,\n MESSAGE_AUTHOR_AVATAR_COLUMN_WIDTH,\n platformFontWeightMedium,\n} from '../../utils/styles'\nimport { ComponentErrorBoundary } from '../page/component_error_boundary'\nimport { MessageAttachments } from './message_attachments'\nimport { MessageMarkdown } from './message_markdown'\nimport { MessageReadReceipts } from './message_read_receipts'\nimport { TheirReplyConnector, MyReplyConnector, AVATAR_CONNECTOR_SPACING } from './reply_connectors'\n\n/** Message\n * Component for display of a message within a conversation list\n */\ninterface MessageProps extends MessageResource {\n canDeleteNonAuthoredMessages: boolean\n conversation_id: number\n latestReadMessageSortKey?: string\n inReplyScreen?: boolean\n}\n\nexport function Message({\n canDeleteNonAuthoredMessages,\n conversation_id,\n latestReadMessageSortKey,\n inReplyScreen,\n ...message\n}: MessageProps) {\n const { reactionCounts, pending, error, attachments, author } = message\n const text = stripEmptyTextCharacters(message.text ?? '')\n const deletingMessageIds = useDeletingIds('deleteMessage')\n const isDeleting = deletingMessageIds.has(message.id)\n const styles = useMessageStyles(message.mine, isDeleting)\n const navigation = useNavigation()\n const { colors } = useTheme()\n const hasReactions = reactionCounts.length > 0\n const [showMessageMetaToggle, setShowMessageMetaToggle] = React.useState(false)\n const showMessageMeta =\n showMessageMetaToggle || message.myLatestInConversation || !!pending || !!error || false\n const timestamp = useLiveRelativeTime(message.createdAt)\n const wasEdited = Boolean(message.textEditedAt)\n const isPersisted = !isNewMessage(message)\n const [temporarilyHidePendingState, setTemporarilyHidePendingState] = React.useState(true)\n const [messageBubbleHeight, setMessageBubbleHeight] = React.useState(0)\n const { animatedBackgroundColor, handleMessagePressIn, handleMessagePressOut } =\n useAnimatedMessageBackgroundColor()\n const { message: replyRootMessage } = useConversationMessage({\n conversation_id,\n messageId: message.replyRootId || '',\n enabled: !!message.replyRootId,\n })\n\n const metaProps = {\n authorName: author.name,\n createdAt: message.createdAt,\n }\n\n const renderAuthor = (!message.mine && message.renderAuthor) || false\n const showReplyCountButton = !inReplyScreen && message.replyRootId === message.id\n const isReplyRootMessage = message.replyRootId === message.id\n const isDeletedReplyRootMessage = isReplyRootMessage && !!message.deletedAt\n const replyToReplyRootMessage = !isReplyRootMessage && !!message.replyRootId\n\n const replyCountText = pluralize(message.replyCount, 'reply')\n const messagePendingLabel = isPersisted ? 'Saving' : 'Sending'\n const replyRootAuthorName = message.replyRootId ? replyRootMessage?.author.name : author.name\n const messageText = isDeletedReplyRootMessage ? 'Message deleted' : text\n\n const messageBottomMargin =\n message.lastInGroup || message.nextIsReplyShadowMessage\n ? 16\n : hasReactions || showMessageMeta || showReplyCountButton\n ? 8\n : 4\n\n const messageIsReplyLabel = replyToReplyRootMessage ? 'Reply' : ''\n const attachmentLabel = some(attachments) ? pluralize(attachments.length, 'attachment') : ''\n const replyCountLabel = isReplyRootMessage ? replyCountText : ''\n const accessibilityLabel = `${author?.name || ''} ${messageIsReplyLabel} ${attachmentLabel} ${\n messageText || ''\n } ${timestamp} ${replyCountLabel}`\n\n useEffect(() => {\n if (pending) {\n const timer = setTimeout(() => {\n setTemporarilyHidePendingState(false)\n }, 2000)\n return () => clearTimeout(timer)\n }\n return () => {}\n }, [pending])\n\n const retryFailedSaveMutation = useMessageCreateOrUpdate({\n conversationId: conversation_id,\n message,\n })\n\n const handleRetry = () => {\n if (text && error) {\n retryFailedSaveMutation.mutateAsync({\n text,\n attachments: message.attachmentsForCreate,\n })\n }\n }\n\n const handleMessagePress = () => {\n setShowMessageMetaToggle(!showMessageMetaToggle)\n }\n\n const handleMessageLongPress = () => {\n if (!isPersisted) return\n\n Haptic.impactLight()\n navigation.navigate('MessageActions', {\n message_id: message.id,\n conversation_id,\n canDeleteNonAuthoredMessages,\n inReplyScreen,\n reply_root_author_name: replyRootAuthorName,\n })\n }\n\n const handleReactionLongPress = (reaction: ReactionCountResource) => {\n Haptic.impactLight()\n navigation.navigate('Reactions', {\n message_id: message.id,\n conversation_id,\n reaction_value: reaction.value,\n })\n }\n\n const handleMessageAttachmentLongPress = (attachment: DenormalizedMessageAttachmentResource) => {\n Haptic.impactLight()\n navigation.navigate('AttachmentActions', {\n attachmentId: attachment?.id,\n attachmentContentType: attachment?.attributes.contentType,\n attachmentUrl: attachment?.attributes.url,\n conversation_id,\n canDeleteNonAuthoredMessages,\n myMessage: message.mine,\n })\n }\n\n const handleNavigateToReplyPress = () => {\n navigation.navigate('ConversationReply', {\n conversation_id,\n reply_root_id: message.id,\n reply_root_author_name: author.name,\n })\n }\n\n const accessibilityActions = [\n {\n name: 'navigateToReplies',\n label: 'Navigate to replies',\n },\n ]\n\n const handleAccessibilityAction = (event: AccessibilityActionEvent) => {\n if (event.nativeEvent.actionName === 'navigateToReplies') {\n handleNavigateToReplyPress()\n }\n }\n\n return (\n <Pressable\n onLongPress={isDeleting ? undefined : handleMessageLongPress}\n onPress={isDeleting ? undefined : handleMessagePress}\n onPressIn={isDeleting ? undefined : handleMessagePressIn}\n onPressOut={isDeleting ? undefined : handleMessagePressOut}\n android_ripple={{ color: colors.androidRippleNeutral, borderless: false, foreground: true }}\n accessibilityRole=\"button\"\n accessibilityLabel={accessibilityLabel}\n accessibilityHint=\"Long press to view message actions like reacting and copying.\"\n accessibilityActions={isReplyRootMessage ? accessibilityActions : undefined}\n onAccessibilityAction={isReplyRootMessage ? handleAccessibilityAction : undefined}\n disabled={isDeletedReplyRootMessage || isDeleting}\n >\n <Animated.View style={[styles.message, animatedBackgroundColor]}>\n {!message.mine && (\n <View>\n {renderAuthor ? (\n <Avatar\n size={'md'}\n sourceUri={author.avatar}\n style={styles.avatar}\n maxFontSizeMultiplier={1}\n minFontSizeMultiplier={1}\n fallbackIconName={isDeletedReplyRootMessage ? 'publishing.trash' : 'general.person'}\n showFallback={isDeletedReplyRootMessage}\n />\n ) : (\n <View style={styles.avatarPlaceholder} />\n )}\n <TheirReplyConnector message={message} messageBubbleHeight={messageBubbleHeight} />\n </View>\n )}\n <View style={[styles.messageContent, { marginBottom: messageBottomMargin }]}>\n {renderAuthor && !isDeletedReplyRootMessage && (\n <Text variant=\"footnote\" style={styles.authorName}>\n {author.name}\n </Text>\n )}\n <View\n style={styles.messageBubble}\n onLayout={e => setMessageBubbleHeight(e.nativeEvent.layout.height)}\n >\n {isDeletedReplyRootMessage ? (\n <View style={styles.messageText}>\n <Text style={styles.replyRootDeletedText}>{messageText}</Text>\n </View>\n ) : (\n <>\n <ComponentErrorBoundary>\n <MessageAttachments\n attachments={attachments}\n metaProps={metaProps}\n onMessageAttachmentLongPress={handleMessageAttachmentLongPress}\n onMessageLongPress={handleMessageLongPress}\n />\n </ComponentErrorBoundary>\n {text && (\n <View style={styles.messageText}>\n <MessageMarkdown text={text} />\n </View>\n )}\n </>\n )}\n </View>\n {showReplyCountButton && (\n <TextButton\n variant=\"footnote\"\n onPress={handleNavigateToReplyPress}\n style={styles.messageReplyCount}\n accessibilityHint=\"Navigates to reply screen for this message\"\n accessibilityRole=\"link\"\n >\n {replyCountText}\n </TextButton>\n )}\n {hasReactions && !isDeletedReplyRootMessage && (\n <View style={styles.messageReactions}>\n {reactionCounts.map(reaction => (\n <MessageReaction\n key={reaction.value}\n reaction={reaction}\n onLongPress={handleReactionLongPress}\n message={message}\n conversationId={conversation_id}\n />\n ))}\n </View>\n )}\n {showMessageMeta && !isDeletedReplyRootMessage && (\n <View style={styles.messageMeta}>\n {message.mine && !pending && !error && (\n <MessageReadReceipts\n message={message}\n latestReadMessageSortKey={latestReadMessageSortKey}\n />\n )}\n {error ? (\n <View style={styles.errorContainer}>\n {retryFailedSaveMutation.isPending ? (\n <Spinner size={12} />\n ) : (\n <Icon name=\"general.exclamationTriangle\" size={12} style={styles.errorIcon} />\n )}\n <Text variant=\"footnote\" style={styles.errorText}>\n Failed to {isPersisted ? 'edit' : 'send'} |{' '}\n <TextInlineButton\n onPress={handleRetry}\n variant=\"footnote\"\n appearance=\"danger\"\n disabled={retryFailedSaveMutation.isPending}\n >\n Try again\n </TextInlineButton>\n </Text>\n </View>\n ) : pending && (!temporarilyHidePendingState || isPersisted) ? (\n <View style={styles.pendingIndicatorContainer}>\n <Icon\n name=\"general.outlinedClock\"\n size={12}\n color={colors.iconColorDefaultSecondary}\n />\n <Text variant=\"footnote\">{messagePendingLabel}</Text>\n </View>\n ) : isPersisted ? (\n <Text variant=\"footnote\">{timestamp}</Text>\n ) : null}\n {!pending && !error && wasEdited && (\n <Text variant=\"footnote\">\n |{' '}\n <Text variant=\"footnote\" style={styles.editedText}>\n Edited\n </Text>\n </Text>\n )}\n </View>\n )}\n </View>\n {message.mine && (\n <MyReplyConnector message={message} messageBubbleHeight={messageBubbleHeight} />\n )}\n </Animated.View>\n </Pressable>\n )\n}\n\nconst useMessageStyles = (mine: boolean, isDeleting: boolean) => {\n const { colors } = useTheme()\n const myMessageBackgroundColor = useInteractionGhostBackgroundColor()\n const { width } = useWindowDimensions()\n const tabletWidth = width >= 744 // Smallest iPad Mini's width\n\n const messageBubbleBackgroundColor = mine ? myMessageBackgroundColor : colors.fillColorNeutral070\n\n return StyleSheet.create({\n message: {\n gap: 8,\n flexDirection: mine ? 'row-reverse' : 'row',\n paddingHorizontal: CONVERSATION_MESSAGE_LIST_PADDING_HORIZONTAL,\n opacity: isDeleting ? 0.5 : 1,\n },\n messageContent: {\n flex: 1,\n gap: 4,\n },\n avatar: {\n marginBottom: AVATAR_CONNECTOR_SPACING,\n },\n avatarPlaceholder: {\n width: MESSAGE_AUTHOR_AVATAR_COLUMN_WIDTH, // Same width as avatar\n },\n authorName: {\n fontWeight: platformFontWeightMedium,\n },\n messageBubble: {\n backgroundColor: messageBubbleBackgroundColor,\n borderRadius: 8,\n maxWidth: tabletWidth ? 360 : '80%',\n alignSelf: mine ? 'flex-end' : 'flex-start',\n },\n messageText: {\n paddingVertical: 6,\n paddingHorizontal: 8,\n },\n messageReactions: {\n flexDirection: 'row',\n gap: 4,\n justifyContent: mine ? 'flex-end' : 'flex-start',\n },\n messageReplyCount: {\n alignSelf: mine ? 'flex-end' : 'flex-start',\n },\n messageMeta: {\n flexDirection: 'row',\n alignItems: 'center',\n justifyContent: mine ? 'flex-end' : 'flex-start',\n gap: 4,\n },\n editedText: {\n fontWeight: platformFontWeightMedium,\n },\n pendingIndicatorContainer: {\n flexDirection: 'row',\n alignItems: 'center',\n gap: 4,\n },\n errorContainer: {\n flexDirection: 'row',\n alignItems: 'center',\n gap: 4,\n },\n errorIcon: {\n color: colors.statusErrorIcon,\n },\n errorText: {\n color: colors.statusErrorText,\n },\n replyRootDeletedText: {\n color: colors.textColorDefaultSecondary,\n fontStyle: 'italic',\n },\n })\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"message_form.d.ts","sourceRoot":"","sources":["../../../src/components/conversation/message_form.tsx"],"names":[],"mappings":"AAEA,OAAO,EAQL,SAAS,EAEV,MAAM,cAAc,CAAA;AAiBrB,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"message_form.d.ts","sourceRoot":"","sources":["../../../src/components/conversation/message_form.tsx"],"names":[],"mappings":"AAEA,OAAO,EAQL,SAAS,EAEV,MAAM,cAAc,CAAA;AAiBrB,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AA6BnE,eAAO,MAAM,WAAW;;;;;;CAOvB,CAAA;AAED,UAAU,qBAAsB,SAAQ,SAAS;IAC/C,YAAY,EAAE,oBAAoB,CAAA;IAClC,uBAAuB,CAAC,EAAE,eAAe,GAAG,IAAI,CAAA;IAChD,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,wBAAwB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACxC,sBAAsB,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAA;CAC9C;AAmCD,iBAAS,eAAe,CAAC,EACvB,YAAY,EACZ,uBAAuB,EACvB,QAAQ,EACR,WAAW,EACX,wBAAwB,EACxB,sBAAsB,GACvB,EAAE,qBAAqB,2CA6KvB;AAyID,iBAAS,gBAAgB,4CAwDxB;AAcD,iBAAS,oBAAoB,4CAgD5B;AAED,iBAAS,2BAA2B,mDAuHnC;AAED,iBAAS,mBAAmB,mDAkC3B"}
|
|
@@ -15,6 +15,7 @@ import { MAX_FONT_SIZE_MULTIPLIER_LANDMARK, platformFontWeightMedium, platformPr
|
|
|
15
15
|
import { pickAttachmentPreviewKind } from '../../utils/attachment_kind';
|
|
16
16
|
import { canSubmitMessage } from '../../utils/can_submit_message';
|
|
17
17
|
import { isInputEditable } from '../../utils/is_input_editable';
|
|
18
|
+
import { hasMessageText, stripEmptyTextCharacters } from '../../utils/message_text';
|
|
18
19
|
import { DocumentPicker, Haptic, ImagePicker, } from '../../utils/native_adapters';
|
|
19
20
|
import { tokens } from '../../vendor/tapestry/tokens';
|
|
20
21
|
import { Button } from '../display/button';
|
|
@@ -115,7 +116,7 @@ function MessageFormRoot({ conversation, currentlyEditingMessage, children, repl
|
|
|
115
116
|
conversationDisabled: conversation.disabled ?? false,
|
|
116
117
|
pendingUploads: !!attachmentUploader?.pendingUploads,
|
|
117
118
|
hasFlaggedAttachments: !!attachmentUploader?.flaggedAttachmentCount,
|
|
118
|
-
hasText: text
|
|
119
|
+
hasText: hasMessageText(text),
|
|
119
120
|
hasSendableAttachments: !!attachmentUploader?.attachmentIds?.length,
|
|
120
121
|
});
|
|
121
122
|
const disabled = !canSubmit;
|
|
@@ -160,12 +161,13 @@ function MessageFormRoot({ conversation, currentlyEditingMessage, children, repl
|
|
|
160
161
|
id: attachment.id,
|
|
161
162
|
file: attachment.file,
|
|
162
163
|
}));
|
|
164
|
+
const messageText = stripEmptyTextCharacters(text);
|
|
163
165
|
if (currentlyEditingMessage) {
|
|
164
|
-
mutateAsync({ text });
|
|
166
|
+
mutateAsync({ text: messageText });
|
|
165
167
|
reset();
|
|
166
168
|
}
|
|
167
169
|
else {
|
|
168
|
-
mutateAsync({ text, attachments: attachmentsForSubmit });
|
|
170
|
+
mutateAsync({ text: messageText, attachments: attachmentsForSubmit });
|
|
169
171
|
reset();
|
|
170
172
|
}
|
|
171
173
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"message_form.js","sourceRoot":"","sources":["../../../src/components/conversation/message_form.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useNavigation, useTheme as useNavigationTheme, useRoute } from '@react-navigation/native'\nimport React, { useCallback, useContext, useEffect, useState } from 'react'\nimport {\n Linking,\n Platform,\n Pressable,\n ScrollView,\n StyleSheet,\n TextInput,\n View,\n ViewProps,\n Keyboard,\n} from 'react-native'\nimport LinearGradient from 'react-native-linear-gradient'\nimport { Heading, Icon, IconButton, IconString, Text, TextButton } from '../../components'\nimport { ChatContext } from '../../contexts/chat_context'\nimport {\n useCreateAndroidRippleColor,\n useTheme,\n useInteractionGhostBackgroundColor,\n useScalableNumberOfLines,\n useFontScale,\n} from '../../hooks'\nimport { useAttachmentUploader } from '../../hooks/use_attachment_uploader'\nimport { useBroadcastTypingStatus } from '../../hooks/use_broadcast_typing_status'\nimport { useChatConfiguration } from '../../hooks/use_chat_configuration'\nimport { useMessageCreateOrUpdate } from '../../hooks/use_message_create_or_update'\nimport { useMessageDraft } from '../../hooks/use_message_draft'\nimport { ConversationScreenProps } from '../../screens/conversation_screen'\nimport { ConversationResource, MessageResource } from '../../types'\nimport {\n DenormalizedAttachmentResourceForCreate,\n DenormalizedMessageAttachmentResourceForCreate,\n FileAttachment,\n} from '../../types/resources/denormalized_attachment_resource_for_create'\nimport {\n MAX_FONT_SIZE_MULTIPLIER_LANDMARK,\n platformFontWeightMedium,\n platformPressedOpacityStyle,\n} from '../../utils'\nimport { pickAttachmentPreviewKind } from '../../utils/attachment_kind'\nimport { canSubmitMessage } from '../../utils/can_submit_message'\nimport { isInputEditable } from '../../utils/is_input_editable'\nimport {\n DocumentPicker,\n DocumentPickerResult,\n Haptic,\n ImagePicker,\n ImagePickerResult,\n} from '../../utils/native_adapters'\nimport { tokens } from '../../vendor/tapestry/tokens'\nimport { Button } from '../display/button'\nimport BannerPrimitive from '../primitive/banner_primitive'\nimport { MessageFormAttachmentFile } from './message_form/message_form_attachment_file'\nimport { MessageFormAttachmentImage } from './message_form/message_form_attachment_image'\nimport { MessageFormAttachmentVideo } from './message_form/message_form_attachment_video'\n\nexport const MessageForm = {\n Root: MessageFormRoot,\n\n TextInput: MessageFormInput,\n SubmitButton: MessageFormSubmitBtn,\n AttachmentPicker: MessageFormAttachmentPicker,\n Commands: MessageFormCommands,\n}\n\ninterface MessagesFormRootProps extends ViewProps {\n conversation: ConversationResource\n currentlyEditingMessage?: MessageResource | null\n replyRootId?: string | null\n replyRootAuthorFirstName?: string | null\n onFlaggedInMessageForm?: (id: string) => void\n}\n\nconst MessageFormContext = React.createContext<{\n text: string\n setText: (text: string) => void\n onSubmit: () => void\n disabled: boolean\n inputEditable: boolean\n canGiphy: boolean\n usingGiphy: boolean\n setUsingGiphy: (usingGiphy: boolean) => void\n attachmentUploader?: ReturnType<typeof useAttachmentUploader>\n currentlyEditingMessage?: MessageResource | null\n reset: () => void\n replyRootId?: string | null\n replyRootAuthorFirstName?: string | null\n}>({\n text: '',\n setText: (_text: string) => {},\n onSubmit: () => {},\n disabled: false,\n inputEditable: true,\n canGiphy: false,\n usingGiphy: false,\n setUsingGiphy: (_usingGiphy: boolean) => {},\n currentlyEditingMessage: null,\n reset: () => {},\n replyRootId: undefined,\n replyRootAuthorFirstName: undefined,\n})\n\nconst GIPHY_MAX_LENGTH = 50\nconst MAX_MESSAGE_LENGTH = 5000\nconst PLACEHOLDER_FONT_SCALE_THRESHOLD = 1.7\n\nfunction MessageFormRoot({\n conversation,\n currentlyEditingMessage,\n children,\n replyRootId,\n replyRootAuthorFirstName,\n onFlaggedInMessageForm,\n}: MessagesFormRootProps) {\n const { giphyApiKey } = useContext(ChatContext)\n const canGiphy = !!giphyApiKey && !currentlyEditingMessage\n const styles = useMessageFormStyles()\n const { draft, saveDraft, clearDraft } = useMessageDraft()\n const [text, setText] = React.useState(() => {\n // Initialize from draft only when not editing a message\n return currentlyEditingMessage ? '' : draft?.text || ''\n })\n const [usingGiphy, setUsingGiphy] = useState(false)\n const navigation = useNavigation()\n const route = useRoute() as ConversationScreenProps['route']\n const {\n status,\n isPending,\n reset: resetMutation,\n mutateAsync,\n } = useMessageCreateOrUpdate({\n conversationId: conversation.id,\n message: currentlyEditingMessage || undefined,\n replyRootId,\n })\n const attachmentUploader = useAttachmentUploader({\n conversationId: conversation.id,\n draftAttachments: currentlyEditingMessage ? undefined : draft?.attachments,\n onFlaggedInMessageForm,\n })\n const resetAttachmentUploader = attachmentUploader.reset\n\n const reset = useCallback(() => {\n resetAttachmentUploader()\n resetMutation()\n setText('')\n setUsingGiphy(false)\n if (!currentlyEditingMessage) {\n clearDraft()\n }\n navigation.setParams({\n editing_message_id: null,\n })\n }, [resetAttachmentUploader, resetMutation, navigation, currentlyEditingMessage, clearDraft])\n\n useEffect(() => {\n if (canGiphy && !usingGiphy && text.startsWith('/giphy ')) {\n setUsingGiphy(true)\n setText('')\n }\n }, [canGiphy, text, usingGiphy])\n\n useEffect(() => {\n switch (status) {\n case 'success':\n reset()\n break\n }\n }, [reset, status])\n\n useEffect(() => {\n if (route.params.clear_input) {\n reset()\n navigation.setParams({ ...route.params, clear_input: false })\n }\n }, [reset, navigation, route.params])\n\n // Save draft when text or attachments change (debounced)\n useEffect(() => {\n // Don't save drafts when editing a message\n if (currentlyEditingMessage) return\n\n const timeoutId = setTimeout(() => {\n saveDraft(text, attachmentUploader.attachments)\n }, 500)\n\n return () => clearTimeout(timeoutId)\n }, [text, attachmentUploader.attachments, saveDraft, currentlyEditingMessage])\n\n const canSubmit = canSubmitMessage({\n isPending,\n conversationDisabled: conversation.disabled ?? false,\n pendingUploads: !!attachmentUploader?.pendingUploads,\n hasFlaggedAttachments: !!attachmentUploader?.flaggedAttachmentCount,\n hasText: text.trim().length > 0,\n hasSendableAttachments: !!attachmentUploader?.attachmentIds?.length,\n })\n const disabled = !canSubmit\n const inputEditable = isInputEditable({\n isPending,\n conversationDisabled: conversation.disabled ?? false,\n })\n\n /*\n Opening a FormSheet on Android while the keyboard is visible breaks the FormSheet's height & position.\n This is a workaround to ensure we don't open the FormSheet while the keyboard is visible.\n */\n const navigateToSendGiphyAfterKeyboardHides = useCallback(() => {\n if (!Keyboard.isVisible() || Platform.OS === 'ios') {\n navigation.navigate('SendGiphy', {\n conversation_id: conversation.id,\n search_term: text,\n })\n } else {\n const keyboardListener = Keyboard.addListener('keyboardDidHide', () => {\n navigation.navigate('SendGiphy', {\n conversation_id: conversation.id,\n search_term: text,\n })\n keyboardListener?.remove()\n })\n }\n }, [conversation.id, navigation, text])\n\n const handleSubmit = () => {\n if (!canSubmit) return\n\n if (canGiphy && usingGiphy) {\n TextInput.State.blurTextInput(TextInput.State.currentlyFocusedInput())\n Haptic.impactLight()\n navigateToSendGiphyAfterKeyboardHides()\n } else {\n let attachmentsForSubmit: DenormalizedAttachmentResourceForCreate[] =\n attachmentUploader.attachments\n .filter(a => a.status === 'success' && a.id)\n .map(\n (attachment): DenormalizedMessageAttachmentResourceForCreate => ({\n type: 'MessageAttachment',\n id: attachment.id as string,\n file: attachment.file,\n })\n )\n if (currentlyEditingMessage) {\n mutateAsync({ text })\n reset()\n } else {\n mutateAsync({ text, attachments: attachmentsForSubmit })\n reset()\n }\n }\n }\n\n useEffect(() => {\n if (currentlyEditingMessage) {\n setText(currentlyEditingMessage.text || '')\n }\n }, [currentlyEditingMessage])\n\n return (\n <MessageFormContext.Provider\n value={{\n text,\n setText,\n onSubmit: handleSubmit,\n disabled,\n inputEditable,\n canGiphy,\n usingGiphy,\n setUsingGiphy,\n attachmentUploader,\n currentlyEditingMessage,\n reset,\n replyRootId,\n replyRootAuthorFirstName,\n }}\n >\n <View style={styles.container}>\n <EditingIndicator />\n <ReplyIndicator />\n <FlaggedContentBanner />\n <View style={styles.textInputContainer}>{children}</View>\n </View>\n </MessageFormContext.Provider>\n )\n}\n\nfunction MessageFormAttachments() {\n const styles = useMessageFormStyles()\n const { attachmentUploader } = React.useContext(MessageFormContext)\n const numberOfAttachments = attachmentUploader?.attachments?.length || 0\n const attachments = attachmentUploader?.attachments || []\n\n if (numberOfAttachments === 0) {\n return null\n }\n\n return (\n <ScrollView\n horizontal\n showsHorizontalScrollIndicator={false}\n contentContainerStyle={styles.messageFormAttachments}\n >\n {attachments.map(attachment => {\n const kind = pickAttachmentPreviewKind(attachment.file.type, attachment.file.name)\n const remove = () => attachmentUploader?.removeAttachment(attachment)\n\n if (kind === 'video') {\n return (\n <MessageFormAttachmentVideo\n key={attachment.file.uri}\n name={attachment.file.name}\n status={attachment.status}\n removeAttachment={remove}\n />\n )\n }\n\n if (kind === 'file') {\n return (\n <MessageFormAttachmentFile\n key={attachment.file.uri}\n name={attachment.file.name}\n contentType={attachment.file.type}\n status={attachment.status}\n removeAttachment={remove}\n />\n )\n }\n\n return (\n <MessageFormAttachmentImage\n key={attachment.file.uri}\n uri={attachment.file.uri}\n alt={attachment.file.name}\n status={attachment.status}\n width={attachment.file.width}\n height={attachment.file.height}\n removeAttachment={remove}\n />\n )\n })}\n </ScrollView>\n )\n}\n\nfunction getFileType(attachments: FileAttachment[]): 'image' | 'video' | 'file' {\n const kinds = new Set(\n attachments.map(({ file }) => {\n if (file.type.startsWith('image/')) return 'image'\n if (file.type.startsWith('video/')) return 'video'\n return 'file'\n })\n )\n return kinds.size === 1 ? [...kinds][0] : 'file'\n}\n\nfunction FlaggedContentBanner() {\n const styles = useMessageFormStyles()\n const { attachmentUploader } = React.useContext(MessageFormContext)\n const flaggedAttachments = attachmentUploader?.attachments.filter(a => a.flagged) ?? []\n const flaggedCount = flaggedAttachments.length\n\n if (flaggedCount === 0) return null\n\n const isSingular = flaggedCount === 1\n const fileType = getFileType(flaggedAttachments)\n const buttonTitle = isSingular ? `Remove flagged ${fileType}` : `Remove flagged ${fileType}s`\n\n return (\n <View style={styles.flaggedBannerContainer}>\n <BannerPrimitive.Root appearance=\"error\">\n <BannerPrimitive.StaticLayout>\n <BannerPrimitive.StatusIcon />\n <BannerPrimitive.Content>\n <BannerMessage isSingular={isSingular} fileType={fileType} />\n <View style={styles.flaggedBannerButtonRow}>\n <Button\n title={buttonTitle}\n size=\"sm\"\n appearance=\"danger\"\n onPress={() => attachmentUploader?.removeFlaggedAttachments()}\n accessibilityLabel={buttonTitle}\n />\n </View>\n </BannerPrimitive.Content>\n </BannerPrimitive.StaticLayout>\n </BannerPrimitive.Root>\n </View>\n )\n}\n\nfunction BannerMessage({ isSingular, fileType }: { isSingular: boolean; fileType: string }) {\n const styles = useMessageFormStyles()\n\n const contentGuidelinesLink = (\n <Text\n style={styles.flaggedBannerLink}\n onPress={() =>\n Linking.openURL(\n 'https://www.planningcenter.com/terms#:~:text=4.%20Acceptable%20Use%20of%20Planning%20Center'\n )\n }\n accessibilityRole=\"link\"\n >\n content guidelines\n </Text>\n )\n\n return isSingular ? (\n <Text style={styles.flaggedBannerText}>\n An uploaded {fileType} was flagged because it doesn't meet our {contentGuidelinesLink}. Please\n remove before proceeding.\n </Text>\n ) : (\n <Text style={styles.flaggedBannerText}>\n Some uploaded {fileType}s were flagged because they don't meet our {contentGuidelinesLink}.\n Please remove them before proceeding.\n </Text>\n )\n}\n\nfunction MessageFormInput() {\n const styles = useMessageFormStyles()\n const theme = useTheme()\n const fontScale = useFontScale()\n const { text, setText, onSubmit, inputEditable, usingGiphy, attachmentUploader, replyRootId } =\n React.useContext(MessageFormContext)\n const attachmentError = attachmentUploader?.errorMessage\n\n const broadcastTypingStatus = useBroadcastTypingStatus()\n\n const handleTextChange = (newText: string) => {\n setText(newText)\n\n if (newText.length > 0) {\n broadcastTypingStatus()\n }\n }\n\n const compactPlaceholder = fontScale >= PLACEHOLDER_FONT_SCALE_THRESHOLD\n let placeholder = compactPlaceholder ? 'Message' : 'Send a message'\n if (replyRootId) {\n placeholder = compactPlaceholder ? 'Reply' : 'Send a reply'\n }\n if (usingGiphy) {\n placeholder = compactPlaceholder ? 'Search' : 'Search GIFs'\n }\n\n return (\n <View style={styles.textInputBoundary}>\n <MessageFormAttachments />\n {attachmentError ? <Text style={styles.inputErrorMessage}>{attachmentError}</Text> : null}\n <View style={styles.textInputRow}>\n {usingGiphy ? (\n <View style={styles.giphyBadge}>\n <Icon name=\"general.bolt\" style={styles.giphyBadgeIcon} />\n <Text variant=\"tertiary\" style={styles.giphyBadgeText}>\n /giphy\n </Text>\n </View>\n ) : null}\n\n <TextInput\n style={[styles.textInput, usingGiphy && styles.textInputWithGiphy]}\n multiline={true}\n placeholder={placeholder}\n placeholderTextColor={theme.colors.textColorDefaultPlaceholder}\n onChangeText={handleTextChange}\n value={text}\n maxLength={usingGiphy ? GIPHY_MAX_LENGTH : MAX_MESSAGE_LENGTH}\n onSubmitEditing={onSubmit}\n submitBehavior={usingGiphy ? 'submit' : 'newline'}\n editable={inputEditable}\n />\n </View>\n </View>\n )\n}\n\nconst SUBMIT_ACCESSIBILITY_LABEL_MAP = {\n giphy: 'Search Giphy',\n editing: 'Save changes',\n send: 'Send message',\n} as const\n\nconst SUBMIT_ICON_NAME_MAP = {\n giphy: 'general.search',\n editing: 'general.check',\n send: 'general.upArrow',\n} as const\n\nfunction MessageFormSubmitBtn() {\n const { onSubmit, disabled, usingGiphy, currentlyEditingMessage } =\n React.useContext(MessageFormContext)\n const styles = useMessageFormStyles()\n const { colors } = useTheme()\n\n const formStateKey = usingGiphy ? 'giphy' : currentlyEditingMessage ? 'editing' : 'send'\n const colorKey = disabled ? 'disabled' : 'interaction'\n const interactionStart = colors.buttonStart || colors.interaction\n const interactionEnd = colors.buttonEnd || colors.interaction\n const colorMap = {\n disabled: [\n colors.fillColorButtonNeutralSolidDisabled,\n colors.fillColorButtonNeutralSolidDisabled,\n ],\n interaction: [interactionStart, interactionEnd],\n }\n\n const androidRippleColor = useCreateAndroidRippleColor({ color: colorMap[colorKey][0] })\n const gradientColors = colorMap[colorKey] as [string, string]\n const iconStyles = [styles.submitIcon, disabled && styles.submitIconDisabled]\n\n return (\n <Pressable\n disabled={disabled}\n onPress={onSubmit}\n accessibilityRole=\"button\"\n accessibilityLabel={SUBMIT_ACCESSIBILITY_LABEL_MAP[formStateKey]}\n style={({ pressed }) => [\n styles.submitPressableWrapper,\n pressed && platformPressedOpacityStyle,\n ]}\n android_ripple={{ color: androidRippleColor, borderless: false, foreground: true }}\n >\n <LinearGradient\n start={{ x: 0.1, y: 0.1 }}\n end={{ x: 0.9, y: 0.9 }}\n colors={gradientColors}\n style={styles.submitGradientWrapper}\n >\n <Icon\n name={SUBMIT_ICON_NAME_MAP[formStateKey]}\n style={iconStyles}\n accessibilityElementsHidden={true}\n />\n </LinearGradient>\n </Pressable>\n )\n}\n\nfunction MessageFormAttachmentPicker() {\n const styles = useMessageFormStyles()\n const { usingGiphy, attachmentUploader, currentlyEditingMessage } =\n React.useContext(MessageFormContext)\n const { allowedMimeTypes } = useChatConfiguration()\n const [isOpen, setIsOpen] = useState(false)\n\n function uploadImagePickerResult(result: ImagePickerResult) {\n if (result.canceled) {\n return\n }\n\n const filteredAssets = result.assets\n .filter(asset => {\n return asset.fileSize && asset.mimeType && asset.uri\n })\n .map(asset => {\n return {\n uri: asset.uri,\n name: asset.fileName || asset.uri.split('/').pop() || 'attachment',\n type: asset.mimeType as string,\n size: asset.fileSize as number,\n height: asset.height,\n width: asset.width,\n }\n })\n\n attachmentUploader?.handleFilesAttached(filteredAssets)\n }\n\n function uploadDocumentPickerResult(result: DocumentPickerResult) {\n if (result.canceled) return\n\n const filteredAssets = result.assets\n .filter(asset => asset.size != null && asset.uri)\n .map(asset => ({\n uri: asset.uri,\n name: asset.name,\n type: asset.mimeType || 'application/octet-stream',\n size: asset.size as number,\n }))\n\n attachmentUploader?.handleFilesAttached(filteredAssets)\n }\n\n const openCamera = async () => {\n setIsOpen(false)\n let result = await ImagePicker.openCameraAsync()\n if (!result.canceled) {\n uploadImagePickerResult(result)\n }\n }\n\n const pickImage = async () => {\n setIsOpen(false)\n let result = await ImagePicker.openImageLibraryAsync()\n if (!result.canceled) {\n uploadImagePickerResult(result)\n }\n }\n\n const pickFile = async () => {\n setIsOpen(false)\n let result = await DocumentPicker.openAsync({ mimeTypes: allowedMimeTypes })\n if (!result.canceled) {\n uploadDocumentPickerResult(result)\n }\n }\n\n if (usingGiphy || currentlyEditingMessage) {\n return null\n }\n\n return (\n <View style={styles.attachmentPicker}>\n {isOpen && (\n <View style={styles.attachmentPickerButtonsContainer}>\n <IconButton\n accessibilityLabel=\"Take a photo\"\n accessibilityHint=\"Opens your camera\"\n size=\"lg\"\n appearance=\"neutral\"\n name=\"chat.camera\"\n onPress={openCamera}\n style={styles.attachmentPickerButton}\n />\n <IconButton\n accessibilityLabel=\"Choose a photo\"\n accessibilityHint=\"Opens your photo gallery\"\n size=\"lg\"\n appearance=\"neutral\"\n name=\"churchCenter.photosIos\"\n onPress={pickImage}\n style={styles.attachmentPickerButton}\n />\n {DocumentPicker.configured && (\n <IconButton\n accessibilityLabel=\"Attach a file\"\n accessibilityHint=\"Opens your files to attach documents\"\n size=\"lg\"\n appearance=\"neutral\"\n name=\"general.blankFile\"\n onPress={pickFile}\n style={styles.attachmentPickerButton}\n />\n )}\n </View>\n )}\n <IconButton\n accessibilityLabel=\"File Menu\"\n accessibilityHint=\"Opens options to attach or take a photo\"\n size=\"lg\"\n appearance=\"neutral\"\n name=\"general.paperclip\"\n onPress={() => setIsOpen(!isOpen)}\n style={styles.formButton}\n />\n </View>\n )\n}\n\nfunction MessageFormCommands() {\n const { text, canGiphy, usingGiphy, setUsingGiphy } = React.useContext(MessageFormContext)\n const styles = useMessageFormStyles()\n\n if (!canGiphy) {\n return null\n }\n\n if (usingGiphy) {\n return (\n <IconButton\n accessibilityLabel=\"Exit Giphy Search\"\n accessibilityHint=\"Changes input back to a text field for sending messages\"\n size=\"lg\"\n appearance=\"neutral\"\n name=\"general.xCircle\"\n onPress={() => setUsingGiphy(false)}\n style={styles.formButton}\n />\n )\n }\n\n return (\n <IconButton\n accessibilityLabel=\"Search Giphy\"\n accessibilityHint=\"Changes input into a search field for finding Giphys\"\n size=\"lg\"\n appearance=\"neutral\"\n name={'general.bolt'}\n onPress={() => setUsingGiphy(true)}\n disabled={text.length > GIPHY_MAX_LENGTH}\n style={styles.formButton}\n />\n )\n}\n\nfunction EditingIndicator() {\n const { currentlyEditingMessage, reset } = React.useContext(MessageFormContext)\n\n if (!currentlyEditingMessage) {\n return null\n }\n\n return (\n <FormIndicatorRow\n title=\"Editing message\"\n buttonText=\"Cancel\"\n accessibilityHint=\"Exit message editing mode without saving\"\n iconName=\"accounts.editor\"\n onPress={() => reset()}\n />\n )\n}\n\nfunction ReplyIndicator() {\n const { replyRootId, replyRootAuthorFirstName } = React.useContext(MessageFormContext)\n const navigation = useNavigation()\n const title = replyRootAuthorFirstName ? `Reply to ${replyRootAuthorFirstName}` : 'Reply'\n\n if (!replyRootId) return null\n\n return (\n <FormIndicatorRow\n title={title}\n buttonText=\"Exit replies\"\n accessibilityHint=\"Return to the main conversation\"\n iconName=\"registrations.undo\"\n onPress={() => navigation.goBack()}\n />\n )\n}\n\ninterface FormIndicatorRowProps {\n title: string\n buttonText: string\n accessibilityHint: string\n onPress: () => void\n iconName: IconString\n}\n\nfunction FormIndicatorRow({\n title,\n buttonText,\n accessibilityHint,\n iconName,\n onPress,\n}: FormIndicatorRowProps) {\n const styles = useMessageFormStyles()\n const scalableNumberOfLines = useScalableNumberOfLines(1)\n\n return (\n <View style={styles.formIndicatorRow}>\n <View style={styles.formIndicatorRowTitleContainer}>\n <Icon name={iconName} size={16} style={styles.formIndicatorRowIcon} />\n <Heading\n variant=\"h4\"\n style={styles.formIndicatorRowTitle}\n numberOfLines={scalableNumberOfLines}\n maxFontSizeMultiplier={MAX_FONT_SIZE_MULTIPLIER_LANDMARK}\n >\n {title}\n </Heading>\n </View>\n <TextButton\n onPress={onPress}\n accessibilityHint={accessibilityHint}\n maxFontSizeMultiplier={MAX_FONT_SIZE_MULTIPLIER_LANDMARK}\n >\n {buttonText}\n </TextButton>\n </View>\n )\n}\n\nconst useMessageFormStyles = () => {\n const theme = useTheme()\n const navigationTheme = useNavigationTheme()\n const buttonSize = 38\n\n const giphyBadgeBackgroundColor = useInteractionGhostBackgroundColor()\n\n return StyleSheet.create({\n container: {\n borderColor: theme.colors.borderColorDefaultDim,\n borderTopWidth: 1,\n padding: 12,\n },\n textInputContainer: {\n backgroundColor: navigationTheme.colors.card,\n flexDirection: 'row',\n alignItems: 'flex-end',\n gap: 16,\n },\n textInputBoundary: {\n overflow: 'hidden',\n borderRadius: 24,\n borderWidth: 1,\n borderColor: theme.colors.fillColorNeutral050Base,\n flex: 1,\n gap: 8,\n },\n textInputRow: {\n flexDirection: 'row',\n alignItems: 'center',\n gap: 8,\n },\n textInput: {\n paddingBottom: 8,\n // TODO: Remove iOS's extra top padding and use `textAlignVertical: \"center\"` for both platforms when services-react-native upgrades to v0.74.5 or greater.\n paddingTop: Platform.select({\n ios: 9, // Extra padding compensates for `textAlignVertical` not working in Services iOS.\n default: 8,\n }),\n textAlignVertical: Platform.select({\n ios: 'top', // Services iOS doesn't support `textAlignVertical` due to its lower React Native version of 0.72.14. (React Native 0.74.5+ seems to support this style.)\n default: 'center', // centers the text vertically for multiline TextInput.\n }),\n paddingHorizontal: 16,\n color: theme.colors.textColorDefaultPrimary,\n justifyContent: 'center',\n flex: 1,\n fontSize: 16,\n maxHeight: 200,\n },\n textInputWithGiphy: {\n paddingLeft: 0,\n },\n giphyBadge: {\n backgroundColor: giphyBadgeBackgroundColor,\n borderRadius: 24,\n paddingVertical: 4,\n paddingHorizontal: 12,\n marginLeft: 6,\n flexDirection: 'row',\n alignItems: 'center',\n gap: 4,\n },\n giphyBadgeText: {\n color: theme.colors.interaction,\n marginBottom: 1,\n },\n giphyBadgeIcon: {\n color: theme.colors.interaction,\n },\n formButton: {\n height: buttonSize,\n },\n submitPressableWrapper: {\n borderRadius: buttonSize,\n overflow: 'hidden',\n },\n submitGradientWrapper: {\n flexDirection: 'row',\n justifyContent: 'center',\n alignItems: 'center',\n borderRadius: buttonSize,\n height: buttonSize,\n width: buttonSize,\n },\n submitIcon: {\n fontSize: 16,\n color: tokens.colorNeutral100White,\n },\n submitIconDisabled: {\n color: theme.colors.iconColorDefaultDisabled,\n },\n attachmentPicker: {\n position: 'relative',\n },\n attachmentPickerButtonsContainer: {\n position: 'absolute',\n left: 0,\n bottom: 40,\n zIndex: 10,\n gap: 12,\n },\n attachmentPickerButton: {\n backgroundColor: theme.colors.fillColorNeutral070,\n borderRadius: 20,\n height: buttonSize,\n width: buttonSize,\n elevation: 3,\n ...Platform.select({\n ios: {\n borderWidth: 1,\n borderColor: theme.colors.borderColorDefaultBase,\n },\n default: null,\n }),\n },\n messageFormAttachments: {\n overflow: 'hidden',\n paddingHorizontal: 12,\n paddingTop: 12,\n gap: 8,\n },\n inputErrorMessage: {\n color: theme.colors.statusErrorText,\n fontSize: 14,\n paddingHorizontal: 16,\n paddingVertical: 4,\n },\n flaggedBannerContainer: {\n paddingBottom: 12,\n },\n flaggedBannerText: {\n color: theme.colors.textColorDefaultPrimary,\n fontSize: 14,\n },\n flaggedBannerLink: {\n color: theme.colors.textColorDefaultPrimary,\n fontSize: 14,\n textDecorationLine: 'underline' as const,\n },\n flaggedBannerButtonRow: {\n flexDirection: 'row',\n justifyContent: 'flex-end',\n marginTop: 4,\n },\n formIndicatorRow: {\n flexDirection: 'row',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: 8,\n paddingBottom: 12,\n },\n formIndicatorRowTitleContainer: {\n flexDirection: 'row',\n alignItems: 'center',\n gap: 8,\n flex: 1,\n },\n formIndicatorRowIcon: {\n color: theme.colors.iconColorDefaultSecondary,\n },\n formIndicatorRowTitle: {\n fontWeight: platformFontWeightMedium,\n textTransform: 'none',\n flexShrink: 1,\n },\n })\n}\n"]}
|
|
1
|
+
{"version":3,"file":"message_form.js","sourceRoot":"","sources":["../../../src/components/conversation/message_form.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useNavigation, useTheme as useNavigationTheme, useRoute } from '@react-navigation/native'\nimport React, { useCallback, useContext, useEffect, useState } from 'react'\nimport {\n Linking,\n Platform,\n Pressable,\n ScrollView,\n StyleSheet,\n TextInput,\n View,\n ViewProps,\n Keyboard,\n} from 'react-native'\nimport LinearGradient from 'react-native-linear-gradient'\nimport { Heading, Icon, IconButton, IconString, Text, TextButton } from '../../components'\nimport { ChatContext } from '../../contexts/chat_context'\nimport {\n useCreateAndroidRippleColor,\n useTheme,\n useInteractionGhostBackgroundColor,\n useScalableNumberOfLines,\n useFontScale,\n} from '../../hooks'\nimport { useAttachmentUploader } from '../../hooks/use_attachment_uploader'\nimport { useBroadcastTypingStatus } from '../../hooks/use_broadcast_typing_status'\nimport { useChatConfiguration } from '../../hooks/use_chat_configuration'\nimport { useMessageCreateOrUpdate } from '../../hooks/use_message_create_or_update'\nimport { useMessageDraft } from '../../hooks/use_message_draft'\nimport { ConversationScreenProps } from '../../screens/conversation_screen'\nimport { ConversationResource, MessageResource } from '../../types'\nimport {\n DenormalizedAttachmentResourceForCreate,\n DenormalizedMessageAttachmentResourceForCreate,\n FileAttachment,\n} from '../../types/resources/denormalized_attachment_resource_for_create'\nimport {\n MAX_FONT_SIZE_MULTIPLIER_LANDMARK,\n platformFontWeightMedium,\n platformPressedOpacityStyle,\n} from '../../utils'\nimport { pickAttachmentPreviewKind } from '../../utils/attachment_kind'\nimport { canSubmitMessage } from '../../utils/can_submit_message'\nimport { isInputEditable } from '../../utils/is_input_editable'\nimport { hasMessageText, stripEmptyTextCharacters } from '../../utils/message_text'\nimport {\n DocumentPicker,\n DocumentPickerResult,\n Haptic,\n ImagePicker,\n ImagePickerResult,\n} from '../../utils/native_adapters'\nimport { tokens } from '../../vendor/tapestry/tokens'\nimport { Button } from '../display/button'\nimport BannerPrimitive from '../primitive/banner_primitive'\nimport { MessageFormAttachmentFile } from './message_form/message_form_attachment_file'\nimport { MessageFormAttachmentImage } from './message_form/message_form_attachment_image'\nimport { MessageFormAttachmentVideo } from './message_form/message_form_attachment_video'\n\nexport const MessageForm = {\n Root: MessageFormRoot,\n\n TextInput: MessageFormInput,\n SubmitButton: MessageFormSubmitBtn,\n AttachmentPicker: MessageFormAttachmentPicker,\n Commands: MessageFormCommands,\n}\n\ninterface MessagesFormRootProps extends ViewProps {\n conversation: ConversationResource\n currentlyEditingMessage?: MessageResource | null\n replyRootId?: string | null\n replyRootAuthorFirstName?: string | null\n onFlaggedInMessageForm?: (id: string) => void\n}\n\nconst MessageFormContext = React.createContext<{\n text: string\n setText: (text: string) => void\n onSubmit: () => void\n disabled: boolean\n inputEditable: boolean\n canGiphy: boolean\n usingGiphy: boolean\n setUsingGiphy: (usingGiphy: boolean) => void\n attachmentUploader?: ReturnType<typeof useAttachmentUploader>\n currentlyEditingMessage?: MessageResource | null\n reset: () => void\n replyRootId?: string | null\n replyRootAuthorFirstName?: string | null\n}>({\n text: '',\n setText: (_text: string) => {},\n onSubmit: () => {},\n disabled: false,\n inputEditable: true,\n canGiphy: false,\n usingGiphy: false,\n setUsingGiphy: (_usingGiphy: boolean) => {},\n currentlyEditingMessage: null,\n reset: () => {},\n replyRootId: undefined,\n replyRootAuthorFirstName: undefined,\n})\n\nconst GIPHY_MAX_LENGTH = 50\nconst MAX_MESSAGE_LENGTH = 5000\nconst PLACEHOLDER_FONT_SCALE_THRESHOLD = 1.7\n\nfunction MessageFormRoot({\n conversation,\n currentlyEditingMessage,\n children,\n replyRootId,\n replyRootAuthorFirstName,\n onFlaggedInMessageForm,\n}: MessagesFormRootProps) {\n const { giphyApiKey } = useContext(ChatContext)\n const canGiphy = !!giphyApiKey && !currentlyEditingMessage\n const styles = useMessageFormStyles()\n const { draft, saveDraft, clearDraft } = useMessageDraft()\n const [text, setText] = React.useState(() => {\n // Initialize from draft only when not editing a message\n return currentlyEditingMessage ? '' : draft?.text || ''\n })\n const [usingGiphy, setUsingGiphy] = useState(false)\n const navigation = useNavigation()\n const route = useRoute() as ConversationScreenProps['route']\n const {\n status,\n isPending,\n reset: resetMutation,\n mutateAsync,\n } = useMessageCreateOrUpdate({\n conversationId: conversation.id,\n message: currentlyEditingMessage || undefined,\n replyRootId,\n })\n const attachmentUploader = useAttachmentUploader({\n conversationId: conversation.id,\n draftAttachments: currentlyEditingMessage ? undefined : draft?.attachments,\n onFlaggedInMessageForm,\n })\n const resetAttachmentUploader = attachmentUploader.reset\n\n const reset = useCallback(() => {\n resetAttachmentUploader()\n resetMutation()\n setText('')\n setUsingGiphy(false)\n if (!currentlyEditingMessage) {\n clearDraft()\n }\n navigation.setParams({\n editing_message_id: null,\n })\n }, [resetAttachmentUploader, resetMutation, navigation, currentlyEditingMessage, clearDraft])\n\n useEffect(() => {\n if (canGiphy && !usingGiphy && text.startsWith('/giphy ')) {\n setUsingGiphy(true)\n setText('')\n }\n }, [canGiphy, text, usingGiphy])\n\n useEffect(() => {\n switch (status) {\n case 'success':\n reset()\n break\n }\n }, [reset, status])\n\n useEffect(() => {\n if (route.params.clear_input) {\n reset()\n navigation.setParams({ ...route.params, clear_input: false })\n }\n }, [reset, navigation, route.params])\n\n // Save draft when text or attachments change (debounced)\n useEffect(() => {\n // Don't save drafts when editing a message\n if (currentlyEditingMessage) return\n\n const timeoutId = setTimeout(() => {\n saveDraft(text, attachmentUploader.attachments)\n }, 500)\n\n return () => clearTimeout(timeoutId)\n }, [text, attachmentUploader.attachments, saveDraft, currentlyEditingMessage])\n\n const canSubmit = canSubmitMessage({\n isPending,\n conversationDisabled: conversation.disabled ?? false,\n pendingUploads: !!attachmentUploader?.pendingUploads,\n hasFlaggedAttachments: !!attachmentUploader?.flaggedAttachmentCount,\n hasText: hasMessageText(text),\n hasSendableAttachments: !!attachmentUploader?.attachmentIds?.length,\n })\n const disabled = !canSubmit\n const inputEditable = isInputEditable({\n isPending,\n conversationDisabled: conversation.disabled ?? false,\n })\n\n /*\n Opening a FormSheet on Android while the keyboard is visible breaks the FormSheet's height & position.\n This is a workaround to ensure we don't open the FormSheet while the keyboard is visible.\n */\n const navigateToSendGiphyAfterKeyboardHides = useCallback(() => {\n if (!Keyboard.isVisible() || Platform.OS === 'ios') {\n navigation.navigate('SendGiphy', {\n conversation_id: conversation.id,\n search_term: text,\n })\n } else {\n const keyboardListener = Keyboard.addListener('keyboardDidHide', () => {\n navigation.navigate('SendGiphy', {\n conversation_id: conversation.id,\n search_term: text,\n })\n keyboardListener?.remove()\n })\n }\n }, [conversation.id, navigation, text])\n\n const handleSubmit = () => {\n if (!canSubmit) return\n\n if (canGiphy && usingGiphy) {\n TextInput.State.blurTextInput(TextInput.State.currentlyFocusedInput())\n Haptic.impactLight()\n navigateToSendGiphyAfterKeyboardHides()\n } else {\n let attachmentsForSubmit: DenormalizedAttachmentResourceForCreate[] =\n attachmentUploader.attachments\n .filter(a => a.status === 'success' && a.id)\n .map(\n (attachment): DenormalizedMessageAttachmentResourceForCreate => ({\n type: 'MessageAttachment',\n id: attachment.id as string,\n file: attachment.file,\n })\n )\n const messageText = stripEmptyTextCharacters(text)\n\n if (currentlyEditingMessage) {\n mutateAsync({ text: messageText })\n reset()\n } else {\n mutateAsync({ text: messageText, attachments: attachmentsForSubmit })\n reset()\n }\n }\n }\n\n useEffect(() => {\n if (currentlyEditingMessage) {\n setText(currentlyEditingMessage.text || '')\n }\n }, [currentlyEditingMessage])\n\n return (\n <MessageFormContext.Provider\n value={{\n text,\n setText,\n onSubmit: handleSubmit,\n disabled,\n inputEditable,\n canGiphy,\n usingGiphy,\n setUsingGiphy,\n attachmentUploader,\n currentlyEditingMessage,\n reset,\n replyRootId,\n replyRootAuthorFirstName,\n }}\n >\n <View style={styles.container}>\n <EditingIndicator />\n <ReplyIndicator />\n <FlaggedContentBanner />\n <View style={styles.textInputContainer}>{children}</View>\n </View>\n </MessageFormContext.Provider>\n )\n}\n\nfunction MessageFormAttachments() {\n const styles = useMessageFormStyles()\n const { attachmentUploader } = React.useContext(MessageFormContext)\n const numberOfAttachments = attachmentUploader?.attachments?.length || 0\n const attachments = attachmentUploader?.attachments || []\n\n if (numberOfAttachments === 0) {\n return null\n }\n\n return (\n <ScrollView\n horizontal\n showsHorizontalScrollIndicator={false}\n contentContainerStyle={styles.messageFormAttachments}\n >\n {attachments.map(attachment => {\n const kind = pickAttachmentPreviewKind(attachment.file.type, attachment.file.name)\n const remove = () => attachmentUploader?.removeAttachment(attachment)\n\n if (kind === 'video') {\n return (\n <MessageFormAttachmentVideo\n key={attachment.file.uri}\n name={attachment.file.name}\n status={attachment.status}\n removeAttachment={remove}\n />\n )\n }\n\n if (kind === 'file') {\n return (\n <MessageFormAttachmentFile\n key={attachment.file.uri}\n name={attachment.file.name}\n contentType={attachment.file.type}\n status={attachment.status}\n removeAttachment={remove}\n />\n )\n }\n\n return (\n <MessageFormAttachmentImage\n key={attachment.file.uri}\n uri={attachment.file.uri}\n alt={attachment.file.name}\n status={attachment.status}\n width={attachment.file.width}\n height={attachment.file.height}\n removeAttachment={remove}\n />\n )\n })}\n </ScrollView>\n )\n}\n\nfunction getFileType(attachments: FileAttachment[]): 'image' | 'video' | 'file' {\n const kinds = new Set(\n attachments.map(({ file }) => {\n if (file.type.startsWith('image/')) return 'image'\n if (file.type.startsWith('video/')) return 'video'\n return 'file'\n })\n )\n return kinds.size === 1 ? [...kinds][0] : 'file'\n}\n\nfunction FlaggedContentBanner() {\n const styles = useMessageFormStyles()\n const { attachmentUploader } = React.useContext(MessageFormContext)\n const flaggedAttachments = attachmentUploader?.attachments.filter(a => a.flagged) ?? []\n const flaggedCount = flaggedAttachments.length\n\n if (flaggedCount === 0) return null\n\n const isSingular = flaggedCount === 1\n const fileType = getFileType(flaggedAttachments)\n const buttonTitle = isSingular ? `Remove flagged ${fileType}` : `Remove flagged ${fileType}s`\n\n return (\n <View style={styles.flaggedBannerContainer}>\n <BannerPrimitive.Root appearance=\"error\">\n <BannerPrimitive.StaticLayout>\n <BannerPrimitive.StatusIcon />\n <BannerPrimitive.Content>\n <BannerMessage isSingular={isSingular} fileType={fileType} />\n <View style={styles.flaggedBannerButtonRow}>\n <Button\n title={buttonTitle}\n size=\"sm\"\n appearance=\"danger\"\n onPress={() => attachmentUploader?.removeFlaggedAttachments()}\n accessibilityLabel={buttonTitle}\n />\n </View>\n </BannerPrimitive.Content>\n </BannerPrimitive.StaticLayout>\n </BannerPrimitive.Root>\n </View>\n )\n}\n\nfunction BannerMessage({ isSingular, fileType }: { isSingular: boolean; fileType: string }) {\n const styles = useMessageFormStyles()\n\n const contentGuidelinesLink = (\n <Text\n style={styles.flaggedBannerLink}\n onPress={() =>\n Linking.openURL(\n 'https://www.planningcenter.com/terms#:~:text=4.%20Acceptable%20Use%20of%20Planning%20Center'\n )\n }\n accessibilityRole=\"link\"\n >\n content guidelines\n </Text>\n )\n\n return isSingular ? (\n <Text style={styles.flaggedBannerText}>\n An uploaded {fileType} was flagged because it doesn't meet our {contentGuidelinesLink}. Please\n remove before proceeding.\n </Text>\n ) : (\n <Text style={styles.flaggedBannerText}>\n Some uploaded {fileType}s were flagged because they don't meet our {contentGuidelinesLink}.\n Please remove them before proceeding.\n </Text>\n )\n}\n\nfunction MessageFormInput() {\n const styles = useMessageFormStyles()\n const theme = useTheme()\n const fontScale = useFontScale()\n const { text, setText, onSubmit, inputEditable, usingGiphy, attachmentUploader, replyRootId } =\n React.useContext(MessageFormContext)\n const attachmentError = attachmentUploader?.errorMessage\n\n const broadcastTypingStatus = useBroadcastTypingStatus()\n\n const handleTextChange = (newText: string) => {\n setText(newText)\n\n if (newText.length > 0) {\n broadcastTypingStatus()\n }\n }\n\n const compactPlaceholder = fontScale >= PLACEHOLDER_FONT_SCALE_THRESHOLD\n let placeholder = compactPlaceholder ? 'Message' : 'Send a message'\n if (replyRootId) {\n placeholder = compactPlaceholder ? 'Reply' : 'Send a reply'\n }\n if (usingGiphy) {\n placeholder = compactPlaceholder ? 'Search' : 'Search GIFs'\n }\n\n return (\n <View style={styles.textInputBoundary}>\n <MessageFormAttachments />\n {attachmentError ? <Text style={styles.inputErrorMessage}>{attachmentError}</Text> : null}\n <View style={styles.textInputRow}>\n {usingGiphy ? (\n <View style={styles.giphyBadge}>\n <Icon name=\"general.bolt\" style={styles.giphyBadgeIcon} />\n <Text variant=\"tertiary\" style={styles.giphyBadgeText}>\n /giphy\n </Text>\n </View>\n ) : null}\n\n <TextInput\n style={[styles.textInput, usingGiphy && styles.textInputWithGiphy]}\n multiline={true}\n placeholder={placeholder}\n placeholderTextColor={theme.colors.textColorDefaultPlaceholder}\n onChangeText={handleTextChange}\n value={text}\n maxLength={usingGiphy ? GIPHY_MAX_LENGTH : MAX_MESSAGE_LENGTH}\n onSubmitEditing={onSubmit}\n submitBehavior={usingGiphy ? 'submit' : 'newline'}\n editable={inputEditable}\n />\n </View>\n </View>\n )\n}\n\nconst SUBMIT_ACCESSIBILITY_LABEL_MAP = {\n giphy: 'Search Giphy',\n editing: 'Save changes',\n send: 'Send message',\n} as const\n\nconst SUBMIT_ICON_NAME_MAP = {\n giphy: 'general.search',\n editing: 'general.check',\n send: 'general.upArrow',\n} as const\n\nfunction MessageFormSubmitBtn() {\n const { onSubmit, disabled, usingGiphy, currentlyEditingMessage } =\n React.useContext(MessageFormContext)\n const styles = useMessageFormStyles()\n const { colors } = useTheme()\n\n const formStateKey = usingGiphy ? 'giphy' : currentlyEditingMessage ? 'editing' : 'send'\n const colorKey = disabled ? 'disabled' : 'interaction'\n const interactionStart = colors.buttonStart || colors.interaction\n const interactionEnd = colors.buttonEnd || colors.interaction\n const colorMap = {\n disabled: [\n colors.fillColorButtonNeutralSolidDisabled,\n colors.fillColorButtonNeutralSolidDisabled,\n ],\n interaction: [interactionStart, interactionEnd],\n }\n\n const androidRippleColor = useCreateAndroidRippleColor({ color: colorMap[colorKey][0] })\n const gradientColors = colorMap[colorKey] as [string, string]\n const iconStyles = [styles.submitIcon, disabled && styles.submitIconDisabled]\n\n return (\n <Pressable\n disabled={disabled}\n onPress={onSubmit}\n accessibilityRole=\"button\"\n accessibilityLabel={SUBMIT_ACCESSIBILITY_LABEL_MAP[formStateKey]}\n style={({ pressed }) => [\n styles.submitPressableWrapper,\n pressed && platformPressedOpacityStyle,\n ]}\n android_ripple={{ color: androidRippleColor, borderless: false, foreground: true }}\n >\n <LinearGradient\n start={{ x: 0.1, y: 0.1 }}\n end={{ x: 0.9, y: 0.9 }}\n colors={gradientColors}\n style={styles.submitGradientWrapper}\n >\n <Icon\n name={SUBMIT_ICON_NAME_MAP[formStateKey]}\n style={iconStyles}\n accessibilityElementsHidden={true}\n />\n </LinearGradient>\n </Pressable>\n )\n}\n\nfunction MessageFormAttachmentPicker() {\n const styles = useMessageFormStyles()\n const { usingGiphy, attachmentUploader, currentlyEditingMessage } =\n React.useContext(MessageFormContext)\n const { allowedMimeTypes } = useChatConfiguration()\n const [isOpen, setIsOpen] = useState(false)\n\n function uploadImagePickerResult(result: ImagePickerResult) {\n if (result.canceled) {\n return\n }\n\n const filteredAssets = result.assets\n .filter(asset => {\n return asset.fileSize && asset.mimeType && asset.uri\n })\n .map(asset => {\n return {\n uri: asset.uri,\n name: asset.fileName || asset.uri.split('/').pop() || 'attachment',\n type: asset.mimeType as string,\n size: asset.fileSize as number,\n height: asset.height,\n width: asset.width,\n }\n })\n\n attachmentUploader?.handleFilesAttached(filteredAssets)\n }\n\n function uploadDocumentPickerResult(result: DocumentPickerResult) {\n if (result.canceled) return\n\n const filteredAssets = result.assets\n .filter(asset => asset.size != null && asset.uri)\n .map(asset => ({\n uri: asset.uri,\n name: asset.name,\n type: asset.mimeType || 'application/octet-stream',\n size: asset.size as number,\n }))\n\n attachmentUploader?.handleFilesAttached(filteredAssets)\n }\n\n const openCamera = async () => {\n setIsOpen(false)\n let result = await ImagePicker.openCameraAsync()\n if (!result.canceled) {\n uploadImagePickerResult(result)\n }\n }\n\n const pickImage = async () => {\n setIsOpen(false)\n let result = await ImagePicker.openImageLibraryAsync()\n if (!result.canceled) {\n uploadImagePickerResult(result)\n }\n }\n\n const pickFile = async () => {\n setIsOpen(false)\n let result = await DocumentPicker.openAsync({ mimeTypes: allowedMimeTypes })\n if (!result.canceled) {\n uploadDocumentPickerResult(result)\n }\n }\n\n if (usingGiphy || currentlyEditingMessage) {\n return null\n }\n\n return (\n <View style={styles.attachmentPicker}>\n {isOpen && (\n <View style={styles.attachmentPickerButtonsContainer}>\n <IconButton\n accessibilityLabel=\"Take a photo\"\n accessibilityHint=\"Opens your camera\"\n size=\"lg\"\n appearance=\"neutral\"\n name=\"chat.camera\"\n onPress={openCamera}\n style={styles.attachmentPickerButton}\n />\n <IconButton\n accessibilityLabel=\"Choose a photo\"\n accessibilityHint=\"Opens your photo gallery\"\n size=\"lg\"\n appearance=\"neutral\"\n name=\"churchCenter.photosIos\"\n onPress={pickImage}\n style={styles.attachmentPickerButton}\n />\n {DocumentPicker.configured && (\n <IconButton\n accessibilityLabel=\"Attach a file\"\n accessibilityHint=\"Opens your files to attach documents\"\n size=\"lg\"\n appearance=\"neutral\"\n name=\"general.blankFile\"\n onPress={pickFile}\n style={styles.attachmentPickerButton}\n />\n )}\n </View>\n )}\n <IconButton\n accessibilityLabel=\"File Menu\"\n accessibilityHint=\"Opens options to attach or take a photo\"\n size=\"lg\"\n appearance=\"neutral\"\n name=\"general.paperclip\"\n onPress={() => setIsOpen(!isOpen)}\n style={styles.formButton}\n />\n </View>\n )\n}\n\nfunction MessageFormCommands() {\n const { text, canGiphy, usingGiphy, setUsingGiphy } = React.useContext(MessageFormContext)\n const styles = useMessageFormStyles()\n\n if (!canGiphy) {\n return null\n }\n\n if (usingGiphy) {\n return (\n <IconButton\n accessibilityLabel=\"Exit Giphy Search\"\n accessibilityHint=\"Changes input back to a text field for sending messages\"\n size=\"lg\"\n appearance=\"neutral\"\n name=\"general.xCircle\"\n onPress={() => setUsingGiphy(false)}\n style={styles.formButton}\n />\n )\n }\n\n return (\n <IconButton\n accessibilityLabel=\"Search Giphy\"\n accessibilityHint=\"Changes input into a search field for finding Giphys\"\n size=\"lg\"\n appearance=\"neutral\"\n name={'general.bolt'}\n onPress={() => setUsingGiphy(true)}\n disabled={text.length > GIPHY_MAX_LENGTH}\n style={styles.formButton}\n />\n )\n}\n\nfunction EditingIndicator() {\n const { currentlyEditingMessage, reset } = React.useContext(MessageFormContext)\n\n if (!currentlyEditingMessage) {\n return null\n }\n\n return (\n <FormIndicatorRow\n title=\"Editing message\"\n buttonText=\"Cancel\"\n accessibilityHint=\"Exit message editing mode without saving\"\n iconName=\"accounts.editor\"\n onPress={() => reset()}\n />\n )\n}\n\nfunction ReplyIndicator() {\n const { replyRootId, replyRootAuthorFirstName } = React.useContext(MessageFormContext)\n const navigation = useNavigation()\n const title = replyRootAuthorFirstName ? `Reply to ${replyRootAuthorFirstName}` : 'Reply'\n\n if (!replyRootId) return null\n\n return (\n <FormIndicatorRow\n title={title}\n buttonText=\"Exit replies\"\n accessibilityHint=\"Return to the main conversation\"\n iconName=\"registrations.undo\"\n onPress={() => navigation.goBack()}\n />\n )\n}\n\ninterface FormIndicatorRowProps {\n title: string\n buttonText: string\n accessibilityHint: string\n onPress: () => void\n iconName: IconString\n}\n\nfunction FormIndicatorRow({\n title,\n buttonText,\n accessibilityHint,\n iconName,\n onPress,\n}: FormIndicatorRowProps) {\n const styles = useMessageFormStyles()\n const scalableNumberOfLines = useScalableNumberOfLines(1)\n\n return (\n <View style={styles.formIndicatorRow}>\n <View style={styles.formIndicatorRowTitleContainer}>\n <Icon name={iconName} size={16} style={styles.formIndicatorRowIcon} />\n <Heading\n variant=\"h4\"\n style={styles.formIndicatorRowTitle}\n numberOfLines={scalableNumberOfLines}\n maxFontSizeMultiplier={MAX_FONT_SIZE_MULTIPLIER_LANDMARK}\n >\n {title}\n </Heading>\n </View>\n <TextButton\n onPress={onPress}\n accessibilityHint={accessibilityHint}\n maxFontSizeMultiplier={MAX_FONT_SIZE_MULTIPLIER_LANDMARK}\n >\n {buttonText}\n </TextButton>\n </View>\n )\n}\n\nconst useMessageFormStyles = () => {\n const theme = useTheme()\n const navigationTheme = useNavigationTheme()\n const buttonSize = 38\n\n const giphyBadgeBackgroundColor = useInteractionGhostBackgroundColor()\n\n return StyleSheet.create({\n container: {\n borderColor: theme.colors.borderColorDefaultDim,\n borderTopWidth: 1,\n padding: 12,\n },\n textInputContainer: {\n backgroundColor: navigationTheme.colors.card,\n flexDirection: 'row',\n alignItems: 'flex-end',\n gap: 16,\n },\n textInputBoundary: {\n overflow: 'hidden',\n borderRadius: 24,\n borderWidth: 1,\n borderColor: theme.colors.fillColorNeutral050Base,\n flex: 1,\n gap: 8,\n },\n textInputRow: {\n flexDirection: 'row',\n alignItems: 'center',\n gap: 8,\n },\n textInput: {\n paddingBottom: 8,\n // TODO: Remove iOS's extra top padding and use `textAlignVertical: \"center\"` for both platforms when services-react-native upgrades to v0.74.5 or greater.\n paddingTop: Platform.select({\n ios: 9, // Extra padding compensates for `textAlignVertical` not working in Services iOS.\n default: 8,\n }),\n textAlignVertical: Platform.select({\n ios: 'top', // Services iOS doesn't support `textAlignVertical` due to its lower React Native version of 0.72.14. (React Native 0.74.5+ seems to support this style.)\n default: 'center', // centers the text vertically for multiline TextInput.\n }),\n paddingHorizontal: 16,\n color: theme.colors.textColorDefaultPrimary,\n justifyContent: 'center',\n flex: 1,\n fontSize: 16,\n maxHeight: 200,\n },\n textInputWithGiphy: {\n paddingLeft: 0,\n },\n giphyBadge: {\n backgroundColor: giphyBadgeBackgroundColor,\n borderRadius: 24,\n paddingVertical: 4,\n paddingHorizontal: 12,\n marginLeft: 6,\n flexDirection: 'row',\n alignItems: 'center',\n gap: 4,\n },\n giphyBadgeText: {\n color: theme.colors.interaction,\n marginBottom: 1,\n },\n giphyBadgeIcon: {\n color: theme.colors.interaction,\n },\n formButton: {\n height: buttonSize,\n },\n submitPressableWrapper: {\n borderRadius: buttonSize,\n overflow: 'hidden',\n },\n submitGradientWrapper: {\n flexDirection: 'row',\n justifyContent: 'center',\n alignItems: 'center',\n borderRadius: buttonSize,\n height: buttonSize,\n width: buttonSize,\n },\n submitIcon: {\n fontSize: 16,\n color: tokens.colorNeutral100White,\n },\n submitIconDisabled: {\n color: theme.colors.iconColorDefaultDisabled,\n },\n attachmentPicker: {\n position: 'relative',\n },\n attachmentPickerButtonsContainer: {\n position: 'absolute',\n left: 0,\n bottom: 40,\n zIndex: 10,\n gap: 12,\n },\n attachmentPickerButton: {\n backgroundColor: theme.colors.fillColorNeutral070,\n borderRadius: 20,\n height: buttonSize,\n width: buttonSize,\n elevation: 3,\n ...Platform.select({\n ios: {\n borderWidth: 1,\n borderColor: theme.colors.borderColorDefaultBase,\n },\n default: null,\n }),\n },\n messageFormAttachments: {\n overflow: 'hidden',\n paddingHorizontal: 12,\n paddingTop: 12,\n gap: 8,\n },\n inputErrorMessage: {\n color: theme.colors.statusErrorText,\n fontSize: 14,\n paddingHorizontal: 16,\n paddingVertical: 4,\n },\n flaggedBannerContainer: {\n paddingBottom: 12,\n },\n flaggedBannerText: {\n color: theme.colors.textColorDefaultPrimary,\n fontSize: 14,\n },\n flaggedBannerLink: {\n color: theme.colors.textColorDefaultPrimary,\n fontSize: 14,\n textDecorationLine: 'underline' as const,\n },\n flaggedBannerButtonRow: {\n flexDirection: 'row',\n justifyContent: 'flex-end',\n marginTop: 4,\n },\n formIndicatorRow: {\n flexDirection: 'row',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: 8,\n paddingBottom: 12,\n },\n formIndicatorRowTitleContainer: {\n flexDirection: 'row',\n alignItems: 'center',\n gap: 8,\n flex: 1,\n },\n formIndicatorRowIcon: {\n color: theme.colors.iconColorDefaultSecondary,\n },\n formIndicatorRowTitle: {\n fontWeight: platformFontWeightMedium,\n textTransform: 'none',\n flexShrink: 1,\n },\n })\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reply_shadow_message.d.ts","sourceRoot":"","sources":["../../../src/components/conversation/reply_shadow_message.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"reply_shadow_message.d.ts","sourceRoot":"","sources":["../../../src/components/conversation/reply_shadow_message.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAkB7C,UAAU,uBAAwB,SAAQ,eAAe;IACvD,SAAS,EAAE,MAAM,CAAA;IACjB,eAAe,EAAE,MAAM,CAAA;IACvB,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,oBAAoB,EAAE,OAAO,CAAA;IAC7B,iBAAiB,EAAE,OAAO,CAAA;CAC3B;AAED,wBAAgB,kBAAkB,CAAC,EACjC,eAAe,EACf,aAAa,EACb,SAAS,EACT,oBAAoB,EACpB,iBAAiB,GAClB,EAAE,uBAAuB,kDAczB"}
|
|
@@ -8,6 +8,7 @@ import { useAnimatedMessageBackgroundColor, useFontScale, useScalableNumberOfLin
|
|
|
8
8
|
import { useConversationMessage } from '../../hooks/use_conversation_message';
|
|
9
9
|
import { useLiveRelativeTime } from '../../hooks/use_live_relative_time';
|
|
10
10
|
import { assertKeysAreNumbers, pluralize } from '../../utils';
|
|
11
|
+
import { stripEmptyTextCharacters } from '../../utils/message_text';
|
|
11
12
|
import { CONVERSATION_MESSAGE_LIST_PADDING_HORIZONTAL, MAX_FONT_SIZE_MULTIPLIER, MESSAGE_AUTHOR_AVATAR_COLUMN_WIDTH, platformFontWeightMedium, } from '../../utils/styles';
|
|
12
13
|
import { Avatar, Icon, Image, Text } from '../display';
|
|
13
14
|
import { TheirReplyConnector, MyReplyConnector } from './reply_connectors';
|
|
@@ -27,7 +28,8 @@ export function ReplyShadowMessage({ conversation_id, inReplyScreen, messageId,
|
|
|
27
28
|
return _jsx(ShadowMessageContent, { conversation_id: conversation_id, ...enrichedMessage });
|
|
28
29
|
}
|
|
29
30
|
function ShadowMessageContent({ conversation_id, ...message }) {
|
|
30
|
-
const {
|
|
31
|
+
const { deletedAt, author, attachments } = message;
|
|
32
|
+
const text = stripEmptyTextCharacters(message.text ?? '');
|
|
31
33
|
const styles = useStyles(message);
|
|
32
34
|
const { colors } = useTheme();
|
|
33
35
|
const navigation = useNavigation();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reply_shadow_message.js","sourceRoot":"","sources":["../../../src/components/conversation/reply_shadow_message.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useNavigation } from '@react-navigation/native'\nimport { some } from 'lodash'\nimport React from 'react'\nimport { Pressable, StyleSheet, useWindowDimensions, View } from 'react-native'\nimport Animated from 'react-native-reanimated'\nimport {\n useAnimatedMessageBackgroundColor,\n useFontScale,\n useScalableNumberOfLines,\n useTheme,\n} from '../../hooks'\nimport { useConversationMessage } from '../../hooks/use_conversation_message'\nimport { useLiveRelativeTime } from '../../hooks/use_live_relative_time'\nimport { MessageResource } from '../../types'\nimport {\n DenormalizedAttachmentResource,\n DenormalizedGiphyAttachmentResource,\n DenormalizedExpandedLinkAttachmentResource,\n DenormalizedMessageAttachmentResource,\n} from '../../types/resources/denormalized_attachment_resource'\nimport { assertKeysAreNumbers, pluralize } from '../../utils'\nimport {\n CONVERSATION_MESSAGE_LIST_PADDING_HORIZONTAL,\n MAX_FONT_SIZE_MULTIPLIER,\n MESSAGE_AUTHOR_AVATAR_COLUMN_WIDTH,\n platformFontWeightMedium,\n} from '../../utils/styles'\nimport { Avatar, Icon, IconProps, Image, Text } from '../display'\nimport { TheirReplyConnector, MyReplyConnector } from './reply_connectors'\n\ninterface ReplyShadowMessageProps extends MessageResource {\n messageId: string\n conversation_id: number\n inReplyScreen?: boolean\n isReplyShadowMessage: boolean\n nextRendersAuthor: boolean\n}\n\nexport function ReplyShadowMessage({\n conversation_id,\n inReplyScreen,\n messageId,\n isReplyShadowMessage,\n nextRendersAuthor,\n}: ReplyShadowMessageProps) {\n const { message, isError, isLoading } = useConversationMessage({ conversation_id, messageId })\n\n if (inReplyScreen) return null\n if (isLoading) return <ShadowMessageFallback text=\"Loading...\" />\n if (isError || !message) return <ShadowMessageFallback text=\"Message deleted\" />\n\n const enrichedMessage = {\n ...message,\n isReplyShadowMessage,\n nextRendersAuthor,\n }\n\n return <ShadowMessageContent conversation_id={conversation_id} {...enrichedMessage} />\n}\n\ninterface ShadowMessageContentProps extends MessageResource {\n conversation_id: number\n}\n\nfunction ShadowMessageContent({ conversation_id, ...message }: ShadowMessageContentProps) {\n const { text, deletedAt, author, attachments } = message\n const styles = useStyles(message)\n const { colors } = useTheme()\n const navigation = useNavigation()\n const timestamp = useLiveRelativeTime(message.createdAt)\n\n const [messageBubbleHeight, setMessageBubbleHeight] = React.useState(0)\n const { animatedBackgroundColor, handleMessagePressIn, handleMessagePressOut } =\n useAnimatedMessageBackgroundColor()\n const scalableNumberOfLines = useScalableNumberOfLines(2)\n const replyCountText = pluralize(message.replyCount, 'reply')\n const isDeleted = !!deletedAt\n const messageText = isDeleted ? 'Message deleted' : text\n\n const handleNavigateToReplies = () => {\n navigation.navigate('ConversationReply', {\n conversation_id,\n reply_root_id: message.replyRootId,\n reply_root_author_name: message.author.name,\n })\n }\n\n const attachmentLabel = some(attachments) ? pluralize(attachments.length, 'attachment') : ''\n const accessibilityLabel = `${author?.name || ''} Reply Preview ${attachmentLabel} ${\n messageText || ''\n } ${timestamp} ${replyCountText}`\n\n return (\n <Pressable\n android_ripple={{ color: colors.androidRippleNeutral }}\n onPress={handleNavigateToReplies}\n onPressIn={handleMessagePressIn}\n onPressOut={handleMessagePressOut}\n accessibilityLabel={accessibilityLabel}\n accessibilityHint=\"Navigate to reply screen for this message\"\n accessibilityRole=\"link\"\n >\n <Animated.View style={[styles.message, animatedBackgroundColor]}>\n {!message.mine && (\n <View>\n <View style={[styles.avatarWrapper, !isDeleted && styles.avatarOpacity]}>\n <Avatar\n size=\"xs\"\n sourceUri={message.author.avatar}\n style={styles.avatar}\n maxFontSizeMultiplier={1}\n fallbackIconName={isDeleted ? 'publishing.trash' : 'general.person'}\n showFallback={isDeleted}\n />\n </View>\n <TheirReplyConnector message={message} messageBubbleHeight={messageBubbleHeight} />\n </View>\n )}\n <View style={styles.messageContent}>\n <View\n style={styles.messageBubble}\n onLayout={e => setMessageBubbleHeight(e.nativeEvent.layout.height)}\n >\n <MessageAttachmentImagery attachments={attachments} />\n {text && (\n <Text\n variant=\"footnote\"\n style={styles.messageText}\n numberOfLines={scalableNumberOfLines}\n >\n {messageText}\n </Text>\n )}\n </View>\n <View style={styles.messageMeta}>\n <Text variant=\"footnote\" style={styles.replyCountText}>\n {replyCountText}\n </Text>\n </View>\n </View>\n {message.mine && (\n <MyReplyConnector message={message} messageBubbleHeight={messageBubbleHeight} />\n )}\n </Animated.View>\n </Pressable>\n )\n}\n\nfunction MessageAttachmentImagery({\n attachments,\n}: {\n attachments: DenormalizedAttachmentResource[]\n}) {\n if (!attachments || attachments.length === 0) return null\n\n const attachment = attachments[0]\n\n if (attachment.type === 'giphy') {\n return <GiphyImage attachment={attachment} />\n }\n if (attachment.type === 'ExpandedLink') {\n return <ExpandedLinkImage attachment={attachment} />\n }\n if (attachment.type === 'MessageAttachment') {\n const contentType = attachment.attributes?.contentType\n const basicType = contentType?.split('/')[0]\n\n switch (basicType) {\n case 'image':\n return <MessageAttachmentImage attachment={attachment} />\n case 'video':\n return <MessageAttachmentIcon iconName=\"general.outlinedVideoFile\" />\n case 'audio':\n return <MessageAttachmentIcon iconName=\"general.outlinedMusicFile\" />\n case 'application':\n return <MessageAttachmentIcon iconName=\"general.outlinedGenericFile\" />\n default:\n return null\n }\n }\n\n return null\n}\n\nfunction GiphyImage({ attachment }: { attachment: DenormalizedGiphyAttachmentResource }) {\n const { title, giphy } = attachment\n const { url } = giphy.fixedWidth\n const { width, height } = assertKeysAreNumbers(giphy.fixedWidth)\n const styles = useStyles({ imageWidth: width, imageHeight: height })\n\n return (\n <Image\n source={{ uri: url }}\n wrapperStyle={styles.imageWrapper}\n style={styles.image}\n alt={title}\n loaderSize={16}\n />\n )\n}\n\nfunction ExpandedLinkImage({\n attachment,\n}: {\n attachment: DenormalizedExpandedLinkAttachmentResource\n}) {\n const { title = '', imageUrl, imageHeight, imageWidth } = attachment.attributes\n const styles = useStyles({ imageWidth, imageHeight })\n\n return (\n <Image\n source={{ uri: imageUrl }}\n wrapperStyle={styles.imageWrapper}\n style={styles.image}\n alt={title}\n loaderSize={16}\n />\n )\n}\n\nfunction MessageAttachmentImage({\n attachment,\n}: {\n attachment: DenormalizedMessageAttachmentResource\n}) {\n const { url, urlMedium, filename, metadata = {} } = attachment.attributes\n const styles = useStyles({ imageWidth: metadata.width, imageHeight: metadata.height })\n\n return (\n <Image\n source={{ uri: urlMedium || url }}\n style={styles.image}\n wrapperStyle={styles.imageWrapper}\n alt={filename}\n loaderSize={16}\n />\n )\n}\n\nfunction MessageAttachmentIcon({ iconName }: { iconName: IconProps['name'] }) {\n const styles = useStyles()\n return (\n <Icon\n name={iconName}\n style={styles.attachmentIcon}\n maxFontSizeMultiplier={MAX_FONT_SIZE_MULTIPLIER}\n />\n )\n}\n\n// TODO: The mine prop is not used yet, but in the future we will be adding a way to find the `mine` value for this fallback.\nfunction ShadowMessageFallback({ text, mine }: { text: string; mine?: boolean }) {\n const styles = useStyles({ mine })\n\n return (\n <View style={styles.message}>\n <View style={styles.messageContent}>\n <View style={styles.messageBubble}>\n <Text variant=\"footnote\" style={styles.messageText}>\n {text}\n </Text>\n </View>\n </View>\n </View>\n )\n}\n\ninterface StylesProps {\n imageWidth?: number\n imageHeight?: number\n mine?: boolean\n}\n\nconst useStyles = ({ mine, imageWidth = 32, imageHeight = 32 }: StylesProps = {}) => {\n const { colors } = useTheme()\n const fontScale = useFontScale({ maxFontSizeMultiplier: MAX_FONT_SIZE_MULTIPLIER })\n const { width } = useWindowDimensions()\n const tabletWidth = width >= 744 // Smallest iPad Mini's width\n\n return StyleSheet.create({\n message: {\n gap: 8,\n flexDirection: mine ? 'row-reverse' : 'row',\n paddingHorizontal: CONVERSATION_MESSAGE_LIST_PADDING_HORIZONTAL,\n },\n messageContent: {\n flex: 1,\n gap: 4,\n marginBottom: 12,\n },\n avatarWrapper: {\n width: MESSAGE_AUTHOR_AVATAR_COLUMN_WIDTH,\n alignItems: 'center',\n },\n avatar: {\n marginBottom: 8,\n },\n avatarOpacity: {\n opacity: 0.5,\n },\n messageBubble: {\n flexDirection: 'row',\n alignSelf: mine ? 'flex-end' : 'flex-start',\n alignItems: 'center',\n gap: 8,\n borderColor: colors.borderColorDefaultBase,\n borderWidth: 1,\n borderRadius: 8,\n maxWidth: tabletWidth ? 360 : '80%',\n paddingVertical: 6,\n paddingHorizontal: 8,\n },\n messageText: {\n color: colors.textColorDefaultPlaceholder,\n flexShrink: 1,\n },\n messageMeta: {\n flexDirection: 'row',\n justifyContent: mine ? 'flex-end' : 'flex-start',\n },\n replyCountText: {\n color: colors.interaction,\n fontWeight: platformFontWeightMedium,\n },\n imageWrapper: {\n width: 32 * fontScale,\n aspectRatio: imageWidth / imageHeight,\n opacity: 0.5,\n },\n image: {\n borderRadius: 4,\n },\n attachmentIcon: {\n color: colors.iconColorDefaultDim,\n fontSize: 16,\n },\n })\n}\n"]}
|
|
1
|
+
{"version":3,"file":"reply_shadow_message.js","sourceRoot":"","sources":["../../../src/components/conversation/reply_shadow_message.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useNavigation } from '@react-navigation/native'\nimport { some } from 'lodash'\nimport React from 'react'\nimport { Pressable, StyleSheet, useWindowDimensions, View } from 'react-native'\nimport Animated from 'react-native-reanimated'\nimport {\n useAnimatedMessageBackgroundColor,\n useFontScale,\n useScalableNumberOfLines,\n useTheme,\n} from '../../hooks'\nimport { useConversationMessage } from '../../hooks/use_conversation_message'\nimport { useLiveRelativeTime } from '../../hooks/use_live_relative_time'\nimport { MessageResource } from '../../types'\nimport {\n DenormalizedAttachmentResource,\n DenormalizedGiphyAttachmentResource,\n DenormalizedExpandedLinkAttachmentResource,\n DenormalizedMessageAttachmentResource,\n} from '../../types/resources/denormalized_attachment_resource'\nimport { assertKeysAreNumbers, pluralize } from '../../utils'\nimport { stripEmptyTextCharacters } from '../../utils/message_text'\nimport {\n CONVERSATION_MESSAGE_LIST_PADDING_HORIZONTAL,\n MAX_FONT_SIZE_MULTIPLIER,\n MESSAGE_AUTHOR_AVATAR_COLUMN_WIDTH,\n platformFontWeightMedium,\n} from '../../utils/styles'\nimport { Avatar, Icon, IconProps, Image, Text } from '../display'\nimport { TheirReplyConnector, MyReplyConnector } from './reply_connectors'\n\ninterface ReplyShadowMessageProps extends MessageResource {\n messageId: string\n conversation_id: number\n inReplyScreen?: boolean\n isReplyShadowMessage: boolean\n nextRendersAuthor: boolean\n}\n\nexport function ReplyShadowMessage({\n conversation_id,\n inReplyScreen,\n messageId,\n isReplyShadowMessage,\n nextRendersAuthor,\n}: ReplyShadowMessageProps) {\n const { message, isError, isLoading } = useConversationMessage({ conversation_id, messageId })\n\n if (inReplyScreen) return null\n if (isLoading) return <ShadowMessageFallback text=\"Loading...\" />\n if (isError || !message) return <ShadowMessageFallback text=\"Message deleted\" />\n\n const enrichedMessage = {\n ...message,\n isReplyShadowMessage,\n nextRendersAuthor,\n }\n\n return <ShadowMessageContent conversation_id={conversation_id} {...enrichedMessage} />\n}\n\ninterface ShadowMessageContentProps extends MessageResource {\n conversation_id: number\n}\n\nfunction ShadowMessageContent({ conversation_id, ...message }: ShadowMessageContentProps) {\n const { deletedAt, author, attachments } = message\n const text = stripEmptyTextCharacters(message.text ?? '')\n const styles = useStyles(message)\n const { colors } = useTheme()\n const navigation = useNavigation()\n const timestamp = useLiveRelativeTime(message.createdAt)\n\n const [messageBubbleHeight, setMessageBubbleHeight] = React.useState(0)\n const { animatedBackgroundColor, handleMessagePressIn, handleMessagePressOut } =\n useAnimatedMessageBackgroundColor()\n const scalableNumberOfLines = useScalableNumberOfLines(2)\n const replyCountText = pluralize(message.replyCount, 'reply')\n const isDeleted = !!deletedAt\n const messageText = isDeleted ? 'Message deleted' : text\n\n const handleNavigateToReplies = () => {\n navigation.navigate('ConversationReply', {\n conversation_id,\n reply_root_id: message.replyRootId,\n reply_root_author_name: message.author.name,\n })\n }\n\n const attachmentLabel = some(attachments) ? pluralize(attachments.length, 'attachment') : ''\n const accessibilityLabel = `${author?.name || ''} Reply Preview ${attachmentLabel} ${\n messageText || ''\n } ${timestamp} ${replyCountText}`\n\n return (\n <Pressable\n android_ripple={{ color: colors.androidRippleNeutral }}\n onPress={handleNavigateToReplies}\n onPressIn={handleMessagePressIn}\n onPressOut={handleMessagePressOut}\n accessibilityLabel={accessibilityLabel}\n accessibilityHint=\"Navigate to reply screen for this message\"\n accessibilityRole=\"link\"\n >\n <Animated.View style={[styles.message, animatedBackgroundColor]}>\n {!message.mine && (\n <View>\n <View style={[styles.avatarWrapper, !isDeleted && styles.avatarOpacity]}>\n <Avatar\n size=\"xs\"\n sourceUri={message.author.avatar}\n style={styles.avatar}\n maxFontSizeMultiplier={1}\n fallbackIconName={isDeleted ? 'publishing.trash' : 'general.person'}\n showFallback={isDeleted}\n />\n </View>\n <TheirReplyConnector message={message} messageBubbleHeight={messageBubbleHeight} />\n </View>\n )}\n <View style={styles.messageContent}>\n <View\n style={styles.messageBubble}\n onLayout={e => setMessageBubbleHeight(e.nativeEvent.layout.height)}\n >\n <MessageAttachmentImagery attachments={attachments} />\n {text && (\n <Text\n variant=\"footnote\"\n style={styles.messageText}\n numberOfLines={scalableNumberOfLines}\n >\n {messageText}\n </Text>\n )}\n </View>\n <View style={styles.messageMeta}>\n <Text variant=\"footnote\" style={styles.replyCountText}>\n {replyCountText}\n </Text>\n </View>\n </View>\n {message.mine && (\n <MyReplyConnector message={message} messageBubbleHeight={messageBubbleHeight} />\n )}\n </Animated.View>\n </Pressable>\n )\n}\n\nfunction MessageAttachmentImagery({\n attachments,\n}: {\n attachments: DenormalizedAttachmentResource[]\n}) {\n if (!attachments || attachments.length === 0) return null\n\n const attachment = attachments[0]\n\n if (attachment.type === 'giphy') {\n return <GiphyImage attachment={attachment} />\n }\n if (attachment.type === 'ExpandedLink') {\n return <ExpandedLinkImage attachment={attachment} />\n }\n if (attachment.type === 'MessageAttachment') {\n const contentType = attachment.attributes?.contentType\n const basicType = contentType?.split('/')[0]\n\n switch (basicType) {\n case 'image':\n return <MessageAttachmentImage attachment={attachment} />\n case 'video':\n return <MessageAttachmentIcon iconName=\"general.outlinedVideoFile\" />\n case 'audio':\n return <MessageAttachmentIcon iconName=\"general.outlinedMusicFile\" />\n case 'application':\n return <MessageAttachmentIcon iconName=\"general.outlinedGenericFile\" />\n default:\n return null\n }\n }\n\n return null\n}\n\nfunction GiphyImage({ attachment }: { attachment: DenormalizedGiphyAttachmentResource }) {\n const { title, giphy } = attachment\n const { url } = giphy.fixedWidth\n const { width, height } = assertKeysAreNumbers(giphy.fixedWidth)\n const styles = useStyles({ imageWidth: width, imageHeight: height })\n\n return (\n <Image\n source={{ uri: url }}\n wrapperStyle={styles.imageWrapper}\n style={styles.image}\n alt={title}\n loaderSize={16}\n />\n )\n}\n\nfunction ExpandedLinkImage({\n attachment,\n}: {\n attachment: DenormalizedExpandedLinkAttachmentResource\n}) {\n const { title = '', imageUrl, imageHeight, imageWidth } = attachment.attributes\n const styles = useStyles({ imageWidth, imageHeight })\n\n return (\n <Image\n source={{ uri: imageUrl }}\n wrapperStyle={styles.imageWrapper}\n style={styles.image}\n alt={title}\n loaderSize={16}\n />\n )\n}\n\nfunction MessageAttachmentImage({\n attachment,\n}: {\n attachment: DenormalizedMessageAttachmentResource\n}) {\n const { url, urlMedium, filename, metadata = {} } = attachment.attributes\n const styles = useStyles({ imageWidth: metadata.width, imageHeight: metadata.height })\n\n return (\n <Image\n source={{ uri: urlMedium || url }}\n style={styles.image}\n wrapperStyle={styles.imageWrapper}\n alt={filename}\n loaderSize={16}\n />\n )\n}\n\nfunction MessageAttachmentIcon({ iconName }: { iconName: IconProps['name'] }) {\n const styles = useStyles()\n return (\n <Icon\n name={iconName}\n style={styles.attachmentIcon}\n maxFontSizeMultiplier={MAX_FONT_SIZE_MULTIPLIER}\n />\n )\n}\n\n// TODO: The mine prop is not used yet, but in the future we will be adding a way to find the `mine` value for this fallback.\nfunction ShadowMessageFallback({ text, mine }: { text: string; mine?: boolean }) {\n const styles = useStyles({ mine })\n\n return (\n <View style={styles.message}>\n <View style={styles.messageContent}>\n <View style={styles.messageBubble}>\n <Text variant=\"footnote\" style={styles.messageText}>\n {text}\n </Text>\n </View>\n </View>\n </View>\n )\n}\n\ninterface StylesProps {\n imageWidth?: number\n imageHeight?: number\n mine?: boolean\n}\n\nconst useStyles = ({ mine, imageWidth = 32, imageHeight = 32 }: StylesProps = {}) => {\n const { colors } = useTheme()\n const fontScale = useFontScale({ maxFontSizeMultiplier: MAX_FONT_SIZE_MULTIPLIER })\n const { width } = useWindowDimensions()\n const tabletWidth = width >= 744 // Smallest iPad Mini's width\n\n return StyleSheet.create({\n message: {\n gap: 8,\n flexDirection: mine ? 'row-reverse' : 'row',\n paddingHorizontal: CONVERSATION_MESSAGE_LIST_PADDING_HORIZONTAL,\n },\n messageContent: {\n flex: 1,\n gap: 4,\n marginBottom: 12,\n },\n avatarWrapper: {\n width: MESSAGE_AUTHOR_AVATAR_COLUMN_WIDTH,\n alignItems: 'center',\n },\n avatar: {\n marginBottom: 8,\n },\n avatarOpacity: {\n opacity: 0.5,\n },\n messageBubble: {\n flexDirection: 'row',\n alignSelf: mine ? 'flex-end' : 'flex-start',\n alignItems: 'center',\n gap: 8,\n borderColor: colors.borderColorDefaultBase,\n borderWidth: 1,\n borderRadius: 8,\n maxWidth: tabletWidth ? 360 : '80%',\n paddingVertical: 6,\n paddingHorizontal: 8,\n },\n messageText: {\n color: colors.textColorDefaultPlaceholder,\n flexShrink: 1,\n },\n messageMeta: {\n flexDirection: 'row',\n justifyContent: mine ? 'flex-end' : 'flex-start',\n },\n replyCountText: {\n color: colors.interaction,\n fontWeight: platformFontWeightMedium,\n },\n imageWrapper: {\n width: 32 * fontScale,\n aspectRatio: imageWidth / imageHeight,\n opacity: 0.5,\n },\n image: {\n borderRadius: 4,\n },\n attachmentIcon: {\n color: colors.iconColorDefaultDim,\n fontSize: 16,\n },\n })\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message_text.d.ts","sourceRoot":"","sources":["../../src/utils/message_text.ts"],"names":[],"mappings":"AAEA,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,UAEpD;AAED,wBAAgB,cAAc,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,WAElD"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
const EMPTY_TEXT_CHARACTERS = /\uFFFC/g;
|
|
2
|
+
export function stripEmptyTextCharacters(text) {
|
|
3
|
+
return text.replace(EMPTY_TEXT_CHARACTERS, '');
|
|
4
|
+
}
|
|
5
|
+
export function hasMessageText(text) {
|
|
6
|
+
return Boolean(text && stripEmptyTextCharacters(text).trim());
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=message_text.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message_text.js","sourceRoot":"","sources":["../../src/utils/message_text.ts"],"names":[],"mappings":"AAAA,MAAM,qBAAqB,GAAG,SAAS,CAAA;AAEvC,MAAM,UAAU,wBAAwB,CAAC,IAAY;IACnD,OAAO,IAAI,CAAC,OAAO,CAAC,qBAAqB,EAAE,EAAE,CAAC,CAAA;AAChD,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,IAAoB;IACjD,OAAO,OAAO,CAAC,IAAI,IAAI,wBAAwB,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,CAAA;AAC/D,CAAC","sourcesContent":["const EMPTY_TEXT_CHARACTERS = /\\uFFFC/g\n\nexport function stripEmptyTextCharacters(text: string) {\n return text.replace(EMPTY_TEXT_CHARACTERS, '')\n}\n\nexport function hasMessageText(text?: string | null) {\n return Boolean(text && stripEmptyTextCharacters(text).trim())\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@planningcenter/chat-react-native",
|
|
3
|
-
"version": "3.44.1
|
|
3
|
+
"version": "3.44.1",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"react-native": "./src/index.tsx",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"dependencies": {
|
|
27
27
|
"@fortawesome/fontawesome-svg-core": "^7.2.0",
|
|
28
28
|
"@fortawesome/react-native-fontawesome": "^0.3.2",
|
|
29
|
-
"@planningcenter/emoji-keyboard": "3.44.1
|
|
29
|
+
"@planningcenter/emoji-keyboard": "3.44.1",
|
|
30
30
|
"lodash-inflection": "^1.5.0",
|
|
31
31
|
"react-compiler-runtime": "^1.0.0"
|
|
32
32
|
},
|
|
@@ -73,5 +73,5 @@
|
|
|
73
73
|
"sf-symbols-typescript": "^2.2.0",
|
|
74
74
|
"typescript": "~6.0.3"
|
|
75
75
|
},
|
|
76
|
-
"gitHead": "
|
|
76
|
+
"gitHead": "b99ac59f9b48fd97f4840d6c9ac46d3160e20bb4"
|
|
77
77
|
}
|
|
@@ -25,6 +25,7 @@ import { DenormalizedMessageAttachmentResource } from '../../types/resources/den
|
|
|
25
25
|
import { ReactionCountResource } from '../../types/resources/reaction'
|
|
26
26
|
import { pluralize } from '../../utils'
|
|
27
27
|
import { isNewMessage } from '../../utils/cache/messages_cache'
|
|
28
|
+
import { stripEmptyTextCharacters } from '../../utils/message_text'
|
|
28
29
|
import { Haptic } from '../../utils/native_adapters'
|
|
29
30
|
import {
|
|
30
31
|
CONVERSATION_MESSAGE_LIST_PADDING_HORIZONTAL,
|
|
@@ -54,7 +55,8 @@ export function Message({
|
|
|
54
55
|
inReplyScreen,
|
|
55
56
|
...message
|
|
56
57
|
}: MessageProps) {
|
|
57
|
-
const {
|
|
58
|
+
const { reactionCounts, pending, error, attachments, author } = message
|
|
59
|
+
const text = stripEmptyTextCharacters(message.text ?? '')
|
|
58
60
|
const deletingMessageIds = useDeletingIds('deleteMessage')
|
|
59
61
|
const isDeleting = deletingMessageIds.has(message.id)
|
|
60
62
|
const styles = useMessageStyles(message.mine, isDeleting)
|
|
@@ -41,6 +41,7 @@ import {
|
|
|
41
41
|
import { pickAttachmentPreviewKind } from '../../utils/attachment_kind'
|
|
42
42
|
import { canSubmitMessage } from '../../utils/can_submit_message'
|
|
43
43
|
import { isInputEditable } from '../../utils/is_input_editable'
|
|
44
|
+
import { hasMessageText, stripEmptyTextCharacters } from '../../utils/message_text'
|
|
44
45
|
import {
|
|
45
46
|
DocumentPicker,
|
|
46
47
|
DocumentPickerResult,
|
|
@@ -193,7 +194,7 @@ function MessageFormRoot({
|
|
|
193
194
|
conversationDisabled: conversation.disabled ?? false,
|
|
194
195
|
pendingUploads: !!attachmentUploader?.pendingUploads,
|
|
195
196
|
hasFlaggedAttachments: !!attachmentUploader?.flaggedAttachmentCount,
|
|
196
|
-
hasText: text
|
|
197
|
+
hasText: hasMessageText(text),
|
|
197
198
|
hasSendableAttachments: !!attachmentUploader?.attachmentIds?.length,
|
|
198
199
|
})
|
|
199
200
|
const disabled = !canSubmit
|
|
@@ -241,11 +242,13 @@ function MessageFormRoot({
|
|
|
241
242
|
file: attachment.file,
|
|
242
243
|
})
|
|
243
244
|
)
|
|
245
|
+
const messageText = stripEmptyTextCharacters(text)
|
|
246
|
+
|
|
244
247
|
if (currentlyEditingMessage) {
|
|
245
|
-
mutateAsync({ text })
|
|
248
|
+
mutateAsync({ text: messageText })
|
|
246
249
|
reset()
|
|
247
250
|
} else {
|
|
248
|
-
mutateAsync({ text, attachments: attachmentsForSubmit })
|
|
251
|
+
mutateAsync({ text: messageText, attachments: attachmentsForSubmit })
|
|
249
252
|
reset()
|
|
250
253
|
}
|
|
251
254
|
}
|
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
DenormalizedMessageAttachmentResource,
|
|
20
20
|
} from '../../types/resources/denormalized_attachment_resource'
|
|
21
21
|
import { assertKeysAreNumbers, pluralize } from '../../utils'
|
|
22
|
+
import { stripEmptyTextCharacters } from '../../utils/message_text'
|
|
22
23
|
import {
|
|
23
24
|
CONVERSATION_MESSAGE_LIST_PADDING_HORIZONTAL,
|
|
24
25
|
MAX_FONT_SIZE_MULTIPLIER,
|
|
@@ -63,7 +64,8 @@ interface ShadowMessageContentProps extends MessageResource {
|
|
|
63
64
|
}
|
|
64
65
|
|
|
65
66
|
function ShadowMessageContent({ conversation_id, ...message }: ShadowMessageContentProps) {
|
|
66
|
-
const {
|
|
67
|
+
const { deletedAt, author, attachments } = message
|
|
68
|
+
const text = stripEmptyTextCharacters(message.text ?? '')
|
|
67
69
|
const styles = useStyles(message)
|
|
68
70
|
const { colors } = useTheme()
|
|
69
71
|
const navigation = useNavigation()
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { hasMessageText, stripEmptyTextCharacters } from '../message_text'
|
|
2
|
+
|
|
3
|
+
const EMPTY = '\uFFFC'
|
|
4
|
+
|
|
5
|
+
describe('stripEmptyTextCharacters', () => {
|
|
6
|
+
it.each([
|
|
7
|
+
['leaves ordinary text alone', 'Come on over after.', 'Come on over after.'],
|
|
8
|
+
[
|
|
9
|
+
'removes a trailing pair',
|
|
10
|
+
`Yes. Come on over after.${EMPTY}${EMPTY}`,
|
|
11
|
+
'Yes. Come on over after.',
|
|
12
|
+
],
|
|
13
|
+
['removes one mid-string', `before${EMPTY}after`, 'beforeafter'],
|
|
14
|
+
['reduces an all-empty body to an empty string', EMPTY, ''],
|
|
15
|
+
['reduces a repeated all-empty body to an empty string', `${EMPTY}${EMPTY}${EMPTY}`, ''],
|
|
16
|
+
['leaves an empty string alone', '', ''],
|
|
17
|
+
])('%s', (_name, input, expected) => {
|
|
18
|
+
expect(stripEmptyTextCharacters(input)).toBe(expected)
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
it('does not disturb emoji or other multi-byte text', () => {
|
|
22
|
+
expect(stripEmptyTextCharacters(`👋 hi${EMPTY}`)).toBe('👋 hi')
|
|
23
|
+
})
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
describe('hasMessageText', () => {
|
|
27
|
+
it.each([
|
|
28
|
+
['ordinary text', 'hello', true],
|
|
29
|
+
['text alongside an empty character', `hello${EMPTY}`, true],
|
|
30
|
+
['only an empty character', EMPTY, false],
|
|
31
|
+
['several empty characters', `${EMPTY}${EMPTY}`, false],
|
|
32
|
+
['an empty character surrounded by whitespace', ` ${EMPTY} `, false],
|
|
33
|
+
['whitespace only', ' ', false],
|
|
34
|
+
['empty string', '', false],
|
|
35
|
+
['undefined', undefined, false],
|
|
36
|
+
['null', null, false],
|
|
37
|
+
])('%s -> %s', (_name, input, expected) => {
|
|
38
|
+
expect(hasMessageText(input)).toBe(expected)
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
it('is not fooled by trim alone, which does not treat the character as whitespace', () => {
|
|
42
|
+
expect(EMPTY.trim()).toBe(EMPTY)
|
|
43
|
+
expect(hasMessageText(EMPTY)).toBe(false)
|
|
44
|
+
})
|
|
45
|
+
})
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
const EMPTY_TEXT_CHARACTERS = /\uFFFC/g
|
|
2
|
+
|
|
3
|
+
export function stripEmptyTextCharacters(text: string) {
|
|
4
|
+
return text.replace(EMPTY_TEXT_CHARACTERS, '')
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export function hasMessageText(text?: string | null) {
|
|
8
|
+
return Boolean(text && stripEmptyTextCharacters(text).trim())
|
|
9
|
+
}
|