@planningcenter/chat-react-native 3.18.0-rc.8 → 3.18.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/messages_disabled_banners.d.ts +3 -0
- package/build/components/conversation/messages_disabled_banners.d.ts.map +1 -0
- package/build/components/conversation/messages_disabled_banners.js +53 -0
- package/build/components/conversation/messages_disabled_banners.js.map +1 -0
- 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/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_details_screen.d.ts.map +1 -1
- package/build/screens/conversation_details_screen.js +6 -2
- 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 +21 -11
- 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/messages_disabled_banners.tsx +69 -0
- package/src/components/conversation/reply_shadow_message.tsx +9 -2
- package/src/hooks/use_conversation_messages.ts +3 -1
- 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_details_screen.tsx +6 -2
- package/src/screens/conversation_screen.tsx +26 -13
- package/build/components/conversation/disabled_replies_banners.d.ts +0 -3
- package/build/components/conversation/disabled_replies_banners.d.ts.map +0 -1
- package/build/components/conversation/disabled_replies_banners.js +0 -41
- package/build/components/conversation/disabled_replies_banners.js.map +0 -1
- package/src/components/conversation/disabled_replies_banners.tsx +0 -58
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import { useNavigation } from '@react-navigation/native'
|
|
2
2
|
import React, { useEffect } from 'react'
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
AccessibilityActionEvent,
|
|
5
|
+
Pressable,
|
|
6
|
+
StyleSheet,
|
|
7
|
+
useWindowDimensions,
|
|
8
|
+
View,
|
|
9
|
+
} from 'react-native'
|
|
4
10
|
import { MessageReaction } from '../../components/conversation/message_reaction'
|
|
5
11
|
import { Avatar, Icon, Spinner, Text, TextButton, TextInlineButton } from '../../components/display'
|
|
6
12
|
import {
|
|
@@ -27,6 +33,7 @@ import { Haptic } from '../../utils/native_adapters'
|
|
|
27
33
|
import { TheirReplyConnector, MyReplyConnector, AVATAR_CONNECTOR_SPACING } from './reply_connectors'
|
|
28
34
|
import { pluralize } from '../../utils'
|
|
29
35
|
import { useConversationMessage } from '../../hooks/use_conversation_message'
|
|
36
|
+
import { some } from 'lodash'
|
|
30
37
|
import { isNewMessage } from '../../utils/cache/messages_cache'
|
|
31
38
|
|
|
32
39
|
/** Message
|
|
@@ -48,7 +55,7 @@ export function Message({
|
|
|
48
55
|
repliesEnabled,
|
|
49
56
|
...message
|
|
50
57
|
}: MessageProps) {
|
|
51
|
-
const { text, reactionCounts, pending, error } = message
|
|
58
|
+
const { text, reactionCounts, pending, error, attachments, author } = message
|
|
52
59
|
const styles = useMessageStyles(message)
|
|
53
60
|
const navigation = useNavigation()
|
|
54
61
|
const { colors } = useTheme()
|
|
@@ -70,7 +77,7 @@ export function Message({
|
|
|
70
77
|
})
|
|
71
78
|
|
|
72
79
|
const metaProps = {
|
|
73
|
-
authorName:
|
|
80
|
+
authorName: author.name,
|
|
74
81
|
createdAt: message.createdAt,
|
|
75
82
|
}
|
|
76
83
|
|
|
@@ -79,12 +86,12 @@ export function Message({
|
|
|
79
86
|
!inReplyScreen && message.replyRootId === message.id && repliesEnabled
|
|
80
87
|
const isReplyRootMessage = message.replyRootId === message.id
|
|
81
88
|
const isDeletedReplyRootMessage = isReplyRootMessage && !!message.deletedAt
|
|
89
|
+
const replyToReplyRootMessage = repliesEnabled && !isReplyRootMessage && !!message.replyRootId
|
|
82
90
|
|
|
83
91
|
const replyCountText = pluralize(message.replyCount, 'reply')
|
|
84
92
|
const messagePendingLabel = isPersisted ? 'Saving' : 'Sending'
|
|
85
|
-
const replyRootAuthorName = message.replyRootId
|
|
86
|
-
|
|
87
|
-
: message.author.name
|
|
93
|
+
const replyRootAuthorName = message.replyRootId ? replyRootMessage?.author.name : author.name
|
|
94
|
+
const messageText = isDeletedReplyRootMessage ? 'Message deleted' : text
|
|
88
95
|
|
|
89
96
|
const messageBottomMargin =
|
|
90
97
|
message.lastInGroup || message.nextIsReplyShadowMessage
|
|
@@ -93,6 +100,11 @@ export function Message({
|
|
|
93
100
|
? 8
|
|
94
101
|
: 4
|
|
95
102
|
|
|
103
|
+
const messageIsReplyLabel = replyToReplyRootMessage ? 'Reply' : ''
|
|
104
|
+
const attachmentLabel = some(attachments) ? pluralize(attachments.length, 'attachment') : ''
|
|
105
|
+
const replyCountLabel = isReplyRootMessage ? replyCountText : ''
|
|
106
|
+
const accessibilityLabel = `${author?.name || ''} ${messageIsReplyLabel} ${attachmentLabel} ${messageText || ''} ${timestamp} ${replyCountLabel}`
|
|
107
|
+
|
|
96
108
|
useEffect(() => {
|
|
97
109
|
if (pending) {
|
|
98
110
|
const timer = setTimeout(() => {
|
|
@@ -159,10 +171,23 @@ export function Message({
|
|
|
159
171
|
navigation.navigate('ConversationReply', {
|
|
160
172
|
conversation_id,
|
|
161
173
|
reply_root_id: message.id,
|
|
162
|
-
reply_root_author_name:
|
|
174
|
+
reply_root_author_name: author.name,
|
|
163
175
|
})
|
|
164
176
|
}
|
|
165
177
|
|
|
178
|
+
const accessibilityActions = [
|
|
179
|
+
{
|
|
180
|
+
name: 'navigateToReplies',
|
|
181
|
+
label: 'Navigate to replies',
|
|
182
|
+
},
|
|
183
|
+
]
|
|
184
|
+
|
|
185
|
+
const handleAccessibilityAction = (event: AccessibilityActionEvent) => {
|
|
186
|
+
if (event.nativeEvent.actionName === 'navigateToReplies') {
|
|
187
|
+
handleNavigateToReplyPress()
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
166
191
|
return (
|
|
167
192
|
<Pressable
|
|
168
193
|
onLongPress={handleMessageLongPress}
|
|
@@ -170,7 +195,11 @@ export function Message({
|
|
|
170
195
|
onPressIn={handleMessagePressIn}
|
|
171
196
|
onPressOut={handleMessagePressOut}
|
|
172
197
|
android_ripple={{ color: colors.androidRippleNeutral, borderless: false, foreground: true }}
|
|
198
|
+
accessibilityRole="button"
|
|
199
|
+
accessibilityLabel={accessibilityLabel}
|
|
173
200
|
accessibilityHint="Long press to view message actions like reacting and copying."
|
|
201
|
+
accessibilityActions={isReplyRootMessage ? accessibilityActions : undefined}
|
|
202
|
+
onAccessibilityAction={isReplyRootMessage ? handleAccessibilityAction : undefined}
|
|
174
203
|
disabled={isDeletedReplyRootMessage}
|
|
175
204
|
>
|
|
176
205
|
<Animated.View style={[styles.message, animatedBackgroundColor]}>
|
|
@@ -179,7 +208,7 @@ export function Message({
|
|
|
179
208
|
{renderAuthor ? (
|
|
180
209
|
<Avatar
|
|
181
210
|
size={'md'}
|
|
182
|
-
sourceUri={
|
|
211
|
+
sourceUri={author.avatar}
|
|
183
212
|
style={styles.avatar}
|
|
184
213
|
maxFontSizeMultiplier={1}
|
|
185
214
|
minFontSizeMultiplier={1}
|
|
@@ -197,7 +226,7 @@ export function Message({
|
|
|
197
226
|
<View style={[styles.messageContent, { marginBottom: messageBottomMargin }]}>
|
|
198
227
|
{renderAuthor && !isDeletedReplyRootMessage && (
|
|
199
228
|
<Text variant="footnote" style={styles.authorName}>
|
|
200
|
-
{
|
|
229
|
+
{author.name}
|
|
201
230
|
</Text>
|
|
202
231
|
)}
|
|
203
232
|
<View
|
|
@@ -206,13 +235,13 @@ export function Message({
|
|
|
206
235
|
>
|
|
207
236
|
{isDeletedReplyRootMessage ? (
|
|
208
237
|
<View style={styles.messageText}>
|
|
209
|
-
<Text style={styles.replyRootDeletedText}>
|
|
238
|
+
<Text style={styles.replyRootDeletedText}>{messageText}</Text>
|
|
210
239
|
</View>
|
|
211
240
|
) : (
|
|
212
241
|
<>
|
|
213
242
|
<ErrorBoundary>
|
|
214
243
|
<MessageAttachments
|
|
215
|
-
attachments={
|
|
244
|
+
attachments={attachments}
|
|
216
245
|
metaProps={metaProps}
|
|
217
246
|
onMessageAttachmentLongPress={handleMessageAttachmentLongPress}
|
|
218
247
|
onMessageLongPress={handleMessageLongPress}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { StyleSheet, View, type ViewStyle } from 'react-native'
|
|
2
|
+
import { useTheme } from '../../hooks'
|
|
3
|
+
import { Text } from '../display'
|
|
4
|
+
import { useSafeAreaInsets } from 'react-native-safe-area-context'
|
|
5
|
+
import { useFeatures } from '../../hooks/use_features'
|
|
6
|
+
import { availableFeatures } from '../../hooks/use_features'
|
|
7
|
+
|
|
8
|
+
export const LeaderMessagesDisabledBanner = () => {
|
|
9
|
+
const { featureEnabled } = useFeatures()
|
|
10
|
+
const repliesEnabled = featureEnabled(availableFeatures.threaded_replies)
|
|
11
|
+
|
|
12
|
+
const description = repliesEnabled
|
|
13
|
+
? 'Only leaders can send messages in this conversation.'
|
|
14
|
+
: 'Replies are frozen for everyone else.'
|
|
15
|
+
|
|
16
|
+
return <MessagesDisabledBanner description={description} />
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export const MemberMessagesDisabledBanner = () => {
|
|
20
|
+
const styles = useStyles()
|
|
21
|
+
const { featureEnabled } = useFeatures()
|
|
22
|
+
const repliesEnabled = featureEnabled(availableFeatures.threaded_replies)
|
|
23
|
+
|
|
24
|
+
const description = repliesEnabled
|
|
25
|
+
? 'Only leaders can send messages, but you can still add reactions.'
|
|
26
|
+
: 'Replies have been disabled by a leader, but you can still add reactions.'
|
|
27
|
+
|
|
28
|
+
return <MessagesDisabledBanner description={description} style={styles.memberBanner} />
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
interface MessagesDisabledBannerProps {
|
|
32
|
+
description: string
|
|
33
|
+
style?: ViewStyle
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const MessagesDisabledBanner = ({ description, style }: MessagesDisabledBannerProps) => {
|
|
37
|
+
const styles = useStyles()
|
|
38
|
+
|
|
39
|
+
return (
|
|
40
|
+
<View style={[styles.baseBanner, style]}>
|
|
41
|
+
<Text style={styles.text} variant="tertiary">
|
|
42
|
+
{description}
|
|
43
|
+
</Text>
|
|
44
|
+
</View>
|
|
45
|
+
)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const useStyles = () => {
|
|
49
|
+
const { colors } = useTheme()
|
|
50
|
+
const { bottom } = useSafeAreaInsets()
|
|
51
|
+
|
|
52
|
+
return StyleSheet.create({
|
|
53
|
+
baseBanner: {
|
|
54
|
+
paddingHorizontal: 16,
|
|
55
|
+
paddingVertical: 4,
|
|
56
|
+
backgroundColor: colors.statusNeutralComposedBackground,
|
|
57
|
+
borderTopWidth: 1,
|
|
58
|
+
borderTopColor: colors.borderColorDefaultBase,
|
|
59
|
+
},
|
|
60
|
+
text: {
|
|
61
|
+
textAlign: 'center',
|
|
62
|
+
},
|
|
63
|
+
memberBanner: {
|
|
64
|
+
paddingTop: 16,
|
|
65
|
+
paddingBottom: 16 + bottom,
|
|
66
|
+
marginBottom: -bottom,
|
|
67
|
+
},
|
|
68
|
+
})
|
|
69
|
+
}
|
|
@@ -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]
|
|
@@ -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"
|
|
@@ -44,6 +44,8 @@ import { HeaderTextButton } from '../components/display/platform_modal_header_bu
|
|
|
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'
|
|
47
|
+
import { useFeatures } from '../hooks/use_features'
|
|
48
|
+
import { availableFeatures } from '../hooks/use_features'
|
|
47
49
|
|
|
48
50
|
// =========================================
|
|
49
51
|
// ====== Factory Constants & Types ========
|
|
@@ -93,6 +95,8 @@ export function ConversationDetailsScreen({ route }: ConversationDetailsScreenPr
|
|
|
93
95
|
const { repliesDisabled, setRepliesDisabled } = useConversationDisableReplies(route.params)
|
|
94
96
|
const { mutate: saveTitle } = useConversationUpdate(route.params)
|
|
95
97
|
const { mutate: deleteConversation } = useConversationDelete(route.params)
|
|
98
|
+
const { featureEnabled } = useFeatures()
|
|
99
|
+
const repliesEnabled = featureEnabled(availableFeatures.threaded_replies)
|
|
96
100
|
|
|
97
101
|
const trimmedTitle = title.trim()
|
|
98
102
|
const emptyTitle = trimmedTitle === '' || title === null
|
|
@@ -250,8 +254,8 @@ export function ConversationDetailsScreen({ route }: ConversationDetailsScreenPr
|
|
|
250
254
|
{
|
|
251
255
|
type: canUpdate ? SectionTypes.setting : SectionTypes.hidden,
|
|
252
256
|
data: {
|
|
253
|
-
title: 'Freeze conversation',
|
|
254
|
-
subtitle: 'Disables replies for everyone except leaders.',
|
|
257
|
+
title: repliesEnabled ? 'Leader messages only' : 'Freeze conversation',
|
|
258
|
+
subtitle: repliesEnabled ? undefined : 'Disables replies for everyone except leaders.',
|
|
255
259
|
rightItem: (
|
|
256
260
|
<Switch value={repliesDisabled} onChange={() => setRepliesDisabled(!repliesDisabled)} />
|
|
257
261
|
),
|
|
@@ -14,9 +14,9 @@ import { FlatList, Platform, StyleSheet, View } from 'react-native'
|
|
|
14
14
|
import { useSafeAreaInsets } from 'react-native-safe-area-context'
|
|
15
15
|
import { Badge, Icon, Text } from '../components'
|
|
16
16
|
import {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
} from '../components/conversation/
|
|
17
|
+
LeaderMessagesDisabledBanner,
|
|
18
|
+
MemberMessagesDisabledBanner,
|
|
19
|
+
} from '../components/conversation/messages_disabled_banners'
|
|
20
20
|
import { EmptyConversationBlankState } from '../components/conversation/empty_conversation_blank_state'
|
|
21
21
|
import BlankState from '../components/primitive/blank_state_primitive'
|
|
22
22
|
import { Message } from '../components/conversation/message'
|
|
@@ -194,7 +194,7 @@ function ConversationScreenContent({ route }: ConversationScreenProps) {
|
|
|
194
194
|
)}
|
|
195
195
|
<JumpToBottomButton onPress={handleReturnToBottom} visible={showJumpToBottomButton} />
|
|
196
196
|
{!noMessages && <TypingIndicator />}
|
|
197
|
-
{showLeaderDisabledReplyBanner && <
|
|
197
|
+
{showLeaderDisabledReplyBanner && <LeaderMessagesDisabledBanner />}
|
|
198
198
|
{canReply ? (
|
|
199
199
|
<MessageForm.Root
|
|
200
200
|
replyRootAuthorFirstName={replyRootAuthorFirstName}
|
|
@@ -215,7 +215,7 @@ function ConversationScreenContent({ route }: ConversationScreenProps) {
|
|
|
215
215
|
<MessageForm.SubmitButton />
|
|
216
216
|
</MessageForm.Root>
|
|
217
217
|
) : (
|
|
218
|
-
<
|
|
218
|
+
<MemberMessagesDisabledBanner />
|
|
219
219
|
)}
|
|
220
220
|
</KeyboardView>
|
|
221
221
|
</View>
|
|
@@ -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
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"disabled_replies_banners.d.ts","sourceRoot":"","sources":["../../../src/components/conversation/disabled_replies_banners.tsx"],"names":[],"mappings":"AAKA,eAAO,MAAM,2BAA2B,mCAEvC,CAAA;AAED,eAAO,MAAM,2BAA2B,mCAQvC,CAAA"}
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { StyleSheet, View } from 'react-native';
|
|
2
|
-
import { useTheme } from '../../hooks';
|
|
3
|
-
import { Text } from '../display';
|
|
4
|
-
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
5
|
-
export const LeaderDisabledRepliesBanner = () => {
|
|
6
|
-
return <DisabledRepliesBanner description="Replies are frozen for everyone else."/>;
|
|
7
|
-
};
|
|
8
|
-
export const MemberDisabledRepliesBanner = () => {
|
|
9
|
-
const styles = useStyles();
|
|
10
|
-
return (<DisabledRepliesBanner description="Replies have been disabled by a leader, but you can still add reactions." style={styles.memberBanner}/>);
|
|
11
|
-
};
|
|
12
|
-
const DisabledRepliesBanner = ({ description, style }) => {
|
|
13
|
-
const styles = useStyles();
|
|
14
|
-
return (<View style={[styles.baseBanner, style]}>
|
|
15
|
-
<Text style={styles.text} variant="tertiary">
|
|
16
|
-
{description}
|
|
17
|
-
</Text>
|
|
18
|
-
</View>);
|
|
19
|
-
};
|
|
20
|
-
const useStyles = () => {
|
|
21
|
-
const { colors } = useTheme();
|
|
22
|
-
const { bottom } = useSafeAreaInsets();
|
|
23
|
-
return StyleSheet.create({
|
|
24
|
-
baseBanner: {
|
|
25
|
-
paddingHorizontal: 16,
|
|
26
|
-
paddingVertical: 4,
|
|
27
|
-
backgroundColor: colors.statusNeutralComposedBackground,
|
|
28
|
-
borderTopWidth: 1,
|
|
29
|
-
borderTopColor: colors.borderColorDefaultBase,
|
|
30
|
-
},
|
|
31
|
-
text: {
|
|
32
|
-
textAlign: 'center',
|
|
33
|
-
},
|
|
34
|
-
memberBanner: {
|
|
35
|
-
paddingTop: 16,
|
|
36
|
-
paddingBottom: 16 + bottom,
|
|
37
|
-
marginBottom: -bottom,
|
|
38
|
-
},
|
|
39
|
-
});
|
|
40
|
-
};
|
|
41
|
-
//# sourceMappingURL=disabled_replies_banners.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"disabled_replies_banners.js","sourceRoot":"","sources":["../../../src/components/conversation/disabled_replies_banners.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,IAAI,EAAkB,MAAM,cAAc,CAAA;AAC/D,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AACtC,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAA;AACjC,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAA;AAElE,MAAM,CAAC,MAAM,2BAA2B,GAAG,GAAG,EAAE;IAC9C,OAAO,CAAC,qBAAqB,CAAC,WAAW,CAAC,uCAAuC,EAAG,CAAA;AACtF,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,2BAA2B,GAAG,GAAG,EAAE;IAC9C,MAAM,MAAM,GAAG,SAAS,EAAE,CAAA;IAC1B,OAAO,CACL,CAAC,qBAAqB,CACpB,WAAW,CAAC,0EAA0E,CACtF,KAAK,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,EAC3B,CACH,CAAA;AACH,CAAC,CAAA;AAOD,MAAM,qBAAqB,GAAG,CAAC,EAAE,WAAW,EAAE,KAAK,EAA8B,EAAE,EAAE;IACnF,MAAM,MAAM,GAAG,SAAS,EAAE,CAAA;IAE1B,OAAO,CACL,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC,CACtC;MAAA,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,UAAU,CAC1C;QAAA,CAAC,WAAW,CACd;MAAA,EAAE,IAAI,CACR;IAAA,EAAE,IAAI,CAAC,CACR,CAAA;AACH,CAAC,CAAA;AAED,MAAM,SAAS,GAAG,GAAG,EAAE;IACrB,MAAM,EAAE,MAAM,EAAE,GAAG,QAAQ,EAAE,CAAA;IAC7B,MAAM,EAAE,MAAM,EAAE,GAAG,iBAAiB,EAAE,CAAA;IAEtC,OAAO,UAAU,CAAC,MAAM,CAAC;QACvB,UAAU,EAAE;YACV,iBAAiB,EAAE,EAAE;YACrB,eAAe,EAAE,CAAC;YAClB,eAAe,EAAE,MAAM,CAAC,+BAA+B;YACvD,cAAc,EAAE,CAAC;YACjB,cAAc,EAAE,MAAM,CAAC,sBAAsB;SAC9C;QACD,IAAI,EAAE;YACJ,SAAS,EAAE,QAAQ;SACpB;QACD,YAAY,EAAE;YACZ,UAAU,EAAE,EAAE;YACd,aAAa,EAAE,EAAE,GAAG,MAAM;YAC1B,YAAY,EAAE,CAAC,MAAM;SACtB;KACF,CAAC,CAAA;AACJ,CAAC,CAAA","sourcesContent":["import { StyleSheet, View, type ViewStyle } from 'react-native'\nimport { useTheme } from '../../hooks'\nimport { Text } from '../display'\nimport { useSafeAreaInsets } from 'react-native-safe-area-context'\n\nexport const LeaderDisabledRepliesBanner = () => {\n return <DisabledRepliesBanner description=\"Replies are frozen for everyone else.\" />\n}\n\nexport const MemberDisabledRepliesBanner = () => {\n const styles = useStyles()\n return (\n <DisabledRepliesBanner\n description=\"Replies have been disabled by a leader, but you can still add reactions.\"\n style={styles.memberBanner}\n />\n )\n}\n\ninterface DisabledRepliesBannerProps {\n description: string\n style?: ViewStyle\n}\n\nconst DisabledRepliesBanner = ({ description, style }: DisabledRepliesBannerProps) => {\n const styles = useStyles()\n\n return (\n <View style={[styles.baseBanner, style]}>\n <Text style={styles.text} variant=\"tertiary\">\n {description}\n </Text>\n </View>\n )\n}\n\nconst useStyles = () => {\n const { colors } = useTheme()\n const { bottom } = useSafeAreaInsets()\n\n return StyleSheet.create({\n baseBanner: {\n paddingHorizontal: 16,\n paddingVertical: 4,\n backgroundColor: colors.statusNeutralComposedBackground,\n borderTopWidth: 1,\n borderTopColor: colors.borderColorDefaultBase,\n },\n text: {\n textAlign: 'center',\n },\n memberBanner: {\n paddingTop: 16,\n paddingBottom: 16 + bottom,\n marginBottom: -bottom,\n },\n })\n}\n"]}
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import { StyleSheet, View, type ViewStyle } from 'react-native'
|
|
2
|
-
import { useTheme } from '../../hooks'
|
|
3
|
-
import { Text } from '../display'
|
|
4
|
-
import { useSafeAreaInsets } from 'react-native-safe-area-context'
|
|
5
|
-
|
|
6
|
-
export const LeaderDisabledRepliesBanner = () => {
|
|
7
|
-
return <DisabledRepliesBanner description="Replies are frozen for everyone else." />
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export const MemberDisabledRepliesBanner = () => {
|
|
11
|
-
const styles = useStyles()
|
|
12
|
-
return (
|
|
13
|
-
<DisabledRepliesBanner
|
|
14
|
-
description="Replies have been disabled by a leader, but you can still add reactions."
|
|
15
|
-
style={styles.memberBanner}
|
|
16
|
-
/>
|
|
17
|
-
)
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
interface DisabledRepliesBannerProps {
|
|
21
|
-
description: string
|
|
22
|
-
style?: ViewStyle
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
const DisabledRepliesBanner = ({ description, style }: DisabledRepliesBannerProps) => {
|
|
26
|
-
const styles = useStyles()
|
|
27
|
-
|
|
28
|
-
return (
|
|
29
|
-
<View style={[styles.baseBanner, style]}>
|
|
30
|
-
<Text style={styles.text} variant="tertiary">
|
|
31
|
-
{description}
|
|
32
|
-
</Text>
|
|
33
|
-
</View>
|
|
34
|
-
)
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
const useStyles = () => {
|
|
38
|
-
const { colors } = useTheme()
|
|
39
|
-
const { bottom } = useSafeAreaInsets()
|
|
40
|
-
|
|
41
|
-
return StyleSheet.create({
|
|
42
|
-
baseBanner: {
|
|
43
|
-
paddingHorizontal: 16,
|
|
44
|
-
paddingVertical: 4,
|
|
45
|
-
backgroundColor: colors.statusNeutralComposedBackground,
|
|
46
|
-
borderTopWidth: 1,
|
|
47
|
-
borderTopColor: colors.borderColorDefaultBase,
|
|
48
|
-
},
|
|
49
|
-
text: {
|
|
50
|
-
textAlign: 'center',
|
|
51
|
-
},
|
|
52
|
-
memberBanner: {
|
|
53
|
-
paddingTop: 16,
|
|
54
|
-
paddingBottom: 16 + bottom,
|
|
55
|
-
marginBottom: -bottom,
|
|
56
|
-
},
|
|
57
|
-
})
|
|
58
|
-
}
|