@planningcenter/chat-react-native 3.42.3-qa-staging.6 → 3.43.0-rc.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.
Files changed (118) hide show
  1. package/build/components/conversation/messages_disabled_banners.d.ts +3 -2
  2. package/build/components/conversation/messages_disabled_banners.d.ts.map +1 -1
  3. package/build/components/conversation/messages_disabled_banners.js +7 -2
  4. package/build/components/conversation/messages_disabled_banners.js.map +1 -1
  5. package/build/components/display/adult_requirement_notice.js +1 -1
  6. package/build/components/display/adult_requirement_notice.js.map +1 -1
  7. package/build/components/display/platform_modal_header_buttons.d.ts +7 -47
  8. package/build/components/display/platform_modal_header_buttons.d.ts.map +1 -1
  9. package/build/components/display/platform_modal_header_buttons.js +9 -119
  10. package/build/components/display/platform_modal_header_buttons.js.map +1 -1
  11. package/build/hooks/index.d.ts +1 -1
  12. package/build/hooks/index.d.ts.map +1 -1
  13. package/build/hooks/index.js +1 -1
  14. package/build/hooks/index.js.map +1 -1
  15. package/build/hooks/use_conversation.d.ts.map +1 -1
  16. package/build/hooks/use_conversation.js +0 -1
  17. package/build/hooks/use_conversation.js.map +1 -1
  18. package/build/hooks/use_conversation_jolt_events.d.ts.map +1 -1
  19. package/build/hooks/use_conversation_jolt_events.js +2 -10
  20. package/build/hooks/use_conversation_jolt_events.js.map +1 -1
  21. package/build/hooks/use_current_person.d.ts.map +1 -1
  22. package/build/hooks/use_current_person.js +0 -1
  23. package/build/hooks/use_current_person.js.map +1 -1
  24. package/build/hooks/use_direct_messages_enabled.d.ts +2 -0
  25. package/build/hooks/use_direct_messages_enabled.d.ts.map +1 -0
  26. package/build/hooks/use_direct_messages_enabled.js +16 -0
  27. package/build/hooks/use_direct_messages_enabled.js.map +1 -0
  28. package/build/hooks/use_features.d.ts +1 -0
  29. package/build/hooks/use_features.d.ts.map +1 -1
  30. package/build/hooks/use_features.js +1 -0
  31. package/build/hooks/use_features.js.map +1 -1
  32. package/build/navigation/index.d.ts +173 -69
  33. package/build/navigation/index.d.ts.map +1 -1
  34. package/build/navigation/index.js +72 -61
  35. package/build/navigation/index.js.map +1 -1
  36. package/build/screens/bug_report_screen.d.ts.map +1 -1
  37. package/build/screens/bug_report_screen.js +13 -10
  38. package/build/screens/bug_report_screen.js.map +1 -1
  39. package/build/screens/conversation_details_screen.d.ts.map +1 -1
  40. package/build/screens/conversation_details_screen.js +12 -11
  41. package/build/screens/conversation_details_screen.js.map +1 -1
  42. package/build/screens/conversation_filters/components/conversation_filters.js +3 -3
  43. package/build/screens/conversation_filters/components/conversation_filters.js.map +1 -1
  44. package/build/screens/conversation_filters/components/rows.js +1 -1
  45. package/build/screens/conversation_filters/components/rows.js.map +1 -1
  46. package/build/screens/conversation_filters_screen.js +2 -2
  47. package/build/screens/conversation_filters_screen.js.map +1 -1
  48. package/build/screens/conversation_screen.d.ts.map +1 -1
  49. package/build/screens/conversation_screen.js +3 -10
  50. package/build/screens/conversation_screen.js.map +1 -1
  51. package/build/screens/conversation_select_recipients/components/groups_recipient_row.js +1 -1
  52. package/build/screens/conversation_select_recipients/components/groups_recipient_row.js.map +1 -1
  53. package/build/screens/conversation_select_recipients/components/restricted_group_row.js +1 -1
  54. package/build/screens/conversation_select_recipients/components/restricted_group_row.js.map +1 -1
  55. package/build/screens/conversation_select_type_screen.d.ts.map +1 -1
  56. package/build/screens/conversation_select_type_screen.js +7 -4
  57. package/build/screens/conversation_select_type_screen.js.map +1 -1
  58. package/build/screens/conversations/components/list_header_component.js +3 -3
  59. package/build/screens/conversations/components/list_header_component.js.map +1 -1
  60. package/build/screens/message_report_screen.d.ts.map +1 -1
  61. package/build/screens/message_report_screen.js +18 -14
  62. package/build/screens/message_report_screen.js.map +1 -1
  63. package/build/screens/notification_settings_screen.d.ts.map +1 -1
  64. package/build/screens/notification_settings_screen.js +14 -0
  65. package/build/screens/notification_settings_screen.js.map +1 -1
  66. package/build/screens/settings_screen.js +3 -3
  67. package/build/screens/settings_screen.js.map +1 -1
  68. package/build/types/jolt_events/conversation_events.d.ts +2 -2
  69. package/build/types/jolt_events/conversation_events.d.ts.map +1 -1
  70. package/build/types/jolt_events/conversation_events.js.map +1 -1
  71. package/build/types/resources/conversation.d.ts +2 -2
  72. package/build/types/resources/conversation.d.ts.map +1 -1
  73. package/build/types/resources/conversation.js.map +1 -1
  74. package/build/types/resources/person.d.ts +0 -1
  75. package/build/types/resources/person.d.ts.map +1 -1
  76. package/build/types/resources/person.js.map +1 -1
  77. package/build/utils/conversation_safety_constants.d.ts +1 -1
  78. package/build/utils/conversation_safety_constants.d.ts.map +1 -1
  79. package/build/utils/conversation_safety_constants.js +1 -1
  80. package/build/utils/conversation_safety_constants.js.map +1 -1
  81. package/build/utils/request/conversation.d.ts.map +1 -1
  82. package/build/utils/request/conversation.js +0 -1
  83. package/build/utils/request/conversation.js.map +1 -1
  84. package/package.json +4 -4
  85. package/src/components/conversation/messages_disabled_banners.tsx +11 -3
  86. package/src/components/display/adult_requirement_notice.tsx +1 -1
  87. package/src/components/display/platform_modal_header_buttons.tsx +13 -254
  88. package/src/hooks/index.ts +1 -1
  89. package/src/hooks/use_conversation.ts +0 -1
  90. package/src/hooks/use_conversation_jolt_events.ts +3 -16
  91. package/src/hooks/use_current_person.ts +0 -1
  92. package/src/hooks/use_direct_messages_enabled.ts +23 -0
  93. package/src/hooks/use_features.ts +1 -0
  94. package/src/navigation/index.tsx +166 -149
  95. package/src/screens/bug_report_screen.tsx +15 -16
  96. package/src/screens/conversation_details_screen.tsx +17 -11
  97. package/src/screens/conversation_filters/components/conversation_filters.tsx +3 -3
  98. package/src/screens/conversation_filters/components/rows.tsx +2 -2
  99. package/src/screens/conversation_filters_screen.tsx +2 -2
  100. package/src/screens/conversation_screen.tsx +3 -11
  101. package/src/screens/conversation_select_recipients/components/groups_recipient_row.tsx +1 -1
  102. package/src/screens/conversation_select_recipients/components/restricted_group_row.tsx +2 -2
  103. package/src/screens/conversation_select_type_screen.tsx +7 -4
  104. package/src/screens/conversations/components/list_header_component.tsx +3 -3
  105. package/src/screens/message_report_screen.tsx +21 -20
  106. package/src/screens/notification_settings_screen.tsx +21 -1
  107. package/src/screens/settings_screen.tsx +3 -3
  108. package/src/types/jolt_events/conversation_events.ts +2 -2
  109. package/src/types/resources/conversation.ts +3 -2
  110. package/src/types/resources/person.ts +0 -1
  111. package/src/utils/conversation_safety_constants.ts +1 -1
  112. package/src/utils/request/conversation.ts +0 -1
  113. package/build/hooks/use_direct_messages_eligible.d.ts +0 -2
  114. package/build/hooks/use_direct_messages_eligible.d.ts.map +0 -1
  115. package/build/hooks/use_direct_messages_eligible.js +0 -9
  116. package/build/hooks/use_direct_messages_eligible.js.map +0 -1
  117. package/src/__tests__/hooks/use_direct_messages_eligible.test.tsx +0 -77
  118. package/src/hooks/use_direct_messages_eligible.ts +0 -11
