@planningcenter/chat-react-native 3.36.2-rc.2 → 3.37.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.
- package/build/hooks/groups/use_group_members_for_new_conversation.d.ts +0 -4
- package/build/hooks/groups/use_group_members_for_new_conversation.d.ts.map +1 -1
- package/build/hooks/groups/use_group_members_for_new_conversation.js +6 -18
- package/build/hooks/groups/use_group_members_for_new_conversation.js.map +1 -1
- package/build/hooks/services/use_team_members_for_new_conversation.d.ts.map +1 -1
- package/build/hooks/services/use_team_members_for_new_conversation.js +11 -4
- package/build/hooks/services/use_team_members_for_new_conversation.js.map +1 -1
- package/build/hooks/use_enrich_people.d.ts +13 -0
- package/build/hooks/use_enrich_people.d.ts.map +1 -0
- package/build/hooks/use_enrich_people.js +25 -0
- package/build/hooks/use_enrich_people.js.map +1 -0
- package/build/hooks/use_jolt.d.ts +2 -1
- package/build/hooks/use_jolt.d.ts.map +1 -1
- package/build/hooks/use_jolt.js.map +1 -1
- package/build/hooks/use_product_analytics.d.ts +7 -1
- package/build/hooks/use_product_analytics.d.ts.map +1 -1
- package/build/hooks/use_product_analytics.js +4 -0
- package/build/hooks/use_product_analytics.js.map +1 -1
- package/build/screens/conversation_details_screen.js +1 -1
- package/build/screens/conversation_details_screen.js.map +1 -1
- package/build/screens/conversation_screen.d.ts.map +1 -1
- package/build/screens/conversation_screen.js +2 -2
- package/build/screens/conversation_screen.js.map +1 -1
- package/build/screens/conversations/conversations_screen.js +2 -2
- package/build/screens/conversations/conversations_screen.js.map +1 -1
- package/build/types/jolt_events/index.d.ts +2 -0
- package/build/types/jolt_events/index.d.ts.map +1 -1
- package/build/types/jolt_events/index.js.map +1 -1
- package/package.json +2 -2
- package/src/__tests__/hooks/use_enrich_people.test.tsx +95 -0
- package/src/hooks/groups/use_group_members_for_new_conversation.ts +9 -23
- package/src/hooks/services/use_team_members_for_new_conversation.ts +18 -7
- package/src/hooks/use_enrich_people.ts +35 -0
- package/src/hooks/use_jolt.ts +2 -1
- package/src/hooks/use_product_analytics.ts +13 -3
- package/src/screens/conversation_details_screen.tsx +1 -1
- package/src/screens/conversation_screen.tsx +2 -1
- package/src/screens/conversations/conversations_screen.tsx +2 -2
- package/src/types/jolt_events/index.ts +3 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conversation_screen.js","sourceRoot":"","sources":["../../src/screens/conversation_screen.tsx"],"names":[],"mappings":"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","sourcesContent":["import { date as formatDate } from '@planningcenter/datetime-fmt'\nimport { HeaderTitle, HeaderTitleProps, PlatformPressable } from '@react-navigation/elements'\nimport {\n CommonActions,\n RouteProp,\n StaticScreenProps,\n useNavigation,\n useTheme as useNavigationTheme,\n useRoute,\n} from '@react-navigation/native'\nimport React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport { ActivityIndicator, FlatList, Platform, StyleSheet, View } from 'react-native'\nimport Animated, { FadeIn, FadeOut } from 'react-native-reanimated'\nimport { useSafeAreaInsets } from 'react-native-safe-area-context'\nimport { Badge, Icon, Text } from '../components'\nimport { EmptyConversationBlankState } from '../components/conversation/empty_conversation_blank_state'\nimport { JumpToBottomButton } from '../components/conversation/jump_to_bottom_button'\nimport { Message } from '../components/conversation/message'\nimport { MessageForm } from '../components/conversation/message_form'\nimport {\n ConversationDisabledBanner,\n LeaderMessagesDisabledBanner,\n MemberMessagesDisabledBanner,\n} from '../components/conversation/messages_disabled_banners'\nimport { ReplyShadowMessage } from '../components/conversation/reply_shadow_message'\nimport { SystemMessage } from '../components/conversation/system_message'\nimport { TypingIndicator } from '../components/conversation/typing_indicator'\nimport { UnreadDivider } from '../components/conversation/unread_divider'\nimport { KeyboardView } from '../components/display/keyboard_view'\nimport BlankState from '../components/primitive/blank_state_primitive'\nimport {\n ConversationContextProvider,\n useConversationContext,\n} from '../contexts/conversation_context'\nimport { useTheme } from '../hooks'\nimport { useConversation } from '../hooks/use_conversation'\nimport { useConversationJoltEvents } from '../hooks/use_conversation_jolt_events'\nimport { useConversationMessages } from '../hooks/use_conversation_messages'\nimport { useConversationMessagesJoltEvents } from '../hooks/use_conversation_messages_jolt_events'\nimport { availableFeatures, useFeatures } from '../hooks/use_features'\nimport { useFlatListViewability } from '../hooks/use_flat_list_viewability'\nimport { useJumpToBottomAction } from '../hooks/use_jump_to_bottom_action'\nimport { useJumpToUnreadAnchor } from '../hooks/use_jump_to_unread_anchor'\nimport { useJumpToUnreadGates } from '../hooks/use_jump_to_unread_gates'\nimport { useMarkLatestMessageRead } from '../hooks/use_mark_latest_message_read'\nimport {\n normalizeAnalyticsMetadata,\n usePublishProductAnalyticsEvent,\n} from '../hooks/use_product_analytics'\nimport { useScrollTracking } from '../hooks/use_scroll_tracking'\nimport { useTrackHighestSeenMessage } from '../hooks/use_track_highest_seen_message'\nimport { ConversationResource } from '../types/resources/conversation'\nimport { ConversationBadgeResource } from '../types/resources/conversation_badge'\nimport { MessageResource } from '../types/resources/message'\nimport { getRelativeDateStatus } from '../utils/date'\nimport {\n groupMessages,\n UNREAD_DIVIDER_KEY,\n type DateSeparator,\n type EnrichedMessage,\n} from '../utils/group_messages'\nimport {\n detectDividerExitTowardNewer,\n reportViewableMessages,\n type ViewabilityObserver,\n} from '../utils/message_viewability'\nimport { CONVERSATION_MESSAGE_LIST_PADDING_HORIZONTAL } from '../utils/styles'\nimport { isSystemMessage } from '../utils/system_messages'\n\nexport type ConversationRouteProps = {\n conversation_id: number\n reply_root_id?: string | null\n reply_root_author_name?: string\n chat_group_graph_id?: string\n clear_input?: boolean\n editing_message_id?: number | null\n message_id?: string\n title?: string\n subtitle?: string\n badge?: ConversationBadgeResource\n deleted?: boolean\n muted?: boolean\n}\n\nexport type ConversationScreenProps = StaticScreenProps<ConversationRouteProps>\n\nconst extractItemKey = (item: EnrichedMessage) => String(item.id)\nconst maintainVisibleContentPosition = { minIndexForVisible: 0 }\n\nexport function ConversationScreen({ route }: ConversationScreenProps) {\n const { conversation_id, message_id, reply_root_id } = route.params\n\n const { data: conversation } = useConversation({ conversation_id })\n const { featureEnabled } = useFeatures()\n\n usePublishProductAnalyticsEvent('chat.mobile.conversations.show.opened', {\n reply_root_id,\n ...normalizeAnalyticsMetadata(conversation),\n })\n\n const lastReadMessageSortKey = conversation.conversationMembership?.lastReadMessageSortKey ?? null\n const jumpToUnreadAnchor =\n featureEnabled(availableFeatures.jump_to_unread) && !reply_root_id\n ? lastReadMessageSortKey\n : null\n const initialMessageId = message_id ?? jumpToUnreadAnchor\n const initialMessageIdIsAnchor = !!initialMessageId && !message_id\n\n return (\n <ConversationContextProvider\n conversationId={conversation_id}\n currentPageReplyRootId={reply_root_id ?? null}\n initialMessageId={initialMessageId}\n initialMessageIdIsAnchor={initialMessageIdIsAnchor}\n >\n <ConversationScreenContent route={route} />\n </ConversationContextProvider>\n )\n}\n\nfunction ConversationScreenContent({ route }: ConversationScreenProps) {\n const styles = useStyles()\n const navigation = useNavigation()\n const {\n conversation_id: conversationId,\n editing_message_id: editingMessageId,\n reply_root_id: replyRootId,\n reply_root_author_name: replyRootAuthorName,\n } = route.params\n const { data: conversation } = useConversation(route.params)\n const {\n messages,\n fetchOlderMessages,\n fetchNewerMessages,\n hasMoreNewerMessages,\n isFetchingNewerMessages,\n cancelFetchNewerMessages,\n } = useConversationMessages({ conversation_id: conversationId, reply_root_id: replyRootId })\n\n const { jumpToUnreadActive } = useJumpToUnreadGates()\n const { initialMessageId } = useConversationContext()\n\n useConversationJoltEvents({ conversationId })\n useConversationMessagesJoltEvents({ conversationId })\n useEnsureConversationsRouteExists()\n useMarkLatestMessageRead({ conversation, messages })\n const { onMessageSeen } = useTrackHighestSeenMessage()\n\n const items = useMemo(\n () =>\n groupMessages({\n ms: messages,\n inReplyScreen: !!replyRootId,\n jumpToUnreadActive,\n initialMessageId,\n }),\n [messages, replyRootId, jumpToUnreadActive, initialMessageId]\n )\n const noMessages = items.length === 0\n\n const { repliesDisabled, memberAbility, badges, title } = conversation\n const canReply = memberAbility?.canReply\n const showLeaderDisabledReplyBanner = canReply && repliesDisabled\n const canDeleteNonAuthoredMessages = memberAbility?.canDeleteNonAuthoredMessages ?? false\n const currentlyEditingMessage = messages.find(m => String(m.id) === String(editingMessageId))\n const replyRootAuthorFirstName = replyRootAuthorName?.split(' ')[0]\n const replyHeaderTitle = replyRootAuthorFirstName\n ? `Reply to ${replyRootAuthorFirstName}`\n : 'Reply'\n // Prefer the membership for optimistic updates.\n const muted = conversation.conversationMembership?.muted ?? conversation.muted\n\n const listRef = useRef<FlatList>(null)\n const [dividerScrolledPast, setDividerScrolledPast] = useState(false)\n\n const observers = useMemo<ViewabilityObserver<EnrichedMessage>[]>(\n () => [\n reportViewableMessages(onMessageSeen),\n detectDividerExitTowardNewer({\n dividerKey: UNREAD_DIVIDER_KEY,\n initialMessageId,\n onExited: () => setDividerScrolledPast(true),\n }),\n ],\n [onMessageSeen, initialMessageId]\n )\n\n const { viewabilityConfigCallbackPairs, onScrollBeginDrag: viewabilityOnScrollBeginDrag } =\n useFlatListViewability({ observers })\n const {\n onContentSizeChange,\n onScrollToIndexFailed,\n onScrollBeginDrag: anchorOnScrollBeginDrag,\n } = useJumpToUnreadAnchor({ listRef, items })\n const onScrollBeginDrag = useCallback(() => {\n viewabilityOnScrollBeginDrag()\n anchorOnScrollBeginDrag()\n }, [viewabilityOnScrollBeginDrag, anchorOnScrollBeginDrag])\n const { onScroll, showJumpToBottomButton } = useScrollTracking({\n hasMoreNewerMessages,\n isFetchingNewerMessages,\n fetchNewerMessages,\n cancelFetchNewerMessages,\n })\n const { handleJumpToBottom, isJumpingToBottom } = useJumpToBottomAction({ listRef })\n\n const listHeader = useMemo(\n () => (\n <View>\n {isFetchingNewerMessages && (\n <Animated.View\n entering={FadeIn.duration(750)}\n exiting={FadeOut.duration(750)}\n style={styles.loadingFooter}\n accessibilityRole=\"progressbar\"\n accessibilityLabel=\"Loading more messages\"\n >\n <ActivityIndicator />\n </Animated.View>\n )}\n <View style={styles.listHeader} />\n </View>\n ),\n [isFetchingNewerMessages, styles.loadingFooter, styles.listHeader]\n )\n\n const renderItem = useCallback(\n ({ item }: { item: EnrichedMessage }) => {\n if (item.type === 'DateSeparator') return <InlineDateSeparator {...item} />\n if (item.type === 'UnreadDivider') return <UnreadDivider scrolledPast={dividerScrolledPast} />\n if (item.type === 'ReplyShadowMessage') {\n return (\n <ReplyShadowMessage\n {...item}\n conversation_id={conversationId}\n inReplyScreen={!!replyRootId}\n />\n )\n }\n if (isSystemMessage(item)) {\n return <SystemMessage message={item} conversationId={conversationId} />\n }\n return (\n <Message\n {...item}\n canDeleteNonAuthoredMessages={canDeleteNonAuthoredMessages}\n conversation_id={conversationId}\n latestReadMessageSortKey={conversation?.latestReadMessageSortKey}\n inReplyScreen={!!replyRootId}\n />\n )\n },\n [\n dividerScrolledPast,\n conversationId,\n replyRootId,\n canDeleteNonAuthoredMessages,\n conversation?.latestReadMessageSortKey,\n ]\n )\n\n useEffect(() => {\n if (replyRootId) {\n navigation.setParams({\n title: replyHeaderTitle,\n })\n } else {\n navigation.setParams({\n title: title,\n badge: badges?.[0],\n deleted: conversation?.deleted,\n muted,\n })\n }\n }, [navigation, title, badges, conversation?.deleted, replyRootId, replyHeaderTitle, muted])\n\n if (!conversation || conversation.deleted) {\n return (\n <View style={styles.container}>\n <BlankState.Root>\n <BlankState.Imagery name=\"general.outlinedTextMessage\" />\n <BlankState.Content>\n <BlankState.Heading>This conversation has been deleted</BlankState.Heading>\n </BlankState.Content>\n <BlankState.Button\n onPress={navigation.goBack}\n title=\"Back to conversations\"\n accessibilityHint=\"Navigates back to the conversations list\"\n accessibilityRole=\"link\"\n />\n </BlankState.Root>\n </View>\n )\n }\n\n return (\n <View style={styles.container}>\n <KeyboardView>\n {noMessages ? (\n <EmptyConversationBlankState />\n ) : (\n <FlatList\n inverted\n ref={listRef}\n contentContainerStyle={styles.listContainer}\n maintainVisibleContentPosition={maintainVisibleContentPosition}\n data={items}\n keyExtractor={extractItemKey}\n onScroll={onScroll}\n onScrollBeginDrag={onScrollBeginDrag}\n scrollEventThrottle={64}\n viewabilityConfigCallbackPairs={viewabilityConfigCallbackPairs}\n onContentSizeChange={onContentSizeChange}\n onScrollToIndexFailed={onScrollToIndexFailed}\n renderItem={renderItem}\n onEndReached={() => fetchOlderMessages()}\n ListHeaderComponent={listHeader}\n />\n )}\n <JumpToBottomButton\n onPress={handleJumpToBottom}\n visible={showJumpToBottomButton}\n loading={isJumpingToBottom}\n />\n {!noMessages && <TypingIndicator />}\n {showLeaderDisabledReplyBanner && <LeaderMessagesDisabledBanner />}\n <ConversationBottomBar\n conversation={conversation}\n canReply={canReply}\n replyRootAuthorFirstName={replyRootAuthorFirstName}\n replyRootId={replyRootId}\n currentlyEditingMessage={currentlyEditingMessage}\n />\n </KeyboardView>\n </View>\n )\n}\n\ninterface ConversationBottomBarProps {\n conversation: ConversationResource\n canReply: boolean | undefined\n replyRootAuthorFirstName: string | undefined\n replyRootId: string | null | undefined\n currentlyEditingMessage: MessageResource | undefined\n}\n\nfunction ConversationBottomBar({\n conversation,\n canReply,\n replyRootAuthorFirstName,\n replyRootId,\n currentlyEditingMessage,\n}: ConversationBottomBarProps) {\n if (conversation.disabled) return <ConversationDisabledBanner />\n if (!canReply) return <MemberMessagesDisabledBanner />\n return (\n <MessageForm.Root\n replyRootAuthorFirstName={replyRootAuthorFirstName}\n conversation={conversation}\n replyRootId={replyRootId}\n currentlyEditingMessage={currentlyEditingMessage}\n key={\n currentlyEditingMessage\n ? `edit-message-form-${currentlyEditingMessage.id}`\n : 'new-message-form'\n }\n >\n <MessageForm.AttachmentPicker />\n <MessageForm.Commands />\n <MessageForm.TextInput />\n <MessageForm.SubmitButton />\n </MessageForm.Root>\n )\n}\n\nfunction InlineDateSeparator({ date }: DateSeparator) {\n const styles = useDateSeparatorStyles()\n const { isThisYear } = getRelativeDateStatus(date)\n const showYear = !isThisYear\n const dateStamp = formatDate(date, { style: 'long', year: showYear })\n\n return (\n <View style={styles.container}>\n <View style={styles.separator} />\n <Text variant=\"footnote\" style={styles.dateText}>\n {dateStamp}\n </Text>\n <View style={styles.separator} />\n </View>\n )\n}\n\nconst useDateSeparatorStyles = () => {\n const theme = useTheme()\n return StyleSheet.create({\n container: {\n alignItems: 'center',\n flexDirection: 'row',\n paddingHorizontal: CONVERSATION_MESSAGE_LIST_PADDING_HORIZONTAL,\n paddingVertical: 16,\n },\n separator: {\n flex: 1,\n height: 1,\n borderTopWidth: 1,\n borderTopColor: theme.colors.borderColorDefaultBase,\n },\n dateText: {\n paddingHorizontal: 8,\n },\n })\n}\n\ninterface ConversationScreenTitleProps extends HeaderTitleProps {\n conversation_id: number\n badge?: ConversationBadgeResource\n deleted?: boolean\n muted?: boolean\n}\n\nexport const ConversationScreenTitle = ({\n conversation_id,\n badge,\n children,\n style,\n deleted,\n muted,\n}: ConversationScreenTitleProps) => {\n const styles = usePressableHeaderStyle()\n const navigation = useNavigation()\n const resourceType = badge?.pcoResourceType || ''\n const productName = badge?.appName\n const name = badge?.text || undefined\n\n return (\n <PlatformPressable\n accessibilityHint=\"Opens details about members and settings\"\n style={styles.container}\n onPress={() => {\n if (deleted) return\n\n navigation.navigate('ConversationDetails', { conversation_id })\n }}\n >\n <View style={styles.titleWrapper}>\n <View style={styles.titleTextContainer}>\n <HeaderTitle maxFontSizeMultiplier={1} style={style}>\n {children}\n </HeaderTitle>\n </View>\n {muted && <Icon name=\"general.bellMuted\" size={12} />}\n {!deleted && <Icon name=\"general.downChevron\" size={12} />}\n </View>\n <Badge\n variant=\"metaSubtle\"\n productLogoName={productName}\n label={resourceType}\n metaLabel={name}\n style={styles.badge}\n maxFontSizeMultiplier={1}\n />\n </PlatformPressable>\n )\n}\n\nconst usePressableHeaderStyle = () => {\n return StyleSheet.create({\n container: {\n alignItems: Platform.select({ android: 'flex-start', default: 'center' }),\n marginRight: Platform.select({ ios: 20, default: 16 }),\n flex: 1,\n },\n titleWrapper: {\n alignItems: 'center',\n columnGap: 4,\n flexDirection: 'row',\n flexShrink: 1,\n },\n titleTextContainer: {\n flexShrink: 1,\n minWidth: 0,\n },\n badge: {\n alignSelf: Platform.select({ android: 'flex-start', default: 'center' }),\n marginTop: 2,\n },\n })\n}\n\nconst useStyles = () => {\n const navigationTheme = useNavigationTheme()\n const { bottom } = useSafeAreaInsets()\n\n return StyleSheet.create({\n container: {\n flex: 1,\n justifyContent: 'center',\n backgroundColor: navigationTheme.colors.card,\n paddingBottom: bottom,\n },\n listContainer: {\n paddingVertical: 12,\n },\n listHeader: {\n // Just whitespace to provide space where the typing indicator can be\n height: 16,\n },\n loadingFooter: {\n paddingVertical: 12,\n alignItems: 'center',\n },\n })\n}\n\n/**\n * useEnsureConversationsRouteExists\n */\nconst useEnsureConversationsRouteExists = () => {\n const navigation = useNavigation()\n const { params } = useRoute<RouteProp<ConversationScreenProps['route']>>()\n\n useEffect(() => {\n const navigationState = navigation.getState()\n const routes = navigationState?.routes || []\n const conversationsRoute = routes.find(r => r.name === 'Conversations')\n\n if (conversationsRoute) return\n\n navigation.dispatch(state => {\n return CommonActions.reset({\n ...state,\n routes: [\n { name: 'Conversations', params: { chat_group_graph_id: params?.chat_group_graph_id } },\n ...routes,\n ],\n index: state.index + 1,\n })\n })\n }, [navigation, params?.chat_group_graph_id])\n}\n"]}
|
|
1
|
+
{"version":3,"file":"conversation_screen.js","sourceRoot":"","sources":["../../src/screens/conversation_screen.tsx"],"names":[],"mappings":"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","sourcesContent":["import { date as formatDate } from '@planningcenter/datetime-fmt'\nimport { HeaderTitle, HeaderTitleProps, PlatformPressable } from '@react-navigation/elements'\nimport {\n CommonActions,\n RouteProp,\n StaticScreenProps,\n useNavigation,\n useTheme as useNavigationTheme,\n useRoute,\n} from '@react-navigation/native'\nimport React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport { ActivityIndicator, FlatList, Platform, StyleSheet, View } from 'react-native'\nimport Animated, { FadeIn, FadeOut } from 'react-native-reanimated'\nimport { useSafeAreaInsets } from 'react-native-safe-area-context'\nimport { Badge, Icon, Text } from '../components'\nimport { EmptyConversationBlankState } from '../components/conversation/empty_conversation_blank_state'\nimport { JumpToBottomButton } from '../components/conversation/jump_to_bottom_button'\nimport { Message } from '../components/conversation/message'\nimport { MessageForm } from '../components/conversation/message_form'\nimport {\n ConversationDisabledBanner,\n LeaderMessagesDisabledBanner,\n MemberMessagesDisabledBanner,\n} from '../components/conversation/messages_disabled_banners'\nimport { ReplyShadowMessage } from '../components/conversation/reply_shadow_message'\nimport { SystemMessage } from '../components/conversation/system_message'\nimport { TypingIndicator } from '../components/conversation/typing_indicator'\nimport { UnreadDivider } from '../components/conversation/unread_divider'\nimport { KeyboardView } from '../components/display/keyboard_view'\nimport BlankState from '../components/primitive/blank_state_primitive'\nimport {\n ConversationContextProvider,\n useConversationContext,\n} from '../contexts/conversation_context'\nimport { useTheme } from '../hooks'\nimport { useConversation } from '../hooks/use_conversation'\nimport { useConversationJoltEvents } from '../hooks/use_conversation_jolt_events'\nimport { useConversationMessages } from '../hooks/use_conversation_messages'\nimport { useConversationMessagesJoltEvents } from '../hooks/use_conversation_messages_jolt_events'\nimport { availableFeatures, useFeatures } from '../hooks/use_features'\nimport { useFlatListViewability } from '../hooks/use_flat_list_viewability'\nimport { useJumpToBottomAction } from '../hooks/use_jump_to_bottom_action'\nimport { useJumpToUnreadAnchor } from '../hooks/use_jump_to_unread_anchor'\nimport { useJumpToUnreadGates } from '../hooks/use_jump_to_unread_gates'\nimport { useMarkLatestMessageRead } from '../hooks/use_mark_latest_message_read'\nimport {\n analyticsEvents,\n normalizeAnalyticsMetadata,\n usePublishProductAnalyticsEvent,\n} from '../hooks/use_product_analytics'\nimport { useScrollTracking } from '../hooks/use_scroll_tracking'\nimport { useTrackHighestSeenMessage } from '../hooks/use_track_highest_seen_message'\nimport { ConversationResource } from '../types/resources/conversation'\nimport { ConversationBadgeResource } from '../types/resources/conversation_badge'\nimport { MessageResource } from '../types/resources/message'\nimport { getRelativeDateStatus } from '../utils/date'\nimport {\n groupMessages,\n UNREAD_DIVIDER_KEY,\n type DateSeparator,\n type EnrichedMessage,\n} from '../utils/group_messages'\nimport {\n detectDividerExitTowardNewer,\n reportViewableMessages,\n type ViewabilityObserver,\n} from '../utils/message_viewability'\nimport { CONVERSATION_MESSAGE_LIST_PADDING_HORIZONTAL } from '../utils/styles'\nimport { isSystemMessage } from '../utils/system_messages'\n\nexport type ConversationRouteProps = {\n conversation_id: number\n reply_root_id?: string | null\n reply_root_author_name?: string\n chat_group_graph_id?: string\n clear_input?: boolean\n editing_message_id?: number | null\n message_id?: string\n title?: string\n subtitle?: string\n badge?: ConversationBadgeResource\n deleted?: boolean\n muted?: boolean\n}\n\nexport type ConversationScreenProps = StaticScreenProps<ConversationRouteProps>\n\nconst extractItemKey = (item: EnrichedMessage) => String(item.id)\nconst maintainVisibleContentPosition = { minIndexForVisible: 0 }\n\nexport function ConversationScreen({ route }: ConversationScreenProps) {\n const { conversation_id, message_id, reply_root_id } = route.params\n\n const { data: conversation } = useConversation({ conversation_id })\n const { featureEnabled } = useFeatures()\n\n usePublishProductAnalyticsEvent(analyticsEvents.conversation_show_opened, {\n reply_root_id,\n ...normalizeAnalyticsMetadata(conversation),\n })\n\n const lastReadMessageSortKey = conversation.conversationMembership?.lastReadMessageSortKey ?? null\n const jumpToUnreadAnchor =\n featureEnabled(availableFeatures.jump_to_unread) && !reply_root_id\n ? lastReadMessageSortKey\n : null\n const initialMessageId = message_id ?? jumpToUnreadAnchor\n const initialMessageIdIsAnchor = !!initialMessageId && !message_id\n\n return (\n <ConversationContextProvider\n conversationId={conversation_id}\n currentPageReplyRootId={reply_root_id ?? null}\n initialMessageId={initialMessageId}\n initialMessageIdIsAnchor={initialMessageIdIsAnchor}\n >\n <ConversationScreenContent route={route} />\n </ConversationContextProvider>\n )\n}\n\nfunction ConversationScreenContent({ route }: ConversationScreenProps) {\n const styles = useStyles()\n const navigation = useNavigation()\n const {\n conversation_id: conversationId,\n editing_message_id: editingMessageId,\n reply_root_id: replyRootId,\n reply_root_author_name: replyRootAuthorName,\n } = route.params\n const { data: conversation } = useConversation(route.params)\n const {\n messages,\n fetchOlderMessages,\n fetchNewerMessages,\n hasMoreNewerMessages,\n isFetchingNewerMessages,\n cancelFetchNewerMessages,\n } = useConversationMessages({ conversation_id: conversationId, reply_root_id: replyRootId })\n\n const { jumpToUnreadActive } = useJumpToUnreadGates()\n const { initialMessageId } = useConversationContext()\n\n useConversationJoltEvents({ conversationId })\n useConversationMessagesJoltEvents({ conversationId })\n useEnsureConversationsRouteExists()\n useMarkLatestMessageRead({ conversation, messages })\n const { onMessageSeen } = useTrackHighestSeenMessage()\n\n const items = useMemo(\n () =>\n groupMessages({\n ms: messages,\n inReplyScreen: !!replyRootId,\n jumpToUnreadActive,\n initialMessageId,\n }),\n [messages, replyRootId, jumpToUnreadActive, initialMessageId]\n )\n const noMessages = items.length === 0\n\n const { repliesDisabled, memberAbility, badges, title } = conversation\n const canReply = memberAbility?.canReply\n const showLeaderDisabledReplyBanner = canReply && repliesDisabled\n const canDeleteNonAuthoredMessages = memberAbility?.canDeleteNonAuthoredMessages ?? false\n const currentlyEditingMessage = messages.find(m => String(m.id) === String(editingMessageId))\n const replyRootAuthorFirstName = replyRootAuthorName?.split(' ')[0]\n const replyHeaderTitle = replyRootAuthorFirstName\n ? `Reply to ${replyRootAuthorFirstName}`\n : 'Reply'\n // Prefer the membership for optimistic updates.\n const muted = conversation.conversationMembership?.muted ?? conversation.muted\n\n const listRef = useRef<FlatList>(null)\n const [dividerScrolledPast, setDividerScrolledPast] = useState(false)\n\n const observers = useMemo<ViewabilityObserver<EnrichedMessage>[]>(\n () => [\n reportViewableMessages(onMessageSeen),\n detectDividerExitTowardNewer({\n dividerKey: UNREAD_DIVIDER_KEY,\n initialMessageId,\n onExited: () => setDividerScrolledPast(true),\n }),\n ],\n [onMessageSeen, initialMessageId]\n )\n\n const { viewabilityConfigCallbackPairs, onScrollBeginDrag: viewabilityOnScrollBeginDrag } =\n useFlatListViewability({ observers })\n const {\n onContentSizeChange,\n onScrollToIndexFailed,\n onScrollBeginDrag: anchorOnScrollBeginDrag,\n } = useJumpToUnreadAnchor({ listRef, items })\n const onScrollBeginDrag = useCallback(() => {\n viewabilityOnScrollBeginDrag()\n anchorOnScrollBeginDrag()\n }, [viewabilityOnScrollBeginDrag, anchorOnScrollBeginDrag])\n const { onScroll, showJumpToBottomButton } = useScrollTracking({\n hasMoreNewerMessages,\n isFetchingNewerMessages,\n fetchNewerMessages,\n cancelFetchNewerMessages,\n })\n const { handleJumpToBottom, isJumpingToBottom } = useJumpToBottomAction({ listRef })\n\n const listHeader = useMemo(\n () => (\n <View>\n {isFetchingNewerMessages && (\n <Animated.View\n entering={FadeIn.duration(750)}\n exiting={FadeOut.duration(750)}\n style={styles.loadingFooter}\n accessibilityRole=\"progressbar\"\n accessibilityLabel=\"Loading more messages\"\n >\n <ActivityIndicator />\n </Animated.View>\n )}\n <View style={styles.listHeader} />\n </View>\n ),\n [isFetchingNewerMessages, styles.loadingFooter, styles.listHeader]\n )\n\n const renderItem = useCallback(\n ({ item }: { item: EnrichedMessage }) => {\n if (item.type === 'DateSeparator') return <InlineDateSeparator {...item} />\n if (item.type === 'UnreadDivider') return <UnreadDivider scrolledPast={dividerScrolledPast} />\n if (item.type === 'ReplyShadowMessage') {\n return (\n <ReplyShadowMessage\n {...item}\n conversation_id={conversationId}\n inReplyScreen={!!replyRootId}\n />\n )\n }\n if (isSystemMessage(item)) {\n return <SystemMessage message={item} conversationId={conversationId} />\n }\n return (\n <Message\n {...item}\n canDeleteNonAuthoredMessages={canDeleteNonAuthoredMessages}\n conversation_id={conversationId}\n latestReadMessageSortKey={conversation?.latestReadMessageSortKey}\n inReplyScreen={!!replyRootId}\n />\n )\n },\n [\n dividerScrolledPast,\n conversationId,\n replyRootId,\n canDeleteNonAuthoredMessages,\n conversation?.latestReadMessageSortKey,\n ]\n )\n\n useEffect(() => {\n if (replyRootId) {\n navigation.setParams({\n title: replyHeaderTitle,\n })\n } else {\n navigation.setParams({\n title: title,\n badge: badges?.[0],\n deleted: conversation?.deleted,\n muted,\n })\n }\n }, [navigation, title, badges, conversation?.deleted, replyRootId, replyHeaderTitle, muted])\n\n if (!conversation || conversation.deleted) {\n return (\n <View style={styles.container}>\n <BlankState.Root>\n <BlankState.Imagery name=\"general.outlinedTextMessage\" />\n <BlankState.Content>\n <BlankState.Heading>This conversation has been deleted</BlankState.Heading>\n </BlankState.Content>\n <BlankState.Button\n onPress={navigation.goBack}\n title=\"Back to conversations\"\n accessibilityHint=\"Navigates back to the conversations list\"\n accessibilityRole=\"link\"\n />\n </BlankState.Root>\n </View>\n )\n }\n\n return (\n <View style={styles.container}>\n <KeyboardView>\n {noMessages ? (\n <EmptyConversationBlankState />\n ) : (\n <FlatList\n inverted\n ref={listRef}\n contentContainerStyle={styles.listContainer}\n maintainVisibleContentPosition={maintainVisibleContentPosition}\n data={items}\n keyExtractor={extractItemKey}\n onScroll={onScroll}\n onScrollBeginDrag={onScrollBeginDrag}\n scrollEventThrottle={64}\n viewabilityConfigCallbackPairs={viewabilityConfigCallbackPairs}\n onContentSizeChange={onContentSizeChange}\n onScrollToIndexFailed={onScrollToIndexFailed}\n renderItem={renderItem}\n onEndReached={() => fetchOlderMessages()}\n ListHeaderComponent={listHeader}\n />\n )}\n <JumpToBottomButton\n onPress={handleJumpToBottom}\n visible={showJumpToBottomButton}\n loading={isJumpingToBottom}\n />\n {!noMessages && <TypingIndicator />}\n {showLeaderDisabledReplyBanner && <LeaderMessagesDisabledBanner />}\n <ConversationBottomBar\n conversation={conversation}\n canReply={canReply}\n replyRootAuthorFirstName={replyRootAuthorFirstName}\n replyRootId={replyRootId}\n currentlyEditingMessage={currentlyEditingMessage}\n />\n </KeyboardView>\n </View>\n )\n}\n\ninterface ConversationBottomBarProps {\n conversation: ConversationResource\n canReply: boolean | undefined\n replyRootAuthorFirstName: string | undefined\n replyRootId: string | null | undefined\n currentlyEditingMessage: MessageResource | undefined\n}\n\nfunction ConversationBottomBar({\n conversation,\n canReply,\n replyRootAuthorFirstName,\n replyRootId,\n currentlyEditingMessage,\n}: ConversationBottomBarProps) {\n if (conversation.disabled) return <ConversationDisabledBanner />\n if (!canReply) return <MemberMessagesDisabledBanner />\n return (\n <MessageForm.Root\n replyRootAuthorFirstName={replyRootAuthorFirstName}\n conversation={conversation}\n replyRootId={replyRootId}\n currentlyEditingMessage={currentlyEditingMessage}\n key={\n currentlyEditingMessage\n ? `edit-message-form-${currentlyEditingMessage.id}`\n : 'new-message-form'\n }\n >\n <MessageForm.AttachmentPicker />\n <MessageForm.Commands />\n <MessageForm.TextInput />\n <MessageForm.SubmitButton />\n </MessageForm.Root>\n )\n}\n\nfunction InlineDateSeparator({ date }: DateSeparator) {\n const styles = useDateSeparatorStyles()\n const { isThisYear } = getRelativeDateStatus(date)\n const showYear = !isThisYear\n const dateStamp = formatDate(date, { style: 'long', year: showYear })\n\n return (\n <View style={styles.container}>\n <View style={styles.separator} />\n <Text variant=\"footnote\" style={styles.dateText}>\n {dateStamp}\n </Text>\n <View style={styles.separator} />\n </View>\n )\n}\n\nconst useDateSeparatorStyles = () => {\n const theme = useTheme()\n return StyleSheet.create({\n container: {\n alignItems: 'center',\n flexDirection: 'row',\n paddingHorizontal: CONVERSATION_MESSAGE_LIST_PADDING_HORIZONTAL,\n paddingVertical: 16,\n },\n separator: {\n flex: 1,\n height: 1,\n borderTopWidth: 1,\n borderTopColor: theme.colors.borderColorDefaultBase,\n },\n dateText: {\n paddingHorizontal: 8,\n },\n })\n}\n\ninterface ConversationScreenTitleProps extends HeaderTitleProps {\n conversation_id: number\n badge?: ConversationBadgeResource\n deleted?: boolean\n muted?: boolean\n}\n\nexport const ConversationScreenTitle = ({\n conversation_id,\n badge,\n children,\n style,\n deleted,\n muted,\n}: ConversationScreenTitleProps) => {\n const styles = usePressableHeaderStyle()\n const navigation = useNavigation()\n const resourceType = badge?.pcoResourceType || ''\n const productName = badge?.appName\n const name = badge?.text || undefined\n\n return (\n <PlatformPressable\n accessibilityHint=\"Opens details about members and settings\"\n style={styles.container}\n onPress={() => {\n if (deleted) return\n\n navigation.navigate('ConversationDetails', { conversation_id })\n }}\n >\n <View style={styles.titleWrapper}>\n <View style={styles.titleTextContainer}>\n <HeaderTitle maxFontSizeMultiplier={1} style={style}>\n {children}\n </HeaderTitle>\n </View>\n {muted && <Icon name=\"general.bellMuted\" size={12} />}\n {!deleted && <Icon name=\"general.downChevron\" size={12} />}\n </View>\n <Badge\n variant=\"metaSubtle\"\n productLogoName={productName}\n label={resourceType}\n metaLabel={name}\n style={styles.badge}\n maxFontSizeMultiplier={1}\n />\n </PlatformPressable>\n )\n}\n\nconst usePressableHeaderStyle = () => {\n return StyleSheet.create({\n container: {\n alignItems: Platform.select({ android: 'flex-start', default: 'center' }),\n marginRight: Platform.select({ ios: 20, default: 16 }),\n flex: 1,\n },\n titleWrapper: {\n alignItems: 'center',\n columnGap: 4,\n flexDirection: 'row',\n flexShrink: 1,\n },\n titleTextContainer: {\n flexShrink: 1,\n minWidth: 0,\n },\n badge: {\n alignSelf: Platform.select({ android: 'flex-start', default: 'center' }),\n marginTop: 2,\n },\n })\n}\n\nconst useStyles = () => {\n const navigationTheme = useNavigationTheme()\n const { bottom } = useSafeAreaInsets()\n\n return StyleSheet.create({\n container: {\n flex: 1,\n justifyContent: 'center',\n backgroundColor: navigationTheme.colors.card,\n paddingBottom: bottom,\n },\n listContainer: {\n paddingVertical: 12,\n },\n listHeader: {\n // Just whitespace to provide space where the typing indicator can be\n height: 16,\n },\n loadingFooter: {\n paddingVertical: 12,\n alignItems: 'center',\n },\n })\n}\n\n/**\n * useEnsureConversationsRouteExists\n */\nconst useEnsureConversationsRouteExists = () => {\n const navigation = useNavigation()\n const { params } = useRoute<RouteProp<ConversationScreenProps['route']>>()\n\n useEffect(() => {\n const navigationState = navigation.getState()\n const routes = navigationState?.routes || []\n const conversationsRoute = routes.find(r => r.name === 'Conversations')\n\n if (conversationsRoute) return\n\n navigation.dispatch(state => {\n return CommonActions.reset({\n ...state,\n routes: [\n { name: 'Conversations', params: { chat_group_graph_id: params?.chat_group_graph_id } },\n ...routes,\n ],\n index: state.index + 1,\n })\n })\n }, [navigation, params?.chat_group_graph_id])\n}\n"]}
|
|
@@ -2,11 +2,11 @@ import React from 'react';
|
|
|
2
2
|
import { StyleSheet, View } from 'react-native';
|
|
3
3
|
import { Conversations } from '../../components';
|
|
4
4
|
import { ConversationsContextProvider } from '../../contexts/conversations_context';
|
|
5
|
-
import { usePublishProductAnalyticsEvent } from '../../hooks';
|
|
5
|
+
import { analyticsEvents, usePublishProductAnalyticsEvent } from '../../hooks/use_product_analytics';
|
|
6
6
|
import { ListHeaderComponent } from './components/list_header_component';
|
|
7
7
|
export function ConversationsScreen({ route }) {
|
|
8
8
|
const styles = useStyles();
|
|
9
|
-
usePublishProductAnalyticsEvent(
|
|
9
|
+
usePublishProductAnalyticsEvent(analyticsEvents.conversation_index_opened);
|
|
10
10
|
return (<View style={styles.container}>
|
|
11
11
|
<ConversationsContextProvider args={route.params}>
|
|
12
12
|
<Conversations ListHeaderComponent={ListHeaderComponent}/>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conversations_screen.js","sourceRoot":"","sources":["../../../src/screens/conversations/conversations_screen.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,cAAc,CAAA;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAChD,OAAO,EAAE,4BAA4B,EAAE,MAAM,sCAAsC,CAAA;AACnF,OAAO,EAAE,+BAA+B,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"conversations_screen.js","sourceRoot":"","sources":["../../../src/screens/conversations/conversations_screen.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,cAAc,CAAA;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAChD,OAAO,EAAE,4BAA4B,EAAE,MAAM,sCAAsC,CAAA;AACnF,OAAO,EAAE,eAAe,EAAE,+BAA+B,EAAE,MAAM,mCAAmC,CAAA;AAGpG,OAAO,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAA;AAQxE,MAAM,UAAU,mBAAmB,CAAC,EAAE,KAAK,EAA4B;IACrE,MAAM,MAAM,GAAG,SAAS,EAAE,CAAA;IAE1B,+BAA+B,CAAC,eAAe,CAAC,yBAAyB,CAAC,CAAA;IAE1E,OAAO,CACL,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAC5B;MAAA,CAAC,4BAA4B,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAC/C;QAAA,CAAC,aAAa,CAAC,mBAAmB,CAAC,CAAC,mBAAmB,CAAC,EAC1D;MAAA,EAAE,4BAA4B,CAChC;IAAA,EAAE,IAAI,CAAC,CACR,CAAA;AACH,CAAC;AAED,MAAM,SAAS,GAAG,GAAG,EAAE;IACrB,OAAO,UAAU,CAAC,MAAM,CAAC;QACvB,SAAS,EAAE;YACT,IAAI,EAAE,CAAC;YACP,cAAc,EAAE,QAAQ;SACzB;KACF,CAAC,CAAA;AACJ,CAAC,CAAA","sourcesContent":["import { StaticScreenProps } from '@react-navigation/native'\nimport React from 'react'\nimport { StyleSheet, View } from 'react-native'\nimport { Conversations } from '../../components'\nimport { ConversationsContextProvider } from '../../contexts/conversations_context'\nimport { analyticsEvents, usePublishProductAnalyticsEvent } from '../../hooks/use_product_analytics'\nimport { AppName } from '../../types/resources/app_name'\nimport { GraphId } from '../../types/resources/group_resource'\nimport { ListHeaderComponent } from './components/list_header_component'\n\nexport type ConversationsScreenProps = StaticScreenProps<{\n title?: string\n chat_group_graph_id?: GraphId\n group_source_app_name?: AppName\n}>\n\nexport function ConversationsScreen({ route }: ConversationsScreenProps) {\n const styles = useStyles()\n\n usePublishProductAnalyticsEvent(analyticsEvents.conversation_index_opened)\n\n return (\n <View style={styles.container}>\n <ConversationsContextProvider args={route.params}>\n <Conversations ListHeaderComponent={ListHeaderComponent} />\n </ConversationsContextProvider>\n </View>\n )\n}\n\nconst useStyles = () => {\n return StyleSheet.create({\n container: {\n flex: 1,\n justifyContent: 'center',\n },\n })\n}\n"]}
|
|
@@ -7,4 +7,6 @@ export type JoltMessageEvent = MessageCreatedEvent | MessageUpdatedEvent | Messa
|
|
|
7
7
|
export type JoltReactionEvent = ReactionCreatedEvent | ReactionDeletedEvent;
|
|
8
8
|
export type JoltTypingEvent = TypingBroadcastEvent;
|
|
9
9
|
export type CustomJoltEvent = JoltConversationEvent | JoltMessageEvent | JoltReactionEvent | JoltTypingEvent;
|
|
10
|
+
export type JoltEventName = CustomJoltEvent['event'] | 'STREAM_USER_UPDATED';
|
|
11
|
+
export type JoltSubscriptionPattern = JoltEventName | 'reaction.*';
|
|
10
12
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/types/jolt_events/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,wBAAwB,EACxB,wBAAwB,EACxB,wBAAwB,EACxB,qBAAqB,EACtB,MAAM,uBAAuB,CAAA;AAC9B,OAAO,KAAK,EACV,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACpB,MAAM,kBAAkB,CAAA;AACzB,OAAO,KAAK,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAA;AACnF,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAA;AAE3D,MAAM,MAAM,qBAAqB,GAC7B,wBAAwB,GACxB,wBAAwB,GACxB,wBAAwB,GACxB,qBAAqB,CAAA;AACzB,MAAM,MAAM,gBAAgB,GAAG,mBAAmB,GAAG,mBAAmB,GAAG,mBAAmB,CAAA;AAC9F,MAAM,MAAM,iBAAiB,GAAG,oBAAoB,GAAG,oBAAoB,CAAA;AAC3E,MAAM,MAAM,eAAe,GAAG,oBAAoB,CAAA;AAElD,MAAM,MAAM,eAAe,GACvB,qBAAqB,GACrB,gBAAgB,GAChB,iBAAiB,GACjB,eAAe,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/types/jolt_events/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,wBAAwB,EACxB,wBAAwB,EACxB,wBAAwB,EACxB,qBAAqB,EACtB,MAAM,uBAAuB,CAAA;AAC9B,OAAO,KAAK,EACV,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACpB,MAAM,kBAAkB,CAAA;AACzB,OAAO,KAAK,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAA;AACnF,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAA;AAE3D,MAAM,MAAM,qBAAqB,GAC7B,wBAAwB,GACxB,wBAAwB,GACxB,wBAAwB,GACxB,qBAAqB,CAAA;AACzB,MAAM,MAAM,gBAAgB,GAAG,mBAAmB,GAAG,mBAAmB,GAAG,mBAAmB,CAAA;AAC9F,MAAM,MAAM,iBAAiB,GAAG,oBAAoB,GAAG,oBAAoB,CAAA;AAC3E,MAAM,MAAM,eAAe,GAAG,oBAAoB,CAAA;AAElD,MAAM,MAAM,eAAe,GACvB,qBAAqB,GACrB,gBAAgB,GAChB,iBAAiB,GACjB,eAAe,CAAA;AAEnB,MAAM,MAAM,aAAa,GAAG,eAAe,CAAC,OAAO,CAAC,GAAG,qBAAqB,CAAA;AAC5E,MAAM,MAAM,uBAAuB,GAAG,aAAa,GAAG,YAAY,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/types/jolt_events/index.ts"],"names":[],"mappings":"","sourcesContent":["import type {\n ConversationCreatedEvent,\n ConversationDeletedEvent,\n ConversationUpdatedEvent,\n ConversationReadEvent,\n} from './conversation_events'\nimport type {\n MessageCreatedEvent,\n MessageDeletedEvent,\n MessageUpdatedEvent,\n} from './message_events'\nimport type { ReactionCreatedEvent, ReactionDeletedEvent } from './reaction_events'\nimport type { TypingBroadcastEvent } from './typing_events'\n\nexport type JoltConversationEvent =\n | ConversationCreatedEvent\n | ConversationUpdatedEvent\n | ConversationDeletedEvent\n | ConversationReadEvent\nexport type JoltMessageEvent = MessageCreatedEvent | MessageUpdatedEvent | MessageDeletedEvent\nexport type JoltReactionEvent = ReactionCreatedEvent | ReactionDeletedEvent\nexport type JoltTypingEvent = TypingBroadcastEvent\n\nexport type CustomJoltEvent =\n | JoltConversationEvent\n | JoltMessageEvent\n | JoltReactionEvent\n | JoltTypingEvent\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/types/jolt_events/index.ts"],"names":[],"mappings":"","sourcesContent":["import type {\n ConversationCreatedEvent,\n ConversationDeletedEvent,\n ConversationUpdatedEvent,\n ConversationReadEvent,\n} from './conversation_events'\nimport type {\n MessageCreatedEvent,\n MessageDeletedEvent,\n MessageUpdatedEvent,\n} from './message_events'\nimport type { ReactionCreatedEvent, ReactionDeletedEvent } from './reaction_events'\nimport type { TypingBroadcastEvent } from './typing_events'\n\nexport type JoltConversationEvent =\n | ConversationCreatedEvent\n | ConversationUpdatedEvent\n | ConversationDeletedEvent\n | ConversationReadEvent\nexport type JoltMessageEvent = MessageCreatedEvent | MessageUpdatedEvent | MessageDeletedEvent\nexport type JoltReactionEvent = ReactionCreatedEvent | ReactionDeletedEvent\nexport type JoltTypingEvent = TypingBroadcastEvent\n\nexport type CustomJoltEvent =\n | JoltConversationEvent\n | JoltMessageEvent\n | JoltReactionEvent\n | JoltTypingEvent\n\nexport type JoltEventName = CustomJoltEvent['event'] | 'STREAM_USER_UPDATED'\nexport type JoltSubscriptionPattern = JoltEventName | 'reaction.*'\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@planningcenter/chat-react-native",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.37.0-rc.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"react-native": "./src/index.tsx",
|
|
@@ -72,5 +72,5 @@
|
|
|
72
72
|
"react-native-url-polyfill": "^2.0.0",
|
|
73
73
|
"typescript": "~5.9.2"
|
|
74
74
|
},
|
|
75
|
-
"gitHead": "
|
|
75
|
+
"gitHead": "aaa319341cab65a69c69df5eada620d1523fb4d7"
|
|
76
76
|
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { QueryClientProvider } from '@tanstack/react-query'
|
|
2
|
+
import { renderHook, waitFor } from '@testing-library/react-native'
|
|
3
|
+
import React from 'react'
|
|
4
|
+
import { buildTestQueryClient } from '../../__utils__/query_client'
|
|
5
|
+
import { useApiClient } from '../../hooks/use_api_client'
|
|
6
|
+
import { useEnrichPeople } from '../../hooks/use_enrich_people'
|
|
7
|
+
|
|
8
|
+
jest.mock('../../hooks/use_api_client')
|
|
9
|
+
|
|
10
|
+
const mockedUseApiClient = useApiClient as jest.MockedFunction<typeof useApiClient>
|
|
11
|
+
const mockPost = jest.fn()
|
|
12
|
+
|
|
13
|
+
beforeEach(() => {
|
|
14
|
+
mockPost.mockReset()
|
|
15
|
+
mockedUseApiClient.mockReturnValue({ chat: { post: mockPost } } as any)
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
const createWrapper = () => {
|
|
19
|
+
const queryClient = buildTestQueryClient()
|
|
20
|
+
return ({ children }: { children: React.ReactNode }) => (
|
|
21
|
+
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
|
|
22
|
+
)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
test('returns empty map and skips the request when personIds is empty', () => {
|
|
26
|
+
const { result } = renderHook(() => useEnrichPeople({ personIds: [] }), {
|
|
27
|
+
wrapper: createWrapper(),
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
expect(result.current.size).toBe(0)
|
|
31
|
+
expect(mockPost).not.toHaveBeenCalled()
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
test('returns enrichment data keyed by person id', async () => {
|
|
35
|
+
mockPost.mockResolvedValue({
|
|
36
|
+
data: [
|
|
37
|
+
{ id: '1', type: 'PersonEnrichment', badges: [{ title: 'Leader' }] },
|
|
38
|
+
{ id: '2', type: 'PersonEnrichment', badges: [] },
|
|
39
|
+
],
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
const { result } = renderHook(() => useEnrichPeople({ personIds: [1, 2] }), {
|
|
43
|
+
wrapper: createWrapper(),
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
await waitFor(() => expect(result.current.size).toBe(2))
|
|
47
|
+
|
|
48
|
+
expect(result.current.get(1)?.badges).toEqual([{ title: 'Leader' }])
|
|
49
|
+
expect(result.current.get(2)?.badges).toEqual([])
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
test('includes group_id in the request when provided', async () => {
|
|
53
|
+
mockPost.mockResolvedValue({ data: [] })
|
|
54
|
+
|
|
55
|
+
renderHook(() => useEnrichPeople({ personIds: [1], groupId: 42 }), {
|
|
56
|
+
wrapper: createWrapper(),
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
await waitFor(() => expect(mockPost).toHaveBeenCalled())
|
|
60
|
+
|
|
61
|
+
expect(mockPost).toHaveBeenCalledWith(
|
|
62
|
+
expect.objectContaining({
|
|
63
|
+
data: expect.objectContaining({
|
|
64
|
+
data: expect.objectContaining({
|
|
65
|
+
attributes: expect.objectContaining({ group_id: 42 }),
|
|
66
|
+
}),
|
|
67
|
+
}),
|
|
68
|
+
})
|
|
69
|
+
)
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
test('omits group_id from the request when not provided', async () => {
|
|
73
|
+
mockPost.mockResolvedValue({ data: [] })
|
|
74
|
+
|
|
75
|
+
renderHook(() => useEnrichPeople({ personIds: [1] }), {
|
|
76
|
+
wrapper: createWrapper(),
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
await waitFor(() => expect(mockPost).toHaveBeenCalled())
|
|
80
|
+
|
|
81
|
+
const attributes = mockPost.mock.calls[0][0].data.data.attributes
|
|
82
|
+
expect(attributes).not.toHaveProperty('group_id')
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
test('returns empty map when the request fails', async () => {
|
|
86
|
+
mockPost.mockRejectedValue(new Error('network error'))
|
|
87
|
+
|
|
88
|
+
const { result } = renderHook(() => useEnrichPeople({ personIds: [1] }), {
|
|
89
|
+
wrapper: createWrapper(),
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
await waitFor(() => expect(mockPost).toHaveBeenCalled())
|
|
93
|
+
|
|
94
|
+
expect(result.current.size).toBe(0)
|
|
95
|
+
})
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useMemo } from 'react'
|
|
2
|
+
import { MemberResource, ResourceObject } from '../../types'
|
|
2
3
|
import { GroupsGroupMemberResource } from '../../types/resources/groups/groups_member_resource_with_person'
|
|
3
|
-
import {
|
|
4
|
+
import { useEnrichPeople } from '../use_enrich_people'
|
|
4
5
|
import { useSuspensePaginator } from '../use_suspense_api'
|
|
5
6
|
|
|
6
7
|
type UseSuspensePaginatorResult<T extends ResourceObject> = ReturnType<
|
|
@@ -16,10 +17,6 @@ export type GroupMembersForNewConversationResult = Omit<
|
|
|
16
17
|
childMembers: MemberResource[]
|
|
17
18
|
}
|
|
18
19
|
|
|
19
|
-
/**
|
|
20
|
-
* This is specifically for the new conversation screen because we assign
|
|
21
|
-
* the "Conversation owner" badge to the current person.
|
|
22
|
-
*/
|
|
23
20
|
export function useGroupMembersForNewConversation({
|
|
24
21
|
id,
|
|
25
22
|
gender,
|
|
@@ -27,7 +24,6 @@ export function useGroupMembersForNewConversation({
|
|
|
27
24
|
id: number
|
|
28
25
|
gender: string | null
|
|
29
26
|
}) {
|
|
30
|
-
const currentPerson = useCurrentPerson()
|
|
31
27
|
const response = useSuspensePaginator<GroupsGroupMemberResource>({
|
|
32
28
|
url: `/me/groups/${id}/memberships`,
|
|
33
29
|
data: {
|
|
@@ -43,12 +39,16 @@ export function useGroupMembersForNewConversation({
|
|
|
43
39
|
})
|
|
44
40
|
|
|
45
41
|
const { data: memberships = [] } = response
|
|
42
|
+
const personIds = useMemo(() => memberships.map(m => +m.person.id), [memberships])
|
|
43
|
+
const enrichmentMap = useEnrichPeople({ personIds, groupId: id })
|
|
44
|
+
|
|
46
45
|
const members: MemberResource[] = memberships.map(membership => {
|
|
47
46
|
const { person } = membership
|
|
47
|
+
const enrichment = enrichmentMap.get(+person.id)
|
|
48
48
|
return {
|
|
49
49
|
type: 'Member',
|
|
50
50
|
avatar: person.avatarUrl,
|
|
51
|
-
badges:
|
|
51
|
+
badges: enrichment?.badges ?? [],
|
|
52
52
|
child: person.child,
|
|
53
53
|
gender: person.gender,
|
|
54
54
|
id: +person.id,
|
|
@@ -57,6 +57,7 @@ export function useGroupMembersForNewConversation({
|
|
|
57
57
|
role: membership.role,
|
|
58
58
|
}
|
|
59
59
|
})
|
|
60
|
+
|
|
60
61
|
const adultMembers = members.filter(member => !member.child)
|
|
61
62
|
const childMembers = members.filter(member => member.child)
|
|
62
63
|
|
|
@@ -67,18 +68,3 @@ export function useGroupMembersForNewConversation({
|
|
|
67
68
|
childMembers,
|
|
68
69
|
}
|
|
69
70
|
}
|
|
70
|
-
|
|
71
|
-
function buildBadges(
|
|
72
|
-
membership: GroupsGroupMemberResource,
|
|
73
|
-
currentPersonId: number
|
|
74
|
-
): MemberBadge[] {
|
|
75
|
-
const { person } = membership
|
|
76
|
-
const badges = []
|
|
77
|
-
if (membership.role === 'leader') {
|
|
78
|
-
badges.push({ title: 'Leader' })
|
|
79
|
-
}
|
|
80
|
-
if (person.id === currentPersonId) {
|
|
81
|
-
badges.push({ title: 'Conversation owner' })
|
|
82
|
-
}
|
|
83
|
-
return badges
|
|
84
|
-
}
|
|
@@ -2,6 +2,7 @@ import { isNil, omitBy } from 'lodash'
|
|
|
2
2
|
import { useMemo } from 'react'
|
|
3
3
|
import { MemberResource, TeamPeopleResource, TeamPersonResponseItem } from '../../types'
|
|
4
4
|
import { useApiGet } from '../use_api'
|
|
5
|
+
import { useEnrichPeople } from '../use_enrich_people'
|
|
5
6
|
|
|
6
7
|
interface Props {
|
|
7
8
|
teamIds: number[]
|
|
@@ -23,14 +24,24 @@ export function useTeamMembersForNewConversation({ teamIds, planId }: Props) {
|
|
|
23
24
|
})
|
|
24
25
|
|
|
25
26
|
const people = data?.people || stableEmptyPersonArray
|
|
27
|
+
const personIds = useMemo(() => people.map(p => p.id), [people])
|
|
28
|
+
const enrichmentMap = useEnrichPeople({ personIds })
|
|
26
29
|
|
|
27
|
-
const members: MemberResource[] = useMemo(
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
30
|
+
const members: MemberResource[] = useMemo(
|
|
31
|
+
() =>
|
|
32
|
+
people.map(person => {
|
|
33
|
+
const enrichedBadges = enrichmentMap.get(person.id)?.badges ?? []
|
|
34
|
+
const existingTitles = new Set(person.badges.map(b => b.title))
|
|
35
|
+
const newBadges = enrichedBadges.filter(b => !existingTitles.has(b.title))
|
|
36
|
+
return {
|
|
37
|
+
...person,
|
|
38
|
+
type: 'Member',
|
|
39
|
+
gender: null,
|
|
40
|
+
badges: [...person.badges, ...newBadges],
|
|
41
|
+
}
|
|
42
|
+
}),
|
|
43
|
+
[people, enrichmentMap]
|
|
44
|
+
)
|
|
34
45
|
|
|
35
46
|
return {
|
|
36
47
|
members,
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { keepPreviousData, useQuery } from '@tanstack/react-query'
|
|
2
|
+
import { useMemo } from 'react'
|
|
3
|
+
import { ApiCollection, ResourceObject } from '../types'
|
|
4
|
+
import { useApiClient } from './use_api_client'
|
|
5
|
+
|
|
6
|
+
export interface PersonEnrichmentResource extends ResourceObject {
|
|
7
|
+
type: 'PersonEnrichment'
|
|
8
|
+
id: string
|
|
9
|
+
badges: { title: string }[]
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function useEnrichPeople({ personIds, groupId }: { personIds: number[]; groupId?: number }) {
|
|
13
|
+
const apiClient = useApiClient()
|
|
14
|
+
|
|
15
|
+
const { data } = useQuery<ApiCollection<PersonEnrichmentResource>>({
|
|
16
|
+
queryKey: ['enrich_people', [...personIds].sort((a, b) => a - b), groupId],
|
|
17
|
+
queryFn: () =>
|
|
18
|
+
apiClient.chat.post<ApiCollection<PersonEnrichmentResource>>({
|
|
19
|
+
url: '/enrich_people',
|
|
20
|
+
data: {
|
|
21
|
+
data: {
|
|
22
|
+
type: 'PersonEnrichment',
|
|
23
|
+
attributes: {
|
|
24
|
+
person_ids: personIds,
|
|
25
|
+
...(groupId !== undefined ? { group_id: groupId } : {}),
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
}),
|
|
30
|
+
enabled: personIds.length > 0,
|
|
31
|
+
placeholderData: keepPreviousData,
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
return useMemo(() => new Map(data?.data.map(e => [+e.id, e]) ?? []), [data])
|
|
35
|
+
}
|
package/src/hooks/use_jolt.ts
CHANGED
|
@@ -11,6 +11,7 @@ import { useQuery, useQueryClient, useSuspenseQuery } from '@tanstack/react-quer
|
|
|
11
11
|
import { useCallback, useEffect, useMemo } from 'react'
|
|
12
12
|
import { useChatContext } from '../contexts/chat_context'
|
|
13
13
|
import { ApiResource } from '../types'
|
|
14
|
+
import type { JoltSubscriptionPattern } from '../types/jolt_events'
|
|
14
15
|
import { Client, Uri } from '../utils'
|
|
15
16
|
|
|
16
17
|
interface JoltResponse {
|
|
@@ -165,7 +166,7 @@ type UserCallbackFn<T> = (_event: T) => void
|
|
|
165
166
|
|
|
166
167
|
export function useJoltEvent<T extends CustomMessage>(
|
|
167
168
|
channel: JoltSubscription | undefined | null,
|
|
168
|
-
eventName:
|
|
169
|
+
eventName: JoltSubscriptionPattern,
|
|
169
170
|
callback: UserCallbackFn<T>
|
|
170
171
|
) {
|
|
171
172
|
useEffect(() => {
|
|
@@ -9,6 +9,13 @@ export interface EventMetadata {
|
|
|
9
9
|
[key: string]: string | number | boolean | null | undefined
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
+
export const analyticsEvents = {
|
|
13
|
+
conversation_index_opened: 'chat.mobile.conversations.index.opened',
|
|
14
|
+
conversation_show_opened: 'chat.mobile.conversations.show.opened',
|
|
15
|
+
} as const satisfies Record<string, `chat.mobile.${string}`>
|
|
16
|
+
|
|
17
|
+
type AnalyticsEventName = (typeof analyticsEvents)[keyof typeof analyticsEvents]
|
|
18
|
+
|
|
12
19
|
interface AnalyticsEvent {
|
|
13
20
|
name: string
|
|
14
21
|
meta: EventMetadata
|
|
@@ -55,7 +62,7 @@ const useProductAnalytics = () => {
|
|
|
55
62
|
)
|
|
56
63
|
|
|
57
64
|
const publishEvent = useCallback(
|
|
58
|
-
(name:
|
|
65
|
+
(name: AnalyticsEventName, meta: EventMetadata = {}): Promise<Response[]> => {
|
|
59
66
|
if (!productAnalyticsConfig) {
|
|
60
67
|
if (__DEV__) {
|
|
61
68
|
console.warn('Product Analytics not available')
|
|
@@ -71,7 +78,7 @@ const useProductAnalytics = () => {
|
|
|
71
78
|
)
|
|
72
79
|
|
|
73
80
|
const publishEvents = useCallback(
|
|
74
|
-
(events: Array<{ name:
|
|
81
|
+
(events: Array<{ name: AnalyticsEventName; meta?: EventMetadata }>): Promise<Response[]> => {
|
|
75
82
|
if (!productAnalyticsConfig) {
|
|
76
83
|
if (__DEV__) {
|
|
77
84
|
console.warn('Product Analytics not available')
|
|
@@ -92,7 +99,10 @@ const useProductAnalytics = () => {
|
|
|
92
99
|
return { publishEvent, publishEvents }
|
|
93
100
|
}
|
|
94
101
|
|
|
95
|
-
export function usePublishProductAnalyticsEvent(
|
|
102
|
+
export function usePublishProductAnalyticsEvent(
|
|
103
|
+
eventName: AnalyticsEventName,
|
|
104
|
+
meta: EventMetadata = {}
|
|
105
|
+
) {
|
|
96
106
|
const { publishEvent } = useProductAnalytics()
|
|
97
107
|
const hasPublishedEventRef = useRef(false)
|
|
98
108
|
|
|
@@ -148,7 +148,7 @@ export function ConversationDetailsScreen({ route }: ConversationDetailsScreenPr
|
|
|
148
148
|
const memberSectionStyle = memberSectionStyleMap[memberPosition]
|
|
149
149
|
|
|
150
150
|
return {
|
|
151
|
-
type:
|
|
151
|
+
type: SectionTypes.members,
|
|
152
152
|
data,
|
|
153
153
|
sectionInnerStyle: memberSectionStyle,
|
|
154
154
|
}
|
|
@@ -44,6 +44,7 @@ import { useJumpToUnreadAnchor } from '../hooks/use_jump_to_unread_anchor'
|
|
|
44
44
|
import { useJumpToUnreadGates } from '../hooks/use_jump_to_unread_gates'
|
|
45
45
|
import { useMarkLatestMessageRead } from '../hooks/use_mark_latest_message_read'
|
|
46
46
|
import {
|
|
47
|
+
analyticsEvents,
|
|
47
48
|
normalizeAnalyticsMetadata,
|
|
48
49
|
usePublishProductAnalyticsEvent,
|
|
49
50
|
} from '../hooks/use_product_analytics'
|
|
@@ -93,7 +94,7 @@ export function ConversationScreen({ route }: ConversationScreenProps) {
|
|
|
93
94
|
const { data: conversation } = useConversation({ conversation_id })
|
|
94
95
|
const { featureEnabled } = useFeatures()
|
|
95
96
|
|
|
96
|
-
usePublishProductAnalyticsEvent(
|
|
97
|
+
usePublishProductAnalyticsEvent(analyticsEvents.conversation_show_opened, {
|
|
97
98
|
reply_root_id,
|
|
98
99
|
...normalizeAnalyticsMetadata(conversation),
|
|
99
100
|
})
|
|
@@ -3,7 +3,7 @@ import React from 'react'
|
|
|
3
3
|
import { StyleSheet, View } from 'react-native'
|
|
4
4
|
import { Conversations } from '../../components'
|
|
5
5
|
import { ConversationsContextProvider } from '../../contexts/conversations_context'
|
|
6
|
-
import { usePublishProductAnalyticsEvent } from '../../hooks'
|
|
6
|
+
import { analyticsEvents, usePublishProductAnalyticsEvent } from '../../hooks/use_product_analytics'
|
|
7
7
|
import { AppName } from '../../types/resources/app_name'
|
|
8
8
|
import { GraphId } from '../../types/resources/group_resource'
|
|
9
9
|
import { ListHeaderComponent } from './components/list_header_component'
|
|
@@ -17,7 +17,7 @@ export type ConversationsScreenProps = StaticScreenProps<{
|
|
|
17
17
|
export function ConversationsScreen({ route }: ConversationsScreenProps) {
|
|
18
18
|
const styles = useStyles()
|
|
19
19
|
|
|
20
|
-
usePublishProductAnalyticsEvent(
|
|
20
|
+
usePublishProductAnalyticsEvent(analyticsEvents.conversation_index_opened)
|
|
21
21
|
|
|
22
22
|
return (
|
|
23
23
|
<View style={styles.container}>
|