@planningcenter/chat-react-native 3.30.0-rc.8 → 3.31.0-rc.0

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.
Files changed (61) hide show
  1. package/build/components/conversation/system_message.d.ts +9 -0
  2. package/build/components/conversation/system_message.d.ts.map +1 -0
  3. package/build/components/conversation/system_message.js +93 -0
  4. package/build/components/conversation/system_message.js.map +1 -0
  5. package/build/navigation/index.d.ts +5 -0
  6. package/build/navigation/index.d.ts.map +1 -1
  7. package/build/navigation/index.js +5 -0
  8. package/build/navigation/index.js.map +1 -1
  9. package/build/screens/conversation_screen.d.ts.map +1 -1
  10. package/build/screens/conversation_screen.js +20 -1
  11. package/build/screens/conversation_screen.js.map +1 -1
  12. package/build/screens/index.d.ts +1 -0
  13. package/build/screens/index.d.ts.map +1 -1
  14. package/build/screens/index.js +1 -0
  15. package/build/screens/index.js.map +1 -1
  16. package/build/screens/message_actions_screen.d.ts +1 -0
  17. package/build/screens/message_actions_screen.d.ts.map +1 -1
  18. package/build/screens/message_actions_screen.js +12 -12
  19. package/build/screens/message_actions_screen.js.map +1 -1
  20. package/build/screens/system_message_people_screen.d.ts +9 -0
  21. package/build/screens/system_message_people_screen.d.ts.map +1 -0
  22. package/build/screens/system_message_people_screen.js +68 -0
  23. package/build/screens/system_message_people_screen.js.map +1 -0
  24. package/build/types/jolt_events/message_events.d.ts +7 -0
  25. package/build/types/jolt_events/message_events.d.ts.map +1 -1
  26. package/build/types/jolt_events/message_events.js.map +1 -1
  27. package/build/types/resources/message.d.ts +7 -0
  28. package/build/types/resources/message.d.ts.map +1 -1
  29. package/build/types/resources/message.js.map +1 -1
  30. package/build/utils/cache/optimistically_create_message.d.ts.map +1 -1
  31. package/build/utils/cache/optimistically_create_message.js +1 -0
  32. package/build/utils/cache/optimistically_create_message.js.map +1 -1
  33. package/build/utils/index.d.ts +1 -0
  34. package/build/utils/index.d.ts.map +1 -1
  35. package/build/utils/index.js +1 -0
  36. package/build/utils/index.js.map +1 -1
  37. package/build/utils/jolt/transform_message_event_data_to_message_resource.d.ts.map +1 -1
  38. package/build/utils/jolt/transform_message_event_data_to_message_resource.js +9 -0
  39. package/build/utils/jolt/transform_message_event_data_to_message_resource.js.map +1 -1
  40. package/build/utils/request/messages_data_options.d.ts.map +1 -1
  41. package/build/utils/request/messages_data_options.js +3 -0
  42. package/build/utils/request/messages_data_options.js.map +1 -1
  43. package/build/utils/system_messages.d.ts +15 -0
  44. package/build/utils/system_messages.d.ts.map +1 -0
  45. package/build/utils/system_messages.js +5 -0
  46. package/build/utils/system_messages.js.map +1 -0
  47. package/package.json +2 -2
  48. package/src/__tests__/utils/system_messages.ts +79 -0
  49. package/src/components/conversation/system_message.tsx +130 -0
  50. package/src/navigation/index.tsx +8 -0
  51. package/src/screens/conversation_screen.tsx +25 -2
  52. package/src/screens/index.ts +1 -0
  53. package/src/screens/message_actions_screen.tsx +64 -57
  54. package/src/screens/system_message_people_screen.tsx +94 -0
  55. package/src/types/jolt_events/message_events.ts +3 -0
  56. package/src/types/resources/message.ts +3 -0
  57. package/src/utils/cache/optimistically_create_message.ts +1 -0
  58. package/src/utils/index.ts +1 -0
  59. package/src/utils/jolt/transform_message_event_data_to_message_resource.ts +9 -0
  60. package/src/utils/request/messages_data_options.ts +3 -0
  61. package/src/utils/system_messages.ts +16 -0
@@ -19,14 +19,14 @@ export const MessageActionsScreenOptions = getFormSheetScreenOptions({
19
19
  headerTitle: 'Message actions',
20
20
  });
21
21
  export function MessageActionsScreen({ route }) {
22
- const { conversation_id, message_id, canDeleteNonAuthoredMessages, inReplyScreen, reply_root_author_name, } = route.params;
22
+ const { conversation_id, message_id, canDeleteNonAuthoredMessages, inReplyScreen, reply_root_author_name, isSystemMessage, } = route.params;
23
23
  const { messages, refetch } = useConversationMessages({ conversation_id }, { refetchOnMount: false });
24
24
  const message = messages.find(m => m.id === message_id);
25
25
  if (!message)
26
26
  return null;
27
- return (<MessageActionsScreenContent message={message} conversation_id={conversation_id} canDeleteNonAuthoredMessages={canDeleteNonAuthoredMessages || false} refetchMessages={refetch} inReplyScreen={inReplyScreen} replyRootAuthorName={reply_root_author_name}/>);
27
+ return (<MessageActionsScreenContent message={message} conversation_id={conversation_id} canDeleteNonAuthoredMessages={canDeleteNonAuthoredMessages || false} refetchMessages={refetch} inReplyScreen={inReplyScreen} replyRootAuthorName={reply_root_author_name} isSystemMessage={isSystemMessage}/>);
28
28
  }
29
- function MessageActionsScreenContent({ message, conversation_id, canDeleteNonAuthoredMessages, refetchMessages, inReplyScreen, replyRootAuthorName, }) {
29
+ function MessageActionsScreenContent({ message, conversation_id, canDeleteNonAuthoredMessages, refetchMessages, inReplyScreen, replyRootAuthorName, isSystemMessage, }) {
30
30
  const navigation = useNavigation();
31
31
  const apiClient = useApiClient();
32
32
  const styles = useStyles();
@@ -158,15 +158,15 @@ function MessageActionsScreenContent({ message, conversation_id, canDeleteNonAut
158
158
  navigation.goBack();
159
159
  }}/>))}
160
160
  </View>
161
- <View style={styles.actions}>
162
- {!inReplyScreen && (<FormSheet.Action onPress={handleReplyPress} title="Reply to message" iconName="registrations.undo" accessibilityHint="Navigates to the reply screen" accessibilityRole="link"/>)}
163
- <FormSheet.Action onPress={handleCopyPress} title="Copy text" iconName="services.fileCopy" accessibilityHint="Copies text and links to clipboard"/>
164
- {showReportMessageAction && (<FormSheet.Action onPress={handleReportPress} title="Report message" iconName="chat.reportMessageO" accessibilityHint="Opens a form to report this message"/>)}
165
- {message?.mine && (<FormSheet.Action onPress={() => handleEditPress()} title="Edit message" iconName="accounts.editor" accessibilityHint="Opens existing text in the message form input."/>)}
166
- {message?.mine && (<FormSheet.Action onPress={() => handleViewReadReceiptsPress()} title="View read receipts" iconName="general.checkPerson" accessibilityHint="Opens a modal with a list of people who read your message."/>)}
167
- {message?.mine && hasExpandedLink && (<FormSheet.Action onPress={() => handleRemoveLinkPreviewConfirm()} title="Remove link preview" iconName="general.brokenLink" accessibilityHint="Removes an expanded link preview from the message."/>)}
168
- {(message?.mine || canDeleteNonAuthoredMessages) && (<FormSheet.Action onPress={() => handleDeleteConfirm()} title="Delete message" iconName="publishing.trash" appearance="danger" disabled={isPending} accessibilityHint="Opens a confirmation alert to delete this message permanently."/>)}
169
- </View>
161
+ {!isSystemMessage && (<View style={styles.actions}>
162
+ {!inReplyScreen && (<FormSheet.Action onPress={handleReplyPress} title="Reply to message" iconName="registrations.undo" accessibilityHint="Navigates to the reply screen" accessibilityRole="link"/>)}
163
+ <FormSheet.Action onPress={handleCopyPress} title="Copy text" iconName="services.fileCopy" accessibilityHint="Copies text and links to clipboard"/>
164
+ {showReportMessageAction && (<FormSheet.Action onPress={handleReportPress} title="Report message" iconName="chat.reportMessageO" accessibilityHint="Opens a form to report this message"/>)}
165
+ {message?.mine && (<FormSheet.Action onPress={() => handleEditPress()} title="Edit message" iconName="accounts.editor" accessibilityHint="Opens existing text in the message form input."/>)}
166
+ {message?.mine && (<FormSheet.Action onPress={() => handleViewReadReceiptsPress()} title="View read receipts" iconName="general.checkPerson" accessibilityHint="Opens a modal with a list of people who read your message."/>)}
167
+ {message?.mine && hasExpandedLink && (<FormSheet.Action onPress={() => handleRemoveLinkPreviewConfirm()} title="Remove link preview" iconName="general.brokenLink" accessibilityHint="Removes an expanded link preview from the message."/>)}
168
+ {(message?.mine || canDeleteNonAuthoredMessages) && (<FormSheet.Action onPress={() => handleDeleteConfirm()} title="Delete message" iconName="publishing.trash" appearance="danger" disabled={isPending} accessibilityHint="Opens a confirmation alert to delete this message permanently."/>)}
169
+ </View>)}
170
170
  </FormSheet.Root>);
171
171
  }
