@planningcenter/chat-react-native 3.18.0-rc.9 → 3.19.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.
- package/build/components/conversation/message.d.ts.map +1 -1
- package/build/components/conversation/message.js +28 -12
- package/build/components/conversation/message.js.map +1 -1
- package/build/components/conversation/message_form.js +1 -1
- package/build/components/conversation/message_form.js.map +1 -1
- package/build/components/conversation/reply_shadow_message.d.ts.map +1 -1
- package/build/components/conversation/reply_shadow_message.js +8 -3
- package/build/components/conversation/reply_shadow_message.js.map +1 -1
- package/build/hooks/use_conversation_messages.d.ts.map +1 -1
- package/build/hooks/use_conversation_messages.js +2 -1
- package/build/hooks/use_conversation_messages.js.map +1 -1
- package/build/hooks/use_message_draft.d.ts +1 -1
- package/build/hooks/use_message_draft.d.ts.map +1 -1
- package/build/hooks/use_message_draft.js +6 -2
- package/build/hooks/use_message_draft.js.map +1 -1
- package/build/screens/age_check/age_check_required_screen.js +1 -1
- package/build/screens/age_check/age_check_required_screen.js.map +1 -1
- package/build/screens/age_check/components/age_check_select_birthdate_modal.js +2 -2
- package/build/screens/age_check/components/age_check_select_birthdate_modal.js.map +1 -1
- package/build/screens/conversation_screen.d.ts.map +1 -1
- package/build/screens/conversation_screen.js +18 -8
- package/build/screens/conversation_screen.js.map +1 -1
- package/package.json +2 -2
- package/src/components/conversation/message.tsx +40 -11
- package/src/components/conversation/message_form.tsx +1 -1
- package/src/components/conversation/reply_shadow_message.tsx +9 -2
- package/src/hooks/use_conversation_messages.ts +3 -1
- package/src/hooks/use_message_draft.ts +6 -2
- package/src/screens/age_check/age_check_required_screen.tsx +1 -1
- package/src/screens/age_check/components/age_check_select_birthdate_modal.tsx +2 -0
- package/src/screens/conversation_screen.tsx +21 -8
|
@@ -25,6 +25,8 @@ import { TheirReplyConnector, MyReplyConnector } from './reply_connectors'
|
|
|
25
25
|
import { assertKeysAreNumbers, pluralize } from '../../utils'
|
|
26
26
|
import { useNavigation } from '@react-navigation/native'
|
|
27
27
|
import { useConversationMessage } from '../../hooks/use_conversation_message'
|
|
28
|
+
import { useLiveRelativeTime } from '../../hooks/use_live_relative_time'
|
|
29
|
+
import { some } from 'lodash'
|
|
28
30
|
|
|
29
31
|
interface ReplyShadowMessageProps extends MessageResource {
|
|
30
32
|
messageId: string
|
|
@@ -61,10 +63,11 @@ interface ShadowMessageContentProps extends MessageResource {
|
|
|
61
63
|
}
|
|
62
64
|
|
|
63
65
|
function ShadowMessageContent({ conversation_id, ...message }: ShadowMessageContentProps) {
|
|
64
|
-
const { text, deletedAt } = message
|
|
66
|
+
const { text, deletedAt, author, attachments } = message
|
|
65
67
|
const styles = useStyles(message)
|
|
66
68
|
const { colors } = useTheme()
|
|
67
69
|
const navigation = useNavigation()
|
|
70
|
+
const timestamp = useLiveRelativeTime(message.createdAt)
|
|
68
71
|
|
|
69
72
|
const [messageBubbleHeight, setMessageBubbleHeight] = React.useState(0)
|
|
70
73
|
const { animatedBackgroundColor, handleMessagePressIn, handleMessagePressOut } =
|
|
@@ -82,12 +85,16 @@ function ShadowMessageContent({ conversation_id, ...message }: ShadowMessageCont
|
|
|
82
85
|
})
|
|
83
86
|
}
|
|
84
87
|
|
|
88
|
+
const attachmentLabel = some(attachments) ? pluralize(attachments.length, 'attachment') : ''
|
|
89
|
+
const accessibilityLabel = `${author?.name || ''} Reply Preview ${attachmentLabel} ${messageText || ''} ${timestamp} ${replyCountText}`
|
|
90
|
+
|
|
85
91
|
return (
|
|
86
92
|
<Pressable
|
|
87
93
|
android_ripple={{ color: colors.androidRippleNeutral }}
|
|
88
94
|
onPress={handleNavigateToReplies}
|
|
89
95
|
onPressIn={handleMessagePressIn}
|
|
90
96
|
onPressOut={handleMessagePressOut}
|
|
97
|
+
accessibilityLabel={accessibilityLabel}
|
|
91
98
|
accessibilityHint="Navigate to reply screen for this message"
|
|
92
99
|
accessibilityRole="link"
|
|
93
100
|
>
|
|
@@ -112,7 +119,7 @@ function ShadowMessageContent({ conversation_id, ...message }: ShadowMessageCont
|
|
|
112
119
|
style={styles.messageBubble}
|
|
113
120
|
onLayout={e => setMessageBubbleHeight(e.nativeEvent.layout.height)}
|
|
114
121
|
>
|
|
115
|
-
<MessageAttachmentImagery attachments={
|
|
122
|
+
<MessageAttachmentImagery attachments={attachments} />
|
|
116
123
|
{text && (
|
|
117
124
|
<Text
|
|
118
125
|
variant="footnote"
|
|
@@ -16,7 +16,9 @@ export const useConversationMessages = (
|
|
|
16
16
|
() =>
|
|
17
17
|
data
|
|
18
18
|
.filter(
|
|
19
|
-
message =>
|
|
19
|
+
message =>
|
|
20
|
+
(!message.deletedAt || message.replyRootId) &&
|
|
21
|
+
(message.attachments?.length || message.text?.length)
|
|
20
22
|
)
|
|
21
23
|
.sort((a, b) => -a.id.localeCompare(b.id)),
|
|
22
24
|
[data]
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { useCallback, useEffect, useRef, useState } from 'react'
|
|
2
2
|
import { useAsyncStorage } from './use_async_storage'
|
|
3
3
|
import type { FileAttachment } from '../types/resources/denormalized_attachment_resource_for_create'
|
|
4
|
+
import { useConversationContext } from '../contexts/conversation_context'
|
|
4
5
|
|
|
5
6
|
interface MessageDraft {
|
|
6
7
|
text: string
|
|
@@ -14,8 +15,11 @@ const DRAFT_EXPIRY_MS = DRAFT_EXPIRY_HOURS * 60 * 60 * 1000
|
|
|
14
15
|
const ATTACHMENT_EXPIRY_HOURS = 48 // 2 days
|
|
15
16
|
const ATTACHMENT_EXPIRY_MS = ATTACHMENT_EXPIRY_HOURS * 60 * 60 * 1000
|
|
16
17
|
|
|
17
|
-
export function useMessageDraft(
|
|
18
|
-
const
|
|
18
|
+
export function useMessageDraft() {
|
|
19
|
+
const { conversationId, currentPageReplyRootId } = useConversationContext()
|
|
20
|
+
const conversationKey = currentPageReplyRootId
|
|
21
|
+
? `${conversationId}/threads/${currentPageReplyRootId}`
|
|
22
|
+
: String(conversationId)
|
|
19
23
|
const [allDrafts, setAllDrafts] = useAsyncStorage<Record<string, MessageDraft>>(
|
|
20
24
|
DRAFT_STORAGE_KEY,
|
|
21
25
|
{}
|
|
@@ -30,7 +30,7 @@ export function AgeCheckRequiredScreen() {
|
|
|
30
30
|
const styles = useStyles()
|
|
31
31
|
|
|
32
32
|
const birthdateStamp = birthdate
|
|
33
|
-
? formatDate(birthdate, { style: 'standard', year: true })
|
|
33
|
+
? formatDate(birthdate, { style: 'standard', year: true, timeZone: 'UTC' })
|
|
34
34
|
: 'Missing'
|
|
35
35
|
|
|
36
36
|
const age = birthdate ? calculateAge(birthdate) : null
|
|
@@ -65,6 +65,7 @@ function IOSBirthdateModal({
|
|
|
65
65
|
</Text>
|
|
66
66
|
<View style={styles.pickerContainer}>
|
|
67
67
|
<DateTimePicker
|
|
68
|
+
timeZoneName="UTC"
|
|
68
69
|
accessibilityLabelledBy="birthdateLabel"
|
|
69
70
|
testID="age-check-date-picker"
|
|
70
71
|
mode="date"
|
|
@@ -101,6 +102,7 @@ function AndroidBirthdatePicker({
|
|
|
101
102
|
|
|
102
103
|
return (
|
|
103
104
|
<DateTimePicker
|
|
105
|
+
timeZoneName="UTC"
|
|
104
106
|
testID="age-check-date-picker-android"
|
|
105
107
|
mode="date"
|
|
106
108
|
display="spinner"
|
|
@@ -310,6 +310,24 @@ export const groupMessages = ({
|
|
|
310
310
|
message.replyRootId &&
|
|
311
311
|
!threadRoot &&
|
|
312
312
|
(prevMessageDifferentThread || prevMessageIsDateSeparator)
|
|
313
|
+
const lastInGroup =
|
|
314
|
+
!nextMessage ||
|
|
315
|
+
nextMessageDifferentAuthor ||
|
|
316
|
+
nextMessageMoreThan5Minutes ||
|
|
317
|
+
nextMessageDifferentThread ||
|
|
318
|
+
nextMessageIsDateSeparator
|
|
319
|
+
const renderAuthor =
|
|
320
|
+
!message.mine &&
|
|
321
|
+
(!prevMessage ||
|
|
322
|
+
prevMessageDifferentAuthor ||
|
|
323
|
+
prevMessageMoreThan5Minutes ||
|
|
324
|
+
prevMessageDifferentThread ||
|
|
325
|
+
prevMessageIsDateSeparator)
|
|
326
|
+
const nextIsReplyShadowMessage =
|
|
327
|
+
repliesEnabled &&
|
|
328
|
+
nextMessageInThread &&
|
|
329
|
+
!nextMessageThreadRoot &&
|
|
330
|
+
(nextMessageDifferentThread || nextMessageIsDateSeparator)
|
|
313
331
|
|
|
314
332
|
if (message.mine && !encounteredOneOfMyMessages) {
|
|
315
333
|
encounteredOneOfMyMessages = true
|
|
@@ -317,17 +335,12 @@ export const groupMessages = ({
|
|
|
317
335
|
} else {
|
|
318
336
|
message.myLatestInConversation = false
|
|
319
337
|
}
|
|
320
|
-
message.lastInGroup =
|
|
321
|
-
message.renderAuthor =
|
|
322
|
-
!message.mine && (!prevMessage || prevMessageDifferentAuthor || prevMessageMoreThan5Minutes)
|
|
338
|
+
message.lastInGroup = lastInGroup
|
|
339
|
+
message.renderAuthor = renderAuthor
|
|
323
340
|
message.threadPosition = null
|
|
324
341
|
message.nextRendersAuthor = nextMessage?.renderAuthor
|
|
325
342
|
message.isReplyShadowMessage = false
|
|
326
|
-
message.nextIsReplyShadowMessage =
|
|
327
|
-
repliesEnabled &&
|
|
328
|
-
nextMessageInThread &&
|
|
329
|
-
!nextMessageThreadRoot &&
|
|
330
|
-
(nextMessageDifferentThread || nextMessageIsDateSeparator)
|
|
343
|
+
message.nextIsReplyShadowMessage = nextIsReplyShadowMessage
|
|
331
344
|
|
|
332
345
|
if (!inReplyScreen && inThread) {
|
|
333
346
|
message.prevIsMyReply = prevMessage?.mine
|