@planningcenter/chat-react-native 3.11.0-rc.8 → 3.11.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/conversation/attachments/image_attachment.d.ts.map +1 -1
- package/build/components/conversation/attachments/image_attachment.js +9 -2
- package/build/components/conversation/attachments/image_attachment.js.map +1 -1
- package/build/components/conversation/message.d.ts +1 -1
- package/build/components/conversation/message.d.ts.map +1 -1
- package/build/components/conversation/message.js +85 -26
- package/build/components/conversation/message.js.map +1 -1
- package/build/components/conversation/message_form/message_form_attachment_image.d.ts +1 -1
- package/build/components/conversation/message_form/message_form_attachment_image.d.ts.map +1 -1
- package/build/components/conversation/message_form/message_form_attachment_image.js.map +1 -1
- package/build/components/conversation/message_form/message_form_attachment_video.d.ts +1 -1
- package/build/components/conversation/message_form/message_form_attachment_video.d.ts.map +1 -1
- package/build/components/conversation/message_form/message_form_attachment_video.js.map +1 -1
- package/build/components/conversation/message_form.d.ts.map +1 -1
- package/build/components/conversation/message_form.js +12 -10
- package/build/components/conversation/message_form.js.map +1 -1
- package/build/components/conversations/conversations.d.ts.map +1 -1
- package/build/components/conversations/conversations.js +5 -1
- package/build/components/conversations/conversations.js.map +1 -1
- package/build/components/display/spinner.d.ts +6 -1
- package/build/components/display/spinner.d.ts.map +1 -1
- package/build/components/display/spinner.js +2 -2
- package/build/components/display/spinner.js.map +1 -1
- package/build/components/display/text.js +10 -2
- package/build/components/display/text.js.map +1 -1
- package/build/components/primitive/form_sheet.d.ts +1 -0
- package/build/components/primitive/form_sheet.d.ts.map +1 -1
- package/build/components/primitive/form_sheet.js +2 -2
- package/build/components/primitive/form_sheet.js.map +1 -1
- package/build/contexts/api_provider.d.ts +1 -0
- package/build/contexts/api_provider.d.ts.map +1 -1
- package/build/contexts/api_provider.js +24 -2
- package/build/contexts/api_provider.js.map +1 -1
- package/build/hooks/groups/use_group_members_for_new_conversation.d.ts +1 -1
- package/build/hooks/groups/use_groups_conversation_create.d.ts.map +1 -1
- package/build/hooks/groups/use_groups_conversation_create.js +3 -1
- package/build/hooks/groups/use_groups_conversation_create.js.map +1 -1
- package/build/hooks/services/use_find_or_create_services_conversation.d.ts +2 -0
- package/build/hooks/services/use_find_or_create_services_conversation.d.ts.map +1 -1
- package/build/hooks/services/use_find_or_create_services_conversation.js +22 -19
- package/build/hooks/services/use_find_or_create_services_conversation.js.map +1 -1
- package/build/hooks/{use_services_team.d.ts → services/use_services_team.d.ts} +1 -1
- package/build/hooks/services/use_services_team.d.ts.map +1 -0
- package/build/hooks/{use_services_team.js → services/use_services_team.js} +1 -1
- package/build/hooks/services/use_services_team.js.map +1 -0
- package/build/hooks/use_attachment_uploader.d.ts +5 -13
- package/build/hooks/use_attachment_uploader.d.ts.map +1 -1
- package/build/hooks/use_attachment_uploader.js.map +1 -1
- package/build/hooks/use_chat_permissions.d.ts +10 -0
- package/build/hooks/use_chat_permissions.d.ts.map +1 -1
- package/build/hooks/use_chat_permissions.js +10 -9
- package/build/hooks/use_chat_permissions.js.map +1 -1
- package/build/hooks/use_conversation.d.ts +1 -1
- package/build/hooks/use_conversation_messages_jolt_events.d.ts.map +1 -1
- package/build/hooks/use_conversation_messages_jolt_events.js +16 -1
- package/build/hooks/use_conversation_messages_jolt_events.js.map +1 -1
- package/build/hooks/use_giphy.d.ts +1 -1
- package/build/hooks/use_giphy.d.ts.map +1 -1
- package/build/hooks/use_giphy.js.map +1 -1
- package/build/hooks/use_message_create_or_update.d.ts +8 -4
- package/build/hooks/use_message_create_or_update.d.ts.map +1 -1
- package/build/hooks/use_message_create_or_update.js +58 -4
- package/build/hooks/use_message_create_or_update.js.map +1 -1
- package/build/hooks/use_read_receipts.d.ts +1 -1
- package/build/hooks/use_suspense_api.d.ts +2 -2
- package/build/index.d.ts +1 -1
- package/build/index.d.ts.map +1 -1
- package/build/index.js +1 -1
- package/build/index.js.map +1 -1
- package/build/navigation/index.d.ts +11 -0
- package/build/navigation/index.d.ts.map +1 -1
- package/build/navigation/index.js +10 -0
- package/build/navigation/index.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_filter_recipients/conversation_filter_recipients_screen.d.ts.map +1 -1
- package/build/screens/conversation_filter_recipients/conversation_filter_recipients_screen.js +81 -17
- package/build/screens/conversation_filter_recipients/conversation_filter_recipients_screen.js.map +1 -1
- package/build/screens/conversation_filter_recipients/hooks/use_service_types_with_teams.d.ts +171 -4
- package/build/screens/conversation_filter_recipients/hooks/use_service_types_with_teams.d.ts.map +1 -1
- package/build/screens/conversation_filter_recipients/hooks/use_service_types_with_teams.js +49 -8
- package/build/screens/conversation_filter_recipients/hooks/use_service_types_with_teams.js.map +1 -1
- package/build/screens/conversation_filter_recipients/types.d.ts +7 -0
- package/build/screens/conversation_filter_recipients/types.d.ts.map +1 -1
- package/build/screens/conversation_filter_recipients/types.js +6 -0
- package/build/screens/conversation_filter_recipients/types.js.map +1 -1
- package/build/screens/conversation_filters/components/rows.js +1 -1
- package/build/screens/conversation_filters/components/rows.js.map +1 -1
- package/build/screens/conversation_new/components/groups_form.js +2 -2
- package/build/screens/conversation_new/components/groups_form.js.map +1 -1
- package/build/screens/conversation_new/components/services_form.d.ts +3 -1
- package/build/screens/conversation_new/components/services_form.d.ts.map +1 -1
- package/build/screens/conversation_new/components/services_form.js +6 -5
- package/build/screens/conversation_new/components/services_form.js.map +1 -1
- package/build/screens/conversation_new/conversation_new_screen.d.ts +2 -0
- package/build/screens/conversation_new/conversation_new_screen.d.ts.map +1 -1
- package/build/screens/conversation_new/conversation_new_screen.js +2 -2
- package/build/screens/conversation_new/conversation_new_screen.js.map +1 -1
- package/build/screens/conversation_select_recipients/conversation_select_recipients_screen.d.ts.map +1 -1
- package/build/screens/conversation_select_recipients/conversation_select_recipients_screen.js +38 -33
- package/build/screens/conversation_select_recipients/conversation_select_recipients_screen.js.map +1 -1
- package/build/screens/team_conversation_screen.d.ts +8 -0
- package/build/screens/team_conversation_screen.d.ts.map +1 -0
- package/build/screens/team_conversation_screen.js +28 -0
- package/build/screens/team_conversation_screen.js.map +1 -0
- package/build/types/resources/denormalized_attachment_resource.d.ts +9 -32
- package/build/types/resources/denormalized_attachment_resource.d.ts.map +1 -1
- package/build/types/resources/denormalized_attachment_resource.js.map +1 -1
- package/build/types/resources/denormalized_attachment_resource_for_create.d.ts +50 -0
- package/build/types/resources/denormalized_attachment_resource_for_create.d.ts.map +1 -0
- package/build/types/resources/denormalized_attachment_resource_for_create.js +2 -0
- package/build/types/resources/denormalized_attachment_resource_for_create.js.map +1 -0
- package/build/types/resources/message.d.ts +4 -0
- package/build/types/resources/message.d.ts.map +1 -1
- package/build/types/resources/message.js.map +1 -1
- package/build/types/resources/services/chat_resource.d.ts +52 -0
- package/build/types/resources/services/chat_resource.d.ts.map +1 -0
- package/build/types/resources/services/chat_resource.js +7 -0
- package/build/types/resources/services/chat_resource.js.map +1 -0
- package/build/types/resources/services/index.d.ts +1 -0
- package/build/types/resources/services/index.d.ts.map +1 -1
- package/build/types/resources/services/index.js +1 -0
- package/build/types/resources/services/index.js.map +1 -1
- package/build/types/resources/services/team_resource.d.ts +9 -41
- package/build/types/resources/services/team_resource.d.ts.map +1 -1
- package/build/types/resources/services/team_resource.js +0 -5
- package/build/types/resources/services/team_resource.js.map +1 -1
- package/build/utils/cache/optimistically_create_message.d.ts +10 -0
- package/build/utils/cache/optimistically_create_message.d.ts.map +1 -0
- package/build/utils/cache/optimistically_create_message.js +43 -0
- package/build/utils/cache/optimistically_create_message.js.map +1 -0
- package/build/utils/cache/optimistically_update_message.d.ts +7 -0
- package/build/utils/cache/optimistically_update_message.d.ts.map +1 -0
- package/build/utils/cache/optimistically_update_message.js +21 -0
- package/build/utils/cache/optimistically_update_message.js.map +1 -0
- package/build/utils/cache/page_mutations.d.ts +6 -3
- package/build/utils/cache/page_mutations.d.ts.map +1 -1
- package/build/utils/cache/page_mutations.js +4 -4
- package/build/utils/cache/page_mutations.js.map +1 -1
- package/build/utils/convert_attachments_for_create.d.ts +12 -0
- package/build/utils/convert_attachments_for_create.d.ts.map +1 -0
- package/build/utils/convert_attachments_for_create.js +70 -0
- package/build/utils/convert_attachments_for_create.js.map +1 -0
- package/build/utils/generate_placeholder_ulid.d.ts +10 -0
- package/build/utils/generate_placeholder_ulid.d.ts.map +1 -0
- package/build/utils/generate_placeholder_ulid.js +28 -0
- package/build/utils/generate_placeholder_ulid.js.map +1 -0
- package/build/utils/index.d.ts +1 -0
- package/build/utils/index.d.ts.map +1 -1
- package/build/utils/index.js +1 -0
- package/build/utils/index.js.map +1 -1
- package/build/utils/response_error.d.ts +1 -0
- package/build/utils/response_error.d.ts.map +1 -1
- package/build/utils/response_error.js +6 -0
- package/build/utils/response_error.js.map +1 -1
- package/package.json +2 -2
- package/src/components/conversation/attachments/image_attachment.tsx +25 -10
- package/src/components/conversation/message.tsx +116 -28
- package/src/components/conversation/message_form/message_form_attachment_image.tsx +1 -1
- package/src/components/conversation/message_form/message_form_attachment_video.tsx +1 -1
- package/src/components/conversation/message_form.tsx +16 -13
- package/src/components/conversations/conversations.tsx +8 -1
- package/src/components/display/spinner.tsx +7 -2
- package/src/components/display/text.tsx +10 -2
- package/src/components/primitive/form_sheet.tsx +3 -2
- package/src/contexts/api_provider.tsx +37 -3
- package/src/hooks/groups/use_groups_conversation_create.ts +3 -1
- package/src/hooks/services/use_find_or_create_services_conversation.ts +29 -21
- package/src/hooks/{use_services_team.ts → services/use_services_team.ts} +2 -2
- package/src/hooks/use_attachment_uploader.ts +9 -25
- package/src/hooks/use_chat_permissions.ts +12 -9
- package/src/hooks/use_conversation_messages_jolt_events.ts +19 -1
- package/src/hooks/use_giphy.ts +1 -1
- package/src/hooks/use_message_create_or_update.ts +82 -6
- package/src/index.tsx +1 -1
- package/src/navigation/index.tsx +10 -0
- package/src/screens/conversation_details_screen.tsx +1 -1
- package/src/screens/conversation_filter_recipients/conversation_filter_recipients_screen.tsx +118 -17
- package/src/screens/conversation_filter_recipients/hooks/use_service_types_with_teams.ts +61 -10
- package/src/screens/conversation_filter_recipients/types.tsx +8 -0
- package/src/screens/conversation_filters/components/rows.tsx +1 -1
- package/src/screens/conversation_new/components/groups_form.tsx +2 -2
- package/src/screens/conversation_new/components/services_form.tsx +17 -3
- package/src/screens/conversation_new/conversation_new_screen.tsx +11 -2
- package/src/screens/conversation_select_recipients/conversation_select_recipients_screen.tsx +90 -74
- package/src/screens/team_conversation_screen.tsx +46 -0
- package/src/types/resources/denormalized_attachment_resource.ts +9 -37
- package/src/types/resources/denormalized_attachment_resource_for_create.ts +65 -0
- package/src/types/resources/message.ts +6 -0
- package/src/types/resources/services/chat_resource.ts +66 -0
- package/src/types/resources/services/index.ts +1 -0
- package/src/types/resources/services/team_resource.ts +10 -53
- package/src/utils/__tests__/convert_attachments_for_create.test.ts +175 -0
- package/src/utils/cache/optimistically_create_message.ts +71 -0
- package/src/utils/cache/optimistically_update_message.ts +37 -0
- package/src/utils/cache/page_mutations.ts +5 -3
- package/src/utils/convert_attachments_for_create.ts +92 -0
- package/src/utils/generate_placeholder_ulid.ts +32 -0
- package/src/utils/index.ts +1 -0
- package/src/utils/response_error.ts +8 -0
- package/build/hooks/use_services_team.d.ts.map +0 -1
- package/build/hooks/use_services_team.js.map +0 -1
|
@@ -1,24 +1,75 @@
|
|
|
1
|
-
import { useMemo } from 'react'
|
|
2
|
-
import { TeamResponseItem } from '../../../types'
|
|
3
|
-
import { ServiceTypeWithTeams } from '../types'
|
|
4
1
|
import { uniqBy } from 'lodash'
|
|
5
|
-
import {
|
|
2
|
+
import { useMemo } from 'react'
|
|
3
|
+
import { useApiGet } from '../../../hooks/use_api'
|
|
4
|
+
import { ServicesChatResource, TeamResponseItem } from '../../../types'
|
|
5
|
+
import { ServiceTypeWithTeams, TeamFilterTypes } from '../types'
|
|
6
6
|
|
|
7
|
-
export function useServiceTypesWithTeams(
|
|
8
|
-
|
|
7
|
+
export function useServiceTypesWithTeams({
|
|
8
|
+
filterType = TeamFilterTypes.TeamsIlead,
|
|
9
|
+
searchQuery,
|
|
10
|
+
}: {
|
|
11
|
+
filterType?: TeamFilterTypes
|
|
12
|
+
searchQuery?: string
|
|
13
|
+
} = {}) {
|
|
14
|
+
const { data, ...rest } = useTeams({ filterType })
|
|
9
15
|
|
|
10
16
|
const decoratedResponse = useMemo(() => {
|
|
11
|
-
return decorateTeamResponseItems(
|
|
12
|
-
}, [
|
|
17
|
+
return decorateTeamResponseItems(data as TeamResponseItem[], searchQuery)
|
|
18
|
+
}, [data, searchQuery])
|
|
13
19
|
|
|
14
20
|
return {
|
|
15
21
|
serviceTypes: decoratedResponse,
|
|
16
|
-
...
|
|
22
|
+
...rest,
|
|
17
23
|
}
|
|
18
24
|
}
|
|
19
25
|
|
|
20
|
-
|
|
26
|
+
const useTeams = ({ filterType }: { filterType: TeamFilterTypes }) => {
|
|
27
|
+
const requestField = useMemo(() => {
|
|
28
|
+
switch (filterType) {
|
|
29
|
+
case TeamFilterTypes.All:
|
|
30
|
+
return 'teams'
|
|
31
|
+
case TeamFilterTypes.MyTeams:
|
|
32
|
+
return 'my_teams'
|
|
33
|
+
default:
|
|
34
|
+
return 'teams_i_lead'
|
|
35
|
+
}
|
|
36
|
+
}, [filterType])
|
|
37
|
+
|
|
38
|
+
const { data, ...rest } = useApiGet<ServicesChatResource>({
|
|
39
|
+
url: '/chat',
|
|
40
|
+
data: {
|
|
41
|
+
fields: {
|
|
42
|
+
Chat: [requestField],
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
app: 'services',
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
const result: TeamResponseItem[] = useMemo(() => {
|
|
49
|
+
switch (filterType) {
|
|
50
|
+
case TeamFilterTypes.All:
|
|
51
|
+
return data?.teams || []
|
|
52
|
+
case TeamFilterTypes.MyTeams:
|
|
53
|
+
return data?.myTeams || []
|
|
54
|
+
default:
|
|
55
|
+
return data?.teamsILead || []
|
|
56
|
+
}
|
|
57
|
+
}, [data, filterType])
|
|
58
|
+
|
|
59
|
+
return { data: result || [], ...rest }
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function decorateTeamResponseItems(teamResponseItems: TeamResponseItem[], searchQuery?: string) {
|
|
21
63
|
return teamResponseItems
|
|
64
|
+
.filter(item => {
|
|
65
|
+
if (!searchQuery) return true
|
|
66
|
+
|
|
67
|
+
const evalMatch = (str: string) => str.toLowerCase().includes(searchQuery.toLowerCase())
|
|
68
|
+
const teamNameMatch = evalMatch(item.name)
|
|
69
|
+
const serviceTypeNamesMatch = evalMatch(item.serviceTypeNames?.join(',') || '')
|
|
70
|
+
|
|
71
|
+
return teamNameMatch || serviceTypeNamesMatch
|
|
72
|
+
})
|
|
22
73
|
.map(({ value, serviceTypeName, teamName }) => ({
|
|
23
74
|
service_type: {
|
|
24
75
|
id: value.serviceTypeId,
|
|
@@ -38,9 +38,17 @@ interface DataItem<T, TName extends SectionTypes> {
|
|
|
38
38
|
sectionStyle?: ViewStyle
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
+
export enum TeamFilterTypes {
|
|
42
|
+
All = 'All teams',
|
|
43
|
+
MyTeams = 'My teams',
|
|
44
|
+
TeamsIlead = 'Teams I lead',
|
|
45
|
+
}
|
|
46
|
+
|
|
41
47
|
export type ConversationFilterRecipientsParams = {
|
|
42
48
|
source_app_name?: AppName
|
|
43
49
|
team_ids?: number[]
|
|
50
|
+
team_filter_type?: TeamFilterTypes
|
|
51
|
+
search_query?: string
|
|
44
52
|
}
|
|
45
53
|
|
|
46
54
|
export type ConversationFilterRecipientsScreenProps =
|
|
@@ -4,7 +4,7 @@ import React, { PropsWithChildren, useContext } from 'react'
|
|
|
4
4
|
import { StyleSheet, View, ViewStyle } from 'react-native'
|
|
5
5
|
import { Heading, Icon, Image, Text, TextButton } from '../../../components'
|
|
6
6
|
import { useTheme } from '../../../hooks'
|
|
7
|
-
import { useServicesTeamsMap } from '../../../hooks/use_services_team'
|
|
7
|
+
import { useServicesTeamsMap } from '../../../hooks/services/use_services_team'
|
|
8
8
|
import { GroupResource } from '../../../types/resources/group_resource'
|
|
9
9
|
import { FilterContext } from '../context/conversation_filter_context'
|
|
10
10
|
import { FilterTypes } from '../filter_types'
|
|
@@ -48,7 +48,7 @@ export const GroupsForm = ({ groupId, chat_group_graph_id }: GroupsFormProps) =>
|
|
|
48
48
|
[chat_group_graph_id, navigation]
|
|
49
49
|
)
|
|
50
50
|
|
|
51
|
-
const { mutate: handleSave } = useGroupsConversationCreate({
|
|
51
|
+
const { mutate: handleSave, isPending } = useGroupsConversationCreate({
|
|
52
52
|
groupId,
|
|
53
53
|
title,
|
|
54
54
|
onSuccess: redirectToConversation,
|
|
@@ -70,7 +70,7 @@ export const GroupsForm = ({ groupId, chat_group_graph_id }: GroupsFormProps) =>
|
|
|
70
70
|
}
|
|
71
71
|
/>
|
|
72
72
|
<ActionButton
|
|
73
|
-
disabled={!title}
|
|
73
|
+
disabled={!title || isPending}
|
|
74
74
|
title="Start Conversation"
|
|
75
75
|
onPress={() => handleSave()}
|
|
76
76
|
infoText="Conversation will be automatically updated if any members are added or removed from this group."
|
|
@@ -12,13 +12,19 @@ import { useTeamMembersForNewConversation } from '../../../hooks/services/use_te
|
|
|
12
12
|
import { useFindOrCreateServicesConversation } from '../../../hooks/services/use_find_or_create_services_conversation'
|
|
13
13
|
import { ConversationResource, MemberResource } from '../../../types'
|
|
14
14
|
import { tokens } from '../../../vendor/tapestry/tokens'
|
|
15
|
+
import { TeamFilterTypes } from '../../conversation_filter_recipients/types'
|
|
15
16
|
|
|
16
17
|
type ServicesFormProps = {
|
|
17
18
|
initialTeamIds?: number[]
|
|
18
19
|
initialPlanId?: number
|
|
20
|
+
teamFilterType?: TeamFilterTypes
|
|
19
21
|
}
|
|
20
22
|
|
|
21
|
-
export const ServicesForm = ({
|
|
23
|
+
export const ServicesForm = ({
|
|
24
|
+
initialTeamIds,
|
|
25
|
+
initialPlanId,
|
|
26
|
+
teamFilterType,
|
|
27
|
+
}: ServicesFormProps) => {
|
|
22
28
|
const styles = useStyles()
|
|
23
29
|
const [selectedPlanId, setSelectedPlanId] = useState<number | undefined>(initialPlanId)
|
|
24
30
|
const initialState = useMemo(() => uniq(initialTeamIds) || [], [initialTeamIds]) // Uniq here because services can send duplicates in the teams_i_lead response.
|
|
@@ -39,7 +45,11 @@ export const ServicesForm = ({ initialTeamIds, initialPlanId }: ServicesFormProp
|
|
|
39
45
|
|
|
40
46
|
const [filerByPlan, setFilterByPlan] = useState(false)
|
|
41
47
|
|
|
42
|
-
const {
|
|
48
|
+
const {
|
|
49
|
+
members,
|
|
50
|
+
isPending,
|
|
51
|
+
isError: isMemberError,
|
|
52
|
+
} = useTeamMembersForNewConversation({
|
|
43
53
|
teamIds: selectedTeamIds,
|
|
44
54
|
planId: selectedPlanId,
|
|
45
55
|
})
|
|
@@ -75,11 +85,12 @@ export const ServicesForm = ({ initialTeamIds, initialPlanId }: ServicesFormProp
|
|
|
75
85
|
setFilterByPlan={setFilterByPlan}
|
|
76
86
|
members={members}
|
|
77
87
|
isMemberError={isMemberError}
|
|
88
|
+
teamFilterType={teamFilterType}
|
|
78
89
|
/>
|
|
79
90
|
}
|
|
80
91
|
/>
|
|
81
92
|
<ActionButton
|
|
82
|
-
disabled={!selectedTeamIds.length}
|
|
93
|
+
disabled={!selectedTeamIds.length || isPending}
|
|
83
94
|
title="Start Conversation"
|
|
84
95
|
onPress={createConversation}
|
|
85
96
|
infoText="Conversation will be automatically updated if any members are added or removed from included teams."
|
|
@@ -97,6 +108,7 @@ interface FormContentProps {
|
|
|
97
108
|
setFilterByPlan: (value: boolean) => void
|
|
98
109
|
members: MemberResource[]
|
|
99
110
|
isMemberError: boolean
|
|
111
|
+
teamFilterType?: TeamFilterTypes
|
|
100
112
|
}
|
|
101
113
|
|
|
102
114
|
function FormContent({
|
|
@@ -108,6 +120,7 @@ function FormContent({
|
|
|
108
120
|
setFilterByPlan,
|
|
109
121
|
members,
|
|
110
122
|
isMemberError,
|
|
123
|
+
teamFilterType,
|
|
111
124
|
}: FormContentProps) {
|
|
112
125
|
const { teamsILead } = useTeamsILead()
|
|
113
126
|
const selectedTeamsILead = useMemo(() => {
|
|
@@ -144,6 +157,7 @@ function FormContent({
|
|
|
144
157
|
params: {
|
|
145
158
|
source_app_name: 'Services',
|
|
146
159
|
team_ids: selectedTeamIds,
|
|
160
|
+
team_filter_type: teamFilterType,
|
|
147
161
|
},
|
|
148
162
|
})
|
|
149
163
|
}
|
|
@@ -5,10 +5,12 @@ import { ServicesForm } from './components/services_form'
|
|
|
5
5
|
import { SourceAppErrorCard } from './components/source_app_error_card'
|
|
6
6
|
import { AppName } from '../../types/resources/app_name'
|
|
7
7
|
import { GraphId } from '../../types/resources/group_resource'
|
|
8
|
+
import { TeamFilterTypes } from '../conversation_filter_recipients/types'
|
|
8
9
|
|
|
9
10
|
type ConversationNewScreenProps = StaticScreenProps<{
|
|
10
11
|
group_id?: number
|
|
11
12
|
team_ids?: number[]
|
|
13
|
+
team_filter_type?: TeamFilterTypes
|
|
12
14
|
plan_id?: number
|
|
13
15
|
source_app_name: AppName
|
|
14
16
|
chat_group_graph_id?: GraphId
|
|
@@ -16,7 +18,8 @@ type ConversationNewScreenProps = StaticScreenProps<{
|
|
|
16
18
|
}>
|
|
17
19
|
|
|
18
20
|
export const ConversationNewScreen = ({ route }: ConversationNewScreenProps) => {
|
|
19
|
-
const { group_id, team_ids, source_app_name, plan_id, chat_group_graph_id } =
|
|
21
|
+
const { group_id, team_ids, source_app_name, plan_id, chat_group_graph_id, team_filter_type } =
|
|
22
|
+
route.params
|
|
20
23
|
|
|
21
24
|
switch (source_app_name) {
|
|
22
25
|
case 'Groups':
|
|
@@ -26,7 +29,13 @@ export const ConversationNewScreen = ({ route }: ConversationNewScreenProps) =>
|
|
|
26
29
|
<SourceAppErrorCard />
|
|
27
30
|
)
|
|
28
31
|
case 'Services':
|
|
29
|
-
return
|
|
32
|
+
return (
|
|
33
|
+
<ServicesForm
|
|
34
|
+
initialTeamIds={team_ids}
|
|
35
|
+
initialPlanId={plan_id}
|
|
36
|
+
teamFilterType={team_filter_type}
|
|
37
|
+
/>
|
|
38
|
+
)
|
|
30
39
|
default:
|
|
31
40
|
return <SourceAppErrorCard />
|
|
32
41
|
}
|
package/src/screens/conversation_select_recipients/conversation_select_recipients_screen.tsx
CHANGED
|
@@ -12,6 +12,8 @@ import { useServiceTypesWithTeams } from '../conversation_filter_recipients/hook
|
|
|
12
12
|
import { ServiceTypeWithTeams } from '../conversation_filter_recipients/types'
|
|
13
13
|
import { TeamRecipientRow } from './components/team_recipient_row'
|
|
14
14
|
import { GroupsRecipientRow } from './components/groups_recipient_row'
|
|
15
|
+
import { DefaultLoading } from '../../components/page/loading'
|
|
16
|
+
import { useAppGrants } from '../../hooks'
|
|
15
17
|
|
|
16
18
|
const MAX_VISIBLE_RECIPIENTS = 5
|
|
17
19
|
|
|
@@ -20,7 +22,13 @@ export const ConversationSelectRecipientsScreen = ({
|
|
|
20
22
|
}: ConversationSelectRecipientsScreenProps) => {
|
|
21
23
|
const styles = useStyles()
|
|
22
24
|
const navigation = useNavigation()
|
|
23
|
-
|
|
25
|
+
const appGrants = useAppGrants()
|
|
26
|
+
const canCreateGroupsConversations = appGrants.data?.some(
|
|
27
|
+
g => g.createConversations && g.appName === 'Groups'
|
|
28
|
+
)
|
|
29
|
+
const canCreateServicesConversations = appGrants.data?.some(
|
|
30
|
+
g => g.createConversations && g.appName === 'Services'
|
|
31
|
+
)
|
|
24
32
|
const { data: groups = [], isFetching: isGroupsFetching } = useGroupsGroups()
|
|
25
33
|
const groupsWithCreatePermission = groups.filter(g => g.canCreateConversation)
|
|
26
34
|
const visibleGroups = groupsWithCreatePermission.slice(0, MAX_VISIBLE_RECIPIENTS)
|
|
@@ -77,83 +85,91 @@ export const ConversationSelectRecipientsScreen = ({
|
|
|
77
85
|
|
|
78
86
|
return (
|
|
79
87
|
<ScrollView contentContainerStyle={styles.contentContainer}>
|
|
80
|
-
|
|
81
|
-
<View style={styles.
|
|
82
|
-
<
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
88
|
+
{canCreateGroupsConversations && (
|
|
89
|
+
<View style={styles.section}>
|
|
90
|
+
<View style={styles.sectionHeader}>
|
|
91
|
+
<Heading variant="h3">My groups</Heading>
|
|
92
|
+
</View>
|
|
93
|
+
<View>
|
|
94
|
+
{isGroupsFetching ? (
|
|
95
|
+
<DefaultLoading />
|
|
96
|
+
) : groupsWithCreatePermission.length === 0 ? (
|
|
97
|
+
<BlankState
|
|
98
|
+
subtitle="Join a group with chat enabled and permissions to start a new conversation."
|
|
99
|
+
style={styles.blankState}
|
|
100
|
+
/>
|
|
101
|
+
) : (
|
|
102
|
+
<>
|
|
103
|
+
{visibleGroups.map(group => {
|
|
104
|
+
return (
|
|
105
|
+
<GroupsRecipientRow
|
|
106
|
+
key={group.id}
|
|
107
|
+
group={group}
|
|
108
|
+
onPress={handleGroupsNavigateToConversationNew}
|
|
109
|
+
/>
|
|
110
|
+
)
|
|
111
|
+
})}
|
|
112
|
+
{hasMoreGroups && (
|
|
113
|
+
<ViewMoreLinkRow
|
|
114
|
+
onPress={handleGroupsViewMore}
|
|
115
|
+
accessibilityHint="Navigate to a full list of your groups."
|
|
98
116
|
/>
|
|
99
|
-
)
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
accessibilityHint="Navigate to a full list of your groups."
|
|
105
|
-
/>
|
|
106
|
-
)}
|
|
107
|
-
{showGroupsDisclaimer && <GroupsWithoutChatDisclaimerRow />}
|
|
108
|
-
</>
|
|
109
|
-
)}
|
|
110
|
-
</View>
|
|
111
|
-
</View>
|
|
112
|
-
<View style={styles.section}>
|
|
113
|
-
<View style={styles.sectionHeader}>
|
|
114
|
-
<Heading variant="h3">Teams I lead</Heading>
|
|
115
|
-
{hasServiceTypes && (
|
|
116
|
-
<Button
|
|
117
|
-
style={styles.selectTeamsButton}
|
|
118
|
-
onPress={() =>
|
|
119
|
-
navigation.navigate('New', {
|
|
120
|
-
screen: 'ConversationFilterRecipients',
|
|
121
|
-
params: {
|
|
122
|
-
source_app_name: 'Services',
|
|
123
|
-
},
|
|
124
|
-
})
|
|
125
|
-
}
|
|
126
|
-
title="Select teams"
|
|
127
|
-
variant="outline"
|
|
128
|
-
iconNameLeft="general.search"
|
|
129
|
-
size="sm"
|
|
130
|
-
/>
|
|
131
|
-
)}
|
|
117
|
+
)}
|
|
118
|
+
{showGroupsDisclaimer && <GroupsWithoutChatDisclaimerRow />}
|
|
119
|
+
</>
|
|
120
|
+
)}
|
|
121
|
+
</View>
|
|
132
122
|
</View>
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
123
|
+
)}
|
|
124
|
+
{canCreateServicesConversations && (
|
|
125
|
+
<View style={styles.section}>
|
|
126
|
+
<View style={styles.sectionHeader}>
|
|
127
|
+
<Heading variant="h3">Teams I lead</Heading>
|
|
128
|
+
{hasServiceTypes && (
|
|
129
|
+
<Button
|
|
130
|
+
style={styles.selectTeamsButton}
|
|
131
|
+
onPress={() =>
|
|
132
|
+
navigation.navigate('New', {
|
|
133
|
+
screen: 'ConversationFilterRecipients',
|
|
134
|
+
params: {
|
|
135
|
+
source_app_name: 'Services',
|
|
136
|
+
},
|
|
137
|
+
})
|
|
138
|
+
}
|
|
139
|
+
title="Select teams"
|
|
140
|
+
variant="outline"
|
|
141
|
+
iconNameLeft="general.search"
|
|
142
|
+
size="sm"
|
|
143
|
+
/>
|
|
144
|
+
)}
|
|
145
|
+
</View>
|
|
146
|
+
<View>
|
|
147
|
+
{isServiceTypesFetching ? (
|
|
148
|
+
<DefaultLoading />
|
|
149
|
+
) : hasServiceTypes ? (
|
|
150
|
+
<>
|
|
151
|
+
{visibleServiceTypes.map(serviceType => {
|
|
152
|
+
return (
|
|
153
|
+
<TeamRecipientRow
|
|
154
|
+
key={serviceType.id}
|
|
155
|
+
serviceType={serviceType}
|
|
156
|
+
onPress={handleTeamsNavigateToConversationNew}
|
|
157
|
+
/>
|
|
158
|
+
)
|
|
159
|
+
})}
|
|
160
|
+
{hasMoreServiceTypes && (
|
|
161
|
+
<ViewMoreLinkRow
|
|
162
|
+
onPress={handleServiceTypesViewMore}
|
|
163
|
+
accessibilityHint="Navigate to a full list of teams you lead."
|
|
142
164
|
/>
|
|
143
|
-
)
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
/>
|
|
150
|
-
)}
|
|
151
|
-
</>
|
|
152
|
-
) : (
|
|
153
|
-
<BlankState subtitle="You don't lead any teams." style={styles.blankState} />
|
|
154
|
-
)}
|
|
165
|
+
)}
|
|
166
|
+
</>
|
|
167
|
+
) : (
|
|
168
|
+
<BlankState subtitle="You don't lead any teams." style={styles.blankState} />
|
|
169
|
+
)}
|
|
170
|
+
</View>
|
|
155
171
|
</View>
|
|
156
|
-
|
|
172
|
+
)}
|
|
157
173
|
</ScrollView>
|
|
158
174
|
)
|
|
159
175
|
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { StackActions, StaticScreenProps, useNavigation } from '@react-navigation/native'
|
|
2
|
+
import { useQuery, useQueryClient } from '@tanstack/react-query'
|
|
3
|
+
import { useEffect } from 'react'
|
|
4
|
+
import { useApiClient } from '../hooks'
|
|
5
|
+
import { findOrCreateServicesConversation } from '../hooks/services/use_find_or_create_services_conversation'
|
|
6
|
+
import { DefaultLoading } from '../components/page/loading'
|
|
7
|
+
|
|
8
|
+
export type TeamConversationRouteProps = {
|
|
9
|
+
plan_id?: number
|
|
10
|
+
team_ids?: number[]
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export type TeamConversationScreenProps = StaticScreenProps<TeamConversationRouteProps>
|
|
14
|
+
|
|
15
|
+
export const TeamConversationScreen = ({ route }: TeamConversationScreenProps) => {
|
|
16
|
+
const apiClient = useApiClient()
|
|
17
|
+
const queryClient = useQueryClient()
|
|
18
|
+
const navigation = useNavigation()
|
|
19
|
+
|
|
20
|
+
const { data: conversation } = useQuery({
|
|
21
|
+
queryKey: ['team-conversation', route.params.team_ids, route.params.plan_id],
|
|
22
|
+
queryFn: () =>
|
|
23
|
+
findOrCreateServicesConversation(
|
|
24
|
+
apiClient,
|
|
25
|
+
route.params.team_ids || [2317674, 5223552],
|
|
26
|
+
route.params.plan_id
|
|
27
|
+
),
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
useEffect(() => {
|
|
31
|
+
if (!conversation?.id) return
|
|
32
|
+
|
|
33
|
+
navigation.dispatch(
|
|
34
|
+
StackActions.replace('Conversation', {
|
|
35
|
+
conversation_id: conversation.id,
|
|
36
|
+
title: conversation.title,
|
|
37
|
+
})
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
return () => {
|
|
41
|
+
queryClient.removeQueries({ queryKey: ['team-conversation'] })
|
|
42
|
+
}
|
|
43
|
+
}, [conversation?.id, conversation?.title, navigation, queryClient])
|
|
44
|
+
|
|
45
|
+
return <DefaultLoading />
|
|
46
|
+
}
|
|
@@ -8,12 +8,7 @@ export type DenormalizedAttachmentResource =
|
|
|
8
8
|
| DenormalizedGiphyAttachmentResource
|
|
9
9
|
| DenormalizedExpandedLinkAttachmentResource
|
|
10
10
|
|
|
11
|
-
export
|
|
12
|
-
| DenormalizedMessageAttachmentResourceForCreate
|
|
13
|
-
| DenormalizedGiphyAttachmentResourceForCreate
|
|
14
|
-
| DenormalizedExpandedLinkAttachmentResource
|
|
15
|
-
|
|
16
|
-
interface GenericAttachmentResource {
|
|
11
|
+
export interface GenericAttachmentResource {
|
|
17
12
|
type: string
|
|
18
13
|
id?: string
|
|
19
14
|
[key: string]: unknown
|
|
@@ -39,11 +34,6 @@ export interface DenormalizedMessageAttachmentResource extends GenericAttachment
|
|
|
39
34
|
}
|
|
40
35
|
}
|
|
41
36
|
|
|
42
|
-
export interface DenormalizedMessageAttachmentResourceForCreate extends GenericAttachmentResource {
|
|
43
|
-
type: 'MessageAttachment'
|
|
44
|
-
id: string
|
|
45
|
-
}
|
|
46
|
-
|
|
47
37
|
export interface DenormalizedGiphyAttachmentResource extends GenericAttachmentResource {
|
|
48
38
|
type: 'giphy'
|
|
49
39
|
id: string
|
|
@@ -52,35 +42,17 @@ export interface DenormalizedGiphyAttachmentResource extends GenericAttachmentRe
|
|
|
52
42
|
titleLink: string
|
|
53
43
|
thumbUrl: string
|
|
54
44
|
giphy: {
|
|
55
|
-
original:
|
|
56
|
-
fixedHeight:
|
|
57
|
-
fixedHeightStill:
|
|
58
|
-
fixedHeightDownsampled:
|
|
59
|
-
fixedWidth:
|
|
60
|
-
fixedWidthStill:
|
|
61
|
-
fixedWidthDownsampled:
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
export interface DenormalizedGiphyAttachmentResourceForCreate extends GenericAttachmentResource {
|
|
66
|
-
type: 'giphy'
|
|
67
|
-
id: string
|
|
68
|
-
title: string
|
|
69
|
-
original_giphy_title: string
|
|
70
|
-
title_link: string
|
|
71
|
-
thumb_url: string
|
|
72
|
-
giphy: {
|
|
73
|
-
original: GiphyVariant
|
|
74
|
-
fixed_height: GiphyVariant
|
|
75
|
-
fixed_height_still: GiphyVariant
|
|
76
|
-
fixed_height_downsampled: GiphyVariant
|
|
77
|
-
fixed_width: GiphyVariant
|
|
78
|
-
fixed_width_still: GiphyVariant
|
|
79
|
-
fixed_width_downsampled: GiphyVariant
|
|
45
|
+
original: GiphyAttachmentVariant
|
|
46
|
+
fixedHeight: GiphyAttachmentVariant
|
|
47
|
+
fixedHeightStill: GiphyAttachmentVariant
|
|
48
|
+
fixedHeightDownsampled: GiphyAttachmentVariant
|
|
49
|
+
fixedWidth: GiphyAttachmentVariant
|
|
50
|
+
fixedWidthStill: GiphyAttachmentVariant
|
|
51
|
+
fixedWidthDownsampled: GiphyAttachmentVariant
|
|
80
52
|
}
|
|
81
53
|
}
|
|
82
54
|
|
|
83
|
-
interface
|
|
55
|
+
export interface GiphyAttachmentVariant {
|
|
84
56
|
url: string
|
|
85
57
|
width: string
|
|
86
58
|
height: string
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DenormalizedExpandedLinkAttachmentResource,
|
|
3
|
+
GenericAttachmentResource,
|
|
4
|
+
GiphyAttachmentVariant,
|
|
5
|
+
} from './denormalized_attachment_resource'
|
|
6
|
+
|
|
7
|
+
export type DenormalizedAttachmentResourceForCreate =
|
|
8
|
+
| DenormalizedMessageAttachmentResourceForCreate
|
|
9
|
+
| DenormalizedGiphyAttachmentResourceForCreate
|
|
10
|
+
| DenormalizedExpandedLinkAttachmentResource
|
|
11
|
+
|
|
12
|
+
export interface DenormalizedMessageAttachmentResourceForCreate extends GenericAttachmentResource {
|
|
13
|
+
type: 'MessageAttachment'
|
|
14
|
+
id: string
|
|
15
|
+
|
|
16
|
+
// Not needed for upload, but is used to preview image during pending send state
|
|
17
|
+
file: NativeAttachmentFile
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface DenormalizedGiphyAttachmentResourceForCreate extends GenericAttachmentResource {
|
|
21
|
+
type: 'giphy'
|
|
22
|
+
id: string
|
|
23
|
+
title: string
|
|
24
|
+
original_giphy_title: string
|
|
25
|
+
title_link: string
|
|
26
|
+
thumb_url: string
|
|
27
|
+
giphy: {
|
|
28
|
+
original: GiphyAttachmentVariant
|
|
29
|
+
fixed_height: GiphyAttachmentVariant
|
|
30
|
+
fixed_height_still: GiphyAttachmentVariant
|
|
31
|
+
fixed_height_downsampled: GiphyAttachmentVariant
|
|
32
|
+
fixed_width: GiphyAttachmentVariant
|
|
33
|
+
fixed_width_still: GiphyAttachmentVariant
|
|
34
|
+
fixed_width_downsampled: GiphyAttachmentVariant
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
type AttachmentStatus = 'uploading' | 'success' | 'error'
|
|
39
|
+
|
|
40
|
+
export interface NativeAttachmentFile {
|
|
41
|
+
uri: string
|
|
42
|
+
name: string
|
|
43
|
+
type: string // Should be a MIME type
|
|
44
|
+
size: number
|
|
45
|
+
width?: number
|
|
46
|
+
height?: number
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export interface FileAttachment {
|
|
50
|
+
id?: string
|
|
51
|
+
file: NativeAttachmentFile
|
|
52
|
+
status: AttachmentStatus
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export interface FileUploadState {
|
|
56
|
+
[fileName: string]: {
|
|
57
|
+
status: AttachmentStatus
|
|
58
|
+
id?: string
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export interface FileUploadError {
|
|
63
|
+
file_type?: string[]
|
|
64
|
+
file_size?: boolean
|
|
65
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { DenormalizedAttachmentResource } from './denormalized_attachment_resource'
|
|
2
|
+
import { DenormalizedAttachmentResourceForCreate } from './denormalized_attachment_resource_for_create'
|
|
2
3
|
import type { PersonResource } from './person'
|
|
3
4
|
import type { ReactionCountResource } from './reaction'
|
|
4
5
|
|
|
@@ -20,4 +21,9 @@ export interface MessageResource {
|
|
|
20
21
|
renderTime?: boolean
|
|
21
22
|
myLatestInConversation?: boolean
|
|
22
23
|
lastInGroup?: boolean
|
|
24
|
+
|
|
25
|
+
// Properties for mutation state
|
|
26
|
+
pending?: boolean // Indicates if the message is optimistically created and pending server response
|
|
27
|
+
error?: string // Error message if the message failed to send
|
|
28
|
+
attachmentsForCreate?: DenormalizedAttachmentResourceForCreate[]
|
|
23
29
|
}
|