172
172
  const Reaction = ({ reaction, onPress, }) => {
@@ -1 +1 @@
1
- {"version":3,"file":"message_actions_screen.js","sourceRoot":"","sources":["../../src/screens/message_actions_screen.tsx"],"names":[],"mappings":"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","sourcesContent":["import { PlatformPressable } from '@react-navigation/elements'\nimport { StackActions, StaticScreenProps, useNavigation } from '@react-navigation/native'\nimport { useMutation } from '@tanstack/react-query'\nimport { isNil, omitBy } from 'lodash'\nimport React, { useCallback } from 'react'\nimport { Alert, Platform, StyleSheet, View } from 'react-native'\nimport { Text } from '../components'\nimport { useReactionStyles } from '../components/conversation/message_reaction'\nimport FormSheet, { getFormSheetScreenOptions } from '../components/primitive/form_sheet'\nimport { useCreateAndroidRippleColor, useFontScale, useTheme } from '../hooks'\nimport { useApiClient } from '../hooks/use_api_client'\nimport { useConversationMessages } from '../hooks/use_conversation_messages'\nimport { availableFeatures, useFeatures } from '../hooks/use_features'\nimport { useMessageReactionToggle } from '../hooks/use_message_reaction_toggle'\nimport { MessageResource } from '../types'\nimport { ReactionCountResource } from '../types/resources/reaction'\nimport { REACTION_EMOJIS } from '../utils'\nimport { Clipboard, Haptic } from '../utils/native_adapters'\n\nexport const MessageActionsScreenOptions = getFormSheetScreenOptions({\n sheetAllowedDetents: [0.5],\n headerTitle: 'Message actions',\n})\n\nexport type MessageActionsScreenProps = StaticScreenProps<{\n message_id: string\n reply_root_author_name?: string\n conversation_id: number\n canDeleteNonAuthoredMessages?: boolean\n inReplyScreen?: boolean\n}>\n\nexport function MessageActionsScreen({ route }: MessageActionsScreenProps) {\n const {\n conversation_id,\n message_id,\n canDeleteNonAuthoredMessages,\n inReplyScreen,\n reply_root_author_name,\n } = route.params\n\n const { messages, refetch } = useConversationMessages(\n { conversation_id },\n { refetchOnMount: false }\n )\n const message = messages.find(m => m.id === message_id)\n\n if (!message) return null\n\n return (\n <MessageActionsScreenContent\n message={message}\n conversation_id={conversation_id}\n canDeleteNonAuthoredMessages={canDeleteNonAuthoredMessages || false}\n refetchMessages={refetch}\n inReplyScreen={inReplyScreen}\n replyRootAuthorName={reply_root_author_name}\n />\n )\n}\n\nfunction MessageActionsScreenContent({\n message,\n conversation_id,\n canDeleteNonAuthoredMessages,\n refetchMessages,\n inReplyScreen,\n replyRootAuthorName,\n}: {\n message: MessageResource\n conversation_id: number\n canDeleteNonAuthoredMessages: boolean\n refetchMessages: () => void\n inReplyScreen?: boolean\n replyRootAuthorName?: string\n}) {\n const navigation = useNavigation()\n const apiClient = useApiClient()\n const styles = useStyles()\n const { featureEnabled } = useFeatures()\n const expandedLink = message.attachments.find(attachment => attachment.type === 'ExpandedLink')\n const hasExpandedLink = !!expandedLink\n\n const myReactions = message?.reactionCounts\n .filter(reaction => reaction.mine)\n .map(reaction => reaction.value)\n\n const availableReactions = Object.entries(REACTION_EMOJIS).map(([value, emoji]) => {\n return {\n value: value as ReactionCountResource['value'],\n emoji,\n mine: myReactions?.includes(value as ReactionCountResource['value']),\n }\n })\n\n const attachmentForCopy = (): string => {\n const giphyTitleLink = message?.attachments.find(\n attachment => attachment.type === 'giphy'\n )?.titleLink\n\n if (giphyTitleLink) return giphyTitleLink\n return ''\n }\n\n const handleReplyPress = useCallback(() => {\n navigation.goBack()\n // Waits for the modal to be dismissed before pushing the reply screen\n requestAnimationFrame(() => {\n navigation.navigate('ConversationReply', {\n conversation_id,\n reply_root_id: message.replyRootId || message.id,\n reply_root_author_name: replyRootAuthorName,\n })\n })\n }, [navigation, conversation_id, message.id, message.replyRootId, replyRootAuthorName])\n\n const handleCopyPress = () => {\n Clipboard.setStringAsync(message?.text || attachmentForCopy() || '')\n navigation.goBack()\n }\n\n const handleReportPress = useCallback(() => {\n Haptic.impactLight()\n navigation.navigate('MessageReport', {\n conversation_id,\n message_id: message.id,\n })\n }, [navigation, conversation_id, message.id])\n\n const { handleReactionToggle, isPending } = useMessageReactionToggle({\n conversation_id,\n message,\n })\n\n const deleteMessage = useCallback(() => {\n const url = `/me/conversations/${conversation_id}/messages/${message.id}/`\n\n return apiClient.chat.delete({ url })\n }, [apiClient, conversation_id, message.id])\n\n const { mutate: handleDeleteMessage } = useMutation({\n mutationFn: deleteMessage,\n mutationKey: ['deleteMessage', message.id],\n onSuccess: () => {\n refetchMessages()\n Haptic.notificationSuccess()\n },\n onError: () => {\n Alert.alert('Oops', 'We were unable to delete this message. Please try again.')\n },\n })\n\n const handleDeleteConfirm = useCallback(() => {\n Alert.alert('Delete message', 'Are you sure you want to permanently delete this message?', [\n { text: 'Cancel', style: 'cancel' },\n {\n text: 'Delete',\n style: 'destructive',\n onPress: () => {\n handleDeleteMessage()\n navigation.goBack()\n },\n },\n ])\n }, [handleDeleteMessage, navigation])\n\n const handleEditPress = useCallback(() => {\n const state = navigation.getState?.()\n const targetRouteName = inReplyScreen ? 'ConversationReply' : 'Conversation'\n const targetRoute = state?.routes?.find(r => r.name === targetRouteName)\n const params = omitBy(\n {\n ...(targetRoute?.params || {}),\n conversation_id,\n editing_message_id: message.id,\n },\n isNil\n )\n navigation.dispatch(StackActions.popTo(targetRouteName, params))\n }, [navigation, conversation_id, message.id, inReplyScreen])\n\n const handleViewReadReceiptsPress = useCallback(() => {\n Haptic.impactLight()\n const params = omitBy(\n {\n conversation_id,\n message_id: message.id,\n },\n isNil\n )\n navigation.dispatch(StackActions.popTo('MessageReadReceipts', params))\n }, [navigation, conversation_id, message.id])\n\n const removeLinkPreview = useCallback(() => {\n const url = `/me/conversations/${conversation_id}/messages/${message.id}/remove_expanded_link`\n const data = {\n data: { type: 'ExpandedLink', attributes: { expanded_link_id: expandedLink?.id } },\n }\n\n return apiClient.chat.post({ url, data })\n }, [apiClient, conversation_id, message.id, expandedLink])\n\n const { mutate: handleRemoveLinkPreview } = useMutation({\n mutationFn: removeLinkPreview,\n onSuccess: () => {\n refetchMessages()\n Haptic.notificationSuccess()\n navigation.goBack()\n },\n onError: () => {\n Alert.alert('Oops', 'We were unable to remove the preview. Please try again.')\n },\n })\n\n const handleRemoveLinkPreviewConfirm = useCallback(() => {\n Alert.alert('Remove link preview?', 'This will remove the image preview but retain the link', [\n { text: 'Cancel', style: 'cancel' },\n { text: 'Remove', style: 'destructive', onPress: () => handleRemoveLinkPreview() },\n ])\n }, [handleRemoveLinkPreview])\n\n const showReportMessageAction =\n !message?.mine && featureEnabled(availableFeatures.message_reporting)\n\n return (\n <FormSheet.Root style={styles.formSheetContent}>\n <View style={styles.reactionList}>\n {availableReactions.map((reaction, index) => (\n <Reaction\n key={index}\n reaction={reaction}\n onPress={() => {\n Haptic.impactLight()\n handleReactionToggle({\n value: reaction.value,\n mine: reaction.mine,\n })\n navigation.goBack()\n }}\n />\n ))}\n </View>\n <View style={styles.actions}>\n {!inReplyScreen && (\n <FormSheet.Action\n onPress={handleReplyPress}\n title=\"Reply to message\"\n iconName=\"registrations.undo\"\n accessibilityHint=\"Navigates to the reply screen\"\n accessibilityRole=\"link\"\n />\n )}\n <FormSheet.Action\n onPress={handleCopyPress}\n title=\"Copy text\"\n iconName=\"services.fileCopy\"\n accessibilityHint=\"Copies text and links to clipboard\"\n />\n {showReportMessageAction && (\n <FormSheet.Action\n onPress={handleReportPress}\n title=\"Report message\"\n iconName=\"chat.reportMessageO\"\n accessibilityHint=\"Opens a form to report this message\"\n />\n )}\n {message?.mine && (\n <FormSheet.Action\n onPress={() => handleEditPress()}\n title=\"Edit message\"\n iconName=\"accounts.editor\"\n accessibilityHint=\"Opens existing text in the message form input.\"\n />\n )}\n {message?.mine && (\n <FormSheet.Action\n onPress={() => handleViewReadReceiptsPress()}\n title=\"View read receipts\"\n iconName=\"general.checkPerson\"\n accessibilityHint=\"Opens a modal with a list of people who read your message.\"\n />\n )}\n {message?.mine && hasExpandedLink && (\n <FormSheet.Action\n onPress={() => handleRemoveLinkPreviewConfirm()}\n title=\"Remove link preview\"\n iconName=\"general.brokenLink\"\n accessibilityHint=\"Removes an expanded link preview from the message.\"\n />\n )}\n {(message?.mine || canDeleteNonAuthoredMessages) && (\n <FormSheet.Action\n onPress={() => handleDeleteConfirm()}\n title=\"Delete message\"\n iconName=\"publishing.trash\"\n appearance=\"danger\"\n disabled={isPending}\n accessibilityHint=\"Opens a confirmation alert to delete this message permanently.\"\n />\n )}\n </View>\n </FormSheet.Root>\n )\n}\n\nconst Reaction = ({\n reaction,\n onPress,\n}: {\n reaction: { value: ReactionCountResource['value']; emoji: string; mine: boolean | undefined }\n onPress: () => void\n}) => {\n const styles = useStyles()\n const reactionStyles = useReactionStyles({ mine: reaction.mine ? 1 : 0 })\n\n const { colors } = useTheme()\n const baseRippleColor = reaction.mine ? colors.interaction : colors.fillColorNeutral060\n const androidRippleColor = useCreateAndroidRippleColor({ color: baseRippleColor })\n\n return (\n <PlatformPressable\n key={reaction.value}\n style={[reactionStyles.reaction, styles.reaction]}\n android_ripple={{ color: androidRippleColor, borderless: false, foreground: true }}\n onPress={onPress}\n >\n <Text style={styles.reactionEmoji} allowFontScaling={false}>\n {REACTION_EMOJIS[reaction.value]}\n </Text>\n </PlatformPressable>\n )\n}\n\nconst useStyles = () => {\n const { colors } = useTheme()\n const fontScale = useFontScale({ maxFontSizeMultiplier: 1.3 })\n\n const btnBorderWidth = 1\n const baseSize = 46 * Math.max(1, fontScale)\n const reactionBtnSize = Platform.select({\n ios: baseSize,\n android: baseSize + btnBorderWidth * 2,\n })\n\n return StyleSheet.create({\n formSheetContent: {\n paddingTop: 16,\n },\n reactionList: {\n flexDirection: 'row',\n justifyContent: 'center',\n alignItems: 'center',\n gap: 16,\n paddingTop: 8,\n paddingBottom: 16,\n borderBottomColor: colors.borderColorDefaultBase,\n borderBottomWidth: 1,\n },\n reaction: {\n height: reactionBtnSize,\n width: reactionBtnSize,\n borderWidth: btnBorderWidth,\n borderRadius: 32,\n justifyContent: 'center',\n overflow: 'hidden',\n },\n reactionEmoji: {\n fontSize: 24,\n textAlign: 'center',\n },\n actions: {\n paddingTop: 4,\n },\n })\n}\n"]}
1
+ {"version":3,"file":"message_actions_screen.js","sourceRoot":"","sources":["../../src/screens/message_actions_screen.tsx"],"names":[],"mappings":"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","sourcesContent":["import { PlatformPressable } from '@react-navigation/elements'\nimport { StackActions, StaticScreenProps, useNavigation } from '@react-navigation/native'\nimport { useMutation } from '@tanstack/react-query'\nimport { isNil, omitBy } from 'lodash'\nimport React, { useCallback } from 'react'\nimport { Alert, Platform, StyleSheet, View } from 'react-native'\nimport { Text } from '../components'\nimport { useReactionStyles } from '../components/conversation/message_reaction'\nimport FormSheet, { getFormSheetScreenOptions } from '../components/primitive/form_sheet'\nimport { useCreateAndroidRippleColor, useFontScale, useTheme } from '../hooks'\nimport { useApiClient } from '../hooks/use_api_client'\nimport { useConversationMessages } from '../hooks/use_conversation_messages'\nimport { availableFeatures, useFeatures } from '../hooks/use_features'\nimport { useMessageReactionToggle } from '../hooks/use_message_reaction_toggle'\nimport { MessageResource } from '../types'\nimport { ReactionCountResource } from '../types/resources/reaction'\nimport { REACTION_EMOJIS } from '../utils'\nimport { Clipboard, Haptic } from '../utils/native_adapters'\n\nexport const MessageActionsScreenOptions = getFormSheetScreenOptions({\n sheetAllowedDetents: [0.5],\n headerTitle: 'Message actions',\n})\n\nexport type MessageActionsScreenProps = StaticScreenProps<{\n message_id: string\n reply_root_author_name?: string\n conversation_id: number\n canDeleteNonAuthoredMessages?: boolean\n inReplyScreen?: boolean\n isSystemMessage?: boolean\n}>\n\nexport function MessageActionsScreen({ route }: MessageActionsScreenProps) {\n const {\n conversation_id,\n message_id,\n canDeleteNonAuthoredMessages,\n inReplyScreen,\n reply_root_author_name,\n isSystemMessage,\n } = route.params\n\n const { messages, refetch } = useConversationMessages(\n { conversation_id },\n { refetchOnMount: false }\n )\n const message = messages.find(m => m.id === message_id)\n\n if (!message) return null\n\n return (\n <MessageActionsScreenContent\n message={message}\n conversation_id={conversation_id}\n canDeleteNonAuthoredMessages={canDeleteNonAuthoredMessages || false}\n refetchMessages={refetch}\n inReplyScreen={inReplyScreen}\n replyRootAuthorName={reply_root_author_name}\n isSystemMessage={isSystemMessage}\n />\n )\n}\n\nfunction MessageActionsScreenContent({\n message,\n conversation_id,\n canDeleteNonAuthoredMessages,\n refetchMessages,\n inReplyScreen,\n replyRootAuthorName,\n isSystemMessage,\n}: {\n message: MessageResource\n conversation_id: number\n canDeleteNonAuthoredMessages: boolean\n refetchMessages: () => void\n inReplyScreen?: boolean\n replyRootAuthorName?: string\n isSystemMessage?: boolean\n}) {\n const navigation = useNavigation()\n const apiClient = useApiClient()\n const styles = useStyles()\n const { featureEnabled } = useFeatures()\n const expandedLink = message.attachments.find(attachment => attachment.type === 'ExpandedLink')\n const hasExpandedLink = !!expandedLink\n\n const myReactions = message?.reactionCounts\n .filter(reaction => reaction.mine)\n .map(reaction => reaction.value)\n\n const availableReactions = Object.entries(REACTION_EMOJIS).map(([value, emoji]) => {\n return {\n value: value as ReactionCountResource['value'],\n emoji,\n mine: myReactions?.includes(value as ReactionCountResource['value']),\n }\n })\n\n const attachmentForCopy = (): string => {\n const giphyTitleLink = message?.attachments.find(\n attachment => attachment.type === 'giphy'\n )?.titleLink\n\n if (giphyTitleLink) return giphyTitleLink\n return ''\n }\n\n const handleReplyPress = useCallback(() => {\n navigation.goBack()\n // Waits for the modal to be dismissed before pushing the reply screen\n requestAnimationFrame(() => {\n navigation.navigate('ConversationReply', {\n conversation_id,\n reply_root_id: message.replyRootId || message.id,\n reply_root_author_name: replyRootAuthorName,\n })\n })\n }, [navigation, conversation_id, message.id, message.replyRootId, replyRootAuthorName])\n\n const handleCopyPress = () => {\n Clipboard.setStringAsync(message?.text || attachmentForCopy() || '')\n navigation.goBack()\n }\n\n const handleReportPress = useCallback(() => {\n Haptic.impactLight()\n navigation.navigate('MessageReport', {\n conversation_id,\n message_id: message.id,\n })\n }, [navigation, conversation_id, message.id])\n\n const { handleReactionToggle, isPending } = useMessageReactionToggle({\n conversation_id,\n message,\n })\n\n const deleteMessage = useCallback(() => {\n const url = `/me/conversations/${conversation_id}/messages/${message.id}/`\n\n return apiClient.chat.delete({ url })\n }, [apiClient, conversation_id, message.id])\n\n const { mutate: handleDeleteMessage } = useMutation({\n mutationFn: deleteMessage,\n mutationKey: ['deleteMessage', message.id],\n onSuccess: () => {\n refetchMessages()\n Haptic.notificationSuccess()\n },\n onError: () => {\n Alert.alert('Oops', 'We were unable to delete this message. Please try again.')\n },\n })\n\n const handleDeleteConfirm = useCallback(() => {\n Alert.alert('Delete message', 'Are you sure you want to permanently delete this message?', [\n { text: 'Cancel', style: 'cancel' },\n {\n text: 'Delete',\n style: 'destructive',\n onPress: () => {\n handleDeleteMessage()\n navigation.goBack()\n },\n },\n ])\n }, [handleDeleteMessage, navigation])\n\n const handleEditPress = useCallback(() => {\n const state = navigation.getState?.()\n const targetRouteName = inReplyScreen ? 'ConversationReply' : 'Conversation'\n const targetRoute = state?.routes?.find(r => r.name === targetRouteName)\n const params = omitBy(\n {\n ...(targetRoute?.params || {}),\n conversation_id,\n editing_message_id: message.id,\n },\n isNil\n )\n navigation.dispatch(StackActions.popTo(targetRouteName, params))\n }, [navigation, conversation_id, message.id, inReplyScreen])\n\n const handleViewReadReceiptsPress = useCallback(() => {\n Haptic.impactLight()\n const params = omitBy(\n {\n conversation_id,\n message_id: message.id,\n },\n isNil\n )\n navigation.dispatch(StackActions.popTo('MessageReadReceipts', params))\n }, [navigation, conversation_id, message.id])\n\n const removeLinkPreview = useCallback(() => {\n const url = `/me/conversations/${conversation_id}/messages/${message.id}/remove_expanded_link`\n const data = {\n data: { type: 'ExpandedLink', attributes: { expanded_link_id: expandedLink?.id } },\n }\n\n return apiClient.chat.post({ url, data })\n }, [apiClient, conversation_id, message.id, expandedLink])\n\n const { mutate: handleRemoveLinkPreview } = useMutation({\n mutationFn: removeLinkPreview,\n onSuccess: () => {\n refetchMessages()\n Haptic.notificationSuccess()\n navigation.goBack()\n },\n onError: () => {\n Alert.alert('Oops', 'We were unable to remove the preview. Please try again.')\n },\n })\n\n const handleRemoveLinkPreviewConfirm = useCallback(() => {\n Alert.alert('Remove link preview?', 'This will remove the image preview but retain the link', [\n { text: 'Cancel', style: 'cancel' },\n { text: 'Remove', style: 'destructive', onPress: () => handleRemoveLinkPreview() },\n ])\n }, [handleRemoveLinkPreview])\n\n const showReportMessageAction =\n !message?.mine && featureEnabled(availableFeatures.message_reporting)\n\n return (\n <FormSheet.Root style={styles.formSheetContent}>\n <View style={styles.reactionList}>\n {availableReactions.map((reaction, index) => (\n <Reaction\n key={index}\n reaction={reaction}\n onPress={() => {\n Haptic.impactLight()\n handleReactionToggle({\n value: reaction.value,\n mine: reaction.mine,\n })\n navigation.goBack()\n }}\n />\n ))}\n </View>\n {!isSystemMessage && (\n <View style={styles.actions}>\n {!inReplyScreen && (\n <FormSheet.Action\n onPress={handleReplyPress}\n title=\"Reply to message\"\n iconName=\"registrations.undo\"\n accessibilityHint=\"Navigates to the reply screen\"\n accessibilityRole=\"link\"\n />\n )}\n <FormSheet.Action\n onPress={handleCopyPress}\n title=\"Copy text\"\n iconName=\"services.fileCopy\"\n accessibilityHint=\"Copies text and links to clipboard\"\n />\n {showReportMessageAction && (\n <FormSheet.Action\n onPress={handleReportPress}\n title=\"Report message\"\n iconName=\"chat.reportMessageO\"\n accessibilityHint=\"Opens a form to report this message\"\n />\n )}\n {message?.mine && (\n <FormSheet.Action\n onPress={() => handleEditPress()}\n title=\"Edit message\"\n iconName=\"accounts.editor\"\n accessibilityHint=\"Opens existing text in the message form input.\"\n />\n )}\n {message?.mine && (\n <FormSheet.Action\n onPress={() => handleViewReadReceiptsPress()}\n title=\"View read receipts\"\n iconName=\"general.checkPerson\"\n accessibilityHint=\"Opens a modal with a list of people who read your message.\"\n />\n )}\n {message?.mine && hasExpandedLink && (\n <FormSheet.Action\n onPress={() => handleRemoveLinkPreviewConfirm()}\n title=\"Remove link preview\"\n iconName=\"general.brokenLink\"\n accessibilityHint=\"Removes an expanded link preview from the message.\"\n />\n )}\n {(message?.mine || canDeleteNonAuthoredMessages) && (\n <FormSheet.Action\n onPress={() => handleDeleteConfirm()}\n title=\"Delete message\"\n iconName=\"publishing.trash\"\n appearance=\"danger\"\n disabled={isPending}\n accessibilityHint=\"Opens a confirmation alert to delete this message permanently.\"\n />\n )}\n </View>\n )}\n </FormSheet.Root>\n )\n}\n\nconst Reaction = ({\n reaction,\n onPress,\n}: {\n reaction: { value: ReactionCountResource['value']; emoji: string; mine: boolean | undefined }\n onPress: () => void\n}) => {\n const styles = useStyles()\n const reactionStyles = useReactionStyles({ mine: reaction.mine ? 1 : 0 })\n\n const { colors } = useTheme()\n const baseRippleColor = reaction.mine ? colors.interaction : colors.fillColorNeutral060\n const androidRippleColor = useCreateAndroidRippleColor({ color: baseRippleColor })\n\n return (\n <PlatformPressable\n key={reaction.value}\n style={[reactionStyles.reaction, styles.reaction]}\n android_ripple={{ color: androidRippleColor, borderless: false, foreground: true }}\n onPress={onPress}\n >\n <Text style={styles.reactionEmoji} allowFontScaling={false}>\n {REACTION_EMOJIS[reaction.value]}\n </Text>\n </PlatformPressable>\n )\n}\n\nconst useStyles = () => {\n const { colors } = useTheme()\n const fontScale = useFontScale({ maxFontSizeMultiplier: 1.3 })\n\n const btnBorderWidth = 1\n const baseSize = 46 * Math.max(1, fontScale)\n const reactionBtnSize = Platform.select({\n ios: baseSize,\n android: baseSize + btnBorderWidth * 2,\n })\n\n return StyleSheet.create({\n formSheetContent: {\n paddingTop: 16,\n },\n reactionList: {\n flexDirection: 'row',\n justifyContent: 'center',\n alignItems: 'center',\n gap: 16,\n paddingTop: 8,\n paddingBottom: 16,\n borderBottomColor: colors.borderColorDefaultBase,\n borderBottomWidth: 1,\n },\n reaction: {\n height: reactionBtnSize,\n width: reactionBtnSize,\n borderWidth: btnBorderWidth,\n borderRadius: 32,\n justifyContent: 'center',\n overflow: 'hidden',\n },\n reactionEmoji: {\n fontSize: 24,\n textAlign: 'center',\n },\n actions: {\n paddingTop: 4,\n },\n })\n}\n"]}
@@ -0,0 +1,9 @@
1
+ import { StaticScreenProps } from '@react-navigation/native';
2
+ import React from 'react';
3
+ export declare const SystemMessagePeopleScreenOptions: import("@react-navigation/native-stack").NativeStackNavigationOptions;
4
+ export type SystemMessagePeopleScreenProps = StaticScreenProps<{
5
+ conversation_id: number;
6
+ person_ids: number[];
7
+ }>;
8
+ export declare function SystemMessagePeopleScreen({ route }: SystemMessagePeopleScreenProps): React.JSX.Element;
9
+ //# sourceMappingURL=system_message_people_screen.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"system_message_people_screen.d.ts","sourceRoot":"","sources":["../../src/screens/system_message_people_screen.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAC5D,OAAO,KAAe,MAAM,OAAO,CAAA;AASnC,eAAO,MAAM,gCAAgC,uEAM3C,CAAA;AAEF,MAAM,MAAM,8BAA8B,GAAG,iBAAiB,CAAC;IAC7D,eAAe,EAAE,MAAM,CAAA;IACvB,UAAU,EAAE,MAAM,EAAE,CAAA;CACrB,CAAC,CAAA;AAEF,wBAAgB,yBAAyB,CAAC,EAAE,KAAK,EAAE,EAAE,8BAA8B,qBA8BlF"}
@@ -0,0 +1,68 @@
1
+ import React, { memo } from 'react';
2
+ import { Platform, StyleSheet, View } from 'react-native';
3
+ import { FlatList } from 'react-native-gesture-handler';
4
+ import { useSafeAreaInsets } from 'react-native-safe-area-context';
5
+ import { Avatar, Text } from '../components';
6
+ import FormSheet, { getFormSheetScreenOptions } from '../components/primitive/form_sheet';
7
+ import { useSuspenseGet } from '../hooks';
8
+ export const SystemMessagePeopleScreenOptions = getFormSheetScreenOptions({
9
+ sheetAllowedDetents: Platform.select({
10
+ android: [0.5, 0.94],
11
+ default: [0.5, 1],
12
+ }),
13
+ headerTitle: 'People',
14
+ });
15
+ export function SystemMessagePeopleScreen({ route }) {
16
+ const { conversation_id, person_ids } = route.params;
17
+ const styles = useStyles();
18
+ const { data: members } = useSuspenseGet({
19
+ url: `/me/conversations/${conversation_id}/members`,
20
+ data: {
21
+ fields: {
22
+ Member: ['id', 'name', 'avatar'],
23
+ },
24
+ where: {
25
+ id: person_ids,
26
+ },
27
+ limit: person_ids.length,
28
+ },
29
+ });
30
+ const orderById = Object.fromEntries(person_ids.map((id, i) => [id, i]));
31
+ const sortedMembers = [...members].sort((a, b) => (orderById[a.id] ?? 0) - (orderById[b.id] ?? 0));
32
+ return (<FormSheet.Root contentStyle={styles.formSheetContent}>
33
+ <FlatList data={sortedMembers} contentContainerStyle={styles.contentContainer} keyExtractor={item => item.id.toString()} renderItem={({ item }) => <Person person={item}/>}/>
34
+ </FormSheet.Root>);
35
+ }
36
+ const Person = memo(({ person }) => {
37
+ const styles = useStyles();
38
+ return (<View style={styles.personRow}>
39
+ <Avatar sourceUri={person.avatar} size="sm"/>
40
+ <Text variant="tertiary" numberOfLines={2} style={styles.personName}>
41
+ {person.name}
42
+ </Text>
43
+ </View>);
44
+ });
45
+ const useStyles = () => {
46
+ const { bottom } = useSafeAreaInsets();
47
+ return StyleSheet.create({
48
+ formSheetContent: {
49
+ paddingTop: 16,
50
+ },
51
+ contentContainer: {
52
+ paddingTop: 8,
53
+ paddingBottom: bottom + 24,
54
+ },
55
+ personRow: {
56
+ flexDirection: 'row',
57
+ alignItems: 'center',
58
+ gap: 8,
59
+ paddingVertical: 8,
60
+ paddingHorizontal: 16,
61
+ flex: 1,
62
+ },
63
+ personName: {
64
+ flex: 1,
65
+ },
66
+ });
67
+ };
68
+ //# sourceMappingURL=system_message_people_screen.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"system_message_people_screen.js","sourceRoot":"","sources":["../../src/screens/system_message_people_screen.tsx"],"names":[],"mappings":"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","sourcesContent":["import { StaticScreenProps } from '@react-navigation/native'\nimport React, { memo } from 'react'\nimport { Platform, StyleSheet, View } from 'react-native'\nimport { FlatList } from 'react-native-gesture-handler'\nimport { useSafeAreaInsets } from 'react-native-safe-area-context'\nimport { Avatar, Text } from '../components'\nimport FormSheet, { getFormSheetScreenOptions } from '../components/primitive/form_sheet'\nimport { useSuspenseGet } from '../hooks'\nimport { MemberResource } from '../types'\n\nexport const SystemMessagePeopleScreenOptions = getFormSheetScreenOptions({\n sheetAllowedDetents: Platform.select({\n android: [0.5, 0.94],\n default: [0.5, 1],\n }),\n headerTitle: 'People',\n})\n\nexport type SystemMessagePeopleScreenProps = StaticScreenProps<{\n conversation_id: number\n person_ids: number[]\n}>\n\nexport function SystemMessagePeopleScreen({ route }: SystemMessagePeopleScreenProps) {\n const { conversation_id, person_ids } = route.params\n const styles = useStyles()\n\n const { data: members } = useSuspenseGet<MemberResource[]>({\n url: `/me/conversations/${conversation_id}/members`,\n data: {\n fields: {\n Member: ['id', 'name', 'avatar'],\n },\n where: {\n id: person_ids,\n },\n limit: person_ids.length,\n },\n })\n\n const orderById = Object.fromEntries(person_ids.map((id, i) => [id, i]))\n const sortedMembers = [...members].sort((a, b) => (orderById[a.id] ?? 0) - (orderById[b.id] ?? 0))\n\n return (\n <FormSheet.Root contentStyle={styles.formSheetContent}>\n <FlatList\n data={sortedMembers}\n contentContainerStyle={styles.contentContainer}\n keyExtractor={item => item.id.toString()}\n renderItem={({ item }) => <Person person={item} />}\n />\n </FormSheet.Root>\n )\n}\n\ntype PersonProps = Pick<MemberResource, 'id' | 'name' | 'avatar'>\n\nconst Person = memo(({ person }: { person: PersonProps }) => {\n const styles = useStyles()\n\n return (\n <View style={styles.personRow}>\n <Avatar sourceUri={person.avatar} size=\"sm\" />\n <Text variant=\"tertiary\" numberOfLines={2} style={styles.personName}>\n {person.name}\n </Text>\n </View>\n )\n})\n\nconst useStyles = () => {\n const { bottom } = useSafeAreaInsets()\n\n return StyleSheet.create({\n formSheetContent: {\n paddingTop: 16,\n },\n contentContainer: {\n paddingTop: 8,\n paddingBottom: bottom + 24,\n },\n personRow: {\n flexDirection: 'row',\n alignItems: 'center',\n gap: 8,\n paddingVertical: 8,\n paddingHorizontal: 16,\n flex: 1,\n },\n personName: {\n flex: 1,\n },\n })\n}\n"]}
@@ -17,6 +17,13 @@ interface BaseMessageEventData extends Record<string, unknown> {
17
17
  idempotent_key?: string | null;
18
18
  reply_count: number;
19
19
  reply_root_id: string | null;
20
+ message_type: string;
21
+ system_event_person_ids: number[] | null;
22
+ system_text_parts: {
23
+ names: string[];
24
+ overflow_count: number;
25
+ action: string;
26
+ } | null;
20
27
  };
21
28
  }
