@planningcenter/chat-react-native 4.4.0-rc.0 → 4.4.0-rc.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/components/conversation/message.d.ts +3 -1
- package/build/components/conversation/message.d.ts.map +1 -1
- package/build/components/conversation/message.js +183 -158
- package/build/components/conversation/message.js.map +1 -1
- package/build/components/conversation/message_list.d.ts.map +1 -1
- package/build/components/conversation/message_list.js +143 -88
- package/build/components/conversation/message_list.js.map +1 -1
- package/build/hooks/use_animated_message_background_color.d.ts +1 -0
- package/build/hooks/use_animated_message_background_color.d.ts.map +1 -1
- package/build/hooks/use_animated_message_background_color.js +26 -9
- package/build/hooks/use_animated_message_background_color.js.map +1 -1
- package/build/hooks/use_product_analytics.d.ts +9 -0
- package/build/hooks/use_product_analytics.d.ts.map +1 -1
- package/build/hooks/use_product_analytics.js +4 -2
- package/build/hooks/use_product_analytics.js.map +1 -1
- package/build/hooks/use_search_enabled.d.ts +2 -0
- package/build/hooks/use_search_enabled.d.ts.map +1 -0
- package/build/hooks/use_search_enabled.js +18 -0
- package/build/hooks/use_search_enabled.js.map +1 -0
- package/build/screens/conversations/components/search_list_header_component.js +3 -3
- package/build/screens/conversations/components/search_list_header_component.js.map +1 -1
- package/build/screens/conversations/conversations_screen.d.ts.map +1 -1
- package/build/screens/conversations/conversations_screen.js +2 -5
- package/build/screens/conversations/conversations_screen.js.map +1 -1
- package/build/screens/search/components/conversation_results.d.ts +1 -1
- package/build/screens/search/components/conversation_results.d.ts.map +1 -1
- package/build/screens/search/components/conversation_results.js +2 -2
- package/build/screens/search/components/conversation_results.js.map +1 -1
- package/build/screens/search/components/search_results_list.d.ts +7 -2
- package/build/screens/search/components/search_results_list.d.ts.map +1 -1
- package/build/screens/search/components/search_results_list.js +135 -105
- package/build/screens/search/components/search_results_list.js.map +1 -1
- package/build/screens/search/search_screen.d.ts.map +1 -1
- package/build/screens/search/search_screen.js +69 -31
- package/build/screens/search/search_screen.js.map +1 -1
- package/package.json +2 -2
- package/src/components/conversation/__tests__/message_list.test.tsx +71 -3
- package/src/components/conversation/message.tsx +12 -1
- package/src/components/conversation/message_list.tsx +26 -1
- package/src/hooks/use_animated_message_background_color.ts +37 -12
- package/src/hooks/use_product_analytics.ts +3 -1
- package/src/hooks/use_search_enabled.ts +9 -0
- package/src/screens/conversations/__tests__/conversations_screen.test.tsx +71 -0
- package/src/screens/conversations/components/search_list_header_component.tsx +1 -1
- package/src/screens/conversations/conversations_screen.tsx +2 -3
- package/src/screens/search/__tests__/search_screen.test.tsx +56 -2
- package/src/screens/search/components/__tests__/conversation_results.test.tsx +2 -2
- package/src/screens/search/components/__tests__/search_results_list.test.tsx +47 -2
- package/src/screens/search/components/conversation_results.tsx +7 -3
- package/src/screens/search/components/search_results_list.tsx +25 -4
- package/src/screens/search/search_screen.tsx +24 -4
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React from 'react'
|
|
1
|
+
import React, { useEffect, useRef } from 'react'
|
|
2
2
|
import { FlatList, StyleSheet, View } from 'react-native'
|
|
3
3
|
import { Banner, Spinner, Text, TextButton } from '../../../components'
|
|
4
4
|
import { useSearchResults } from '../../../hooks/use_search_results'
|
|
@@ -14,12 +14,18 @@ import { NoResultsBlankState } from './search_blank_states'
|
|
|
14
14
|
|
|
15
15
|
const SEARCH_ERROR_MESSAGE = "Couldn't search right now. Try again."
|
|
16
16
|
|
|
17
|
+
export interface SearchResultCounts {
|
|
18
|
+
conversationResultCount: number
|
|
19
|
+
messageResultCount: number
|
|
20
|
+
}
|
|
21
|
+
|
|
17
22
|
interface SearchResultsListProps {
|
|
18
23
|
term: string
|
|
19
|
-
onSelect: (result: SearchResultResource) => void
|
|
24
|
+
onSelect: (result: SearchResultResource, position: number) => void
|
|
25
|
+
onSettled: (term: string, counts: SearchResultCounts) => void
|
|
20
26
|
}
|
|
21
27
|
|
|
22
|
-
export function SearchResultsList({ term, onSelect }: SearchResultsListProps) {
|
|
28
|
+
export function SearchResultsList({ term, onSelect, onSettled }: SearchResultsListProps) {
|
|
23
29
|
const {
|
|
24
30
|
results,
|
|
25
31
|
failedTypes,
|
|
@@ -32,6 +38,19 @@ export function SearchResultsList({ term, onSelect }: SearchResultsListProps) {
|
|
|
32
38
|
} = useSearchResults(term)
|
|
33
39
|
const conversationResults = results.filter(isConversationResult)
|
|
34
40
|
const messageResults = results.filter(isMessageResult)
|
|
41
|
+
const settled = !isPending && !isError
|
|
42
|
+
|
|
43
|
+
const settledTermRef = useRef<string | undefined>(undefined)
|
|
44
|
+
|
|
45
|
+
useEffect(() => {
|
|
46
|
+
if (!settled || settledTermRef.current === term) return
|
|
47
|
+
|
|
48
|
+
settledTermRef.current = term
|
|
49
|
+
onSettled(term, {
|
|
50
|
+
conversationResultCount: conversationResults.length,
|
|
51
|
+
messageResultCount: messageResults.length,
|
|
52
|
+
})
|
|
53
|
+
}, [settled, term, conversationResults.length, messageResults.length, onSettled])
|
|
35
54
|
|
|
36
55
|
return (
|
|
37
56
|
<FlatList
|
|
@@ -40,7 +59,9 @@ export function SearchResultsList({ term, onSelect }: SearchResultsListProps) {
|
|
|
40
59
|
keyboardShouldPersistTaps="handled"
|
|
41
60
|
keyboardDismissMode="on-drag"
|
|
42
61
|
contentContainerStyle={styles.content}
|
|
43
|
-
renderItem={({ item }) =>
|
|
62
|
+
renderItem={({ item, index }) => (
|
|
63
|
+
<MessageResultRow result={item} onPress={() => onSelect(item, index)} />
|
|
64
|
+
)}
|
|
44
65
|
ListHeaderComponent={
|
|
45
66
|
<>
|
|
46
67
|
{conversationResults.length > 0 && (
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
NativeStackNavigationOptions,
|
|
4
4
|
NativeStackScreenProps,
|
|
5
5
|
} from '@react-navigation/native-stack'
|
|
6
|
-
import React, { useState } from 'react'
|
|
6
|
+
import React, { useRef, useState } from 'react'
|
|
7
7
|
import { Keyboard, StyleSheet, View } from 'react-native'
|
|
8
8
|
import { KeyboardView } from '../../components'
|
|
9
9
|
import {
|
|
@@ -11,10 +11,11 @@ import {
|
|
|
11
11
|
withMinimalBack,
|
|
12
12
|
} from '../../components/display/platform_modal_header_buttons'
|
|
13
13
|
import { useDebouncedSearchTerm } from '../../hooks/use_debounced_search_term'
|
|
14
|
+
import { analyticsEvents, useProductAnalytics } from '../../hooks/use_product_analytics'
|
|
14
15
|
import type { SearchResultResource } from '../../types/resources/search_result'
|
|
15
16
|
import { SearchPromptBlankState } from './components/search_blank_states'
|
|
16
17
|
import { SearchField } from './components/search_field'
|
|
17
|
-
import { SearchResultsList } from './components/search_results_list'
|
|
18
|
+
import { SearchResultsList, type SearchResultCounts } from './components/search_results_list'
|
|
18
19
|
|
|
19
20
|
export const SearchScreenOptions = ({
|
|
20
21
|
navigation,
|
|
@@ -28,9 +29,23 @@ export function SearchScreen() {
|
|
|
28
29
|
const navigation = useNavigation()
|
|
29
30
|
const [term, setTerm] = useState('')
|
|
30
31
|
const debouncedTerm = useDebouncedSearchTerm(term)
|
|
32
|
+
const { publishEvent } = useProductAnalytics()
|
|
33
|
+
const publishedTerms = useRef(new Set<string>())
|
|
31
34
|
|
|
32
|
-
const
|
|
35
|
+
const publishSearch = (settledTerm: string, counts: SearchResultCounts) => {
|
|
36
|
+
if (publishedTerms.current.has(settledTerm)) return
|
|
37
|
+
|
|
38
|
+
publishedTerms.current.add(settledTerm)
|
|
39
|
+
publishEvent(analyticsEvents.search_performed, {
|
|
40
|
+
term_length: settledTerm.length,
|
|
41
|
+
conversation_result_count: counts.conversationResultCount,
|
|
42
|
+
message_result_count: counts.messageResultCount,
|
|
43
|
+
})
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const openResult = (result: SearchResultResource, position: number) => {
|
|
33
47
|
Keyboard.dismiss()
|
|
48
|
+
publishEvent(analyticsEvents.search_result_opened, { result_type: result.type, position })
|
|
34
49
|
|
|
35
50
|
if (result.type === 'conversation') {
|
|
36
51
|
navigation.navigate('Conversation', {
|
|
@@ -51,7 +66,12 @@ export function SearchScreen() {
|
|
|
51
66
|
<View style={styles.container} testID="search-screen">
|
|
52
67
|
<SearchField term={term} onChange={setTerm} />
|
|
53
68
|
{debouncedTerm.length > 0 ? (
|
|
54
|
-
<SearchResultsList
|
|
69
|
+
<SearchResultsList
|
|
70
|
+
key={debouncedTerm}
|
|
71
|
+
term={debouncedTerm}
|
|
72
|
+
onSelect={openResult}
|
|
73
|
+
onSettled={publishSearch}
|
|
74
|
+
/>
|
|
55
75
|
) : (
|
|
56
76
|
<SearchPromptBlankState />
|
|
57
77
|
)}
|