@planningcenter/chat-react-native 3.23.0 → 3.23.1-qa-538.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/components/display/toggle_button.d.ts +11 -4
- package/build/components/display/toggle_button.d.ts.map +1 -1
- package/build/components/display/toggle_button.js +6 -5
- package/build/components/display/toggle_button.js.map +1 -1
- package/build/components/primitive/form_sheet.d.ts +1 -1
- package/build/components/primitive/form_sheet.d.ts.map +1 -1
- package/build/components/primitive/form_sheet.js +1 -1
- package/build/components/primitive/form_sheet.js.map +1 -1
- package/build/hooks/index.d.ts +1 -0
- package/build/hooks/index.d.ts.map +1 -1
- package/build/hooks/index.js +1 -0
- package/build/hooks/index.js.map +1 -1
- package/build/hooks/use_conversation.d.ts.map +1 -1
- package/build/hooks/use_conversation.js +6 -1
- package/build/hooks/use_conversation.js.map +1 -1
- package/build/hooks/use_conversation_membership.d.ts +5 -0
- package/build/hooks/use_conversation_membership.d.ts.map +1 -0
- package/build/hooks/use_conversation_membership.js +54 -0
- package/build/hooks/use_conversation_membership.js.map +1 -0
- package/build/hooks/use_features.d.ts +1 -0
- package/build/hooks/use_features.d.ts.map +1 -1
- package/build/hooks/use_features.js +1 -0
- package/build/hooks/use_features.js.map +1 -1
- package/build/hooks/use_new_conversation_entry.d.ts +3 -0
- package/build/hooks/use_new_conversation_entry.d.ts.map +1 -0
- package/build/hooks/use_new_conversation_entry.js +20 -0
- package/build/hooks/use_new_conversation_entry.js.map +1 -0
- package/build/hooks/use_report_message.d.ts +6 -0
- package/build/hooks/use_report_message.d.ts.map +1 -0
- package/build/hooks/use_report_message.js +28 -0
- package/build/hooks/use_report_message.js.map +1 -0
- package/build/navigation/index.d.ts +18 -8
- package/build/navigation/index.d.ts.map +1 -1
- package/build/navigation/index.js +16 -6
- package/build/navigation/index.js.map +1 -1
- package/build/screens/conversation_details_screen.d.ts.map +1 -1
- package/build/screens/conversation_details_screen.js +18 -10
- package/build/screens/conversation_details_screen.js.map +1 -1
- package/build/screens/conversation_filter_recipients/conversation_filter_recipients_screen.js +5 -3
- package/build/screens/conversation_filter_recipients/conversation_filter_recipients_screen.js.map +1 -1
- package/build/screens/conversation_select_recipients/conversation_new_entry_screen.d.ts +4 -0
- package/build/screens/conversation_select_recipients/conversation_new_entry_screen.d.ts.map +1 -0
- package/build/screens/conversation_select_recipients/conversation_new_entry_screen.js +67 -0
- package/build/screens/conversation_select_recipients/conversation_new_entry_screen.js.map +1 -0
- package/build/screens/conversation_select_recipients/conversation_select_teams_i_lead_recipients_screen.d.ts.map +1 -1
- package/build/screens/conversation_select_recipients/conversation_select_teams_i_lead_recipients_screen.js +17 -2
- package/build/screens/conversation_select_recipients/conversation_select_teams_i_lead_recipients_screen.js.map +1 -1
- package/build/screens/conversation_select_type_screen.d.ts +11 -0
- package/build/screens/conversation_select_type_screen.d.ts.map +1 -0
- package/build/screens/conversation_select_type_screen.js +32 -0
- package/build/screens/conversation_select_type_screen.js.map +1 -0
- package/build/screens/conversations/components/list_header_component.d.ts.map +1 -1
- package/build/screens/conversations/components/list_header_component.js +54 -25
- package/build/screens/conversations/components/list_header_component.js.map +1 -1
- package/build/screens/index.d.ts +1 -1
- package/build/screens/index.d.ts.map +1 -1
- package/build/screens/index.js +1 -1
- package/build/screens/index.js.map +1 -1
- package/build/screens/message_actions_screen.js +14 -2
- package/build/screens/message_actions_screen.js.map +1 -1
- package/build/screens/message_report/components/message_preview.d.ts +10 -0
- package/build/screens/message_report/components/message_preview.d.ts.map +1 -0
- package/build/screens/message_report/components/message_preview.js +81 -0
- package/build/screens/message_report/components/message_preview.js.map +1 -0
- package/build/screens/message_report/components/report_reason_list.d.ts +9 -0
- package/build/screens/message_report/components/report_reason_list.d.ts.map +1 -0
- package/build/screens/message_report/components/report_reason_list.js +67 -0
- package/build/screens/message_report/components/report_reason_list.js.map +1 -0
- package/build/screens/message_report_screen.d.ts +10 -0
- package/build/screens/message_report_screen.d.ts.map +1 -0
- package/build/screens/message_report_screen.js +214 -0
- package/build/screens/message_report_screen.js.map +1 -0
- package/build/types/resources/conversation.d.ts +2 -3
- package/build/types/resources/conversation.d.ts.map +1 -1
- package/build/types/resources/conversation.js.map +1 -1
- package/build/types/resources/conversation_membership.d.ts +14 -0
- package/build/types/resources/conversation_membership.d.ts.map +1 -0
- package/build/types/resources/conversation_membership.js +2 -0
- package/build/types/resources/conversation_membership.js.map +1 -0
- package/build/types/resources/index.d.ts +1 -0
- package/build/types/resources/index.d.ts.map +1 -1
- package/build/types/resources/index.js +1 -0
- package/build/types/resources/index.js.map +1 -1
- package/build/types/resources/message_report.d.ts +19 -0
- package/build/types/resources/message_report.d.ts.map +1 -0
- package/build/types/resources/message_report.js +9 -0
- package/build/types/resources/message_report.js.map +1 -0
- package/build/utils/deep_snake_case_keys.d.ts +4 -0
- package/build/utils/deep_snake_case_keys.d.ts.map +1 -0
- package/build/utils/deep_snake_case_keys.js +13 -0
- package/build/utils/deep_snake_case_keys.js.map +1 -0
- package/package.json +2 -2
- package/src/components/display/toggle_button.tsx +27 -15
- package/src/components/primitive/form_sheet.tsx +4 -2
- package/src/hooks/index.ts +1 -0
- package/src/hooks/use_conversation.ts +6 -1
- package/src/hooks/use_conversation_membership.ts +82 -0
- package/src/hooks/use_features.ts +1 -0
- package/src/hooks/use_new_conversation_entry.ts +31 -0
- package/src/hooks/use_report_message.ts +37 -0
- package/src/navigation/index.tsx +19 -6
- package/src/screens/conversation_details_screen.tsx +34 -16
- package/src/screens/conversation_filter_recipients/conversation_filter_recipients_screen.tsx +10 -3
- package/src/screens/conversation_select_recipients/conversation_new_entry_screen.tsx +100 -0
- package/src/screens/conversation_select_recipients/conversation_select_teams_i_lead_recipients_screen.tsx +23 -3
- package/src/screens/conversation_select_type_screen.tsx +53 -0
- package/src/screens/conversations/components/list_header_component.tsx +103 -67
- package/src/screens/index.ts +1 -1
- package/src/screens/message_actions_screen.tsx +24 -2
- package/src/screens/message_report/components/message_preview.tsx +99 -0
- package/src/screens/message_report/components/report_reason_list.tsx +106 -0
- package/src/screens/message_report_screen.tsx +278 -0
- package/src/types/resources/conversation.ts +2 -3
- package/src/types/resources/conversation_membership.ts +15 -0
- package/src/types/resources/index.ts +1 -0
- package/src/types/resources/message_report.ts +20 -0
- package/src/utils/deep_snake_case_keys.ts +16 -0
- package/build/screens/conversation_select_recipients/conversation_select_recipients_screen.d.ts +0 -4
- package/build/screens/conversation_select_recipients/conversation_select_recipients_screen.d.ts.map +0 -1
- package/build/screens/conversation_select_recipients/conversation_select_recipients_screen.js +0 -146
- package/build/screens/conversation_select_recipients/conversation_select_recipients_screen.js.map +0 -1
- package/src/screens/conversation_select_recipients/conversation_select_recipients_screen.tsx +0 -215
|
@@ -1,25 +1,25 @@
|
|
|
1
|
+
import { HeaderTitle as ElementsHeaderTitle, HeaderTitleProps } from '@react-navigation/elements'
|
|
1
2
|
import { StackActions, StaticScreenProps, useNavigation } from '@react-navigation/native'
|
|
2
3
|
import React, {
|
|
3
4
|
useCallback,
|
|
4
5
|
useEffect,
|
|
6
|
+
useRef,
|
|
5
7
|
useState,
|
|
6
|
-
type SetStateAction,
|
|
7
8
|
type Dispatch,
|
|
8
9
|
type ReactNode,
|
|
9
|
-
|
|
10
|
+
type SetStateAction,
|
|
10
11
|
} from 'react'
|
|
11
12
|
import {
|
|
13
|
+
Alert,
|
|
12
14
|
FlatList,
|
|
15
|
+
Platform,
|
|
16
|
+
Pressable,
|
|
13
17
|
StyleSheet,
|
|
14
18
|
TextInput,
|
|
15
19
|
View,
|
|
16
|
-
type ViewStyle,
|
|
17
20
|
type ViewProps,
|
|
18
|
-
|
|
19
|
-
Alert,
|
|
20
|
-
Platform,
|
|
21
|
+
type ViewStyle,
|
|
21
22
|
} from 'react-native'
|
|
22
|
-
import { HeaderTitle as ElementsHeaderTitle, HeaderTitleProps } from '@react-navigation/elements'
|
|
23
23
|
import {
|
|
24
24
|
Badge,
|
|
25
25
|
ChildNotice,
|
|
@@ -31,21 +31,20 @@ import {
|
|
|
31
31
|
TextButton,
|
|
32
32
|
type TextStyle,
|
|
33
33
|
} from '../components'
|
|
34
|
+
import { HeaderTextButton } from '../components/display/platform_modal_header_buttons'
|
|
35
|
+
import { ButtonAppearanceUnion } from '../components/display/utils/button_colors'
|
|
34
36
|
import { useSuspensePaginator, useTheme } from '../hooks'
|
|
35
37
|
import {
|
|
36
38
|
useConversation,
|
|
37
39
|
useConversationDelete,
|
|
38
40
|
useConversationDisableReplies,
|
|
39
|
-
useConversationMute,
|
|
40
41
|
useConversationUpdate,
|
|
41
42
|
} from '../hooks/use_conversation'
|
|
43
|
+
import { useConversationMembershipUpdate } from '../hooks/use_conversation_membership'
|
|
44
|
+
import { availableFeatures, useFeatures } from '../hooks/use_features'
|
|
42
45
|
import { MemberResource, isDefined } from '../types'
|
|
43
|
-
import { HeaderTextButton } from '../components/display/platform_modal_header_buttons'
|
|
44
|
-
import { tokens } from '../vendor/tapestry/tokens'
|
|
45
|
-
import { ButtonAppearanceUnion } from '../components/display/utils/button_colors'
|
|
46
46
|
import { GroupResource } from '../types/resources/group_resource'
|
|
47
|
-
import {
|
|
48
|
-
import { availableFeatures } from '../hooks/use_features'
|
|
47
|
+
import { tokens } from '../vendor/tapestry/tokens'
|
|
49
48
|
|
|
50
49
|
// =========================================
|
|
51
50
|
// ====== Factory Constants & Types ========
|
|
@@ -91,7 +90,7 @@ export function ConversationDetailsScreen({ route }: ConversationDetailsScreenPr
|
|
|
91
90
|
|
|
92
91
|
const { data: conversation } = useConversation(route.params)
|
|
93
92
|
const [title, setTitle] = useState(conversation.title)
|
|
94
|
-
const {
|
|
93
|
+
const { mutate: updateMembership } = useConversationMembershipUpdate(route.params)
|
|
95
94
|
const { repliesDisabled, setRepliesDisabled } = useConversationDisableReplies(route.params)
|
|
96
95
|
const { mutate: saveTitle } = useConversationUpdate(route.params)
|
|
97
96
|
const { mutate: deleteConversation } = useConversationDelete(route.params)
|
|
@@ -101,6 +100,10 @@ export function ConversationDetailsScreen({ route }: ConversationDetailsScreenPr
|
|
|
101
100
|
const trimmedTitle = title.trim()
|
|
102
101
|
const emptyTitle = trimmedTitle === '' || title === null
|
|
103
102
|
|
|
103
|
+
const notificationsEnabled =
|
|
104
|
+
conversation.conversationMembership?.notificationLevel === 'everything'
|
|
105
|
+
const notificationLevelDescription =
|
|
106
|
+
conversation?.conversationMembership?.notificationLevelDescription
|
|
104
107
|
const canUpdate = conversation.memberAbility?.canUpdate || false
|
|
105
108
|
const canDelete = conversation.memberAbility?.canDelete || false
|
|
106
109
|
const isLeader = conversation.memberAbility?.leader || false
|
|
@@ -163,6 +166,15 @@ export function ConversationDetailsScreen({ route }: ConversationDetailsScreenPr
|
|
|
163
166
|
const productName = badge?.appName
|
|
164
167
|
const name = badge?.text || undefined
|
|
165
168
|
|
|
169
|
+
const handleToggleNotificationPreferences = useCallback(
|
|
170
|
+
(value: boolean) => {
|
|
171
|
+
updateMembership({
|
|
172
|
+
notificationLevel: value ? 'everything' : 'nothing',
|
|
173
|
+
})
|
|
174
|
+
},
|
|
175
|
+
[updateMembership]
|
|
176
|
+
)
|
|
177
|
+
|
|
166
178
|
const handleDelete = useCallback(() => {
|
|
167
179
|
Alert.alert(
|
|
168
180
|
'Delete conversation',
|
|
@@ -246,8 +258,14 @@ export function ConversationDetailsScreen({ route }: ConversationDetailsScreenPr
|
|
|
246
258
|
{
|
|
247
259
|
type: SectionTypes.setting,
|
|
248
260
|
data: {
|
|
249
|
-
title: '
|
|
250
|
-
|
|
261
|
+
title: 'Enable notifications',
|
|
262
|
+
subtitle: notificationLevelDescription,
|
|
263
|
+
rightItem: (
|
|
264
|
+
<Switch
|
|
265
|
+
value={notificationsEnabled}
|
|
266
|
+
onValueChange={handleToggleNotificationPreferences}
|
|
267
|
+
/>
|
|
268
|
+
),
|
|
251
269
|
},
|
|
252
270
|
showBottomBorder: true,
|
|
253
271
|
},
|
package/src/screens/conversation_filter_recipients/conversation_filter_recipients_screen.tsx
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { RouteProp, StackActions, useNavigation, useRoute } from '@react-navigation/native'
|
|
2
2
|
import { NativeStackNavigationProp } from '@react-navigation/native-stack'
|
|
3
3
|
import React, { useCallback, useMemo, useState } from 'react'
|
|
4
|
-
import { LayoutChangeEvent, Platform, StyleSheet, View } from 'react-native'
|
|
4
|
+
import { LayoutChangeEvent, Platform, ScrollView, StyleSheet, View } from 'react-native'
|
|
5
5
|
import { FlatList, TextInput } from 'react-native-gesture-handler'
|
|
6
6
|
import { useSafeAreaInsets } from 'react-native-safe-area-context'
|
|
7
7
|
import { Heading, ToggleButton } from '../../components'
|
|
@@ -192,7 +192,12 @@ const TeamFilters = ({ onLayout }: { onLayout?: (event: LayoutChangeEvent) => vo
|
|
|
192
192
|
})
|
|
193
193
|
}}
|
|
194
194
|
/>
|
|
195
|
-
<
|
|
195
|
+
<ScrollView
|
|
196
|
+
horizontal
|
|
197
|
+
showsHorizontalScrollIndicator={false}
|
|
198
|
+
contentContainerStyle={styles.filterToggleContainer}
|
|
199
|
+
accessibilityRole="toolbar"
|
|
200
|
+
>
|
|
196
201
|
<ToggleButton
|
|
197
202
|
active={active === TeamFilterTypes.TeamsIlead}
|
|
198
203
|
title={TeamFilterTypes.TeamsIlead}
|
|
@@ -211,7 +216,7 @@ const TeamFilters = ({ onLayout }: { onLayout?: (event: LayoutChangeEvent) => vo
|
|
|
211
216
|
accessibilityLabel="Show all teams"
|
|
212
217
|
onPress={() => handleFilterChange(TeamFilterTypes.All)}
|
|
213
218
|
/>
|
|
214
|
-
</
|
|
219
|
+
</ScrollView>
|
|
215
220
|
</View>
|
|
216
221
|
)
|
|
217
222
|
}
|
|
@@ -253,7 +258,9 @@ const useStyles = () => {
|
|
|
253
258
|
},
|
|
254
259
|
filterToggleContainer: {
|
|
255
260
|
flexDirection: 'row',
|
|
261
|
+
justifyContent: 'flex-start',
|
|
256
262
|
gap: 8,
|
|
263
|
+
flexGrow: 1,
|
|
257
264
|
},
|
|
258
265
|
searchInput: {
|
|
259
266
|
paddingVertical: 16,
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { useNavigation } from '@react-navigation/native'
|
|
2
|
+
import type { NativeStackNavigationProp } from '@react-navigation/native-stack'
|
|
3
|
+
import React, { useEffect } from 'react'
|
|
4
|
+
import { ScrollView, StyleSheet, View } from 'react-native'
|
|
5
|
+
import { Button, Heading } from '../../components'
|
|
6
|
+
import { DefaultLoading } from '../../components/page/loading'
|
|
7
|
+
import { useSafeAreaInsets } from 'react-native-safe-area-context'
|
|
8
|
+
import type {
|
|
9
|
+
ConversationSelectRecipientsParams,
|
|
10
|
+
ConversationSelectRecipientsScreenProps,
|
|
11
|
+
} from './types/screen_props'
|
|
12
|
+
import { useNewConversationEntry } from '../../hooks/use_new_conversation_entry'
|
|
13
|
+
import { Haptic } from '../../utils/native_adapters'
|
|
14
|
+
|
|
15
|
+
type NewConversationStackParamList = {
|
|
16
|
+
ConversationNewEntry: ConversationSelectRecipientsParams | undefined
|
|
17
|
+
ConversationSelectGroupRecipients: ConversationSelectRecipientsParams | undefined
|
|
18
|
+
ConversationSelectTeamsILeadRecipients: ConversationSelectRecipientsParams | undefined
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export const ConversationNewEntryScreen = ({ route }: ConversationSelectRecipientsScreenProps) => {
|
|
22
|
+
const styles = useStyles()
|
|
23
|
+
const navigation = useNavigation<NativeStackNavigationProp<NewConversationStackParamList>>()
|
|
24
|
+
const entryMode = useNewConversationEntry()
|
|
25
|
+
|
|
26
|
+
useEffect(() => {
|
|
27
|
+
if (entryMode === 'groups') {
|
|
28
|
+
navigation.replace('ConversationSelectGroupRecipients', route.params)
|
|
29
|
+
return
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (entryMode === 'teams') {
|
|
33
|
+
navigation.replace('ConversationSelectTeamsILeadRecipients', route.params)
|
|
34
|
+
return
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (entryMode === 'none') {
|
|
38
|
+
navigation.goBack()
|
|
39
|
+
return
|
|
40
|
+
}
|
|
41
|
+
}, [entryMode, navigation, route.params])
|
|
42
|
+
|
|
43
|
+
if (entryMode !== 'select_type') return <DefaultLoading />
|
|
44
|
+
|
|
45
|
+
const handleGroupPress = () => {
|
|
46
|
+
Haptic.impactLight()
|
|
47
|
+
navigation.navigate('ConversationSelectGroupRecipients', route.params)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const handleTeamPress = () => {
|
|
51
|
+
Haptic.impactLight()
|
|
52
|
+
navigation.navigate('ConversationSelectTeamsILeadRecipients', route.params)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return (
|
|
56
|
+
<ScrollView contentContainerStyle={styles.contentContainer}>
|
|
57
|
+
<View style={styles.header}>
|
|
58
|
+
<Heading variant="h2">Start a conversation by</Heading>
|
|
59
|
+
</View>
|
|
60
|
+
<View style={styles.actions}>
|
|
61
|
+
<Button
|
|
62
|
+
title="Group"
|
|
63
|
+
onPress={handleGroupPress}
|
|
64
|
+
size="lg"
|
|
65
|
+
variant="outline"
|
|
66
|
+
accessibilityHint="Opens group selection screen"
|
|
67
|
+
/>
|
|
68
|
+
<Button
|
|
69
|
+
title="Team"
|
|
70
|
+
onPress={handleTeamPress}
|
|
71
|
+
size="lg"
|
|
72
|
+
variant="outline"
|
|
73
|
+
accessibilityHint="Opens team selection screen"
|
|
74
|
+
/>
|
|
75
|
+
</View>
|
|
76
|
+
</ScrollView>
|
|
77
|
+
)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const useStyles = () => {
|
|
81
|
+
const { bottom } = useSafeAreaInsets()
|
|
82
|
+
|
|
83
|
+
return StyleSheet.create({
|
|
84
|
+
contentContainer: {
|
|
85
|
+
flexGrow: 1,
|
|
86
|
+
padding: 16,
|
|
87
|
+
paddingBottom: 16 + bottom,
|
|
88
|
+
justifyContent: 'center',
|
|
89
|
+
},
|
|
90
|
+
header: {
|
|
91
|
+
marginBottom: 24,
|
|
92
|
+
alignItems: 'center',
|
|
93
|
+
},
|
|
94
|
+
actions: {
|
|
95
|
+
gap: 12,
|
|
96
|
+
flexDirection: 'row',
|
|
97
|
+
justifyContent: 'center',
|
|
98
|
+
},
|
|
99
|
+
})
|
|
100
|
+
}
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { useNavigation } from '@react-navigation/native'
|
|
2
2
|
import React from 'react'
|
|
3
3
|
import { FlatList, StyleSheet, View } from 'react-native'
|
|
4
|
-
import { Heading } from '../../components'
|
|
4
|
+
import { Button, Heading } from '../../components'
|
|
5
5
|
import { useSafeAreaInsets } from 'react-native-safe-area-context'
|
|
6
6
|
import { ConversationSelectRecipientsScreenProps } from './types/screen_props'
|
|
7
7
|
import { useServiceTypesWithTeams } from '../conversation_filter_recipients/hooks/use_service_types_with_teams'
|
|
8
|
-
import { ServiceTypeWithTeams } from '../conversation_filter_recipients/types'
|
|
8
|
+
import { ServiceTypeWithTeams, TeamFilterTypes } from '../conversation_filter_recipients/types'
|
|
9
9
|
import { TeamRecipientRow } from './components/team_recipient_row'
|
|
10
|
+
import { Haptic } from '../../utils/native_adapters'
|
|
10
11
|
|
|
11
12
|
export const ConversationSelectTeamsILeadRecipientsScreen = ({
|
|
12
13
|
route,
|
|
@@ -14,6 +15,7 @@ export const ConversationSelectTeamsILeadRecipientsScreen = ({
|
|
|
14
15
|
const styles = useStyles()
|
|
15
16
|
const navigation = useNavigation()
|
|
16
17
|
const { serviceTypes } = useServiceTypesWithTeams()
|
|
18
|
+
const hasServiceTypes = serviceTypes.length > 0
|
|
17
19
|
|
|
18
20
|
const handleNavigateToConversationNew = (teams: ServiceTypeWithTeams['teams']) => {
|
|
19
21
|
const teamIds = teams.map(team => team.id)
|
|
@@ -35,7 +37,25 @@ export const ConversationSelectTeamsILeadRecipientsScreen = ({
|
|
|
35
37
|
contentContainerStyle={styles.contentContainer}
|
|
36
38
|
ListHeaderComponent={
|
|
37
39
|
<View style={styles.sectionHeader}>
|
|
38
|
-
<Heading variant="h3">
|
|
40
|
+
<Heading variant="h3">Teams I lead</Heading>
|
|
41
|
+
<Button
|
|
42
|
+
onPress={() => {
|
|
43
|
+
Haptic.impactLight()
|
|
44
|
+
navigation.navigate('New', {
|
|
45
|
+
screen: 'ConversationFilterRecipients',
|
|
46
|
+
params: {
|
|
47
|
+
source_app_name: 'Services',
|
|
48
|
+
team_filter_type: hasServiceTypes
|
|
49
|
+
? TeamFilterTypes.TeamsIlead
|
|
50
|
+
: TeamFilterTypes.All,
|
|
51
|
+
},
|
|
52
|
+
})
|
|
53
|
+
}}
|
|
54
|
+
title="Select teams"
|
|
55
|
+
variant="outline"
|
|
56
|
+
iconNameLeft="general.search"
|
|
57
|
+
size="sm"
|
|
58
|
+
/>
|
|
39
59
|
</View>
|
|
40
60
|
}
|
|
41
61
|
renderItem={({ item: serviceType }: { item: ServiceTypeWithTeams }) => {
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { StaticScreenProps, useNavigation } from '@react-navigation/native'
|
|
3
|
+
import FormSheet, { getFormSheetScreenOptions } from '../components/primitive/form_sheet'
|
|
4
|
+
import { Haptic } from '../utils/native_adapters'
|
|
5
|
+
import { AppName } from '../types/resources/app_name'
|
|
6
|
+
import { GraphId } from '../types/resources/group_resource'
|
|
7
|
+
|
|
8
|
+
export const ConversationSelectTypeScreenOptions = getFormSheetScreenOptions({
|
|
9
|
+
headerTitle: 'New conversation',
|
|
10
|
+
})
|
|
11
|
+
|
|
12
|
+
export type ConversationSelectTypeScreenProps = StaticScreenProps<{
|
|
13
|
+
chat_group_graph_id?: GraphId
|
|
14
|
+
group_source_app_name?: AppName
|
|
15
|
+
}>
|
|
16
|
+
|
|
17
|
+
export function ConversationSelectTypeScreen({ route }: ConversationSelectTypeScreenProps) {
|
|
18
|
+
const navigation = useNavigation()
|
|
19
|
+
|
|
20
|
+
const handleGroupPress = () => {
|
|
21
|
+
Haptic.impactLight()
|
|
22
|
+
navigation.navigate('New', {
|
|
23
|
+
screen: 'ConversationSelectGroupRecipients',
|
|
24
|
+
params: { ...route.params },
|
|
25
|
+
})
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const handleTeamPress = () => {
|
|
29
|
+
Haptic.impactLight()
|
|
30
|
+
navigation.navigate('New', {
|
|
31
|
+
screen: 'ConversationSelectTeamsILeadRecipients',
|
|
32
|
+
params: { ...route.params },
|
|
33
|
+
})
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return (
|
|
37
|
+
<FormSheet.Root>
|
|
38
|
+
<FormSheet.Header>
|
|
39
|
+
<FormSheet.HeaderTitle>Start a conversation by</FormSheet.HeaderTitle>
|
|
40
|
+
</FormSheet.Header>
|
|
41
|
+
<FormSheet.Action
|
|
42
|
+
title="Group"
|
|
43
|
+
onPress={handleGroupPress}
|
|
44
|
+
accessibilityHint="Opens group selection screen"
|
|
45
|
+
/>
|
|
46
|
+
<FormSheet.Action
|
|
47
|
+
title="Team"
|
|
48
|
+
onPress={handleTeamPress}
|
|
49
|
+
accessibilityHint="Opens team selection screen"
|
|
50
|
+
/>
|
|
51
|
+
</FormSheet.Root>
|
|
52
|
+
)
|
|
53
|
+
}
|
|
@@ -6,6 +6,7 @@ import { useAtFontScaleBreakpoint, useCurrentPersonCache, useTheme } from '../..
|
|
|
6
6
|
import { useMarkAllRead } from '../../../hooks/use_conversations_actions'
|
|
7
7
|
import { useCanDisplayGroups } from '../../../hooks/use_groups'
|
|
8
8
|
import { useCanCreateConversations } from '../../../hooks'
|
|
9
|
+
import { useNewConversationEntry } from '../../../hooks/use_new_conversation_entry'
|
|
9
10
|
import { useAppName } from '../../../hooks/use_app_name'
|
|
10
11
|
import { ConversationsScreenProps } from '../conversations_screen'
|
|
11
12
|
import { ChatGroupBadge } from './chat_group_badge'
|
|
@@ -23,7 +24,6 @@ enum FilterTypes {
|
|
|
23
24
|
}
|
|
24
25
|
|
|
25
26
|
export const ListHeaderComponent = () => {
|
|
26
|
-
const styles = useStyles()
|
|
27
27
|
const navigation = useNavigation()
|
|
28
28
|
const canFilterByTeams = useCanDisplayGroups({ source_app_name: 'Services', source_type: 'Team' })
|
|
29
29
|
const canFilterByGroups = useCanDisplayGroups({ source_app_name: 'Groups', source_type: 'Group' })
|
|
@@ -32,6 +32,7 @@ export const ListHeaderComponent = () => {
|
|
|
32
32
|
const currentPersonCache = useCurrentPersonCache()
|
|
33
33
|
const { markAllRead, isPending } = useMarkAllRead()
|
|
34
34
|
const canCreateConversations = useCanCreateConversations()
|
|
35
|
+
const entryMode = useNewConversationEntry()
|
|
35
36
|
const appName = useAppName()
|
|
36
37
|
|
|
37
38
|
const active: FilterTypes = useMemo(() => {
|
|
@@ -47,18 +48,36 @@ export const ListHeaderComponent = () => {
|
|
|
47
48
|
}, [chat_group_graph_id, group_source_app_name])
|
|
48
49
|
|
|
49
50
|
const handleNewConversationNavigation = useCallback(() => {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
51
|
+
if (entryMode === 'select_type') {
|
|
52
|
+
return navigation.navigate('ConversationSelectType', { ...route.params })
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (entryMode === 'groups') {
|
|
56
|
+
return navigation.navigate('New', {
|
|
57
|
+
screen: 'ConversationSelectGroupRecipients',
|
|
58
|
+
params: { ...route.params },
|
|
59
|
+
})
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (entryMode === 'teams') {
|
|
63
|
+
return navigation.navigate('New', {
|
|
64
|
+
screen: 'ConversationSelectTeamsILeadRecipients',
|
|
65
|
+
params: { ...route.params },
|
|
66
|
+
})
|
|
67
|
+
}
|
|
68
|
+
}, [navigation, route.params, entryMode])
|
|
57
69
|
|
|
58
70
|
const handleGetHelp = useCallback(() => {
|
|
59
71
|
navigation.navigate('GetHelp', { type: 'chat' })
|
|
60
72
|
}, [navigation])
|
|
61
73
|
|
|
74
|
+
const handleOpenConversationFilters = useCallback(() => {
|
|
75
|
+
navigation.navigate('ConversationFilters', {
|
|
76
|
+
chat_group_graph_id,
|
|
77
|
+
group_source_app_name,
|
|
78
|
+
})
|
|
79
|
+
}, [navigation, chat_group_graph_id, group_source_app_name])
|
|
80
|
+
|
|
62
81
|
const handleMarkAllRead = useCallback(() => {
|
|
63
82
|
currentPersonCache.update({ unreadCount: 0 })
|
|
64
83
|
Haptic.notificationSuccess()
|
|
@@ -74,7 +93,22 @@ export const ListHeaderComponent = () => {
|
|
|
74
93
|
])
|
|
75
94
|
}, [active, handleMarkAllRead])
|
|
76
95
|
|
|
77
|
-
const
|
|
96
|
+
const hasSomeSourceFilterCapability = canFilterByTeams || canFilterByGroups
|
|
97
|
+
const hasMultiSourceFilterCapabilities = canFilterByTeams && canFilterByGroups
|
|
98
|
+
const shouldShowHeaderFiltersButton =
|
|
99
|
+
hasSomeSourceFilterCapability && !hasMultiSourceFilterCapabilities
|
|
100
|
+
const moreFiltersButtonA11yLabel = shouldShowHeaderFiltersButton
|
|
101
|
+
? 'View filters'
|
|
102
|
+
: 'View more filters'
|
|
103
|
+
|
|
104
|
+
const moreFiltersButtonProps = {
|
|
105
|
+
onPress: handleOpenConversationFilters,
|
|
106
|
+
active: active === FilterTypes.More,
|
|
107
|
+
iconNameRight: 'general.threeReducingHorizontalBars' as const,
|
|
108
|
+
accessibilityLabel: moreFiltersButtonA11yLabel,
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const styles = useStyles({ shouldShowHeaderFiltersButton })
|
|
78
112
|
|
|
79
113
|
return (
|
|
80
114
|
<View style={styles.listHeader}>
|
|
@@ -111,73 +145,70 @@ export const ListHeaderComponent = () => {
|
|
|
111
145
|
maxFontSizeMultiplier={MAX_FONT_SIZE_MULTIPLIER_LANDMARK}
|
|
112
146
|
/>
|
|
113
147
|
)}
|
|
148
|
+
{shouldShowHeaderFiltersButton && <ToggleButton {...moreFiltersButtonProps} />}
|
|
114
149
|
</View>
|
|
115
150
|
</View>
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
151
|
+
{hasMultiSourceFilterCapabilities && (
|
|
152
|
+
<ScrollView
|
|
153
|
+
horizontal
|
|
154
|
+
showsHorizontalScrollIndicator={false}
|
|
155
|
+
contentContainerStyle={styles.filterRow}
|
|
156
|
+
accessibilityRole="toolbar"
|
|
157
|
+
>
|
|
158
|
+
<ToggleButton
|
|
159
|
+
title={FilterTypes.All}
|
|
160
|
+
active={active === FilterTypes.All}
|
|
161
|
+
onPress={() =>
|
|
162
|
+
navigation.setParams({
|
|
163
|
+
chat_group_graph_id: undefined,
|
|
164
|
+
group_source_app_name: undefined,
|
|
165
|
+
})
|
|
166
|
+
}
|
|
167
|
+
accessibilityLabel="Show all conversations"
|
|
168
|
+
style={styles.filterButton}
|
|
169
|
+
/>
|
|
170
|
+
<ToggleButton
|
|
171
|
+
title={FilterTypes.Groups}
|
|
172
|
+
active={active === FilterTypes.Groups}
|
|
173
|
+
onPress={() =>
|
|
174
|
+
navigation.setParams({
|
|
175
|
+
chat_group_graph_id: undefined,
|
|
176
|
+
group_source_app_name: 'Groups',
|
|
177
|
+
})
|
|
178
|
+
}
|
|
179
|
+
accessibilityLabel="Filter to group conversations"
|
|
180
|
+
style={styles.filterButton}
|
|
181
|
+
/>
|
|
146
182
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
onPress={() =>
|
|
163
|
-
navigation.navigate('ConversationFilters', {
|
|
164
|
-
chat_group_graph_id,
|
|
165
|
-
group_source_app_name,
|
|
166
|
-
})
|
|
167
|
-
}
|
|
168
|
-
active={active === FilterTypes.More}
|
|
169
|
-
iconNameRight="general.threeReducingHorizontalBars"
|
|
170
|
-
accessibilityLabel={showAppFilters ? 'View all filters' : 'View more filters'}
|
|
171
|
-
/>
|
|
172
|
-
</ScrollView>
|
|
183
|
+
<ToggleButton
|
|
184
|
+
title={FilterTypes.Teams}
|
|
185
|
+
active={active === FilterTypes.Teams}
|
|
186
|
+
onPress={() =>
|
|
187
|
+
navigation.setParams({
|
|
188
|
+
chat_group_graph_id: undefined,
|
|
189
|
+
group_source_app_name: 'Services',
|
|
190
|
+
})
|
|
191
|
+
}
|
|
192
|
+
accessibilityLabel="Filter to team conversations"
|
|
193
|
+
style={styles.filterButton}
|
|
194
|
+
/>
|
|
195
|
+
<ToggleButton {...moreFiltersButtonProps} />
|
|
196
|
+
</ScrollView>
|
|
197
|
+
)}
|
|
173
198
|
<ChatGroupBadge rowPaddingHorizontal={ROW_PADDING_HORIZONTAL} />
|
|
174
199
|
</View>
|
|
175
200
|
)
|
|
176
201
|
}
|
|
177
202
|
|
|
178
|
-
const useStyles = (
|
|
203
|
+
const useStyles = ({
|
|
204
|
+
shouldShowHeaderFiltersButton,
|
|
205
|
+
}: {
|
|
206
|
+
shouldShowHeaderFiltersButton: boolean
|
|
207
|
+
}) => {
|
|
179
208
|
const theme = useTheme()
|
|
180
|
-
const atFontScaleBreakpoint = useAtFontScaleBreakpoint(
|
|
209
|
+
const atFontScaleBreakpoint = useAtFontScaleBreakpoint(
|
|
210
|
+
shouldShowHeaderFiltersButton ? 1.2 : undefined
|
|
211
|
+
)
|
|
181
212
|
|
|
182
213
|
return StyleSheet.create({
|
|
183
214
|
listHeader: {
|
|
@@ -210,6 +241,11 @@ const useStyles = () => {
|
|
|
210
241
|
justifyContent: 'flex-start',
|
|
211
242
|
gap: 8,
|
|
212
243
|
paddingHorizontal: ROW_PADDING_HORIZONTAL,
|
|
244
|
+
flexGrow: 1,
|
|
245
|
+
},
|
|
246
|
+
filterButton: {
|
|
247
|
+
flex: 1,
|
|
248
|
+
minWidth: 65,
|
|
213
249
|
},
|
|
214
250
|
})
|
|
215
251
|
}
|
package/src/screens/index.ts
CHANGED
|
@@ -3,8 +3,8 @@ export * from './conversation_details_screen'
|
|
|
3
3
|
export * from './conversation_screen'
|
|
4
4
|
export * from './conversation_new/conversation_new_screen'
|
|
5
5
|
export * from './conversation_filter_recipients/conversation_filter_recipients_screen'
|
|
6
|
-
export * from './conversation_select_recipients/conversation_select_recipients_screen'
|
|
7
6
|
export * from './message_actions_screen'
|
|
7
|
+
export * from './message_report_screen'
|
|
8
8
|
export * from './send_giphy_screen'
|
|
9
9
|
export * from './not_found'
|
|
10
10
|
export * from './reactions_screen'
|
|
@@ -120,6 +120,14 @@ function MessageActionsScreenContent({
|
|
|
120
120
|
navigation.goBack()
|
|
121
121
|
}
|
|
122
122
|
|
|
123
|
+
const handleReportPress = useCallback(() => {
|
|
124
|
+
Haptic.impactLight()
|
|
125
|
+
navigation.navigate('MessageReport', {
|
|
126
|
+
conversation_id,
|
|
127
|
+
message_id: message.id,
|
|
128
|
+
})
|
|
129
|
+
}, [navigation, conversation_id, message.id])
|
|
130
|
+
|
|
123
131
|
const { handleReactionToggle, isPending } = useMessageReactionToggle({
|
|
124
132
|
conversation_id,
|
|
125
133
|
message,
|
|
@@ -212,6 +220,9 @@ function MessageActionsScreenContent({
|
|
|
212
220
|
])
|
|
213
221
|
}, [handleRemoveLinkPreview])
|
|
214
222
|
|
|
223
|
+
const showReportMessageAction =
|
|
224
|
+
!message?.mine && featureEnabled(availableFeatures.message_reporting)
|
|
225
|
+
|
|
215
226
|
return (
|
|
216
227
|
<FormSheet.Root style={styles.formSheetContent}>
|
|
217
228
|
<View style={styles.reactionList}>
|
|
@@ -246,6 +257,14 @@ function MessageActionsScreenContent({
|
|
|
246
257
|
iconName="services.fileCopy"
|
|
247
258
|
accessibilityHint="Copies text and links to clipboard"
|
|
248
259
|
/>
|
|
260
|
+
{showReportMessageAction && (
|
|
261
|
+
<FormSheet.Action
|
|
262
|
+
onPress={handleReportPress}
|
|
263
|
+
title="Report message"
|
|
264
|
+
iconName="chat.reportMessageO"
|
|
265
|
+
accessibilityHint="Opens a form to report this message"
|
|
266
|
+
/>
|
|
267
|
+
)}
|
|
249
268
|
{message?.mine && (
|
|
250
269
|
<FormSheet.Action
|
|
251
270
|
onPress={() => handleEditPress()}
|
|
@@ -306,7 +325,9 @@ const Reaction = ({
|
|
|
306
325
|
android_ripple={{ color: androidRippleColor, borderless: false, foreground: true }}
|
|
307
326
|
onPress={onPress}
|
|
308
327
|
>
|
|
309
|
-
<Text style={styles.reactionEmoji}
|
|
328
|
+
<Text style={styles.reactionEmoji} allowFontScaling={false}>
|
|
329
|
+
{REACTION_EMOJIS[reaction.value]}
|
|
330
|
+
</Text>
|
|
310
331
|
</PlatformPressable>
|
|
311
332
|
)
|
|
312
333
|
}
|
|
@@ -316,7 +337,7 @@ const useStyles = () => {
|
|
|
316
337
|
const fontScale = useFontScale({ maxFontSizeMultiplier: 1.3 })
|
|
317
338
|
|
|
318
339
|
const btnBorderWidth = 1
|
|
319
|
-
const baseSize = 46 * fontScale
|
|
340
|
+
const baseSize = 46 * Math.max(1, fontScale)
|
|
320
341
|
const reactionBtnSize = Platform.select({
|
|
321
342
|
ios: baseSize,
|
|
322
343
|
android: baseSize + btnBorderWidth * 2,
|
|
@@ -346,6 +367,7 @@ const useStyles = () => {
|
|
|
346
367
|
},
|
|
347
368
|
reactionEmoji: {
|
|
348
369
|
fontSize: 24,
|
|
370
|
+
textAlign: 'center',
|
|
349
371
|
},
|
|
350
372
|
actions: {
|
|
351
373
|
paddingTop: 4,
|