22
29
  export interface MessageCreatedEvent extends CustomMessage {
@@ -1 +1 @@
1
- {"version":3,"file":"message_events.d.ts","sourceRoot":"","sources":["../../../src/types/jolt_events/message_events.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uDAAuD,CAAA;AAC1F,OAAO,EAAE,8BAA8B,EAAE,MAAM,+CAA+C,CAAA;AAE9F,UAAU,oBAAqB,SAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAC5D,IAAI,EAAE;QACJ,aAAa,EAAE,MAAM,CAAA;QACrB,SAAS,EAAE,MAAM,CAAA;QACjB,WAAW,EAAE,MAAM,CAAA;QACnB,eAAe,EAAE,MAAM,CAAA;QACvB,UAAU,EAAE,MAAM,CAAA;QAClB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;QACzB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAA;QAC9B,QAAQ,EAAE,MAAM,CAAA;QAChB,IAAI,EAAE,MAAM,CAAA;QACZ,cAAc,EAAE,MAAM,GAAG,IAAI,CAAA;QAC7B,IAAI,EAAE,MAAM,CAAA;QACZ,WAAW,EAAE,8BAA8B,EAAE,CAAA;QAC7C,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;QAC9B,WAAW,EAAE,MAAM,CAAA;QACnB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;KAC7B,CAAA;CACF;AAED,MAAM,WAAW,mBAAoB,SAAQ,aAAa;IACxD,KAAK,EAAE,iBAAiB,CAAA;IACxB,IAAI,EAAE,oBAAoB,CAAA;CAC3B;AAED,MAAM,WAAW,mBAAoB,SAAQ,aAAa;IACxD,KAAK,EAAE,iBAAiB,CAAA;IACxB,IAAI,EAAE,oBAAoB,CAAA;CAC3B;AAED,MAAM,WAAW,mBAAoB,SAAQ,aAAa;IACxD,KAAK,EAAE,mBAAmB,CAAA;IAC1B,IAAI,EAAE,oBAAoB,CAAA;CAC3B"}
1
+ {"version":3,"file":"message_events.d.ts","sourceRoot":"","sources":["../../../src/types/jolt_events/message_events.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uDAAuD,CAAA;AAC1F,OAAO,EAAE,8BAA8B,EAAE,MAAM,+CAA+C,CAAA;AAE9F,UAAU,oBAAqB,SAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAC5D,IAAI,EAAE;QACJ,aAAa,EAAE,MAAM,CAAA;QACrB,SAAS,EAAE,MAAM,CAAA;QACjB,WAAW,EAAE,MAAM,CAAA;QACnB,eAAe,EAAE,MAAM,CAAA;QACvB,UAAU,EAAE,MAAM,CAAA;QAClB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;QACzB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAA;QAC9B,QAAQ,EAAE,MAAM,CAAA;QAChB,IAAI,EAAE,MAAM,CAAA;QACZ,cAAc,EAAE,MAAM,GAAG,IAAI,CAAA;QAC7B,IAAI,EAAE,MAAM,CAAA;QACZ,WAAW,EAAE,8BAA8B,EAAE,CAAA;QAC7C,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;QAC9B,WAAW,EAAE,MAAM,CAAA;QACnB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;QAC5B,YAAY,EAAE,MAAM,CAAA;QACpB,uBAAuB,EAAE,MAAM,EAAE,GAAG,IAAI,CAAA;QACxC,iBAAiB,EAAE;YAAE,KAAK,EAAE,MAAM,EAAE,CAAC;YAAC,cAAc,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,GAAG,IAAI,CAAA;KACtF,CAAA;CACF;AAED,MAAM,WAAW,mBAAoB,SAAQ,aAAa;IACxD,KAAK,EAAE,iBAAiB,CAAA;IACxB,IAAI,EAAE,oBAAoB,CAAA;CAC3B;AAED,MAAM,WAAW,mBAAoB,SAAQ,aAAa;IACxD,KAAK,EAAE,iBAAiB,CAAA;IACxB,IAAI,EAAE,oBAAoB,CAAA;CAC3B;AAED,MAAM,WAAW,mBAAoB,SAAQ,aAAa;IACxD,KAAK,EAAE,mBAAmB,CAAA;IAC1B,IAAI,EAAE,oBAAoB,CAAA;CAC3B"}
@@ -1 +1 @@
1
- {"version":3,"file":"message_events.js","sourceRoot":"","sources":["../../../src/types/jolt_events/message_events.ts"],"names":[],"mappings":"","sourcesContent":["import type { CustomMessage } from '@planningcenter/jolt-client/dist/types/JoltConnection'\nimport { DenormalizedAttachmentResource } from '../resources/denormalized_attachment_resource'\n\ninterface BaseMessageEventData extends Record<string, unknown> {\n data: {\n author_avatar: string\n author_id: number\n author_name: string\n conversation_id: number\n created_at: string\n deleted_at: string | null\n organization_id: number | null\n sort_key: string\n text: string\n text_edited_at: string | null\n html: string\n attachments: DenormalizedAttachmentResource[]\n idempotent_key?: string | null\n reply_count: number\n reply_root_id: string | null\n }\n}\n\nexport interface MessageCreatedEvent extends CustomMessage {\n event: 'message.created'\n data: BaseMessageEventData\n}\n\nexport interface MessageUpdatedEvent extends CustomMessage {\n event: 'message.updated'\n data: BaseMessageEventData\n}\n\nexport interface MessageDeletedEvent extends CustomMessage {\n event: 'message.destroyed'\n data: BaseMessageEventData\n}\n"]}
1
+ {"version":3,"file":"message_events.js","sourceRoot":"","sources":["../../../src/types/jolt_events/message_events.ts"],"names":[],"mappings":"","sourcesContent":["import type { CustomMessage } from '@planningcenter/jolt-client/dist/types/JoltConnection'\nimport { DenormalizedAttachmentResource } from '../resources/denormalized_attachment_resource'\n\ninterface BaseMessageEventData extends Record<string, unknown> {\n data: {\n author_avatar: string\n author_id: number\n author_name: string\n conversation_id: number\n created_at: string\n deleted_at: string | null\n organization_id: number | null\n sort_key: string\n text: string\n text_edited_at: string | null\n html: string\n attachments: DenormalizedAttachmentResource[]\n idempotent_key?: string | null\n reply_count: number\n reply_root_id: string | null\n message_type: string\n system_event_person_ids: number[] | null\n system_text_parts: { names: string[]; overflow_count: number; action: string } | null\n }\n}\n\nexport interface MessageCreatedEvent extends CustomMessage {\n event: 'message.created'\n data: BaseMessageEventData\n}\n\nexport interface MessageUpdatedEvent extends CustomMessage {\n event: 'message.updated'\n data: BaseMessageEventData\n}\n\nexport interface MessageDeletedEvent extends CustomMessage {\n event: 'message.destroyed'\n data: BaseMessageEventData\n}\n"]}
@@ -16,6 +16,13 @@ export interface MessageResource {
16
16
  reactionCounts: ReactionCountResource[];
17
17
  replyCount: number;
18
18
  replyRootId?: string | null;
19
+ messageType: string;
20
+ personIdsForSystemEvent?: number[] | null;
21
+ systemTextParts?: {
22
+ names: string[];
23
+ overflowCount: number;
24
+ action: string;
25
+ } | null;
19
26
  renderAuthor?: boolean;
20
27
  renderTime?: boolean;
21
28
  myLatestInConversation?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"message.d.ts","sourceRoot":"","sources":["../../../src/types/resources/message.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,8BAA8B,EAAE,MAAM,oCAAoC,CAAA;AACnF,OAAO,EAAE,uCAAuC,EAAE,MAAM,+CAA+C,CAAA;AACvG,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAC9C,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAA;AAEvD,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,SAAS,CAAA;IACf,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,IAAI,EAAE,OAAO,CAAA;IACb,WAAW,EAAE,8BAA8B,EAAE,CAAA;IAC7C,MAAM,EAAE,cAAc,CAAA;IACtB,cAAc,EAAE,qBAAqB,EAAE,CAAA;IACvC,UAAU,EAAE,MAAM,CAAA;IAClB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAG3B,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,sBAAsB,CAAC,EAAE,OAAO,CAAA;IAChC,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,cAAc,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,MAAM,GAAG,IAAI,CAAA;IACnD,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B,oBAAoB,CAAC,EAAE,OAAO,CAAA;IAC9B,wBAAwB,CAAC,EAAE,OAAO,CAAA;IAGlC,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,oBAAoB,CAAC,EAAE,uCAAuC,EAAE,CAAA;CACjE"}
1
+ {"version":3,"file":"message.d.ts","sourceRoot":"","sources":["../../../src/types/resources/message.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,8BAA8B,EAAE,MAAM,oCAAoC,CAAA;AACnF,OAAO,EAAE,uCAAuC,EAAE,MAAM,+CAA+C,CAAA;AACvG,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAC9C,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAA;AAEvD,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,SAAS,CAAA;IACf,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,IAAI,EAAE,OAAO,CAAA;IACb,WAAW,EAAE,8BAA8B,EAAE,CAAA;IAC7C,MAAM,EAAE,cAAc,CAAA;IACtB,cAAc,EAAE,qBAAqB,EAAE,CAAA;IACvC,UAAU,EAAE,MAAM,CAAA;IAClB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,WAAW,EAAE,MAAM,CAAA;IACnB,uBAAuB,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAA;IACzC,eAAe,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QAAC,aAAa,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAA;IAGnF,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,sBAAsB,CAAC,EAAE,OAAO,CAAA;IAChC,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,cAAc,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,MAAM,GAAG,IAAI,CAAA;IACnD,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B,oBAAoB,CAAC,EAAE,OAAO,CAAA;IAC9B,wBAAwB,CAAC,EAAE,OAAO,CAAA;IAGlC,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,oBAAoB,CAAC,EAAE,uCAAuC,EAAE,CAAA;CACjE"}
@@ -1 +1 @@
1
- {"version":3,"file":"message.js","sourceRoot":"","sources":["../../../src/types/resources/message.ts"],"names":[],"mappings":"","sourcesContent":["import { DenormalizedAttachmentResource } from './denormalized_attachment_resource'\nimport { DenormalizedAttachmentResourceForCreate } from './denormalized_attachment_resource_for_create'\nimport type { PersonResource } from './person'\nimport type { ReactionCountResource } from './reaction'\n\nexport interface MessageResource {\n type: 'Message'\n id: string\n text: string | null\n html: string\n createdAt: string\n deletedAt: string | null\n textEditedAt: string | null\n mine: boolean\n attachments: DenormalizedAttachmentResource[]\n author: PersonResource\n reactionCounts: ReactionCountResource[]\n replyCount: number\n replyRootId?: string | null\n\n // Custom Local Properties we set for rendering\n renderAuthor?: boolean\n renderTime?: boolean\n myLatestInConversation?: boolean\n lastInGroup?: boolean\n threadPosition?: 'first' | 'center' | 'last' | null\n prevIsMyReply?: boolean\n nextIsMyReply?: boolean\n nextRendersAuthor?: boolean\n isReplyShadowMessage?: boolean\n nextIsReplyShadowMessage?: boolean\n\n // Properties for mutation state\n pending?: boolean // Indicates if the message is optimistically created and pending server response\n error?: string // Error message if the message failed to send\n attachmentsForCreate?: DenormalizedAttachmentResourceForCreate[]\n}\n"]}
1
+ {"version":3,"file":"message.js","sourceRoot":"","sources":["../../../src/types/resources/message.ts"],"names":[],"mappings":"","sourcesContent":["import { DenormalizedAttachmentResource } from './denormalized_attachment_resource'\nimport { DenormalizedAttachmentResourceForCreate } from './denormalized_attachment_resource_for_create'\nimport type { PersonResource } from './person'\nimport type { ReactionCountResource } from './reaction'\n\nexport interface MessageResource {\n type: 'Message'\n id: string\n text: string | null\n html: string\n createdAt: string\n deletedAt: string | null\n textEditedAt: string | null\n mine: boolean\n attachments: DenormalizedAttachmentResource[]\n author: PersonResource\n reactionCounts: ReactionCountResource[]\n replyCount: number\n replyRootId?: string | null\n messageType: string\n personIdsForSystemEvent?: number[] | null\n systemTextParts?: { names: string[]; overflowCount: number; action: string } | null\n\n // Custom Local Properties we set for rendering\n renderAuthor?: boolean\n renderTime?: boolean\n myLatestInConversation?: boolean\n lastInGroup?: boolean\n threadPosition?: 'first' | 'center' | 'last' | null\n prevIsMyReply?: boolean\n nextIsMyReply?: boolean\n nextRendersAuthor?: boolean\n isReplyShadowMessage?: boolean\n nextIsReplyShadowMessage?: boolean\n\n // Properties for mutation state\n pending?: boolean // Indicates if the message is optimistically created and pending server response\n error?: string // Error message if the message failed to send\n attachmentsForCreate?: DenormalizedAttachmentResourceForCreate[]\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"optimistically_create_message.d.ts","sourceRoot":"","sources":["../../../src/utils/cache/optimistically_create_message.ts"],"names":[],"mappings":"AAEA,OAAO,EAAiB,qBAAqB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAEnF,OAAO,EAAE,uCAAuC,EAAE,MAAM,mEAAmE,CAAA;AAM3H,wBAAgB,2BAA2B,CAAC,EAC1C,cAAc,EACd,IAAI,EACJ,WAAW,EACX,aAAa,EACb,OAAO,EACP,WAAW,GACZ,EAAE;IACD,cAAc,EAAE,MAAM,CAAA;IACtB,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,CAAC,EAAE,uCAAuC,EAAE,CAAA;IACvD,aAAa,EAAE,qBAAqB,CAAA;IACpC,OAAO,CAAC,EAAE,eAAe,CAAA;IACzB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAC5B,mBA+CA"}
1
+ {"version":3,"file":"optimistically_create_message.d.ts","sourceRoot":"","sources":["../../../src/utils/cache/optimistically_create_message.ts"],"names":[],"mappings":"AAEA,OAAO,EAAiB,qBAAqB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAEnF,OAAO,EAAE,uCAAuC,EAAE,MAAM,mEAAmE,CAAA;AAM3H,wBAAgB,2BAA2B,CAAC,EAC1C,cAAc,EACd,IAAI,EACJ,WAAW,EACX,aAAa,EACb,OAAO,EACP,WAAW,GACZ,EAAE;IACD,cAAc,EAAE,MAAM,CAAA;IACtB,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,CAAC,EAAE,uCAAuC,EAAE,CAAA;IACvD,aAAa,EAAE,qBAAqB,CAAA;IACpC,OAAO,CAAC,EAAE,eAAe,CAAA;IACzB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAC5B,mBAgDA"}
@@ -11,6 +11,7 @@ export function optimisticallyCreateMessage({ conversationId, text, attachments,
11
11
  const optimisticMessage = {
12
12
  ...message,
13
13
  type: 'Message',
14
+ messageType: 'user',
14
15
  id,
15
16
  text,
16
17
  html: '', // Will be filled by server
@@ -1 +1 @@
1
- {"version":3,"file":"optimistically_create_message.js","sourceRoot":"","sources":["../../../src/utils/cache/optimistically_create_message.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAA;AAI7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAA;AACtE,OAAO,EAAE,2BAA2B,EAAE,MAAM,mCAAmC,CAAA;AAC/E,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAA;AACtE,OAAO,EAAE,+BAA+B,EAAE,MAAM,kBAAkB,CAAA;AAElE,MAAM,UAAU,2BAA2B,CAAC,EAC1C,cAAc,EACd,IAAI,EACJ,WAAW,EACX,aAAa,EACb,OAAO,EACP,WAAW,GAQZ;IACC,MAAM,EAAE,GAAG,OAAO,EAAE,EAAE,IAAI,qBAAqB,EAAE,CAAA;IAEjD,+DAA+D;IAC/D,MAAM,oBAAoB,GAAqC,2BAA2B,CACxF,WAAW,IAAI,EAAE,CAClB,CAAA;IAED,+BAA+B;IAC/B,MAAM,iBAAiB,GAAoB;QACzC,GAAG,OAAO;QACV,IAAI,EAAE,SAAS;QACf,EAAE;QACF,IAAI;QACJ,IAAI,EAAE,EAAE,EAAE,2BAA2B;QACrC,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,SAAS,EAAE,IAAI;QACf,YAAY,EAAE,IAAI;QAClB,IAAI,EAAE,IAAI;QACV,WAAW,EAAE,oBAAoB;QACjC,oBAAoB,EAAE,WAAW,IAAI,EAAE;QACvC,MAAM,EAAE,aAAa;QACrB,cAAc,EAAE,EAAE;QAClB,YAAY,EAAE,KAAK;QACnB,UAAU,EAAE,IAAI;QAChB,sBAAsB,EAAE,IAAI;QAC5B,WAAW,EAAE,IAAI;QACjB,OAAO,EAAE,IAAI;QACb,UAAU,EAAE,CAAC;QACb,WAAW,EAAE,WAAW,IAAI,IAAI;KACjC,CAAA;IAID,MAAM,QAAQ,GAAG,mBAAmB,CAAC;QACnC,eAAe,EAAE,cAAc;QAC/B,aAAa,EAAE,WAAW;KAC3B,CAAC,CAAA;IAEF,eAAe,CAAC,YAAY,CAAY,QAAQ,EAAE,IAAI,CAAC,EAAE,CACvD,+BAA+B,CAAC;QAC9B,IAAI;QACJ,MAAM,EAAE,iBAAoC;KAC7C,CAAC,CACH,CAAA;IAED,OAAO,iBAAiB,CAAA;AAC1B,CAAC;AAED,MAAM,qBAAqB,GAAG,GAAG,EAAE;IACjC,0FAA0F;IAC1F,sEAAsE;IACtE,OAAO,GAAG,uBAAuB,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,OAAO,CAAA;AAC9D,CAAC,CAAA","sourcesContent":["import { InfiniteData } from '@tanstack/react-query'\nimport { chatQueryClient } from '../../contexts/api_provider'\nimport { ApiCollection, CurrentPersonResource, MessageResource } from '../../types'\nimport { DenormalizedAttachmentResource } from '../../types/resources/denormalized_attachment_resource'\nimport { DenormalizedAttachmentResourceForCreate } from '../../types/resources/denormalized_attachment_resource_for_create'\nimport { getMessagesQueryKey } from '../../utils/request/get_messages'\nimport { convertAttachmentsForCreate } from '../convert_attachments_for_create'\nimport { generatePlaceholderUlid } from '../generate_placeholder_ulid'\nimport { updateOrCreateRecordInPagesData } from './page_mutations'\n\nexport function optimisticallyCreateMessage({\n conversationId,\n text,\n attachments,\n currentPerson,\n message,\n replyRootId,\n}: {\n conversationId: number\n text: string\n attachments?: DenormalizedAttachmentResourceForCreate[]\n currentPerson: CurrentPersonResource\n message?: MessageResource\n replyRootId?: string | null\n}) {\n const id = message?.id || generateTempMessageId()\n\n // Convert attachments to denormalized format for optimistic UI\n const decoratedAttachments: DenormalizedAttachmentResource[] = convertAttachmentsForCreate(\n attachments || []\n )\n\n // Create an optimistic message\n const optimisticMessage: MessageResource = {\n ...message,\n type: 'Message',\n id,\n text,\n html: '', // Will be filled by server\n createdAt: new Date().toISOString(),\n deletedAt: null,\n textEditedAt: null,\n mine: true,\n attachments: decoratedAttachments,\n attachmentsForCreate: attachments || [],\n author: currentPerson,\n reactionCounts: [],\n renderAuthor: false,\n renderTime: true,\n myLatestInConversation: true,\n lastInGroup: true,\n pending: true,\n replyCount: 0,\n replyRootId: replyRootId || null,\n }\n\n // Add the optimistic message to the cache\n type QueryData = InfiniteData<ApiCollection<MessageResource>>\n const queryKey = getMessagesQueryKey({\n conversation_id: conversationId,\n reply_root_id: replyRootId,\n })\n\n chatQueryClient.setQueryData<QueryData>(queryKey, data =>\n updateOrCreateRecordInPagesData({\n data,\n record: optimisticMessage as MessageResource,\n })\n )\n\n return optimisticMessage\n}\n\nconst generateTempMessageId = () => {\n // Put it 5 seconds in the future to account for server lag of previously created messages\n // that are still pending. This gets overwritten by the server anyway.\n return `${generatePlaceholderUlid({ offsetMs: 5000 })}-temp`\n}\n"]}
1
+ {"version":3,"file":"optimistically_create_message.js","sourceRoot":"","sources":["../../../src/utils/cache/optimistically_create_message.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAA;AAI7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAA;AACtE,OAAO,EAAE,2BAA2B,EAAE,MAAM,mCAAmC,CAAA;AAC/E,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAA;AACtE,OAAO,EAAE,+BAA+B,EAAE,MAAM,kBAAkB,CAAA;AAElE,MAAM,UAAU,2BAA2B,CAAC,EAC1C,cAAc,EACd,IAAI,EACJ,WAAW,EACX,aAAa,EACb,OAAO,EACP,WAAW,GAQZ;IACC,MAAM,EAAE,GAAG,OAAO,EAAE,EAAE,IAAI,qBAAqB,EAAE,CAAA;IAEjD,+DAA+D;IAC/D,MAAM,oBAAoB,GAAqC,2BAA2B,CACxF,WAAW,IAAI,EAAE,CAClB,CAAA;IAED,+BAA+B;IAC/B,MAAM,iBAAiB,GAAoB;QACzC,GAAG,OAAO;QACV,IAAI,EAAE,SAAS;QACf,WAAW,EAAE,MAAM;QACnB,EAAE;QACF,IAAI;QACJ,IAAI,EAAE,EAAE,EAAE,2BAA2B;QACrC,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,SAAS,EAAE,IAAI;QACf,YAAY,EAAE,IAAI;QAClB,IAAI,EAAE,IAAI;QACV,WAAW,EAAE,oBAAoB;QACjC,oBAAoB,EAAE,WAAW,IAAI,EAAE;QACvC,MAAM,EAAE,aAAa;QACrB,cAAc,EAAE,EAAE;QAClB,YAAY,EAAE,KAAK;QACnB,UAAU,EAAE,IAAI;QAChB,sBAAsB,EAAE,IAAI;QAC5B,WAAW,EAAE,IAAI;QACjB,OAAO,EAAE,IAAI;QACb,UAAU,EAAE,CAAC;QACb,WAAW,EAAE,WAAW,IAAI,IAAI;KACjC,CAAA;IAID,MAAM,QAAQ,GAAG,mBAAmB,CAAC;QACnC,eAAe,EAAE,cAAc;QAC/B,aAAa,EAAE,WAAW;KAC3B,CAAC,CAAA;IAEF,eAAe,CAAC,YAAY,CAAY,QAAQ,EAAE,IAAI,CAAC,EAAE,CACvD,+BAA+B,CAAC;QAC9B,IAAI;QACJ,MAAM,EAAE,iBAAoC;KAC7C,CAAC,CACH,CAAA;IAED,OAAO,iBAAiB,CAAA;AAC1B,CAAC;AAED,MAAM,qBAAqB,GAAG,GAAG,EAAE;IACjC,0FAA0F;IAC1F,sEAAsE;IACtE,OAAO,GAAG,uBAAuB,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,OAAO,CAAA;AAC9D,CAAC,CAAA","sourcesContent":["import { InfiniteData } from '@tanstack/react-query'\nimport { chatQueryClient } from '../../contexts/api_provider'\nimport { ApiCollection, CurrentPersonResource, MessageResource } from '../../types'\nimport { DenormalizedAttachmentResource } from '../../types/resources/denormalized_attachment_resource'\nimport { DenormalizedAttachmentResourceForCreate } from '../../types/resources/denormalized_attachment_resource_for_create'\nimport { getMessagesQueryKey } from '../../utils/request/get_messages'\nimport { convertAttachmentsForCreate } from '../convert_attachments_for_create'\nimport { generatePlaceholderUlid } from '../generate_placeholder_ulid'\nimport { updateOrCreateRecordInPagesData } from './page_mutations'\n\nexport function optimisticallyCreateMessage({\n conversationId,\n text,\n attachments,\n currentPerson,\n message,\n replyRootId,\n}: {\n conversationId: number\n text: string\n attachments?: DenormalizedAttachmentResourceForCreate[]\n currentPerson: CurrentPersonResource\n message?: MessageResource\n replyRootId?: string | null\n}) {\n const id = message?.id || generateTempMessageId()\n\n // Convert attachments to denormalized format for optimistic UI\n const decoratedAttachments: DenormalizedAttachmentResource[] = convertAttachmentsForCreate(\n attachments || []\n )\n\n // Create an optimistic message\n const optimisticMessage: MessageResource = {\n ...message,\n type: 'Message',\n messageType: 'user',\n id,\n text,\n html: '', // Will be filled by server\n createdAt: new Date().toISOString(),\n deletedAt: null,\n textEditedAt: null,\n mine: true,\n attachments: decoratedAttachments,\n attachmentsForCreate: attachments || [],\n author: currentPerson,\n reactionCounts: [],\n renderAuthor: false,\n renderTime: true,\n myLatestInConversation: true,\n lastInGroup: true,\n pending: true,\n replyCount: 0,\n replyRootId: replyRootId || null,\n }\n\n // Add the optimistic message to the cache\n type QueryData = InfiniteData<ApiCollection<MessageResource>>\n const queryKey = getMessagesQueryKey({\n conversation_id: conversationId,\n reply_root_id: replyRootId,\n })\n\n chatQueryClient.setQueryData<QueryData>(queryKey, data =>\n updateOrCreateRecordInPagesData({\n data,\n record: optimisticMessage as MessageResource,\n })\n )\n\n return optimisticMessage\n}\n\nconst generateTempMessageId = () => {\n // Put it 5 seconds in the future to account for server lag of previously created messages\n // that are still pending. This gets overwritten by the server anyway.\n return `${generatePlaceholderUlid({ offsetMs: 5000 })}-temp`\n}\n"]}
@@ -10,4 +10,5 @@ export * from './reaction_constants';
10
10
  export * from './destructure_chat_group_graph_id';
11
11
  export * from './convert_attachments_for_create';
12
12
  export * from './assert_keys_are_numbers';
13
+ export * from './system_messages';
13
14
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAA;AACzB,cAAc,SAAS,CAAA;AACvB,cAAc,UAAU,CAAA;AACxB,cAAc,UAAU,CAAA;AACxB,cAAc,OAAO,CAAA;AACrB,cAAc,SAAS,CAAA;AACvB,cAAc,mBAAmB,CAAA;AACjC,cAAc,aAAa,CAAA;AAC3B,cAAc,sBAAsB,CAAA;AACpC,cAAc,mCAAmC,CAAA;AACjD,cAAc,kCAAkC,CAAA;AAChD,cAAc,2BAA2B,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAA;AACzB,cAAc,SAAS,CAAA;AACvB,cAAc,UAAU,CAAA;AACxB,cAAc,UAAU,CAAA;AACxB,cAAc,OAAO,CAAA;AACrB,cAAc,SAAS,CAAA;AACvB,cAAc,mBAAmB,CAAA;AACjC,cAAc,aAAa,CAAA;AAC3B,cAAc,sBAAsB,CAAA;AACpC,cAAc,mCAAmC,CAAA;AACjD,cAAc,kCAAkC,CAAA;AAChD,cAAc,2BAA2B,CAAA;AACzC,cAAc,mBAAmB,CAAA"}
@@ -10,4 +10,5 @@ export * from './reaction_constants';
10
10
  export * from './destructure_chat_group_graph_id';
11
11
  export * from './convert_attachments_for_create';
12
12
  export * from './assert_keys_are_numbers';
13
+ export * from './system_messages';
13
14
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAA;AACzB,cAAc,SAAS,CAAA;AACvB,cAAc,UAAU,CAAA;AACxB,cAAc,UAAU,CAAA;AACxB,cAAc,OAAO,CAAA;AACrB,cAAc,SAAS,CAAA;AACvB,cAAc,mBAAmB,CAAA;AACjC,cAAc,aAAa,CAAA;AAC3B,cAAc,sBAAsB,CAAA;AACpC,cAAc,mCAAmC,CAAA;AACjD,cAAc,kCAAkC,CAAA;AAChD,cAAc,2BAA2B,CAAA","sourcesContent":["export * from './session'\nexport * from './theme'\nexport * from './styles'\nexport * from './client'\nexport * from './uri'\nexport * from './cache'\nexport * from './native_adapters'\nexport * from './pluralize'\nexport * from './reaction_constants'\nexport * from './destructure_chat_group_graph_id'\nexport * from './convert_attachments_for_create'\nexport * from './assert_keys_are_numbers'\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAA;AACzB,cAAc,SAAS,CAAA;AACvB,cAAc,UAAU,CAAA;AACxB,cAAc,UAAU,CAAA;AACxB,cAAc,OAAO,CAAA;AACrB,cAAc,SAAS,CAAA;AACvB,cAAc,mBAAmB,CAAA;AACjC,cAAc,aAAa,CAAA;AAC3B,cAAc,sBAAsB,CAAA;AACpC,cAAc,mCAAmC,CAAA;AACjD,cAAc,kCAAkC,CAAA;AAChD,cAAc,2BAA2B,CAAA;AACzC,cAAc,mBAAmB,CAAA","sourcesContent":["export * from './session'\nexport * from './theme'\nexport * from './styles'\nexport * from './client'\nexport * from './uri'\nexport * from './cache'\nexport * from './native_adapters'\nexport * from './pluralize'\nexport * from './reaction_constants'\nexport * from './destructure_chat_group_graph_id'\nexport * from './convert_attachments_for_create'\nexport * from './assert_keys_are_numbers'\nexport * from './system_messages'\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"transform_message_event_data_to_message_resource.d.ts","sourceRoot":"","sources":["../../../src/utils/jolt/transform_message_event_data_to_message_resource.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAC7C,OAAO,EAAE,mBAAmB,EAAE,MAAM,wCAAwC,CAAA;AAI5E,wBAAgB,0CAA0C,CAAC,EACzD,IAAI,EACJ,eAAe,GAChB,EAAE;IACD,IAAI,EAAE,mBAAmB,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAA;IACzC,eAAe,EAAE,MAAM,CAAA;CACxB,GAAG,eAAe,CAqBlB"}
1
+ {"version":3,"file":"transform_message_event_data_to_message_resource.d.ts","sourceRoot":"","sources":["../../../src/utils/jolt/transform_message_event_data_to_message_resource.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAC7C,OAAO,EAAE,mBAAmB,EAAE,MAAM,wCAAwC,CAAA;AAI5E,wBAAgB,0CAA0C,CAAC,EACzD,IAAI,EACJ,eAAe,GAChB,EAAE;IACD,IAAI,EAAE,mBAAmB,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAA;IACzC,eAAe,EAAE,MAAM,CAAA;CACxB,GAAG,eAAe,CA8BlB"}
@@ -19,6 +19,15 @@ export function transformMessageEventDataToMessageResource({ data, currentPerson
19
19
  reactionCounts: [],
20
20
  replyCount: data.reply_count || 0,
21
21
  replyRootId: data.reply_root_id || null,
22
+ messageType: data.message_type,
23
+ personIdsForSystemEvent: data.system_event_person_ids,
24
+ systemTextParts: data.system_text_parts
25
+ ? {
26
+ names: data.system_text_parts.names,
27
+ overflowCount: data.system_text_parts.overflow_count,
28
+ action: data.system_text_parts.action,
29
+ }
30
+ : null,
22
31
  };
23
32
  }
24
33
  //# sourceMappingURL=transform_message_event_data_to_message_resource.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"transform_message_event_data_to_message_resource.js","sourceRoot":"","sources":["../../../src/utils/jolt/transform_message_event_data_to_message_resource.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AAExD,MAAM,UAAU,0CAA0C,CAAC,EACzD,IAAI,EACJ,eAAe,GAIhB;IACC,OAAO;QACL,IAAI,EAAE,SAAS;QACf,EAAE,EAAE,IAAI,CAAC,QAAQ;QACjB,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,SAAS,EAAE,IAAI,CAAC,UAAU;QAC1B,SAAS,EAAE,IAAI,CAAC,UAAU;QAC1B,YAAY,EAAE,IAAI,CAAC,cAAc;QACjC,IAAI,EAAE,IAAI,CAAC,SAAS,KAAK,eAAe;QACxC,WAAW,EAAE,iBAAiB,CAAmC,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE;QACxF,MAAM,EAAE;YACN,IAAI,EAAE,QAAQ;YACd,EAAE,EAAE,IAAI,CAAC,SAAS;YAClB,IAAI,EAAE,IAAI,CAAC,WAAW;YACtB,MAAM,EAAE,IAAI,CAAC,aAAa;SAC3B;QACD,cAAc,EAAE,EAAE;QAClB,UAAU,EAAE,IAAI,CAAC,WAAW,IAAI,CAAC;QACjC,WAAW,EAAE,IAAI,CAAC,aAAa,IAAI,IAAI;KACxC,CAAA;AACH,CAAC","sourcesContent":["import { MessageResource } from '../../types'\nimport { MessageCreatedEvent } from '../../types/jolt_events/message_events'\nimport { DenormalizedAttachmentResource } from '../../types/resources/denormalized_attachment_resource'\nimport { deepCamelCaseKeys } from '../deepCamelCaseKeys'\n\nexport function transformMessageEventDataToMessageResource({\n data,\n currentPersonId,\n}: {\n data: MessageCreatedEvent['data']['data']\n currentPersonId: number\n}): MessageResource {\n return {\n type: 'Message',\n id: data.sort_key,\n text: data.text,\n html: data.html,\n createdAt: data.created_at,\n deletedAt: data.deleted_at,\n textEditedAt: data.text_edited_at,\n mine: data.author_id === currentPersonId,\n attachments: deepCamelCaseKeys<DenormalizedAttachmentResource[]>(data.attachments) || [],\n author: {\n type: 'Person',\n id: data.author_id,\n name: data.author_name,\n avatar: data.author_avatar,\n },\n reactionCounts: [],\n replyCount: data.reply_count || 0,\n replyRootId: data.reply_root_id || null,\n }\n}\n"]}
1
+ {"version":3,"file":"transform_message_event_data_to_message_resource.js","sourceRoot":"","sources":["../../../src/utils/jolt/transform_message_event_data_to_message_resource.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AAExD,MAAM,UAAU,0CAA0C,CAAC,EACzD,IAAI,EACJ,eAAe,GAIhB;IACC,OAAO;QACL,IAAI,EAAE,SAAS;QACf,EAAE,EAAE,IAAI,CAAC,QAAQ;QACjB,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,SAAS,EAAE,IAAI,CAAC,UAAU;QAC1B,SAAS,EAAE,IAAI,CAAC,UAAU;QAC1B,YAAY,EAAE,IAAI,CAAC,cAAc;QACjC,IAAI,EAAE,IAAI,CAAC,SAAS,KAAK,eAAe;QACxC,WAAW,EAAE,iBAAiB,CAAmC,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE;QACxF,MAAM,EAAE;YACN,IAAI,EAAE,QAAQ;YACd,EAAE,EAAE,IAAI,CAAC,SAAS;YAClB,IAAI,EAAE,IAAI,CAAC,WAAW;YACtB,MAAM,EAAE,IAAI,CAAC,aAAa;SAC3B;QACD,cAAc,EAAE,EAAE;QAClB,UAAU,EAAE,IAAI,CAAC,WAAW,IAAI,CAAC;QACjC,WAAW,EAAE,IAAI,CAAC,aAAa,IAAI,IAAI;QACvC,WAAW,EAAE,IAAI,CAAC,YAAY;QAC9B,uBAAuB,EAAE,IAAI,CAAC,uBAAuB;QACrD,eAAe,EAAE,IAAI,CAAC,iBAAiB;YACrC,CAAC,CAAC;gBACE,KAAK,EAAE,IAAI,CAAC,iBAAiB,CAAC,KAAK;gBACnC,aAAa,EAAE,IAAI,CAAC,iBAAiB,CAAC,cAAc;gBACpD,MAAM,EAAE,IAAI,CAAC,iBAAiB,CAAC,MAAM;aACtC;YACH,CAAC,CAAC,IAAI;KACT,CAAA;AACH,CAAC","sourcesContent":["import { MessageResource } from '../../types'\nimport { MessageCreatedEvent } from '../../types/jolt_events/message_events'\nimport { DenormalizedAttachmentResource } from '../../types/resources/denormalized_attachment_resource'\nimport { deepCamelCaseKeys } from '../deepCamelCaseKeys'\n\nexport function transformMessageEventDataToMessageResource({\n data,\n currentPersonId,\n}: {\n data: MessageCreatedEvent['data']['data']\n currentPersonId: number\n}): MessageResource {\n return {\n type: 'Message',\n id: data.sort_key,\n text: data.text,\n html: data.html,\n createdAt: data.created_at,\n deletedAt: data.deleted_at,\n textEditedAt: data.text_edited_at,\n mine: data.author_id === currentPersonId,\n attachments: deepCamelCaseKeys<DenormalizedAttachmentResource[]>(data.attachments) || [],\n author: {\n type: 'Person',\n id: data.author_id,\n name: data.author_name,\n avatar: data.author_avatar,\n },\n reactionCounts: [],\n replyCount: data.reply_count || 0,\n replyRootId: data.reply_root_id || null,\n messageType: data.message_type,\n personIdsForSystemEvent: data.system_event_person_ids,\n systemTextParts: data.system_text_parts\n ? {\n names: data.system_text_parts.names,\n overflowCount: data.system_text_parts.overflow_count,\n action: data.system_text_parts.action,\n }\n : null,\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"messages_data_options.d.ts","sourceRoot":"","sources":["../../../src/utils/request/messages_data_options.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB;;;;CAe5B,CAAA;AAED,eAAO,MAAM,kBAAkB,UAAgC,CAAA"}
1
+ {"version":3,"file":"messages_data_options.d.ts","sourceRoot":"","sources":["../../../src/utils/request/messages_data_options.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB;;;;CAkB5B,CAAA;AAED,eAAO,MAAM,kBAAkB,UAAgC,CAAA"}
@@ -10,6 +10,9 @@ export const getMessageFields = {
10
10
  'reaction_counts',
11
11
  'reply_count',
12
12
  'reply_root',
13
+ 'message_type',
14
+ 'person_ids_for_system_event',
15
+ 'system_text_parts',
13
16
  ],
14
17
  Person: ['name', 'avatar'],
15
18
  ReactionCount: ['value', 'count', 'mine', 'message_id', 'author_ids'],
@@ -1 +1 @@
1
- {"version":3,"file":"messages_data_options.js","sourceRoot":"","sources":["../../../src/utils/request/messages_data_options.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,OAAO,EAAE;QACP,MAAM;QACN,gBAAgB;QAChB,MAAM;QACN,aAAa;QACb,YAAY;QACZ,YAAY;QACZ,QAAQ;QACR,iBAAiB;QACjB,aAAa;QACb,YAAY;KACb;IACD,MAAM,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC;IAC1B,aAAa,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,YAAY,CAAC;CACtE,CAAA;AAED,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,QAAQ,EAAE,iBAAiB,CAAC,CAAA","sourcesContent":["export const getMessageFields = {\n Message: [\n 'text',\n 'text_edited_at',\n 'mine',\n 'attachments',\n 'created_at',\n 'deleted_at',\n 'author',\n 'reaction_counts',\n 'reply_count',\n 'reply_root',\n ],\n Person: ['name', 'avatar'],\n ReactionCount: ['value', 'count', 'mine', 'message_id', 'author_ids'],\n}\n\nexport const getMessagesInclude = ['author', 'reaction_counts']\n"]}
1
+ {"version":3,"file":"messages_data_options.js","sourceRoot":"","sources":["../../../src/utils/request/messages_data_options.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,OAAO,EAAE;QACP,MAAM;QACN,gBAAgB;QAChB,MAAM;QACN,aAAa;QACb,YAAY;QACZ,YAAY;QACZ,QAAQ;QACR,iBAAiB;QACjB,aAAa;QACb,YAAY;QACZ,cAAc;QACd,6BAA6B;QAC7B,mBAAmB;KACpB;IACD,MAAM,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC;IAC1B,aAAa,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,YAAY,CAAC;CACtE,CAAA;AAED,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,QAAQ,EAAE,iBAAiB,CAAC,CAAA","sourcesContent":["export const getMessageFields = {\n Message: [\n 'text',\n 'text_edited_at',\n 'mine',\n 'attachments',\n 'created_at',\n 'deleted_at',\n 'author',\n 'reaction_counts',\n 'reply_count',\n 'reply_root',\n 'message_type',\n 'person_ids_for_system_event',\n 'system_text_parts',\n ],\n Person: ['name', 'avatar'],\n ReactionCount: ['value', 'count', 'mine', 'message_id', 'author_ids'],\n}\n\nexport const getMessagesInclude = ['author', 'reaction_counts']\n"]}
@@ -0,0 +1,15 @@
1
+ import { MessageResource } from '../types';
2
+ declare const SYSTEM_MESSAGE_TYPES: readonly ["user_joined"];
3
+ type SystemMessageType = (typeof SYSTEM_MESSAGE_TYPES)[number];
4
+ export interface SystemMessageResource extends MessageResource {
5
+ messageType: SystemMessageType;
6
+ systemTextParts: {
7
+ names: string[];
8
+ overflowCount: number;
9
+ action: string;
10
+ };
11
+ personIdsForSystemEvent: number[];
12
+ }
13
+ export declare const isSystemMessage: (message: MessageResource) => message is SystemMessageResource;
14
+ export {};
15
+ //# sourceMappingURL=system_messages.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"system_messages.d.ts","sourceRoot":"","sources":["../../src/utils/system_messages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAE1C,QAAA,MAAM,oBAAoB,0BAA2B,CAAA;AAErD,KAAK,iBAAiB,GAAG,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAA;AAE9D,MAAM,WAAW,qBAAsB,SAAQ,eAAe;IAC5D,WAAW,EAAE,iBAAiB,CAAA;IAC9B,eAAe,EAAE;QAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QAAC,aAAa,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAA;IAC3E,uBAAuB,EAAE,MAAM,EAAE,CAAA;CAClC;AAED,eAAO,MAAM,eAAe,YAAa,eAAe,KAAG,OAAO,IAAI,qBAG7B,CAAA"}
@@ -0,0 +1,5 @@
1
+ const SYSTEM_MESSAGE_TYPES = ['user_joined'];
2
+ export const isSystemMessage = (message) => SYSTEM_MESSAGE_TYPES.includes(message.messageType) &&
3
+ message.systemTextParts != null &&
4
+ message.personIdsForSystemEvent != null;
5
+ //# sourceMappingURL=system_messages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"system_messages.js","sourceRoot":"","sources":["../../src/utils/system_messages.ts"],"names":[],"mappings":"AAEA,MAAM,oBAAoB,GAAG,CAAC,aAAa,CAAU,CAAA;AAUrD,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,OAAwB,EAAoC,EAAE,CAC5F,oBAAoB,CAAC,QAAQ,CAAC,OAAO,CAAC,WAAgC,CAAC;IACvE,OAAO,CAAC,eAAe,IAAI,IAAI;IAC/B,OAAO,CAAC,uBAAuB,IAAI,IAAI,CAAA","sourcesContent":["import { MessageResource } from '../types'\n\nconst SYSTEM_MESSAGE_TYPES = ['user_joined'] as const\n\ntype SystemMessageType = (typeof SYSTEM_MESSAGE_TYPES)[number]\n\nexport interface SystemMessageResource extends MessageResource {\n messageType: SystemMessageType\n systemTextParts: { names: string[]; overflowCount: number; action: string }\n personIdsForSystemEvent: number[]\n}\n\nexport const isSystemMessage = (message: MessageResource): message is SystemMessageResource =>\n SYSTEM_MESSAGE_TYPES.includes(message.messageType as SystemMessageType) &&\n message.systemTextParts != null &&\n message.personIdsForSystemEvent != null\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@planningcenter/chat-react-native",
3
- "version": "3.30.0-rc.8",
3
+ "version": "3.31.0-rc.0",
4
4
  "description": "",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -63,5 +63,5 @@
63
63
  "react-native-url-polyfill": "^2.0.0",
64
64
  "typescript": "<5.6.0"
65
65
  },
66
- "gitHead": "899c053eee50e34f2cbd49d683a9fc5a37166fb2"
66
+ "gitHead": "fa356fa66131d03bce2d2f9aab170ca1e35371f3"
67
67
  }
@@ -0,0 +1,79 @@
1
+ import { MessageResource } from '../../types'
2
+ import { isSystemMessage } from '../../utils/system_messages'
3
+
4
+ const makeMessage = (overrides: Partial<MessageResource> = {}): MessageResource => ({
5
+ type: 'Message',
6
+ id: '1',
7
+ text: null,
8
+ html: '',
9
+ createdAt: '2026-01-01T00:00:00Z',
10
+ deletedAt: null,
11
+ textEditedAt: null,
12
+ mine: false,
13
+ attachments: [],
14
+ author: { id: -1, name: 'System', avatar: '' },
15
+ reactionCounts: [],
16
+ replyCount: 0,
17
+ replyRootId: null,
18
+ messageType: 'user',
19
+ personIdsForSystemEvent: null,
20
+ systemTextParts: null,
21
+ ...overrides,
22
+ })
23
+
24
+ describe('isSystemMessage', () => {
25
+ it('returns true for user_joined messages', () => {
26
+ const message = makeMessage({
27
+ messageType: 'user_joined',
28
+ personIdsForSystemEvent: [1],
29
+ systemTextParts: { names: ['Alice'], overflowCount: 0, action: 'joined the conversation' },
30
+ })
31
+ expect(isSystemMessage(message)).toBe(true)
32
+ })
33
+
34
+ it('narrows the type so systemTextParts and personIdsForSystemEvent are non-null', () => {
35
+ const message = makeMessage({
36
+ messageType: 'user_joined',
37
+ personIdsForSystemEvent: [1, 2],
38
+ systemTextParts: {
39
+ names: ['Alice', 'Bob'],
40
+ overflowCount: 0,
41
+ action: 'joined the conversation',
42
+ },
43
+ })
44
+ if (isSystemMessage(message)) {
45
+ expect(message.systemTextParts.names).toEqual(['Alice', 'Bob'])
46
+ expect(message.personIdsForSystemEvent).toEqual([1, 2])
47
+ } else {
48
+ throw new Error('Expected isSystemMessage to return true')
49
+ }
50
+ })
51
+
52
+ it('returns false for regular user messages', () => {
53
+ const message = makeMessage({ messageType: 'user' })
54
+ expect(isSystemMessage(message)).toBe(false)
55
+ })
56
+
57
+ it('returns false for unknown message types', () => {
58
+ const message = makeMessage({ messageType: 'some_future_type' })
59
+ expect(isSystemMessage(message)).toBe(false)
60
+ })
61
+
62
+ it('returns false when systemTextParts is null', () => {
63
+ const message = makeMessage({
64
+ messageType: 'user_joined',
65
+ personIdsForSystemEvent: [1],
66
+ systemTextParts: null,
67
+ })
68
+ expect(isSystemMessage(message)).toBe(false)
69
+ })
70
+
71
+ it('returns false when personIdsForSystemEvent is null', () => {
72
+ const message = makeMessage({
73
+ messageType: 'user_joined',
74
+ personIdsForSystemEvent: null,
75
+ systemTextParts: { names: ['Alice'], overflowCount: 0, action: 'joined the conversation' },
76
+ })
77
+ expect(isSystemMessage(message)).toBe(false)
78
+ })
79
+ })