@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,9 +1,16 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
focusManager,
|
|
3
|
+
QueryClient,
|
|
4
|
+
QueryClientProvider,
|
|
5
|
+
QueryKey,
|
|
6
|
+
usePrefetchQuery,
|
|
7
|
+
} from '@tanstack/react-query'
|
|
2
8
|
import React, { useContext, useEffect, useRef } from 'react'
|
|
3
9
|
import { ViewProps } from 'react-native'
|
|
4
10
|
import { ChatContext, ChatContextValue } from './chat_context'
|
|
5
|
-
import { RequestQueryKey } from '../hooks'
|
|
11
|
+
import { appGrantsRequestArgs, getRequestQueryKey, RequestQueryKey } from '../hooks'
|
|
6
12
|
import { ApiClient, useApiClient } from '../hooks/use_api_client'
|
|
13
|
+
import { useAppState } from '../hooks/use_app_state'
|
|
7
14
|
|
|
8
15
|
let apiClient: ApiClient | undefined
|
|
9
16
|
|
|
@@ -38,7 +45,34 @@ export function ApiProvider({ children }: ViewProps) {
|
|
|
38
45
|
chatQueryClient.clear()
|
|
39
46
|
}, [sessionChanged])
|
|
40
47
|
|
|
41
|
-
return
|
|
48
|
+
return (
|
|
49
|
+
<QueryClientProvider client={chatQueryClient}>
|
|
50
|
+
<PrefetchQueries />
|
|
51
|
+
{children}
|
|
52
|
+
</QueryClientProvider>
|
|
53
|
+
)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Component to prefetch queries when the app is focused
|
|
57
|
+
// This needs to live in the provider so that it can access the api client
|
|
58
|
+
// and the chat query client
|
|
59
|
+
const PrefetchQueries = () => {
|
|
60
|
+
usePrefetchQuery({
|
|
61
|
+
queryKey: getRequestQueryKey(appGrantsRequestArgs),
|
|
62
|
+
queryFn: defaultQueryFn,
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
return null
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export function useFocusManager() {
|
|
69
|
+
const appState = useAppState()
|
|
70
|
+
|
|
71
|
+
useEffect(() => {
|
|
72
|
+
focusManager.setFocused(appState === 'active')
|
|
73
|
+
}, [appState])
|
|
74
|
+
|
|
75
|
+
return appState
|
|
42
76
|
}
|
|
43
77
|
|
|
44
78
|
function useSessionChanged(value: Pick<ChatContextValue, 'token' | 'env'>): boolean {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { useMutation } from '@tanstack/react-query'
|
|
2
2
|
import { ApiResource, ConversationResource, ResourceObject } from '../../types'
|
|
3
3
|
import { useApiClient } from '../use_api_client'
|
|
4
|
+
import { throwResponseError } from '../../utils/response_error'
|
|
4
5
|
|
|
5
6
|
interface Props {
|
|
6
7
|
groupId: number
|
|
@@ -41,7 +42,8 @@ export function useGroupsConversationCreate({ groupId, title, onSuccess }: Props
|
|
|
41
42
|
},
|
|
42
43
|
},
|
|
43
44
|
})
|
|
44
|
-
)
|
|
45
|
+
)
|
|
46
|
+
.catch(throwResponseError),
|
|
45
47
|
})
|
|
46
48
|
}
|
|
47
49
|
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
ServicesChatPayloadResource,
|
|
8
8
|
} from '../../types'
|
|
9
9
|
import { ApiClient, useApiClient } from '../use_api_client'
|
|
10
|
+
import { throwResponseError } from '../../utils/response_error'
|
|
10
11
|
|
|
11
12
|
interface Props {
|
|
12
13
|
teamIds: number[]
|
|
@@ -15,34 +16,41 @@ interface Props {
|
|
|
15
16
|
}
|
|
16
17
|
|
|
17
18
|
export function useFindOrCreateServicesConversation({ teamIds, planId, onSuccess }: Props) {
|
|
18
|
-
const teamAndPlanParams: TeamAndPlanParams = {
|
|
19
|
-
team_id: teamIds.join(','),
|
|
20
|
-
...(planId ? { plan_id: planId } : {}),
|
|
21
|
-
}
|
|
22
|
-
|
|
23
19
|
const apiClient = useApiClient()
|
|
24
20
|
return useMutation({
|
|
25
21
|
throwOnError: true,
|
|
26
22
|
onSuccess: result => {
|
|
27
23
|
onSuccess && onSuccess(result)
|
|
28
24
|
},
|
|
29
|
-
mutationFn: async () =>
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
.then(groupIdentifiers => findConversationWithExactTeams(apiClient, groupIdentifiers))
|
|
33
|
-
.catch(() => null)
|
|
34
|
-
const foundConversation = foundConversations?.data[0]
|
|
25
|
+
mutationFn: async () => findOrCreateServicesConversation(apiClient, teamIds, planId),
|
|
26
|
+
})
|
|
27
|
+
}
|
|
35
28
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
29
|
+
export const findOrCreateServicesConversation = async (
|
|
30
|
+
apiClient: ApiClient,
|
|
31
|
+
teamIds: number[],
|
|
32
|
+
planId?: number
|
|
33
|
+
) => {
|
|
34
|
+
const teamAndPlanParams: TeamAndPlanParams = {
|
|
35
|
+
team_id: teamIds.join(','),
|
|
36
|
+
...(planId ? { plan_id: planId } : {}),
|
|
37
|
+
}
|
|
39
38
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
39
|
+
const foundConversations = await getGroupIdsFromServices(apiClient, teamAndPlanParams)
|
|
40
|
+
.then(res => res.data.groupIdentifiers)
|
|
41
|
+
.then(groupIdentifiers => findConversationWithExactTeams(apiClient, groupIdentifiers))
|
|
42
|
+
.catch(() => null)
|
|
43
|
+
const foundConversation = foundConversations?.data[0]
|
|
44
|
+
|
|
45
|
+
if (foundConversation?.id) {
|
|
46
|
+
return foundConversation
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return fetchServicesPayload(apiClient, teamAndPlanParams)
|
|
50
|
+
.then(res => res.data.payload)
|
|
51
|
+
.then(payload => createConversation(apiClient, payload))
|
|
52
|
+
.then(res => res.data)
|
|
53
|
+
.catch(throwResponseError)
|
|
46
54
|
}
|
|
47
55
|
|
|
48
56
|
interface TeamAndPlanParams {
|
|
@@ -79,7 +87,7 @@ function findConversationWithExactTeams(apiClient: ApiClient, groupIdentifiers:
|
|
|
79
87
|
url: '/me/conversations',
|
|
80
88
|
data: {
|
|
81
89
|
fields: {
|
|
82
|
-
Conversation: ['stream_channel'],
|
|
90
|
+
Conversation: ['stream_channel', 'title'],
|
|
83
91
|
},
|
|
84
92
|
filter: 'with_exact_groups',
|
|
85
93
|
gids: groupIdentifiers.join(','),
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { TeamOptionResource, TeamOptionResponseItem } from '
|
|
2
|
-
import { useApiGet } from '
|
|
1
|
+
import { TeamOptionResource, TeamOptionResponseItem } from '../../types'
|
|
2
|
+
import { useApiGet } from '../use_api'
|
|
3
3
|
|
|
4
4
|
export const useServicesTeams = () => {
|
|
5
5
|
const { data: chat } = useApiGet<TeamOptionResource>({
|
|
@@ -1,31 +1,15 @@
|
|
|
1
1
|
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
|
2
2
|
import { SUPPORTED_EXTENSIONS } from './attachments/supported_extensions'
|
|
3
|
-
import {
|
|
3
|
+
import { useUploadClient } from './use_upload_client'
|
|
4
4
|
import { useApiClient } from './use_api_client'
|
|
5
5
|
import { ApiResource } from '../types'
|
|
6
|
+
import {
|
|
7
|
+
FileAttachment,
|
|
8
|
+
FileUploadState,
|
|
9
|
+
NativeAttachmentFile,
|
|
10
|
+
} from '../types/resources/denormalized_attachment_resource_for_create'
|
|
6
11
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
interface AttachmentFile extends FileForUploadClient {
|
|
10
|
-
size: number
|
|
11
|
-
width?: number
|
|
12
|
-
height?: number
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export interface FileAttachment {
|
|
16
|
-
id?: string
|
|
17
|
-
file: AttachmentFile
|
|
18
|
-
status: AttachmentStatus
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
interface UploadState {
|
|
22
|
-
[fileName: string]: {
|
|
23
|
-
status: AttachmentStatus
|
|
24
|
-
id?: string
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
interface FileError {
|
|
12
|
+
export interface FileError {
|
|
29
13
|
file_type?: string[]
|
|
30
14
|
file_size?: boolean
|
|
31
15
|
}
|
|
@@ -38,13 +22,13 @@ export function useAttachmentUploader({ conversationId }: { conversationId: numb
|
|
|
38
22
|
const apiClient = useApiClient()
|
|
39
23
|
const uploadApi = useUploadClient()
|
|
40
24
|
const [attachments, setAttachments] = useState<FileAttachment[]>([])
|
|
41
|
-
const uploadState = useRef<
|
|
25
|
+
const uploadState = useRef<FileUploadState>({})
|
|
42
26
|
const [lastUploadId, setLastUploadId] = useState<string>()
|
|
43
27
|
const numberOfAttachments = attachments.length
|
|
44
28
|
const [errorMessage, setErrorMessage] = useState<string | null>(null)
|
|
45
29
|
|
|
46
30
|
const handleFilesAttached = useCallback(
|
|
47
|
-
(files:
|
|
31
|
+
(files: NativeAttachmentFile[]) => {
|
|
48
32
|
const fileErrors = {} as FileError
|
|
49
33
|
|
|
50
34
|
const validFiles = files.filter(file => {
|
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
import { AppGrantsResource } from '../types'
|
|
2
2
|
import { useApiGet } from './use_api'
|
|
3
|
+
import { App } from './use_api_client'
|
|
3
4
|
|
|
4
|
-
export
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
AppGrant: ['create_conversations', 'app_name'],
|
|
10
|
-
},
|
|
5
|
+
export const appGrantsRequestArgs = {
|
|
6
|
+
url: '/me/app_grants',
|
|
7
|
+
data: {
|
|
8
|
+
fields: {
|
|
9
|
+
AppGrant: ['create_conversations', 'app_name'],
|
|
11
10
|
},
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
},
|
|
12
|
+
app: 'chat' as App,
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function useAppGrants() {
|
|
16
|
+
return useApiGet<AppGrantsResource[]>(appGrantsRequestArgs)
|
|
14
17
|
}
|
|
15
18
|
|
|
16
19
|
export function useCanCreateConversations(): boolean {
|
|
@@ -14,6 +14,7 @@ import { JoltReactionEvent, JoltTypingEvent } from '../types/jolt_events'
|
|
|
14
14
|
import { transformReactionEventDataToReactionCountResource } from '../utils/jolt/transform_reaction_event_data_to_reaction_count_resource'
|
|
15
15
|
import { getMessagesRequestArgs } from '../utils/request/messages'
|
|
16
16
|
import { TYPING_TIMEOUT_INTERVAL, useTypingStatusCache } from './use_typing_status_cache'
|
|
17
|
+
import { isTemporaryMessageId } from './use_message_create_or_update'
|
|
17
18
|
|
|
18
19
|
interface Props {
|
|
19
20
|
conversationId: number
|
|
@@ -42,8 +43,25 @@ export function useConversationMessagesJoltEvents({ conversationId }: Props) {
|
|
|
42
43
|
|
|
43
44
|
queryClient.setQueryData<QueryData>(messagesQueryKey, prev => {
|
|
44
45
|
if (e.event === 'message.created') {
|
|
46
|
+
// Before adding the new message, remove any pending temporary messages
|
|
47
|
+
// with matching text to prevent duplicates from race conditions
|
|
48
|
+
let dataAfterTempRemoval = prev
|
|
49
|
+
if (prev && message.text && message.mine) {
|
|
50
|
+
dataAfterTempRemoval = deleteRecordInPagesData({
|
|
51
|
+
data: prev,
|
|
52
|
+
record: message,
|
|
53
|
+
matchFn: (existingMessage, _record) => {
|
|
54
|
+
return (
|
|
55
|
+
isTemporaryMessageId(existingMessage.id) &&
|
|
56
|
+
existingMessage.text === message.text &&
|
|
57
|
+
existingMessage.mine
|
|
58
|
+
)
|
|
59
|
+
},
|
|
60
|
+
})
|
|
61
|
+
}
|
|
62
|
+
|
|
45
63
|
return updateOrCreateRecordInPagesData({
|
|
46
|
-
data:
|
|
64
|
+
data: dataAfterTempRemoval,
|
|
47
65
|
record: message,
|
|
48
66
|
processRecord: (record, current) => {
|
|
49
67
|
return { ...current, ...record }
|
package/src/hooks/use_giphy.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useCallback, useContext, useEffect, useState } from 'react'
|
|
2
|
-
import { DenormalizedGiphyAttachmentResourceForCreate } from '../types/resources/
|
|
2
|
+
import { DenormalizedGiphyAttachmentResourceForCreate } from '../types/resources/denormalized_attachment_resource_for_create'
|
|
3
3
|
import { ChatContext } from '../contexts/chat_context'
|
|
4
4
|
|
|
5
5
|
interface GiphyGif {
|
|
@@ -3,17 +3,27 @@ import { getMessagesQueryKey, getMessagesRequestArgs } from './use_conversation_
|
|
|
3
3
|
import { useApiClient } from './use_api_client'
|
|
4
4
|
import { ApiCollection, ApiResource, MessageResource } from '../types'
|
|
5
5
|
import { chatQueryClient } from '../contexts/api_provider'
|
|
6
|
-
import {
|
|
7
|
-
|
|
6
|
+
import {
|
|
7
|
+
deleteRecordInPagesData,
|
|
8
|
+
updateOrCreateRecordInPagesData,
|
|
9
|
+
updateRecordInPagesData,
|
|
10
|
+
} from '../utils'
|
|
11
|
+
import { DenormalizedAttachmentResourceForCreate } from '../types/resources/denormalized_attachment_resource_for_create'
|
|
12
|
+
import { useCurrentPerson } from './use_current_person'
|
|
13
|
+
import { optimisticallyUpdateMessage } from '../utils/cache/optimistically_update_message'
|
|
14
|
+
import { optimisticallyCreateMessage } from '../utils/cache/optimistically_create_message'
|
|
8
15
|
|
|
9
16
|
interface Props {
|
|
10
17
|
conversationId: number
|
|
11
|
-
|
|
18
|
+
message?: MessageResource
|
|
12
19
|
}
|
|
13
20
|
|
|
14
|
-
export function useMessageCreateOrUpdate({ conversationId,
|
|
15
|
-
const
|
|
21
|
+
export function useMessageCreateOrUpdate({ conversationId, message }: Props) {
|
|
22
|
+
const messageId = message?.id || null
|
|
23
|
+
const isEditing = !isNewMessage(message)
|
|
16
24
|
const apiClient = useApiClient()
|
|
25
|
+
const currentPerson = useCurrentPerson()
|
|
26
|
+
|
|
17
27
|
const mutation = useMutation({
|
|
18
28
|
mutationFn: ({
|
|
19
29
|
text,
|
|
@@ -47,11 +57,70 @@ export function useMessageCreateOrUpdate({ conversationId, messageId }: Props) {
|
|
|
47
57
|
})
|
|
48
58
|
}
|
|
49
59
|
},
|
|
50
|
-
|
|
60
|
+
onMutate: async ({
|
|
61
|
+
text,
|
|
62
|
+
attachments,
|
|
63
|
+
}: {
|
|
64
|
+
text: string
|
|
65
|
+
attachments?: DenormalizedAttachmentResourceForCreate[]
|
|
66
|
+
}) => {
|
|
67
|
+
if (message && isEditing) {
|
|
68
|
+
const optimisticMessage = optimisticallyUpdateMessage({
|
|
69
|
+
conversationId,
|
|
70
|
+
message,
|
|
71
|
+
text,
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
return { message: optimisticMessage }
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const optimisticMessage = optimisticallyCreateMessage({
|
|
78
|
+
conversationId,
|
|
79
|
+
message,
|
|
80
|
+
text,
|
|
81
|
+
attachments,
|
|
82
|
+
currentPerson,
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
return { message: optimisticMessage }
|
|
86
|
+
},
|
|
87
|
+
onError: (error, variables, context) => {
|
|
88
|
+
const { message: optimisticMessage } = context || {}
|
|
89
|
+
// Add error to the optimistic message from the cache on error
|
|
90
|
+
if (optimisticMessage) {
|
|
91
|
+
const queryKey = getMessagesQueryKey({ conversation_id: conversationId })
|
|
92
|
+
chatQueryClient.setQueryData(
|
|
93
|
+
queryKey,
|
|
94
|
+
(data: InfiniteData<ApiCollection<MessageResource>> | undefined) =>
|
|
95
|
+
updateRecordInPagesData({
|
|
96
|
+
data,
|
|
97
|
+
record: optimisticMessage,
|
|
98
|
+
processRecord: (_next, prev) => ({
|
|
99
|
+
...prev,
|
|
100
|
+
error: error.message || 'Failed to send message',
|
|
101
|
+
pending: false, // Mark as no longer pending
|
|
102
|
+
}),
|
|
103
|
+
})
|
|
104
|
+
)
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
onSuccess: (result: ApiResource<MessageResource>, variables, context) => {
|
|
108
|
+
const { message: optimisticMessage } = context || {}
|
|
51
109
|
const updatedMessage = result.data
|
|
52
110
|
type QueryData = InfiniteData<ApiCollection<MessageResource>>
|
|
53
111
|
const queryKey = getMessagesQueryKey({ conversation_id: conversationId })
|
|
54
112
|
|
|
113
|
+
// First remove the optimistic message if it exists
|
|
114
|
+
if (optimisticMessage) {
|
|
115
|
+
chatQueryClient.setQueryData<QueryData>(queryKey, data =>
|
|
116
|
+
deleteRecordInPagesData({
|
|
117
|
+
data,
|
|
118
|
+
record: optimisticMessage,
|
|
119
|
+
})
|
|
120
|
+
)
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Then add the real message
|
|
55
124
|
chatQueryClient.setQueryData<QueryData>(queryKey, data =>
|
|
56
125
|
updateOrCreateRecordInPagesData({
|
|
57
126
|
data,
|
|
@@ -63,3 +132,10 @@ export function useMessageCreateOrUpdate({ conversationId, messageId }: Props) {
|
|
|
63
132
|
|
|
64
133
|
return mutation
|
|
65
134
|
}
|
|
135
|
+
|
|
136
|
+
export function isTemporaryMessageId(messageId?: string | null): boolean {
|
|
137
|
+
return !!messageId && messageId.endsWith('-temp')
|
|
138
|
+
}
|
|
139
|
+
export function isNewMessage(message?: MessageResource): boolean {
|
|
140
|
+
return !message?.id || isTemporaryMessageId(message.id)
|
|
141
|
+
}
|
package/src/index.tsx
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { GroupConversations } from './components'
|
|
2
|
-
export { ApiProvider, chatQueryClient } from './contexts/api_provider'
|
|
2
|
+
export { ApiProvider, chatQueryClient, useFocusManager } from './contexts/api_provider'
|
|
3
3
|
export * from './contexts/chat_context'
|
|
4
4
|
export * from './navigation'
|
|
5
5
|
export { ScreenLayout } from './navigation/screenLayout'
|
package/src/navigation/index.tsx
CHANGED
|
@@ -43,6 +43,8 @@ import {
|
|
|
43
43
|
} from '../screens/conversation/message_read_receipts_screen'
|
|
44
44
|
import { Platform } from 'react-native'
|
|
45
45
|
import { HeaderSubmitButton } from '../components/display/platform_modal_header_buttons'
|
|
46
|
+
import { TeamConversationScreen } from '../screens/team_conversation_screen'
|
|
47
|
+
import { CardStyleInterpolators } from '@react-navigation/stack'
|
|
46
48
|
|
|
47
49
|
const HEADER_BACK_BUTTON_LAYOUT_RESET_STYLES = {
|
|
48
50
|
marginLeft: Platform.select({ ios: -8, default: -3 }),
|
|
@@ -179,6 +181,14 @@ export const ChatStack = createNativeStackNavigator({
|
|
|
179
181
|
),
|
|
180
182
|
}),
|
|
181
183
|
},
|
|
184
|
+
TeamConversation: {
|
|
185
|
+
screen: TeamConversationScreen,
|
|
186
|
+
options: {
|
|
187
|
+
title: 'Finding conversation...',
|
|
188
|
+
animation: 'none',
|
|
189
|
+
cardStyleInterpolator: CardStyleInterpolators.forNoAnimation,
|
|
190
|
+
},
|
|
191
|
+
},
|
|
182
192
|
ConversationDetails: {
|
|
183
193
|
screen: ConversationDetailsScreen,
|
|
184
194
|
options: ({ navigation }) => ({
|
|
@@ -242,7 +242,7 @@ export function ConversationDetailsScreen({ route }: ConversationDetailsScreenPr
|
|
|
242
242
|
{
|
|
243
243
|
type: canUpdate ? SectionTypes.setting : SectionTypes.hidden,
|
|
244
244
|
data: {
|
|
245
|
-
title: 'Freeze
|
|
245
|
+
title: 'Freeze conversation',
|
|
246
246
|
subtitle: 'Disables replies for everyone except leaders.',
|
|
247
247
|
rightItem: (
|
|
248
248
|
<Switch value={repliesDisabled} onChange={() => setRepliesDisabled(!repliesDisabled)} />
|
package/src/screens/conversation_filter_recipients/conversation_filter_recipients_screen.tsx
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { StackActions, useNavigation } from '@react-navigation/native'
|
|
1
|
+
import { RouteProp, StackActions, useNavigation, useRoute } from '@react-navigation/native'
|
|
2
2
|
import { NativeStackNavigationProp } from '@react-navigation/native-stack'
|
|
3
|
-
import React, { useCallback } from 'react'
|
|
4
|
-
import { Platform, StyleSheet } from 'react-native'
|
|
5
|
-
import { FlatList } from 'react-native-gesture-handler'
|
|
3
|
+
import React, { useCallback, useMemo, useState } from 'react'
|
|
4
|
+
import { LayoutChangeEvent, Platform, StyleSheet, View } from 'react-native'
|
|
5
|
+
import { FlatList, TextInput } from 'react-native-gesture-handler'
|
|
6
6
|
import { useSafeAreaInsets } from 'react-native-safe-area-context'
|
|
7
|
-
import { Heading } from '../../components'
|
|
7
|
+
import { BlankState, Heading, ToggleButton } from '../../components'
|
|
8
8
|
import FormSheet, { getFormSheetScreenOptions } from '../../components/primitive/form_sheet'
|
|
9
9
|
import { useTheme } from '../../hooks'
|
|
10
10
|
import { tokens } from '../../vendor/tapestry/tokens'
|
|
@@ -12,7 +12,8 @@ import { CheckboxRow } from './components/checkbox_row'
|
|
|
12
12
|
import { HeaderRow } from './components/header_row'
|
|
13
13
|
import { useFlattenedArrayOfServiceTypesWithTeams } from './hooks/use_flattened_array_of_service_types_with_teams'
|
|
14
14
|
import { useServiceTypesWithTeams } from './hooks/use_service_types_with_teams'
|
|
15
|
-
import { ConversationFilterRecipientsScreenProps, SectionTypes } from './types'
|
|
15
|
+
import { ConversationFilterRecipientsScreenProps, SectionTypes, TeamFilterTypes } from './types'
|
|
16
|
+
import { DefaultLoading } from '../../components/page/loading'
|
|
16
17
|
|
|
17
18
|
const SERVICE_TYPE_LABELLED_BY_PREFIX = 'header-'
|
|
18
19
|
|
|
@@ -28,18 +29,34 @@ export const ConversationFilterRecipientsScreen = ({
|
|
|
28
29
|
route,
|
|
29
30
|
}: ConversationFilterRecipientsScreenProps) => {
|
|
30
31
|
const styles = useStyles()
|
|
32
|
+
|
|
33
|
+
// Set the height of the container to accommodate the team filters
|
|
34
|
+
const [teamFiltersHeight, setTeamFiltersHeight] = useState(200)
|
|
35
|
+
const { top, bottom } = useSafeAreaInsets()
|
|
36
|
+
const listContainerStyle = useMemo(
|
|
37
|
+
() => Platform.select({ ios: { paddingBottom: teamFiltersHeight + bottom + top } }),
|
|
38
|
+
[teamFiltersHeight, bottom, top]
|
|
39
|
+
)
|
|
40
|
+
|
|
31
41
|
const navigation =
|
|
32
42
|
useNavigation<NativeStackNavigationProp<ConversationFilterRecipientsScreenProps>>()
|
|
33
43
|
const { team_ids: teamIds } = route.params
|
|
44
|
+
const { params } = route
|
|
45
|
+
const teamIdCount = Number(teamIds?.length)
|
|
46
|
+
const headerTitle = useMemo(() => {
|
|
47
|
+
return teamIdCount >= 1 ? `Selected teams (${teamIdCount})` : 'Select teams'
|
|
48
|
+
}, [teamIdCount])
|
|
34
49
|
|
|
35
|
-
const { serviceTypes } = useServiceTypesWithTeams(
|
|
50
|
+
const { serviceTypes, isFetched } = useServiceTypesWithTeams({
|
|
51
|
+
filterType: params.team_filter_type,
|
|
52
|
+
searchQuery: params.search_query,
|
|
53
|
+
})
|
|
36
54
|
const data = useFlattenedArrayOfServiceTypesWithTeams({
|
|
37
55
|
data: serviceTypes,
|
|
38
56
|
firstRowStyle: styles.firstRow,
|
|
39
57
|
lastRowStyle: styles.lastRow,
|
|
40
58
|
})
|
|
41
59
|
|
|
42
|
-
const { params } = route
|
|
43
60
|
const noTeamsSelected = params.team_ids?.length === 0 || !params.team_ids
|
|
44
61
|
const applyButtonAccessibilityHint = noTeamsSelected
|
|
45
62
|
? 'Select at least one team to navigate to the final step in creating your conversation.'
|
|
@@ -47,9 +64,7 @@ export const ConversationFilterRecipientsScreen = ({
|
|
|
47
64
|
|
|
48
65
|
const setTeamFilters = useCallback(
|
|
49
66
|
({ team_ids }: { team_ids: number[] }) => {
|
|
50
|
-
navigation.setParams({
|
|
51
|
-
team_ids,
|
|
52
|
-
})
|
|
67
|
+
navigation.setParams({ team_ids })
|
|
53
68
|
},
|
|
54
69
|
[navigation]
|
|
55
70
|
)
|
|
@@ -62,13 +77,14 @@ export const ConversationFilterRecipientsScreen = ({
|
|
|
62
77
|
navigation.dispatch(StackActions.popTo('ConversationNew', params))
|
|
63
78
|
}, [navigation, params])
|
|
64
79
|
|
|
65
|
-
const
|
|
66
|
-
|
|
80
|
+
const handleTeamFiltersLayout = useCallback((event: LayoutChangeEvent) => {
|
|
81
|
+
setTeamFiltersHeight(event.nativeEvent.layout.height)
|
|
82
|
+
}, [])
|
|
67
83
|
|
|
68
84
|
return (
|
|
69
85
|
<FormSheet.Root style={styles.root}>
|
|
70
|
-
<FormSheet.Header>
|
|
71
|
-
<FormSheet.HeaderTitle>
|
|
86
|
+
<FormSheet.Header style={styles.header}>
|
|
87
|
+
<FormSheet.HeaderTitle>{headerTitle}</FormSheet.HeaderTitle>
|
|
72
88
|
<FormSheet.HeaderActions>
|
|
73
89
|
<FormSheet.HeaderSecondaryButton
|
|
74
90
|
onPress={resetTeamFilters}
|
|
@@ -84,7 +100,7 @@ export const ConversationFilterRecipientsScreen = ({
|
|
|
84
100
|
/>
|
|
85
101
|
</FormSheet.HeaderActions>
|
|
86
102
|
</FormSheet.Header>
|
|
87
|
-
|
|
103
|
+
<TeamFilters onLayout={handleTeamFiltersLayout} />
|
|
88
104
|
<FlatList
|
|
89
105
|
data={data}
|
|
90
106
|
ListHeaderComponent={
|
|
@@ -92,10 +108,11 @@ export const ConversationFilterRecipientsScreen = ({
|
|
|
92
108
|
Service Types
|
|
93
109
|
</Heading>
|
|
94
110
|
}
|
|
95
|
-
contentContainerStyle={styles.listContentContainer}
|
|
111
|
+
contentContainerStyle={[styles.listContentContainer, listContainerStyle]}
|
|
96
112
|
keyExtractor={item =>
|
|
97
113
|
`${item.type === SectionTypes.header ? item.data.serviceTypeId : item.data.teamId}`
|
|
98
114
|
}
|
|
115
|
+
ListEmptyComponent={isFetched ? <BlankState title="No teams found" /> : <DefaultLoading />}
|
|
99
116
|
renderItem={({ item }) => {
|
|
100
117
|
switch (item.type) {
|
|
101
118
|
case SectionTypes.header:
|
|
@@ -125,6 +142,63 @@ export const ConversationFilterRecipientsScreen = ({
|
|
|
125
142
|
)
|
|
126
143
|
}
|
|
127
144
|
|
|
145
|
+
const TeamFilters = ({ onLayout }: { onLayout?: (event: LayoutChangeEvent) => void }) => {
|
|
146
|
+
const styles = useStyles()
|
|
147
|
+
const { colors } = useTheme()
|
|
148
|
+
const navigation =
|
|
149
|
+
useNavigation<NativeStackNavigationProp<ConversationFilterRecipientsScreenProps>>()
|
|
150
|
+
const route = useRoute<RouteProp<ConversationFilterRecipientsScreenProps['route']>>()
|
|
151
|
+
const { params } = route
|
|
152
|
+
|
|
153
|
+
const active = params.team_filter_type || TeamFilterTypes.TeamsIlead
|
|
154
|
+
|
|
155
|
+
const handleFilterChange = useCallback(
|
|
156
|
+
(filter: TeamFilterTypes) => {
|
|
157
|
+
navigation.setParams({
|
|
158
|
+
team_filter_type: filter,
|
|
159
|
+
team_ids: [],
|
|
160
|
+
})
|
|
161
|
+
},
|
|
162
|
+
[navigation]
|
|
163
|
+
)
|
|
164
|
+
|
|
165
|
+
return (
|
|
166
|
+
<View style={styles.teamFiltersContainer} onLayout={onLayout}>
|
|
167
|
+
<TextInput
|
|
168
|
+
defaultValue={params.search_query}
|
|
169
|
+
placeholder="Search teams"
|
|
170
|
+
placeholderTextColor={colors.textColorDefaultPlaceholder}
|
|
171
|
+
style={styles.searchInput}
|
|
172
|
+
onChangeText={text => {
|
|
173
|
+
navigation.setParams({
|
|
174
|
+
search_query: text,
|
|
175
|
+
})
|
|
176
|
+
}}
|
|
177
|
+
/>
|
|
178
|
+
<View style={styles.filterToggleContainer}>
|
|
179
|
+
<ToggleButton
|
|
180
|
+
active={active === TeamFilterTypes.TeamsIlead}
|
|
181
|
+
title={TeamFilterTypes.TeamsIlead}
|
|
182
|
+
accessibilityLabel="Show all teams I lead"
|
|
183
|
+
onPress={() => handleFilterChange(TeamFilterTypes.TeamsIlead)}
|
|
184
|
+
/>
|
|
185
|
+
<ToggleButton
|
|
186
|
+
active={active === TeamFilterTypes.MyTeams}
|
|
187
|
+
title={TeamFilterTypes.MyTeams}
|
|
188
|
+
accessibilityLabel="Show all my teams"
|
|
189
|
+
onPress={() => handleFilterChange(TeamFilterTypes.MyTeams)}
|
|
190
|
+
/>
|
|
191
|
+
<ToggleButton
|
|
192
|
+
active={active === TeamFilterTypes.All}
|
|
193
|
+
title={TeamFilterTypes.All}
|
|
194
|
+
accessibilityLabel="Show all teams"
|
|
195
|
+
onPress={() => handleFilterChange(TeamFilterTypes.All)}
|
|
196
|
+
/>
|
|
197
|
+
</View>
|
|
198
|
+
</View>
|
|
199
|
+
)
|
|
200
|
+
}
|
|
201
|
+
|
|
128
202
|
const useStyles = () => {
|
|
129
203
|
const { colors } = useTheme()
|
|
130
204
|
const { bottom } = useSafeAreaInsets()
|
|
@@ -133,6 +207,9 @@ const useStyles = () => {
|
|
|
133
207
|
root: {
|
|
134
208
|
backgroundColor: colors.surfaceColor080,
|
|
135
209
|
},
|
|
210
|
+
header: {
|
|
211
|
+
borderBottomWidth: 0,
|
|
212
|
+
},
|
|
136
213
|
listContentContainer: {
|
|
137
214
|
padding: 16,
|
|
138
215
|
paddingBottom: bottom + Platform.select({ android: 24, default: 16 }),
|
|
@@ -149,5 +226,29 @@ const useStyles = () => {
|
|
|
149
226
|
borderBottomEndRadius: tokens.borderRadiusLg,
|
|
150
227
|
marginBottom: 16,
|
|
151
228
|
},
|
|
229
|
+
teamFiltersContainer: {
|
|
230
|
+
gap: 12,
|
|
231
|
+
paddingHorizontal: 16,
|
|
232
|
+
paddingBottom: 28,
|
|
233
|
+
backgroundColor: colors.fillColorNeutral100Inverted,
|
|
234
|
+
borderBottomWidth: 1,
|
|
235
|
+
borderBottomColor: colors.borderColorDefaultBase,
|
|
236
|
+
},
|
|
237
|
+
filterToggleContainer: {
|
|
238
|
+
flexDirection: 'row',
|
|
239
|
+
gap: 8,
|
|
240
|
+
},
|
|
241
|
+
searchInput: {
|
|
242
|
+
paddingVertical: 16,
|
|
243
|
+
paddingHorizontal: 16,
|
|
244
|
+
color: colors.textColorDefaultPrimary,
|
|
245
|
+
textAlignVertical: 'center',
|
|
246
|
+
justifyContent: 'center',
|
|
247
|
+
fontSize: 16,
|
|
248
|
+
borderWidth: 1,
|
|
249
|
+
borderColor: colors.borderColorDefaultBase,
|
|
250
|
+
borderRadius: 24,
|
|
251
|
+
backgroundColor: colors.fillColorNeutral100Inverted,
|
|
252
|
+
},
|
|
152
253
|
})
|
|
153
254
|
}
|