@@ -1,19 +1,18 @@
1
+ import { HeaderBackButton } from '@react-navigation/elements'
1
2
  import { StaticParamList } from '@react-navigation/native'
2
3
  import {
3
4
  createNativeStackNavigator,
4
5
  NativeStackHeaderRightProps,
5
- NativeStackNavigationOptions,
6
6
  } from '@react-navigation/native-stack'
7
7
  import { CardStyleInterpolators } from '@react-navigation/stack'
8
8
  import React from 'react'
9
+ import { Platform } from 'react-native'
10
+ import { Icon } from '../components'
9
11
  import {
10
- composeOptions,
11
- createMinimalHeaderBackButton,
12
- withMinimalBack,
13
- withRightClose,
14
- withRightDone,
12
+ HeaderDoneButton,
13
+ HeaderTextButton,
15
14
  } from '../components/display/platform_modal_header_buttons'
16
- import { useDirectMessagesEligible, useQualifiedByAge } from '../hooks'
15
+ import { useDirectMessagesEnabled, useQualifiedByAge } from '../hooks'
17
16
  import {
18
17
  AttachmentActionsScreen,
19
18
  AttachmentActionsScreenOptions,
@@ -80,66 +79,69 @@ import {
80
79
  SystemMessagePeopleScreenOptions,
81
80
  } from '../screens/system_message_people_screen'
82
81
  import { TeamConversationScreen } from '../screens/team_conversation_screen'
83
- import { isLiquidGlassEnabled } from '../utils/liquid_glass'
84
82
  import { ScreenLayoutWithChatAccessGate } from './screenLayout'
85
83
 
86
- const globalScreenOptions: () => NativeStackNavigationOptions = () => ({
87
- headerBackButtonDisplayMode: 'minimal',
88
- ...(isLiquidGlassEnabled() ? { headerShadowVisible: false } : {}),
89
- })
84
+ const HEADER_BACK_BUTTON_LAYOUT_RESET_STYLES = {
85
+ marginLeft: Platform.select({ ios: -8, default: -3 }),
86
+ marginRight: Platform.select({ ios: 0, default: 30 }),
87
+ }
90
88
 
91
89
  export const NewConversationStack = createNativeStackNavigator({
92
90
  initialRouteName: 'ConversationNewEntry',
93
- screenOptions: globalScreenOptions,
91
+ screenOptions: {
92
+ headerBackButtonDisplayMode: 'minimal',
93
+ },
94
94
  screenLayout: ScreenLayoutWithChatAccessGate,
95
95
  screens: {
96
96
  ConversationNewEntry: {
97
97
  screen: ConversationNewEntryScreen,
98
- options: ({ navigation }) =>
99
- composeOptions(
100
- {
101
- title: 'New conversation',
102
- headerBackVisible: false,
103
- },
104
- withRightClose({ onPress: navigation.goBack })
98
+ options: ({ navigation }) => ({
99
+ title: 'New conversation',
100
+ headerRight: (props: NativeStackHeaderRightProps) => (
101
+ <HeaderTextButton {...props} onPress={navigation.goBack} title="Cancel" />
105
102
  ),
103
+ headerBackVisible: false,
104
+ }),
106
105
  },
107
106
  ConversationSelectGroupRecipients: {
108
107
  screen: ConversationSelectGroupRecipientsScreen,
109
- options: ({ navigation, route }) =>
110
- composeOptions(
111
- {
112
- title: 'New conversation',
113
- },
114
- withRightClose({
115
- onPress: () => navigation.popTo('Conversations', route.params),
116
- })
108
+ options: ({ navigation, route }) => ({
109
+ title: 'New conversation',
110
+ headerRight: (props: NativeStackHeaderRightProps) => (
111
+ <HeaderTextButton
112
+ {...props}
113
+ onPress={() => navigation.popTo('Conversations', route.params)}
114
+ title="Cancel"
115
+ />
117
116
  ),
117
+ }),
118
118
  },
119
119
  ConversationSelectTeamsILeadRecipients: {
120
120
  screen: ConversationSelectTeamsILeadRecipientsScreen,
121
- options: ({ navigation, route }) =>
122
- composeOptions(
123
- {
124
- title: 'New conversation',
125
- },
126
- withRightClose({
127
- onPress: () => navigation.popTo('Conversations', route.params),
128
- })
121
+ options: ({ navigation, route }) => ({
122
+ title: 'New conversation',
123
+ headerRight: (props: NativeStackHeaderRightProps) => (
124
+ <HeaderTextButton
125
+ {...props}
126
+ onPress={() => navigation.popTo('Conversations', route.params)}
127
+ title="Cancel"
128
+ />
129
129
  ),
130
+ }),
130
131
  },
131
132
  ConversationSelectDirectMessageRecipients: {
132
133
  screen: ConversationSelectDirectMessageRecipientsScreen,
133
- if: useDirectMessagesEligible,
134
- options: ({ navigation, route }) =>
135
- composeOptions(
136
- {
137
- title: 'New conversation',
138
- },
139
- withRightClose({
140
- onPress: () => navigation.popTo('Conversations', route.params),
141
- })
134
+ if: useDirectMessagesEnabled,
135
+ options: ({ navigation, route }) => ({
136
+ title: 'New conversation',
137
+ headerRight: (props: NativeStackHeaderRightProps) => (
138
+ <HeaderTextButton
139
+ {...props}
140
+ onPress={() => navigation.popTo('Conversations', route.params)}
141
+ title="Cancel"
142
+ />
142
143
  ),
144
+ }),
143
145
  },
144
146
  ConversationFilterRecipients: {
145
147
  screen: ConversationFilterRecipientsScreen,
@@ -147,20 +149,21 @@ export const NewConversationStack = createNativeStackNavigator({
147
149
  },
148
150
  ConversationNew: {
149
151
  screen: ConversationNewScreen,
150
- options: ({ navigation, route }) =>
151
- composeOptions(
152
- {
153
- title: 'New conversation',
154
- headerLeft: () => null,
155
- },
156
- withRightClose({
157
- onPress: () => {
152
+ options: ({ navigation, route }) => ({
153
+ title: 'New conversation',
154
+ headerLeft: () => null,
155
+ headerRight: (props: NativeStackHeaderRightProps) => (
156
+ <HeaderTextButton
157
+ {...props}
158
+ onPress={() => {
158
159
  const { chat_group_graph_id, group_source_app_name } =
159
160
  route.params as ConversationSelectRecipientsParams
160
161
  navigation.popTo('Conversations', { chat_group_graph_id, group_source_app_name })
161
- },
162
- })
162
+ }}
163
+ title="Cancel"
164
+ />
163
165
  ),
166
+ }),
164
167
  },
165
168
  AvatarPicker: {
166
169
  screen: AvatarPickerScreen,
@@ -170,19 +173,24 @@ export const NewConversationStack = createNativeStackNavigator({
170
173
  })
171
174
 
172
175
  export const ChatStack = createNativeStackNavigator({
173
- screenOptions: globalScreenOptions,
176
+ screenOptions: {
177
+ headerBackButtonDisplayMode: 'minimal',
178
+ },
174
179
  screenLayout: ScreenLayoutWithChatAccessGate,
175
180
  screens: {
176
181
  Conversations: {
177
182
  screen: ConversationsScreen,
178
- options: ({ route, navigation }) =>
179
- composeOptions(
180
- {
181
- headerTitle: (route.params as { title?: string })?.title ?? 'Chat',
182
- headerBackVisible: false,
183
- },
184
- withRightClose({ onPress: navigation.goBack })
183
+ options: ({ route, navigation }) => ({
184
+ headerTitle: (route.params as { title?: string })?.title ?? 'Chat',
185
+ headerBackVisible: false,
186
+ headerRight: (props: NativeStackHeaderRightProps) => (
187
+ <HeaderBackButton
188
+ backImage={() => <Icon name="general.x" size={18} color={props.tintColor} />}
189
+ onPress={navigation.goBack}
190
+ {...props}
191
+ />
185
192
  ),
193
+ }),
186
194
  },
187
195
  ConversationFilters: {
188
196
  screen: ConversationFiltersScreen,
@@ -190,48 +198,61 @@ export const ChatStack = createNativeStackNavigator({
190
198
  },
191
199
  Conversation: {
192
200
  screen: ConversationScreen,
193
- options: ({ route, navigation }) =>
194
- composeOptions(
195
- {
196
- headerTitle: (props: NativeStackHeaderRightProps) => {
197
- const { conversation_id, title, badge, deleted, muted } =
198
- route.params as ConversationRouteProps
201
+ options: ({ route, navigation }) => ({
202
+ headerTitle: (props: NativeStackHeaderRightProps) => {
203
+ const { conversation_id, title, badge, deleted, muted } =
204
+ route.params as ConversationRouteProps
199
205
 
200
- return (
201
- <ConversationScreenTitle
202
- conversation_id={conversation_id}
203
- badge={badge}
204
- deleted={deleted}
205
- muted={muted}
206
- {...props}
207
- >
208
- {title ?? 'Conversation'}
209
- </ConversationScreenTitle>
210
- )
211
- },
212
- headerLeft: createMinimalHeaderBackButton({
213
- onPress: () => {
214
- const params = route.params as ConversationRouteProps
215
- if ((params as ConversationFiltersParams)?.chat_group_graph_id) {
216
- // Ensure that conversations with a graph id pass them back to the conversation list
217
- const { chat_group_graph_id } = params
218
- navigation.popTo('Conversations', { chat_group_graph_id })
219
- } else {
220
- navigation.goBack()
221
- }
222
- },
223
- }),
224
- },
225
- withRightClose({ onPress: () => navigation.getParent()?.goBack() })
206
+ return (
207
+ <ConversationScreenTitle
208
+ conversation_id={conversation_id}
209
+ badge={badge}
210
+ deleted={deleted}
211
+ muted={muted}
212
+ {...props}
213
+ >
214
+ {title ?? 'Conversation'}
215
+ </ConversationScreenTitle>
216
+ )
217
+ },
218
+ headerRight: (props: NativeStackHeaderRightProps) => (
219
+ <HeaderBackButton
220
+ backImage={() => <Icon name="general.x" size={18} color={props.tintColor} />}
221
+ onPress={() => navigation.getParent()?.goBack()}
222
+ />
226
223
  ),
224
+ headerLeft: props => (
225
+ <HeaderBackButton
226
+ style={HEADER_BACK_BUTTON_LAYOUT_RESET_STYLES}
227
+ displayMode="minimal"
228
+ onPress={() => {
229
+ const params = route.params as ConversationRouteProps
230
+ if ((params as ConversationFiltersParams)?.chat_group_graph_id) {
231
+ // Ensure that conversations with a graph id pass them back to the conversation list
232
+ const { chat_group_graph_id } = params
233
+ navigation.popTo('Conversations', { chat_group_graph_id })
234
+ } else {
235
+ navigation.goBack()
236
+ }
237
+ }}
238
+ {...props}
239
+ />
240
+ ),
241
+ }),
227
242
  },
228
243
  ConversationReply: {
229
244
  screen: ConversationScreen,
230
- options: ({ route, navigation }) =>
231
- composeOptions(
232
- { title: (route.params as ConversationRouteProps)?.title ?? 'Reply' },
233
- withMinimalBack({ onPress: navigation.goBack })
245
+ options: ({ route, navigation }) => ({
246
+ title: (route.params as ConversationRouteProps)?.title ?? 'Reply',
247
+ headerLeft: props => (
248
+ <HeaderBackButton
249
+ style={HEADER_BACK_BUTTON_LAYOUT_RESET_STYLES}
250
+ displayMode="minimal"
251
+ onPress={() => navigation.goBack()}
252
+ {...props}
253
+ />
234
254
  ),
255
+ }),
235
256
  },
236
257
  TeamConversation: {
237
258
  screen: TeamConversationScreen,
@@ -244,14 +265,13 @@ export const ChatStack = createNativeStackNavigator({
244
265
  },
245
266
  ConversationDetails: {
246
267
  screen: ConversationDetailsScreen,
247
- options: ({ navigation }) =>
248
- composeOptions(
249
- {
250
- presentation: 'modal',
251
- title: 'Conversation details',
252
- },
253
- withRightDone({ onPress: navigation.goBack })
268
+ options: ({ navigation }) => ({
269
+ presentation: 'modal',
270
+ title: 'Conversation details',
271
+ headerRight: (props: NativeStackHeaderRightProps) => (
272
+ <HeaderTextButton {...props} onPress={navigation.goBack} title="Done" />
254
273
  ),
274
+ }),
255
275
  },
256
276
  AvatarPicker: {
257
277
  screen: AvatarPickerScreen,
@@ -259,43 +279,38 @@ export const ChatStack = createNativeStackNavigator({
259
279
  },
260
280
  ChatSettings: {
261
281
  screen: SettingsScreen,
262
- options: ({ navigation }) =>
263
- composeOptions({ title: 'Chat settings' }, withMinimalBack({ onPress: navigation.goBack })),
282
+ options: ({ navigation }) => ({
283
+ title: 'Chat settings',
284
+ headerBackVisible: false,
285
+ headerRight: (props: NativeStackHeaderRightProps) => (
286
+ <HeaderTextButton {...props} onPress={navigation.goBack} title="Done" />
287
+ ),
288
+ }),
264
289
  },
265
290
  NotificationSettings: {
266
291
  screen: NotificationSettingsScreen,
267
- options: ({ navigation }) =>
268
- navigation.getState().index === 0
269
- ? composeOptions(
270
- { title: 'Chat notifications' },
271
- withRightClose({ onPress: navigation.goBack })
272
- )
273
- : composeOptions(
274
- { title: 'Chat notifications' },
275
- withMinimalBack({ onPress: navigation.goBack })
276
- ),
292
+ options: ({ navigation }) => ({
293
+ title: 'Chat',
294
+ headerBackVisible: false,
295
+ headerRight: (props: NativeStackHeaderRightProps) => (
296
+ <HeaderTextButton {...props} onPress={navigation.goBack} title="Done" />
297
+ ),
298
+ }),
277
299
  },
278
300
  PreferredAppSelection: {
279
301
  screen: PreferredAppSelectionScreen,
280
- options: ({ navigation }) =>
281
- composeOptions({ title: 'Preferred app' }, withMinimalBack({ onPress: navigation.goBack })),
302
+ options: {
303
+ title: 'Preferred app',
304
+ },
282
305
  },
283
306
  GroupNotificationSettings: {
284
307
  screen: GroupNotificationSettingsScreen,
285
- options: ({ route, navigation }) => {
286
- const title = (route.params as { title?: string })?.title || 'Group Settings'
287
-
288
- // The dismiss button only shows when this is the entry screen (e.g.
289
- // deep links); deeper in the stack the back button covers dismissal.
290
- return navigation.getState().index === 0
291
- ? composeOptions(
292
- {
293
- title,
294
- },
295
- withRightClose({ onPress: navigation.goBack })
296
- )
297
- : composeOptions({ title }, withMinimalBack({ onPress: navigation.goBack }))
298
- },
308
+ options: ({ route, navigation }) => ({
309
+ title: (route.params as { title?: string })?.title || 'Group Settings',
310
+ headerRight: (props: NativeStackHeaderRightProps) => (
311
+ <HeaderDoneButton {...props} navigation={navigation} />
312
+ ),
313
+ }),
299
314
  },
300
315
  GroupNotificationLevelSelect: {
301
316
  screen: GroupNotificationLevelSelectScreen,
@@ -316,14 +331,17 @@ export const ChatStack = createNativeStackNavigator({
316
331
  GroupConversationNew: {
317
332
  screen: ConversationNewScreen,
318
333
  if: useQualifiedByAge,
319
- options: ({ navigation }) =>
320
- composeOptions(
321
- {
322
- title: 'New conversation',
323
- headerLeft: () => null,
324
- },
325
- withRightClose({ onPress: () => navigation.getParent()?.goBack() })
334
+ options: ({ navigation }) => ({
335
+ title: 'New conversation',
336
+ headerLeft: () => null,
337
+ headerRight: props => (
338
+ <HeaderTextButton
339
+ {...props}
340
+ onPress={() => navigation.getParent()?.goBack()}
341
+ title="Cancel"
342
+ />
326
343
  ),
344
+ }),
327
345
  },
328
346
  SendGiphy: {
329
347
  screen: SendGiphyScreen,
@@ -364,15 +382,14 @@ export const ChatStack = createNativeStackNavigator({
364
382
  },
365
383
  GetHelp: {
366
384
  screen: GetHelpScreen,
367
- options: ({ navigation }) =>
368
- composeOptions(
369
- {
370
- headerTitle: 'Get help',
371
- headerBackVisible: false,
372
- presentation: 'modal',
373
- },
374
- withRightClose({ onPress: navigation.goBack })
385
+ options: ({ navigation }) => ({
386
+ headerTitle: 'Get help',
387
+ headerBackVisible: false,
388
+ presentation: 'modal',
389
+ headerRight: props => (
390
+ <HeaderTextButton {...props} onPress={navigation.goBack} title="Close" />
375
391
  ),
392
+ }),
376
393
  },
377
394
  NotFound: {
378
395
  screen: NotFound,
@@ -4,7 +4,7 @@ import type {
4
4
  NativeStackScreenProps,
5
5
  } from '@react-navigation/native-stack'
6
6
  import { startsWith } from 'lodash'
7
- import React, { useCallback, useState } from 'react'
7
+ import React, { useCallback, useLayoutEffect, useState } from 'react'
8
8
  import {
9
9
  View,
10
10
  StyleSheet,
@@ -25,10 +25,8 @@ import {
25
25
  KeyboardView,
26
26
  } from '../components'
27
27
  import {
28
- composeOptions,
29
28
  HeaderDismissButton,
30
- useHeaderRight,
31
- withLeftClose,
29
+ HeaderTextButton,
32
30
  } from '../components/display/platform_modal_header_buttons'
33
31
  import { VideoAttachmentPreview } from '../components/display/video_attachment_preview'
34
32
  import { DefaultLoading } from '../components/page/loading'
@@ -57,11 +55,11 @@ enum BUG_TYPE_OPTIONS {
57
55
 
58
56
  export const BugReportScreenOptions = ({
59
57
  navigation,
60
- }: NativeStackScreenProps<any>): NativeStackNavigationOptions =>
61
- composeOptions(
62
- { presentation: 'modal', title: 'Report a bug' },
63
- withLeftClose({ onPress: () => navigation.goBack() })
64
- )
58
+ }: NativeStackScreenProps<any>): NativeStackNavigationOptions => ({
59
+ presentation: 'modal',
60
+ title: 'Report a bug',
61
+ headerLeft: () => <HeaderDismissButton title="Cancel" onPress={() => navigation.goBack()} />,
62
+ })
65
63
 
66
64
  interface Attachment {
67
65
  id: string
@@ -158,13 +156,14 @@ export function BugReportScreen() {
158
156
  return ImagePicker.openImageLibraryAsync().then(result => uploadImagePickerResult(result))
159
157
  }
160
158
 
161
- useHeaderRight({
162
- icon: 'general.message',
163
- accessibilityLabel: 'Submit',
164
- variant: 'fill',
165
- onPress: handleSubmit,
166
- disabled: !formValid,
167
- })
159
+ useLayoutEffect(() => {
160
+ navigation.setOptions({
161
+ // eslint-disable-next-line react/no-unstable-nested-components
162
+ headerRight: () => (
163
+ <HeaderTextButton title="Submit" onPress={handleSubmit} disabled={!formValid} />
164
+ ),
165
+ })
166
+ }, [formValid, handleSubmit, navigation])
168
167
 
169
168
  if (status === 'pending') {
170
169
  return (
@@ -38,7 +38,7 @@ import {
38
38
  type TextStyle,
39
39
  } from '../components'
40
40
  import { ConversationAvatar } from '../components/display/conversation_avatar'
41
- import { useHeaderRight } from '../components/display/platform_modal_header_buttons'
41
+ import { HeaderTextButton } from '../components/display/platform_modal_header_buttons'
42
42
  import { ButtonAppearanceUnion } from '../components/display/utils/button_colors'
43
43
  import { useSuspensePaginator, useTheme } from '../hooks'
44
44
  import {
@@ -222,18 +222,24 @@ export function ConversationDetailsScreen({ route }: ConversationDetailsScreenPr
222
222
  [name, productName, resourceType, styles.headerTitleBadge, styles.headerTitleContainer]
223
223
  )
224
224
 
225
- useHeaderRight({
226
- icon: 'general.check',
227
- accessibilityLabel: 'Done',
228
- onPress: () => {
229
- saveTitle({ title: trimmedTitle || conversation.title })
230
- navigation.goBack()
231
- },
232
- })
225
+ const HeaderRight = useCallback(() => {
226
+ return (
227
+ <HeaderTextButton
228
+ onPress={() => {
229
+ saveTitle({ title: trimmedTitle || conversation.title })
230
+ navigation.goBack()
231
+ }}
232
+ title="Done"
233
+ />
234
+ )
235
+ }, [conversation.title, navigation, saveTitle, trimmedTitle])
233
236
 
234
237
  useEffect(() => {
235
- navigation.setOptions({ headerTitle: HeaderTitle })
236
- }, [HeaderTitle, navigation])
238
+ navigation.setOptions({
239
+ headerRight: HeaderRight,
240
+ headerTitle: HeaderTitle,
241
+ })
242
+ }, [HeaderRight, HeaderTitle, navigation])
237
243
 
238
244
  const listData = [
239
245
  {
@@ -4,7 +4,7 @@ import { FlatList } from 'react-native-gesture-handler'
4
4
  import { Heading } from '../../../components'
5
5
  import {
6
6
  useAtFontScaleBreakpoint,
7
- useDirectMessagesEligible,
7
+ useDirectMessagesEnabled,
8
8
  useHasDirectMessages,
9
9
  useTheme,
10
10
  } from '../../../hooks'
@@ -59,9 +59,9 @@ export const ConversationFilters = () => {
59
59
  const { setScrollOffset, params } = useContext(FilterContext)
60
60
  const { chat_group_graph_id, group_source_app_name = '', show_direct_messages } = params
61
61
 
62
- const directMessagesEligible = useDirectMessagesEligible()
62
+ const directMessagesEnabled = useDirectMessagesEnabled()
63
63
  const hasDirectMessages = useHasDirectMessages()
64
- const canFilterByDMs = directMessagesEligible && hasDirectMessages
64
+ const canFilterByDMs = directMessagesEnabled && hasDirectMessages
65
65
 
66
66
  const activeFilter: FilterTypes = useMemo(() => {
67
67
  if (chat_group_graph_id) {
@@ -59,9 +59,9 @@ export const GroupRow = ({ group, isActive }: GroupRowProps) => {
59
59
 
60
60
  return (
61
61
  <PressableRow onPress={handleFilterByGroup} isActive={isActive}>
62
- {headerImage?.medium && (
62
+ {headerImage?.thumbnail && (
63
63
  <Image
64
- source={{ uri: headerImage?.medium }}
64
+ source={{ uri: headerImage?.thumbnail }}
65
65
  resizeMode="cover"
66
66
  style={styles.rowImage}
67
67
  alt=""
@@ -1,5 +1,5 @@
1
1
  import { useHeaderHeight } from '@react-navigation/elements'
2
- import { RouteProp, useRoute } from '@react-navigation/native'
2
+ import { createComponentForStaticNavigation, RouteProp, useRoute } from '@react-navigation/native'
3
3
  import { createNativeStackNavigator } from '@react-navigation/native-stack'
4
4
  import React, { useCallback } from 'react'
5
5
  import { LayoutChangeEvent, Platform, StyleSheet, useWindowDimensions, View } from 'react-native'
@@ -58,7 +58,7 @@ const FilterNavigator = createNativeStackNavigator<ConversationFilterStackParamL
58
58
  },
59
59
  })
60
60
 
61
- const Filters = FilterNavigator.getComponent()
61
+ const Filters = createComponentForStaticNavigation(FilterNavigator, 'Filters')
62
62
 
63
63
  export const ConversationFiltersScreen = (_props: ConversationFiltersScreenProps) => {
64
64
  const styles = useStyles()
@@ -9,7 +9,7 @@ import {
9
9
  useRoute,
10
10
  } from '@react-navigation/native'
11
11
  import React, { useCallback, useEffect, useRef, useState } from 'react'
12
- import { FlatList, Platform, StyleSheet, useWindowDimensions, View } from 'react-native'
12
+ import { FlatList, Platform, StyleSheet, View } from 'react-native'
13
13
  import { useSafeAreaInsets } from 'react-native-safe-area-context'
14
14
  import { Badge, Icon, Text } from '../components'
15
15
  import { ConversationStartBanner } from '../components/conversation/conversation_start_banner'
@@ -25,7 +25,6 @@ import { ReplyShadowMessage } from '../components/conversation/reply_shadow_mess
25
25
  import { SystemMessage } from '../components/conversation/system_message'
26
26
  import { TypingIndicator } from '../components/conversation/typing_indicator'
27
27
  import { KeyboardView } from '../components/display/keyboard_view'
28
- import { useHeaderSlotReserve } from '../components/display/platform_modal_header_buttons'
29
28
  import BlankState from '../components/primitive/blank_state_primitive'
30
29
  import { ConversationContextProvider } from '../contexts/conversation_context'
31
30
  import { useTheme } from '../hooks'
@@ -46,7 +45,6 @@ import { ConversationBadgeResource } from '../types/resources/conversation_badge
46
45
  import { MessageResource } from '../types/resources/message'
47
46
  import { getRelativeDateStatus } from '../utils/date'
48
47
  import { groupMessages, type DateSeparator } from '../utils/group_messages'
49
- import { isLiquidGlassEnabled } from '../utils/liquid_glass'
50
48
  import { CONVERSATION_MESSAGE_LIST_PADDING_HORIZONTAL } from '../utils/styles'
51
49
  import { isSystemMessage } from '../utils/system_messages'
52
50
 
@@ -259,7 +257,7 @@ function ConversationBottomBar({
259
257
  if (conversation.disabled)
260
258
  return (
261
259
  <ConversationDisabledBanner
262
- message={conversation.disabledMessage ?? null}
260
+ disabledReason={conversation.disabledReason}
263
261
  messageLink={messageLink}
264
262
  />
265
263
  )
@@ -376,17 +374,11 @@ export const ConversationScreenTitle = ({
376
374
  }
377
375
 
378
376
  const usePressableHeaderStyle = () => {
379
- const { width } = useWindowDimensions()
380
- const slotReserve = useHeaderSlotReserve()
381
- const headerContainerStyle = isLiquidGlassEnabled()
382
- ? { maxWidth: width - slotReserve * 2 }
383
- : { marginRight: Platform.select({ default: 20, android: 16 }) }
384
-
385
377
  return StyleSheet.create({
386
378
  container: {
387
379
  alignItems: Platform.select({ android: 'flex-start', default: 'center' }),
380
+ marginRight: Platform.select({ ios: 20, default: 16 }),
388
381
  flex: 1,
389
- ...headerContainerStyle,
390
382
  },
391
383
  titleWrapper: {
392
384
  alignItems: 'center',
@@ -12,7 +12,7 @@ export const GroupsRecipientRow = ({ group, onPress }: GroupsRecipientRowProps)
12
12
 
13
13
  return (
14
14
  <RecipientLinkRow
15
- imageUri={group.headerImage?.medium}
15
+ imageUri={group.headerImage?.thumbnail}
16
16
  title={group.name}
17
17
  subtitle={`${group.membershipsCount} members`}
18
18
  onPress={() => onPress(group)}
@@ -29,9 +29,9 @@ export const RestrictedGroupRow = ({ group }: RestrictedGroupRowProps) => {
29
29
  accessibilityLabel={`${group.name} — ${reasonText(group.canCreateConversationReasonCode)}`}
30
30
  >
31
31
  <View style={styles.innerContainer}>
32
- {group.headerImage?.medium && (
32
+ {group.headerImage?.thumbnail && (
33
33
  <Image
34
- source={{ uri: group.headerImage.medium }}
34
+ source={{ uri: group.headerImage.thumbnail }}
35
35
  resizeMode="cover"
36
36
  style={styles.image}
37
37
  alt=""