@planningcenter/chat-react-native 4.4.1-qa-staging.13 → 4.4.1-qa-staging.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/components/conversation/message.d.ts +2 -1
- package/build/components/conversation/message.d.ts.map +1 -1
- package/build/components/conversation/message.js +3 -1
- package/build/components/conversation/message.js.map +1 -1
- package/build/components/conversation/message_list.d.ts.map +1 -1
- package/build/components/conversation/message_list.js +35 -31
- package/build/components/conversation/message_list.js.map +1 -1
- package/build/components/conversation/message_reaction.d.ts +2 -1
- package/build/components/conversation/message_reaction.d.ts.map +1 -1
- package/build/components/conversation/message_reaction.js +67 -60
- package/build/components/conversation/message_reaction.js.map +1 -1
- package/build/components/conversation/messages_disabled_banners.d.ts +7 -5
- package/build/components/conversation/messages_disabled_banners.d.ts.map +1 -1
- package/build/components/conversation/messages_disabled_banners.js +15 -14
- package/build/components/conversation/messages_disabled_banners.js.map +1 -1
- package/build/components/conversation/system_message.d.ts +2 -1
- package/build/components/conversation/system_message.d.ts.map +1 -1
- package/build/components/conversation/system_message.js +87 -65
- package/build/components/conversation/system_message.js.map +1 -1
- package/build/components/display/filter_dropdown.d.ts +13 -0
- package/build/components/display/filter_dropdown.d.ts.map +1 -0
- package/build/components/display/filter_dropdown.js +188 -0
- package/build/components/display/filter_dropdown.js.map +1 -0
- package/build/components/display/index.d.ts +1 -0
- package/build/components/display/index.d.ts.map +1 -1
- package/build/components/display/index.js +1 -0
- package/build/components/display/index.js.map +1 -1
- package/build/hooks/use_conversation.d.ts +73 -1
- package/build/hooks/use_conversation.d.ts.map +1 -1
- package/build/hooks/use_conversation.js +122 -3
- package/build/hooks/use_conversation.js.map +1 -1
- package/build/hooks/use_unarchive_conversation_action.d.ts +7 -0
- package/build/hooks/use_unarchive_conversation_action.d.ts.map +1 -0
- package/build/hooks/use_unarchive_conversation_action.js +52 -0
- package/build/hooks/use_unarchive_conversation_action.js.map +1 -0
- package/build/screens/attachment_actions/attachment_actions_screen.d.ts.map +1 -1
- package/build/screens/attachment_actions/attachment_actions_screen.js +84 -61
- package/build/screens/attachment_actions/attachment_actions_screen.js.map +1 -1
- package/build/screens/conversation_details_screen.d.ts.map +1 -1
- package/build/screens/conversation_details_screen.js +487 -393
- package/build/screens/conversation_details_screen.js.map +1 -1
- package/build/screens/conversation_screen.d.ts.map +1 -1
- package/build/screens/conversation_screen.js +12 -9
- package/build/screens/conversation_screen.js.map +1 -1
- package/build/screens/design_system_screen.d.ts.map +1 -1
- package/build/screens/design_system_screen.js +275 -215
- package/build/screens/design_system_screen.js.map +1 -1
- package/build/screens/message_actions_screen.d.ts.map +1 -1
- package/build/screens/message_actions_screen.js +112 -92
- package/build/screens/message_actions_screen.js.map +1 -1
- package/build/types/resources/member_ability.d.ts +2 -0
- package/build/types/resources/member_ability.d.ts.map +1 -1
- package/build/types/resources/member_ability.js.map +1 -1
- package/build/utils/archived_conversation.d.ts +5 -0
- package/build/utils/archived_conversation.d.ts.map +1 -0
- package/build/utils/archived_conversation.js +5 -0
- package/build/utils/archived_conversation.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/native_adapters/configuration.d.ts +3 -0
- package/build/utils/native_adapters/configuration.d.ts.map +1 -1
- package/build/utils/native_adapters/configuration.js +3 -0
- package/build/utils/native_adapters/configuration.js.map +1 -1
- package/build/utils/native_adapters/index.d.ts +1 -0
- package/build/utils/native_adapters/index.d.ts.map +1 -1
- package/build/utils/native_adapters/index.js +1 -0
- package/build/utils/native_adapters/index.js.map +1 -1
- package/build/utils/native_adapters/menu.d.ts +40 -0
- package/build/utils/native_adapters/menu.d.ts.map +1 -0
- package/build/utils/native_adapters/menu.js +55 -0
- package/build/utils/native_adapters/menu.js.map +1 -0
- package/package.json +3 -3
- package/src/__tests__/screens/message_actions_screen.test.tsx +65 -2
- package/src/components/conversation/__tests__/message_list.test.tsx +68 -2
- package/src/components/conversation/__tests__/system_message.test.tsx +3 -1
- package/src/components/conversation/message.tsx +3 -0
- package/src/components/conversation/message_list.tsx +9 -1
- package/src/components/conversation/message_reaction.tsx +7 -2
- package/src/components/conversation/messages_disabled_banners.tsx +17 -18
- package/src/components/conversation/system_message.tsx +24 -10
- package/src/components/display/__tests__/filter_dropdown.test.tsx +106 -0
- package/src/components/display/filter_dropdown.tsx +123 -0
- package/src/components/display/index.ts +1 -0
- package/src/hooks/__tests__/use_conversation_archive.test.tsx +130 -0
- package/src/hooks/__tests__/use_conversation_jolt_events.test.tsx +74 -0
- package/src/hooks/__tests__/use_unarchive_conversation_action.test.tsx +67 -0
- package/src/hooks/use_conversation.ts +41 -3
- package/src/hooks/use_unarchive_conversation_action.ts +24 -0
- package/src/screens/__tests__/conversation_details_screen.test.tsx +289 -0
- package/src/screens/attachment_actions/__tests__/attachment_actions_screen.test.tsx +72 -0
- package/src/screens/attachment_actions/attachment_actions_screen.tsx +3 -1
- package/src/screens/conversation_details_screen.tsx +78 -14
- package/src/screens/conversation_screen.tsx +3 -1
- package/src/screens/design_system_screen.tsx +26 -0
- package/src/screens/message_actions_screen.tsx +29 -20
- package/src/types/resources/member_ability.ts +2 -0
- package/src/utils/archived_conversation.ts +13 -0
- package/src/utils/index.ts +1 -0
- package/src/utils/native_adapters/__tests__/menu.test.tsx +42 -0
- package/src/utils/native_adapters/configuration.ts +5 -0
- package/src/utils/native_adapters/index.ts +1 -0
- package/src/utils/native_adapters/menu.tsx +68 -0
|
@@ -9,6 +9,7 @@ import { useReactionStyles } from '../components/conversation/message_reaction'
|
|
|
9
9
|
import FormSheet, { getFormSheetScreenOptions } from '../components/primitive/form_sheet'
|
|
10
10
|
import { useCreateAndroidRippleColor, useFontScale, useTheme } from '../hooks'
|
|
11
11
|
import { useApiClient } from '../hooks/use_api_client'
|
|
12
|
+
import { useConversation } from '../hooks/use_conversation'
|
|
12
13
|
import { useConversationMessages } from '../hooks/use_conversation_messages'
|
|
13
14
|
import { availableFeatures, useFeatures } from '../hooks/use_features'
|
|
14
15
|
import { useMessageReactionToggle } from '../hooks/use_message_reaction_toggle'
|
|
@@ -49,6 +50,7 @@ export function MessageActionsScreen({ route }: MessageActionsScreenProps) {
|
|
|
49
50
|
{ conversation_id },
|
|
50
51
|
{ refetchOnMount: false }
|
|
51
52
|
)
|
|
53
|
+
const { data: conversation } = useConversation({ conversation_id }, { refetchOnMount: false })
|
|
52
54
|
const message = messages.find(m => m.id === message_id)
|
|
53
55
|
|
|
54
56
|
if (!message) return null
|
|
@@ -57,6 +59,7 @@ export function MessageActionsScreen({ route }: MessageActionsScreenProps) {
|
|
|
57
59
|
<MessageActionsScreenContent
|
|
58
60
|
message={message}
|
|
59
61
|
conversation_id={conversation_id}
|
|
62
|
+
conversationDisabled={!!conversation.disabled}
|
|
60
63
|
canDeleteNonAuthoredMessages={canDeleteNonAuthoredMessages || false}
|
|
61
64
|
refetchMessages={refetch}
|
|
62
65
|
inReplyScreen={inReplyScreen}
|
|
@@ -69,6 +72,7 @@ export function MessageActionsScreen({ route }: MessageActionsScreenProps) {
|
|
|
69
72
|
function MessageActionsScreenContent({
|
|
70
73
|
message,
|
|
71
74
|
conversation_id,
|
|
75
|
+
conversationDisabled,
|
|
72
76
|
canDeleteNonAuthoredMessages,
|
|
73
77
|
refetchMessages,
|
|
74
78
|
inReplyScreen,
|
|
@@ -77,6 +81,7 @@ function MessageActionsScreenContent({
|
|
|
77
81
|
}: {
|
|
78
82
|
message: MessageResource
|
|
79
83
|
conversation_id: number
|
|
84
|
+
conversationDisabled: boolean
|
|
80
85
|
canDeleteNonAuthoredMessages: boolean
|
|
81
86
|
refetchMessages: () => void
|
|
82
87
|
inReplyScreen?: boolean
|
|
@@ -241,28 +246,32 @@ function MessageActionsScreenContent({
|
|
|
241
246
|
|
|
242
247
|
const showReportMessageAction =
|
|
243
248
|
!message?.mine && featureEnabled(availableFeatures.message_reporting)
|
|
249
|
+
const showDeleteMessageAction =
|
|
250
|
+
!conversationDisabled && (message?.mine || canDeleteNonAuthoredMessages)
|
|
244
251
|
|
|
245
252
|
return (
|
|
246
253
|
<FormSheet.Root style={styles.formSheetContent}>
|
|
247
|
-
|
|
248
|
-
{
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
254
|
+
{!conversationDisabled && (
|
|
255
|
+
<View style={styles.reactionList}>
|
|
256
|
+
{availableReactions.map((reaction, index) => (
|
|
257
|
+
<Reaction
|
|
258
|
+
key={index}
|
|
259
|
+
reaction={reaction}
|
|
260
|
+
onPress={() => {
|
|
261
|
+
Haptic.impactLight()
|
|
262
|
+
handleReactionToggle({
|
|
263
|
+
value: reaction.value,
|
|
264
|
+
mine: reaction.mine,
|
|
265
|
+
})
|
|
266
|
+
navigation.goBack()
|
|
267
|
+
}}
|
|
268
|
+
/>
|
|
269
|
+
))}
|
|
270
|
+
</View>
|
|
271
|
+
)}
|
|
263
272
|
{!isSystemMessage && (
|
|
264
273
|
<View style={styles.actions}>
|
|
265
|
-
{!inReplyScreen && (
|
|
274
|
+
{!inReplyScreen && !conversationDisabled && (
|
|
266
275
|
<FormSheet.Action
|
|
267
276
|
onPress={handleReplyPress}
|
|
268
277
|
title="Reply to message"
|
|
@@ -285,7 +294,7 @@ function MessageActionsScreenContent({
|
|
|
285
294
|
accessibilityHint="Opens a form to report this message"
|
|
286
295
|
/>
|
|
287
296
|
)}
|
|
288
|
-
{message?.mine && (
|
|
297
|
+
{message?.mine && !conversationDisabled && (
|
|
289
298
|
<FormSheet.Action
|
|
290
299
|
onPress={() => handleEditPress()}
|
|
291
300
|
title="Edit message"
|
|
@@ -301,7 +310,7 @@ function MessageActionsScreenContent({
|
|
|
301
310
|
accessibilityHint="Opens a modal with a list of people who read your message."
|
|
302
311
|
/>
|
|
303
312
|
)}
|
|
304
|
-
{message?.mine && hasExpandedLink && (
|
|
313
|
+
{message?.mine && hasExpandedLink && !conversationDisabled && (
|
|
305
314
|
<FormSheet.Action
|
|
306
315
|
onPress={() => handleRemoveLinkPreviewConfirm()}
|
|
307
316
|
title="Remove link preview"
|
|
@@ -309,7 +318,7 @@ function MessageActionsScreenContent({
|
|
|
309
318
|
accessibilityHint="Removes an expanded link preview from the message."
|
|
310
319
|
/>
|
|
311
320
|
)}
|
|
312
|
-
{
|
|
321
|
+
{showDeleteMessageAction && (
|
|
313
322
|
<FormSheet.Action
|
|
314
323
|
onPress={() => handleDeleteConfirm()}
|
|
315
324
|
title="Delete message"
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ConversationResource } from '../types/resources/conversation'
|
|
2
|
+
|
|
3
|
+
export const ARCHIVED_DISABLED_REASON = 'archived'
|
|
4
|
+
|
|
5
|
+
const DEFAULT_ARCHIVED_MESSAGE = 'This conversation is archived.'
|
|
6
|
+
|
|
7
|
+
export const isArchivedConversation = (
|
|
8
|
+
conversation: Pick<ConversationResource, 'disabledReason'>
|
|
9
|
+
) => conversation.disabledReason === ARCHIVED_DISABLED_REASON
|
|
10
|
+
|
|
11
|
+
export const archivedConversationMessage = (
|
|
12
|
+
conversation: Pick<ConversationResource, 'disabledMessage'>
|
|
13
|
+
) => conversation.disabledMessage || DEFAULT_ARCHIVED_MESSAGE
|
package/src/utils/index.ts
CHANGED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { render, screen } from '@testing-library/react-native'
|
|
2
|
+
import React from 'react'
|
|
3
|
+
import { Text } from 'react-native'
|
|
4
|
+
import { MenuAdapter, MenuViewProps } from '../menu'
|
|
5
|
+
|
|
6
|
+
const actions = [{ id: 'all', title: 'All' }]
|
|
7
|
+
|
|
8
|
+
describe('MenuAdapter', () => {
|
|
9
|
+
it('renders the trigger and warns when the host configured no menu', () => {
|
|
10
|
+
const warn = jest.spyOn(console, 'warn').mockImplementation(() => {})
|
|
11
|
+
const { View } = new MenuAdapter()
|
|
12
|
+
|
|
13
|
+
render(
|
|
14
|
+
<View actions={actions}>
|
|
15
|
+
<Text>Trigger</Text>
|
|
16
|
+
</View>
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
expect(screen.getByText('Trigger')).toBeTruthy()
|
|
20
|
+
expect(warn).toHaveBeenCalledTimes(1)
|
|
21
|
+
warn.mockRestore()
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
it('renders through the view the host supplies', () => {
|
|
25
|
+
const HostMenuView = ({ actions: hostActions, children }: MenuViewProps) => (
|
|
26
|
+
<>
|
|
27
|
+
{children}
|
|
28
|
+
<Text>{hostActions.map(action => action.title).join(',')}</Text>
|
|
29
|
+
</>
|
|
30
|
+
)
|
|
31
|
+
const { View } = new MenuAdapter({ View: HostMenuView })
|
|
32
|
+
|
|
33
|
+
render(
|
|
34
|
+
<View actions={actions}>
|
|
35
|
+
<Text>Trigger</Text>
|
|
36
|
+
</View>
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
expect(screen.getByText('Trigger')).toBeTruthy()
|
|
40
|
+
expect(screen.getByText('All')).toBeTruthy()
|
|
41
|
+
})
|
|
42
|
+
})
|
|
@@ -7,6 +7,7 @@ import { HapticAdapter } from './haptic'
|
|
|
7
7
|
import { ImagePickerAdapter } from './image_picker'
|
|
8
8
|
import { LinkingAdapter } from './linking'
|
|
9
9
|
import { LogAdapter } from './log'
|
|
10
|
+
import { MenuAdapter } from './menu'
|
|
10
11
|
import { StorageAdapter } from './storage_adapter'
|
|
11
12
|
import { VideoAdapter } from './video'
|
|
12
13
|
|
|
@@ -19,6 +20,7 @@ type ChatConfigurations = {
|
|
|
19
20
|
log?: LogAdapter
|
|
20
21
|
linking?: LinkingAdapter
|
|
21
22
|
haptic?: HapticAdapter
|
|
23
|
+
menu?: MenuAdapter
|
|
22
24
|
}
|
|
23
25
|
|
|
24
26
|
export class ChatAdapters {
|
|
@@ -31,6 +33,7 @@ export class ChatAdapters {
|
|
|
31
33
|
Log = configurations.log || new LogAdapter()
|
|
32
34
|
Linking = configurations.linking || new LinkingAdapter(RNLinking)
|
|
33
35
|
Haptic = configurations.haptic || new HapticAdapter()
|
|
36
|
+
Menu = configurations.menu || new MenuAdapter()
|
|
34
37
|
}
|
|
35
38
|
}
|
|
36
39
|
|
|
@@ -82,6 +85,8 @@ export let Linking: LinkingAdapter = new LinkingAdapter(RNLinking)
|
|
|
82
85
|
|
|
83
86
|
export let Haptic: HapticAdapter = new HapticAdapter()
|
|
84
87
|
|
|
88
|
+
export let Menu: MenuAdapter = new MenuAdapter()
|
|
89
|
+
|
|
85
90
|
export let Storage = new StorageAdapter({
|
|
86
91
|
getItem: AsyncStorage.getItem,
|
|
87
92
|
setItem: AsyncStorage.setItem,
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import React, { useEffect } from 'react'
|
|
2
|
+
import { StyleProp, View, ViewStyle } from 'react-native'
|
|
3
|
+
|
|
4
|
+
// =================================
|
|
5
|
+
// ====== Types ====================
|
|
6
|
+
// =================================
|
|
7
|
+
|
|
8
|
+
// Mirrors the props shared by `@expo/ui/community/menu` and
|
|
9
|
+
// `@react-native-menu/menu`, so a host can pass either `MenuView` straight in.
|
|
10
|
+
|
|
11
|
+
export type MenuActionState = 'on' | 'off'
|
|
12
|
+
|
|
13
|
+
export interface MenuActionAttributes {
|
|
14
|
+
destructive?: boolean
|
|
15
|
+
disabled?: boolean
|
|
16
|
+
hidden?: boolean
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface MenuAction {
|
|
20
|
+
id?: string
|
|
21
|
+
title: string
|
|
22
|
+
state?: MenuActionState
|
|
23
|
+
attributes?: MenuActionAttributes
|
|
24
|
+
subactions?: MenuAction[]
|
|
25
|
+
displayInline?: boolean
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface MenuActionEvent {
|
|
29
|
+
nativeEvent: { event: string }
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface MenuViewProps {
|
|
33
|
+
actions: MenuAction[]
|
|
34
|
+
onPressAction?: (event: MenuActionEvent) => void
|
|
35
|
+
onOpenMenu?: () => void
|
|
36
|
+
onCloseMenu?: () => void
|
|
37
|
+
shouldOpenOnLongPress?: boolean
|
|
38
|
+
title?: string
|
|
39
|
+
style?: StyleProp<ViewStyle>
|
|
40
|
+
testID?: string
|
|
41
|
+
children?: React.ReactNode
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export type MenuView = React.ComponentType<MenuViewProps>
|
|
45
|
+
|
|
46
|
+
// =================================
|
|
47
|
+
// ====== Adapter ==================
|
|
48
|
+
// =================================
|
|
49
|
+
|
|
50
|
+
function UnconfiguredMenuView({ children, style, testID }: MenuViewProps) {
|
|
51
|
+
useEffect(() => {
|
|
52
|
+
console.warn('ChatAdapters.configure() must include a menu adapter before rendering a menu')
|
|
53
|
+
}, [])
|
|
54
|
+
|
|
55
|
+
return (
|
|
56
|
+
<View style={style} testID={testID}>
|
|
57
|
+
{children}
|
|
58
|
+
</View>
|
|
59
|
+
)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export class MenuAdapter {
|
|
63
|
+
View: MenuView
|
|
64
|
+
|
|
65
|
+
constructor(methods?: { View: MenuView }) {
|
|
66
|
+
this.View = methods?.View ?? UnconfiguredMenuView
|
|
67
|
+
}
|
|
68
|
+
}
|