@planningcenter/chat-react-native 3.17.2 → 3.17.3-qa-456.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/message.d.ts.map +1 -1
- package/build/components/conversation/message.js +19 -16
- package/build/components/conversation/message.js.map +1 -1
- package/build/components/conversation/reply_connectors.d.ts.map +1 -1
- package/build/components/conversation/reply_connectors.js +55 -32
- package/build/components/conversation/reply_connectors.js.map +1 -1
- package/build/components/conversation/reply_shadow_message.js +9 -5
- package/build/components/conversation/reply_shadow_message.js.map +1 -1
- package/build/components/conversations/conversations.d.ts.map +1 -1
- package/build/components/conversations/conversations.js +2 -3
- package/build/components/conversations/conversations.js.map +1 -1
- package/build/screens/conversation_details_screen.d.ts.map +1 -1
- package/build/screens/conversation_details_screen.js +3 -4
- package/build/screens/conversation_details_screen.js.map +1 -1
- package/build/screens/conversation_new/components/form_list.d.ts +2 -2
- package/build/screens/conversation_new/components/form_list.d.ts.map +1 -1
- package/build/screens/conversation_new/components/form_list.js +2 -3
- package/build/screens/conversation_new/components/form_list.js.map +1 -1
- package/build/screens/conversation_screen.d.ts.map +1 -1
- package/build/screens/conversation_screen.js +1 -1
- package/build/screens/conversation_screen.js.map +1 -1
- package/build/screens/conversation_select_recipients/conversation_select_group_recipients_screen.d.ts.map +1 -1
- package/build/screens/conversation_select_recipients/conversation_select_group_recipients_screen.js +2 -3
- package/build/screens/conversation_select_recipients/conversation_select_group_recipients_screen.js.map +1 -1
- package/build/screens/conversation_select_recipients/conversation_select_teams_i_lead_recipients_screen.d.ts.map +1 -1
- package/build/screens/conversation_select_recipients/conversation_select_teams_i_lead_recipients_screen.js +2 -3
- package/build/screens/conversation_select_recipients/conversation_select_teams_i_lead_recipients_screen.js.map +1 -1
- package/package.json +2 -3
- package/src/components/conversation/message.tsx +25 -19
- package/src/components/conversation/reply_connectors.tsx +90 -32
- package/src/components/conversation/reply_shadow_message.tsx +10 -4
- package/src/components/conversations/conversations.tsx +7 -9
- package/src/screens/conversation_details_screen.tsx +3 -4
- package/src/screens/conversation_new/components/form_list.tsx +3 -5
- package/src/screens/conversation_screen.tsx +1 -2
- package/src/screens/conversation_select_recipients/conversation_select_group_recipients_screen.tsx +2 -4
- package/src/screens/conversation_select_recipients/conversation_select_teams_i_lead_recipients_screen.tsx +2 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@planningcenter/chat-react-native",
|
|
3
|
-
"version": "3.17.
|
|
3
|
+
"version": "3.17.3-qa-456.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
@@ -29,7 +29,6 @@
|
|
|
29
29
|
"@react-navigation/elements": "*",
|
|
30
30
|
"@react-navigation/native": ">=7.0.0",
|
|
31
31
|
"@react-navigation/native-stack": ">=7.0.0",
|
|
32
|
-
"@shopify/flash-list": "<2.0.0",
|
|
33
32
|
"@tanstack/react-query": "^5.0.0",
|
|
34
33
|
"color": "^3.1.2",
|
|
35
34
|
"lodash": "*",
|
|
@@ -59,5 +58,5 @@
|
|
|
59
58
|
"react-native-url-polyfill": "^2.0.0",
|
|
60
59
|
"typescript": "<5.6.0"
|
|
61
60
|
},
|
|
62
|
-
"gitHead": "
|
|
61
|
+
"gitHead": "d509a7a88fb84b1517a4b0dc70be90dfd316a63a"
|
|
63
62
|
}
|
|
@@ -66,10 +66,31 @@ export function Message({
|
|
|
66
66
|
enabled: !!message.replyRootId,
|
|
67
67
|
})
|
|
68
68
|
|
|
69
|
+
const metaProps = {
|
|
70
|
+
authorName: message.author.name,
|
|
71
|
+
createdAt: message.createdAt,
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const renderAuthor = (!message.mine && message.renderAuthor) || false
|
|
75
|
+
const showReplyCountButton =
|
|
76
|
+
!inReplyScreen && message.replyRootId === message.id && REPLIES_FEATURE_ENABLED
|
|
77
|
+
const isReplyRootMessage = message.replyRootId === message.id
|
|
78
|
+
const isDeletedReplyRootMessage = isReplyRootMessage && !!message.deletedAt
|
|
79
|
+
|
|
80
|
+
const messageText = isDeletedReplyRootMessage ? 'Message deleted' : text
|
|
81
|
+
const replyCountText = pluralize(message.replyCount, 'reply')
|
|
82
|
+
const messagePendingLabel = isPersisted ? 'Saving' : 'Sending'
|
|
69
83
|
const replyRootAuthorName = message.replyRootId
|
|
70
84
|
? replyRootMessage?.author.name
|
|
71
85
|
: message.author.name
|
|
72
86
|
|
|
87
|
+
const messageBottomMargin =
|
|
88
|
+
message.lastInGroup || message.nextIsReplyShadowMessage
|
|
89
|
+
? 16
|
|
90
|
+
: hasReactions || showMessageMeta || showReplyCountButton
|
|
91
|
+
? 8
|
|
92
|
+
: 4
|
|
93
|
+
|
|
73
94
|
useEffect(() => {
|
|
74
95
|
if (pending) {
|
|
75
96
|
const timer = setTimeout(() => {
|
|
@@ -135,23 +156,6 @@ export function Message({
|
|
|
135
156
|
})
|
|
136
157
|
}
|
|
137
158
|
|
|
138
|
-
const metaProps = {
|
|
139
|
-
authorName: message.author.name,
|
|
140
|
-
createdAt: message.createdAt,
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
const renderAuthor = (!message.mine && message.renderAuthor) || false
|
|
144
|
-
const messagePendingLabel = isPersisted ? 'Saving' : 'Sending'
|
|
145
|
-
const showReplyCountButton =
|
|
146
|
-
!inReplyScreen && message.replyRootId === message.id && REPLIES_FEATURE_ENABLED
|
|
147
|
-
const replyCountText = pluralize(message.replyCount, 'reply')
|
|
148
|
-
const messageBottomMargin =
|
|
149
|
-
message.lastInGroup || message.nextIsReplyShadowMessage
|
|
150
|
-
? 16
|
|
151
|
-
: hasReactions || showMessageMeta || showReplyCountButton
|
|
152
|
-
? 8
|
|
153
|
-
: 4
|
|
154
|
-
|
|
155
159
|
return (
|
|
156
160
|
<Pressable
|
|
157
161
|
onLongPress={handleMessageLongPress}
|
|
@@ -171,6 +175,8 @@ export function Message({
|
|
|
171
175
|
style={styles.avatar}
|
|
172
176
|
maxFontSizeMultiplier={1}
|
|
173
177
|
minFontSizeMultiplier={1}
|
|
178
|
+
fallbackIconName={isDeletedReplyRootMessage ? 'publishing.trash' : 'general.person'}
|
|
179
|
+
showFallback={isDeletedReplyRootMessage}
|
|
174
180
|
/>
|
|
175
181
|
) : (
|
|
176
182
|
<View style={styles.avatarPlaceholder} />
|
|
@@ -196,9 +202,9 @@ export function Message({
|
|
|
196
202
|
onMessageLongPress={handleMessageLongPress}
|
|
197
203
|
/>
|
|
198
204
|
</ErrorBoundary>
|
|
199
|
-
{
|
|
205
|
+
{messageText && (
|
|
200
206
|
<View style={styles.messageText}>
|
|
201
|
-
<MessageMarkdown text={
|
|
207
|
+
<MessageMarkdown text={messageText} />
|
|
202
208
|
</View>
|
|
203
209
|
)}
|
|
204
210
|
</View>
|
|
@@ -94,7 +94,11 @@ export function MyReplyConnector({ message, messageBubbleHeight }: ReplyConnecto
|
|
|
94
94
|
|
|
95
95
|
const spacerStyle = nextRendersAuthor ? styles.myReplyConnectorSpacer : null
|
|
96
96
|
|
|
97
|
-
return
|
|
97
|
+
return (
|
|
98
|
+
<EnforceLeftPositionForMyReplyConnector>
|
|
99
|
+
<View style={[styles.myReplyConnectorContainer, spacerStyle]}>{ConnectorComponent}</View>
|
|
100
|
+
</EnforceLeftPositionForMyReplyConnector>
|
|
101
|
+
)
|
|
98
102
|
}
|
|
99
103
|
|
|
100
104
|
function VerticalLineConnector({ style }: { style?: ViewStyle }) {
|
|
@@ -104,22 +108,74 @@ function VerticalLineConnector({ style }: { style?: ViewStyle }) {
|
|
|
104
108
|
|
|
105
109
|
function LongHeadCurveConnector({ height, style }: { height: number; style?: ViewStyle }) {
|
|
106
110
|
const styles = useStyles()
|
|
107
|
-
|
|
111
|
+
const { colors } = useTheme()
|
|
112
|
+
|
|
113
|
+
return (
|
|
114
|
+
<View style={[styles.longHeadCurveConnector, { marginTop: height }, style]}>
|
|
115
|
+
<Svg width={MY_REPLY_CONNECTOR_WIDTH} height={18} fill="none">
|
|
116
|
+
<Path
|
|
117
|
+
d="M 2 18 L 2 16 A 14 14 0 0 1 16 2 L 38 2"
|
|
118
|
+
stroke={colors.borderColorDefaultBase}
|
|
119
|
+
strokeWidth={CONNECTOR_BORDER_WIDTH}
|
|
120
|
+
/>
|
|
121
|
+
</Svg>
|
|
122
|
+
<View style={styles.svgConnnectorVerticalLineTail} />
|
|
123
|
+
</View>
|
|
124
|
+
)
|
|
108
125
|
}
|
|
109
126
|
|
|
110
127
|
function LongTailCurveConnector({ height, style }: { height: number; style?: ViewStyle }) {
|
|
111
128
|
const styles = useStyles()
|
|
112
|
-
|
|
129
|
+
const { colors } = useTheme()
|
|
130
|
+
|
|
131
|
+
return (
|
|
132
|
+
<View style={[{ height }, style]}>
|
|
133
|
+
<View style={styles.svgConnnectorVerticalLineHead} />
|
|
134
|
+
<Svg width={MY_REPLY_CONNECTOR_WIDTH} height={18} fill="none">
|
|
135
|
+
<Path
|
|
136
|
+
d="M 2 0 L 2 2 A 14 14 0 0 0 16 16 L 38 16"
|
|
137
|
+
stroke={colors.borderColorDefaultBase}
|
|
138
|
+
strokeWidth={CONNECTOR_BORDER_WIDTH}
|
|
139
|
+
/>
|
|
140
|
+
</Svg>
|
|
141
|
+
</View>
|
|
142
|
+
)
|
|
113
143
|
}
|
|
114
144
|
|
|
115
145
|
function ShortHeadCurveConnector({ height }: { height: number }) {
|
|
116
146
|
const styles = useStyles()
|
|
117
|
-
|
|
147
|
+
const { colors } = useTheme()
|
|
148
|
+
|
|
149
|
+
return (
|
|
150
|
+
<View style={[styles.shortHeadCurveConnector, { marginTop: height }]}>
|
|
151
|
+
<Svg width={20} height={18} fill="none">
|
|
152
|
+
<Path
|
|
153
|
+
d="M 2 18 L 2 16 A 14 14 0 0 1 16 2 L 20 2"
|
|
154
|
+
stroke={colors.borderColorDefaultBase}
|
|
155
|
+
strokeWidth={CONNECTOR_BORDER_WIDTH}
|
|
156
|
+
/>
|
|
157
|
+
</Svg>
|
|
158
|
+
<View style={styles.svgConnnectorVerticalLineTail} />
|
|
159
|
+
</View>
|
|
160
|
+
)
|
|
118
161
|
}
|
|
119
162
|
|
|
120
163
|
function ShortTailCurveConnector({ height }: { height: number }) {
|
|
121
164
|
const styles = useStyles()
|
|
122
|
-
|
|
165
|
+
const { colors } = useTheme()
|
|
166
|
+
|
|
167
|
+
return (
|
|
168
|
+
<View style={{ height }}>
|
|
169
|
+
<View style={styles.svgConnnectorVerticalLineHead} />
|
|
170
|
+
<Svg width={20} height={18} fill="none">
|
|
171
|
+
<Path
|
|
172
|
+
d="M 2 0 L 2 2 A 14 14 0 0 0 16 16 L 20 16"
|
|
173
|
+
stroke={colors.borderColorDefaultBase}
|
|
174
|
+
strokeWidth={CONNECTOR_BORDER_WIDTH}
|
|
175
|
+
/>
|
|
176
|
+
</Svg>
|
|
177
|
+
</View>
|
|
178
|
+
)
|
|
123
179
|
}
|
|
124
180
|
|
|
125
181
|
function SwirlConnector({ style, height }: { style?: ViewStyle; height: number }) {
|
|
@@ -129,7 +185,7 @@ function SwirlConnector({ style, height }: { style?: ViewStyle; height: number }
|
|
|
129
185
|
return (
|
|
130
186
|
<View style={[styles.swirlConnectorContainer, style]}>
|
|
131
187
|
<View style={{ height }}>
|
|
132
|
-
<View style={styles.
|
|
188
|
+
<View style={styles.svgConnnectorVerticalLineHead} />
|
|
133
189
|
<Svg width={27} height={34} fill="none">
|
|
134
190
|
<Path
|
|
135
191
|
stroke={colors.borderColorDefaultBase}
|
|
@@ -137,9 +193,25 @@ function SwirlConnector({ style, height }: { style?: ViewStyle; height: number }
|
|
|
137
193
|
d="M2.07 34c0-6.142 1.201-12.283 3.343-17m0 0c2.305-5.075 5.699-8.5 9.857-8.5 4.86 0 8.8 3.806 8.8 8.5s-3.94 8.5-8.8 8.5c-4.158 0-7.552-3.425-9.857-8.5zm0 0C3.271 12.283 2.07 6.142 2.07 0"
|
|
138
194
|
/>
|
|
139
195
|
</Svg>
|
|
140
|
-
<View style={styles.
|
|
196
|
+
<View style={styles.svgConnnectorVerticalLineTail} />
|
|
141
197
|
</View>
|
|
142
|
-
<View style={styles.
|
|
198
|
+
<View style={styles.svgConnnectorVerticalLineTail} />
|
|
199
|
+
</View>
|
|
200
|
+
)
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// TODO: Remove when Services React Native bumps to React Native 0.74 or higher.
|
|
204
|
+
// This fixes a React Native bug where using `flexDirection: 'row-reverse'` also switches the `left`/`right` absolute positioning values.
|
|
205
|
+
// The wrapper ensures the MyReplyConnector is always positioned to the left of the message bubble on older versions of React Native.
|
|
206
|
+
// Long term fix is described here: https://reactnative.dev/blog/2024/04/22/release-0.74#new-layout-behaviors
|
|
207
|
+
function EnforceLeftPositionForMyReplyConnector({ children }: { children: React.ReactNode }) {
|
|
208
|
+
const styles = useStyles()
|
|
209
|
+
return (
|
|
210
|
+
<View
|
|
211
|
+
style={styles.resetPosition}
|
|
212
|
+
pointerEvents="none" // ensures wrapper does not block press events
|
|
213
|
+
>
|
|
214
|
+
{children}
|
|
143
215
|
</View>
|
|
144
216
|
)
|
|
145
217
|
}
|
|
@@ -177,47 +249,33 @@ const useStyles = () => {
|
|
|
177
249
|
borderLeftColor: borderColor,
|
|
178
250
|
},
|
|
179
251
|
longHeadCurveConnector: {
|
|
180
|
-
width: MY_REPLY_CONNECTOR_WIDTH,
|
|
181
|
-
borderColor: borderColor,
|
|
182
|
-
borderLeftWidth: CONNECTOR_BORDER_WIDTH,
|
|
183
|
-
borderTopWidth: CONNECTOR_BORDER_WIDTH,
|
|
184
|
-
borderTopLeftRadius: 16,
|
|
185
252
|
flex: 1,
|
|
186
253
|
},
|
|
187
|
-
longTailCurveConnector: {
|
|
188
|
-
width: MY_REPLY_CONNECTOR_WIDTH,
|
|
189
|
-
borderColor: borderColor,
|
|
190
|
-
borderLeftWidth: CONNECTOR_BORDER_WIDTH,
|
|
191
|
-
borderBottomWidth: CONNECTOR_BORDER_WIDTH,
|
|
192
|
-
borderBottomLeftRadius: 16,
|
|
193
|
-
},
|
|
194
254
|
shortHeadCurveConnector: {
|
|
195
|
-
borderColor: borderColor,
|
|
196
|
-
borderLeftWidth: CONNECTOR_BORDER_WIDTH,
|
|
197
|
-
borderTopWidth: CONNECTOR_BORDER_WIDTH,
|
|
198
|
-
borderTopLeftRadius: 16,
|
|
199
255
|
flex: 1,
|
|
200
256
|
},
|
|
201
|
-
shortTailCurveConnector: {
|
|
202
|
-
borderColor: borderColor,
|
|
203
|
-
borderLeftWidth: CONNECTOR_BORDER_WIDTH,
|
|
204
|
-
borderBottomWidth: CONNECTOR_BORDER_WIDTH,
|
|
205
|
-
borderBottomLeftRadius: 16,
|
|
206
|
-
},
|
|
207
257
|
swirlConnectorContainer: {
|
|
208
258
|
flex: 1,
|
|
209
259
|
},
|
|
210
|
-
|
|
260
|
+
svgConnnectorVerticalLineHead: {
|
|
211
261
|
backgroundColor: borderColor,
|
|
212
262
|
width: CONNECTOR_BORDER_WIDTH,
|
|
213
263
|
flex: 1,
|
|
214
264
|
marginBottom: -1, // Ensures there is no gap between the vertical line and the swirl connector
|
|
215
265
|
},
|
|
216
|
-
|
|
266
|
+
svgConnnectorVerticalLineTail: {
|
|
217
267
|
backgroundColor: borderColor,
|
|
218
268
|
width: CONNECTOR_BORDER_WIDTH,
|
|
219
269
|
flex: 1,
|
|
220
270
|
marginTop: -1, // Ensures there is no gap between the vertical line and the swirl connector
|
|
221
271
|
},
|
|
272
|
+
// TODO: Remove when Services React Native bumps to React Native 0.74 or higher.
|
|
273
|
+
resetPosition: {
|
|
274
|
+
position: 'absolute',
|
|
275
|
+
left: 0,
|
|
276
|
+
right: 0,
|
|
277
|
+
top: 0,
|
|
278
|
+
bottom: 0,
|
|
279
|
+
},
|
|
222
280
|
})
|
|
223
281
|
}
|
|
@@ -45,7 +45,7 @@ export function ReplyShadowMessage({
|
|
|
45
45
|
|
|
46
46
|
if (inReplyScreen) return null
|
|
47
47
|
if (isLoading) return <ShadowMessageFallback text="Loading..." />
|
|
48
|
-
if (isError || !message) return <ShadowMessageFallback text="Message
|
|
48
|
+
if (isError || !message) return <ShadowMessageFallback text="Message deleted" />
|
|
49
49
|
|
|
50
50
|
const enrichedMessage = {
|
|
51
51
|
...message,
|
|
@@ -61,7 +61,7 @@ interface ShadowMessageContentProps extends MessageResource {
|
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
function ShadowMessageContent({ conversation_id, ...message }: ShadowMessageContentProps) {
|
|
64
|
-
const { text } = message
|
|
64
|
+
const { text, deletedAt } = message
|
|
65
65
|
const styles = useStyles(message)
|
|
66
66
|
const { colors } = useTheme()
|
|
67
67
|
const navigation = useNavigation()
|
|
@@ -71,6 +71,8 @@ function ShadowMessageContent({ conversation_id, ...message }: ShadowMessageCont
|
|
|
71
71
|
useAnimatedMessageBackgroundColor()
|
|
72
72
|
const scalableNumberOfLines = useScalableNumberOfLines(2)
|
|
73
73
|
const replyCountText = pluralize(message.replyCount, 'reply')
|
|
74
|
+
const isDeleted = !!deletedAt
|
|
75
|
+
const messageText = isDeleted ? 'Message deleted' : text
|
|
74
76
|
|
|
75
77
|
const handleNavigateToReplies = () => {
|
|
76
78
|
navigation.navigate('ConversationReply', {
|
|
@@ -92,12 +94,14 @@ function ShadowMessageContent({ conversation_id, ...message }: ShadowMessageCont
|
|
|
92
94
|
<Animated.View style={[styles.message, animatedBackgroundColor]}>
|
|
93
95
|
{!message.mine && (
|
|
94
96
|
<View>
|
|
95
|
-
<View style={styles.avatarWrapper}>
|
|
97
|
+
<View style={[styles.avatarWrapper, !isDeleted && styles.avatarOpacity]}>
|
|
96
98
|
<Avatar
|
|
97
99
|
size="xs"
|
|
98
100
|
sourceUri={message.author.avatar}
|
|
99
101
|
style={styles.avatar}
|
|
100
102
|
maxFontSizeMultiplier={1}
|
|
103
|
+
fallbackIconName={isDeleted ? 'publishing.trash' : 'general.person'}
|
|
104
|
+
showFallback={isDeleted}
|
|
101
105
|
/>
|
|
102
106
|
</View>
|
|
103
107
|
<TheirReplyConnector message={message} messageBubbleHeight={messageBubbleHeight} />
|
|
@@ -115,7 +119,7 @@ function ShadowMessageContent({ conversation_id, ...message }: ShadowMessageCont
|
|
|
115
119
|
style={styles.messageText}
|
|
116
120
|
numberOfLines={scalableNumberOfLines}
|
|
117
121
|
>
|
|
118
|
-
{
|
|
122
|
+
{messageText}
|
|
119
123
|
</Text>
|
|
120
124
|
)}
|
|
121
125
|
</View>
|
|
@@ -281,6 +285,8 @@ const useStyles = ({ mine, imageWidth = 32, imageHeight = 32 }: StylesProps = {}
|
|
|
281
285
|
},
|
|
282
286
|
avatar: {
|
|
283
287
|
marginBottom: 8,
|
|
288
|
+
},
|
|
289
|
+
avatarOpacity: {
|
|
284
290
|
opacity: 0.5,
|
|
285
291
|
},
|
|
286
292
|
messageBubble: {
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { useNavigation } from '@react-navigation/native'
|
|
2
|
-
import { FlashList } from '@shopify/flash-list'
|
|
3
2
|
import React, { useMemo } from 'react'
|
|
4
|
-
import { StyleSheet, View } from 'react-native'
|
|
3
|
+
import { FlatList, StyleSheet, View } from 'react-native'
|
|
5
4
|
import { useConversationsContext } from '../../contexts/conversations_context'
|
|
6
5
|
import { useTheme } from '../../hooks'
|
|
7
6
|
import { ConversationResource } from '../../types'
|
|
@@ -35,7 +34,7 @@ export const Conversations = ({ ListHeaderComponent }: ConversationsProps) => {
|
|
|
35
34
|
|
|
36
35
|
const showBadges = !chat_group_graph_id
|
|
37
36
|
|
|
38
|
-
const data:
|
|
37
|
+
const data: FlatListItem[] = useMemo(() => {
|
|
39
38
|
if (isLoading) {
|
|
40
39
|
return loadingPlaceholder
|
|
41
40
|
}
|
|
@@ -54,9 +53,8 @@ export const Conversations = ({ ListHeaderComponent }: ConversationsProps) => {
|
|
|
54
53
|
|
|
55
54
|
return (
|
|
56
55
|
<View style={styles.container}>
|
|
57
|
-
<
|
|
56
|
+
<FlatList
|
|
58
57
|
data={data}
|
|
59
|
-
estimatedItemSize={97}
|
|
60
58
|
keyExtractor={item => item.id.toString()}
|
|
61
59
|
contentContainerStyle={styles.contentContainer}
|
|
62
60
|
onRefresh={refetch}
|
|
@@ -114,18 +112,18 @@ const useStyles = () => {
|
|
|
114
112
|
})
|
|
115
113
|
}
|
|
116
114
|
|
|
117
|
-
interface
|
|
115
|
+
interface FlatListLoadingItem {
|
|
118
116
|
type: 'loading'
|
|
119
117
|
id: string
|
|
120
118
|
}
|
|
121
|
-
interface
|
|
119
|
+
interface FlatListConversationItem {
|
|
122
120
|
type: 'conversation'
|
|
123
121
|
resource: ConversationResource
|
|
124
122
|
id: number
|
|
125
123
|
}
|
|
126
|
-
type
|
|
124
|
+
type FlatListItem = FlatListLoadingItem | FlatListConversationItem
|
|
127
125
|
|
|
128
|
-
const loadingPlaceholder:
|
|
126
|
+
const loadingPlaceholder: FlatListItem[] = Array.from({ length: 5 }, (_, i) => ({
|
|
129
127
|
type: 'loading',
|
|
130
128
|
id: `loading${i}`,
|
|
131
129
|
}))
|
|
@@ -9,6 +9,7 @@ import React, {
|
|
|
9
9
|
useRef,
|
|
10
10
|
} from 'react'
|
|
11
11
|
import {
|
|
12
|
+
FlatList,
|
|
12
13
|
StyleSheet,
|
|
13
14
|
TextInput,
|
|
14
15
|
View,
|
|
@@ -40,7 +41,6 @@ import {
|
|
|
40
41
|
} from '../hooks/use_conversation'
|
|
41
42
|
import { MemberResource, isDefined } from '../types'
|
|
42
43
|
import { HeaderTextButton } from '../components/display/platform_modal_header_buttons'
|
|
43
|
-
import { FlashList } from '@shopify/flash-list'
|
|
44
44
|
import { tokens } from '../vendor/tapestry/tokens'
|
|
45
45
|
import { ButtonAppearanceUnion } from '../components/display/utils/button_colors'
|
|
46
46
|
import { GroupResource } from '../types/resources/group_resource'
|
|
@@ -300,9 +300,8 @@ export function ConversationDetailsScreen({ route }: ConversationDetailsScreenPr
|
|
|
300
300
|
|
|
301
301
|
return (
|
|
302
302
|
<View style={styles.listContainer}>
|
|
303
|
-
<
|
|
303
|
+
<FlatList
|
|
304
304
|
data={listData as SectionListData}
|
|
305
|
-
estimatedItemSize={52}
|
|
306
305
|
contentContainerStyle={styles.contentContainer}
|
|
307
306
|
renderItem={({ item, index }) => {
|
|
308
307
|
const [isStart, isEnd] = [
|
|
@@ -375,7 +374,7 @@ export function ConversationDetailsScreen({ route }: ConversationDetailsScreenPr
|
|
|
375
374
|
return null
|
|
376
375
|
}
|
|
377
376
|
}}
|
|
378
|
-
onEndReached={fetchNextPageOfMembers}
|
|
377
|
+
onEndReached={() => fetchNextPageOfMembers()}
|
|
379
378
|
/>
|
|
380
379
|
</View>
|
|
381
380
|
)
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
|
-
import { StyleSheet, View } from 'react-native'
|
|
3
|
-
import { FlashList, type FlashListProps } from '@shopify/flash-list'
|
|
2
|
+
import { FlatList, type FlatListProps, StyleSheet, View } from 'react-native'
|
|
4
3
|
import { MemberResource } from '../../../types'
|
|
5
4
|
import { Person, Text } from '../../../components/display'
|
|
6
5
|
import { useTheme } from '../../../hooks'
|
|
@@ -8,7 +7,7 @@ import { useTheme } from '../../../hooks'
|
|
|
8
7
|
interface FormListProps {
|
|
9
8
|
memberData: MemberResource[]
|
|
10
9
|
loadingMore?: boolean
|
|
11
|
-
FormContent?:
|
|
10
|
+
FormContent?: FlatListProps<MemberResource>['ListHeaderComponent']
|
|
12
11
|
listEmptyText?: string
|
|
13
12
|
onEndReached?: () => void
|
|
14
13
|
}
|
|
@@ -23,7 +22,7 @@ export const FormList = ({
|
|
|
23
22
|
const styles = useStyles()
|
|
24
23
|
|
|
25
24
|
return (
|
|
26
|
-
<
|
|
25
|
+
<FlatList
|
|
27
26
|
data={memberData}
|
|
28
27
|
ListHeaderComponent={FormContent}
|
|
29
28
|
renderItem={({ item }) => <Person person={item} style={styles.person} />}
|
|
@@ -31,7 +30,6 @@ export const FormList = ({
|
|
|
31
30
|
loadingMore ? <Text style={styles.loadingMore}>Loading more...</Text> : null
|
|
32
31
|
}
|
|
33
32
|
keyExtractor={item => item.id.toString()}
|
|
34
|
-
estimatedItemSize={45}
|
|
35
33
|
ListEmptyComponent={<ListEmptyText text={listEmptyText || 'No members found'} />}
|
|
36
34
|
onEndReached={onEndReached}
|
|
37
35
|
/>
|
|
@@ -314,8 +314,7 @@ export const groupMessages = ({ ms, inReplyScreen }: GroupMessagesProps) => {
|
|
|
314
314
|
message.threadPosition = null // ensures we don't render a connector for root replies that aren't immediately followed up a reply
|
|
315
315
|
else if (firstInThread) message.threadPosition = 'first'
|
|
316
316
|
else if (lastInThread) message.threadPosition = 'last'
|
|
317
|
-
else
|
|
318
|
-
message.threadPosition = 'center'
|
|
317
|
+
else message.threadPosition = 'center'
|
|
319
318
|
}
|
|
320
319
|
|
|
321
320
|
enrichedMessages.push(message)
|
package/src/screens/conversation_select_recipients/conversation_select_group_recipients_screen.tsx
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { useNavigation } from '@react-navigation/native'
|
|
2
2
|
import React from 'react'
|
|
3
|
-
import { StyleSheet, View } from 'react-native'
|
|
4
|
-
import { FlashList } from '@shopify/flash-list'
|
|
3
|
+
import { FlatList, StyleSheet, View } from 'react-native'
|
|
5
4
|
import { Heading } from '../../components'
|
|
6
5
|
import { GroupsGroupResource } from '../../types'
|
|
7
6
|
import { useGroupsGroups } from '../../hooks/use_groups_groups'
|
|
@@ -31,10 +30,9 @@ export const ConversationSelectGroupRecipientsScreen = ({
|
|
|
31
30
|
}
|
|
32
31
|
|
|
33
32
|
return (
|
|
34
|
-
<
|
|
33
|
+
<FlatList
|
|
35
34
|
data={groupsWithCreatePermission}
|
|
36
35
|
keyExtractor={item => item.id.toString()}
|
|
37
|
-
estimatedItemSize={65}
|
|
38
36
|
contentContainerStyle={styles.contentContainer}
|
|
39
37
|
ListHeaderComponent={
|
|
40
38
|
<View style={styles.sectionHeader}>
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { useNavigation } from '@react-navigation/native'
|
|
2
2
|
import React from 'react'
|
|
3
|
-
import { StyleSheet, View } from 'react-native'
|
|
4
|
-
import { FlashList } from '@shopify/flash-list'
|
|
3
|
+
import { FlatList, StyleSheet, View } from 'react-native'
|
|
5
4
|
import { Heading } from '../../components'
|
|
6
5
|
import { useSafeAreaInsets } from 'react-native-safe-area-context'
|
|
7
6
|
import { ConversationSelectRecipientsScreenProps } from './types/screen_props'
|
|
@@ -30,10 +29,9 @@ export const ConversationSelectTeamsILeadRecipientsScreen = ({
|
|
|
30
29
|
}
|
|
31
30
|
|
|
32
31
|
return (
|
|
33
|
-
<
|
|
32
|
+
<FlatList
|
|
34
33
|
data={serviceTypes}
|
|
35
34
|
keyExtractor={item => item.id.toString()}
|
|
36
|
-
estimatedItemSize={65}
|
|
37
35
|
contentContainerStyle={styles.contentContainer}
|
|
38
36
|
ListHeaderComponent={
|
|
39
37
|
<View style={styles.sectionHeader}>
|