@planningcenter/chat-react-native 3.16.2-rc.0 → 3.17.0-rc.1
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 +16 -6
- package/build/components/conversation/message.js.map +1 -1
- package/build/components/conversation/message_form.d.ts +1 -1
- package/build/components/conversation/message_form.d.ts.map +1 -1
- package/build/components/conversation/message_form.js.map +1 -1
- package/build/components/conversation/reply_connectors.d.ts +1 -0
- package/build/components/conversation/reply_connectors.d.ts.map +1 -1
- package/build/components/conversation/reply_connectors.js +57 -23
- package/build/components/conversation/reply_connectors.js.map +1 -1
- package/build/components/conversation/reply_shadow_message.d.ts +12 -0
- package/build/components/conversation/reply_shadow_message.d.ts.map +1 -0
- package/build/components/conversation/{shadow_message.js → reply_shadow_message.js} +35 -5
- package/build/components/conversation/reply_shadow_message.js.map +1 -0
- package/build/hooks/use_conversation_message.d.ts +11 -0
- package/build/hooks/use_conversation_message.d.ts.map +1 -0
- package/build/hooks/use_conversation_message.js +8 -0
- package/build/hooks/use_conversation_message.js.map +1 -0
- package/build/hooks/use_conversation_messages.d.ts +1 -20
- package/build/hooks/use_conversation_messages.d.ts.map +1 -1
- package/build/hooks/use_conversation_messages.js +2 -33
- package/build/hooks/use_conversation_messages.js.map +1 -1
- package/build/hooks/use_conversation_messages_jolt_events.js +1 -1
- package/build/hooks/use_conversation_messages_jolt_events.js.map +1 -1
- package/build/hooks/use_message_create_or_update.d.ts +1 -1
- package/build/hooks/use_message_create_or_update.d.ts.map +1 -1
- package/build/hooks/use_message_create_or_update.js +1 -1
- package/build/hooks/use_message_create_or_update.js.map +1 -1
- package/build/hooks/use_message_reaction_toggle.js +1 -1
- package/build/hooks/use_message_reaction_toggle.js.map +1 -1
- package/build/screens/conversation_screen.d.ts +14 -2
- package/build/screens/conversation_screen.d.ts.map +1 -1
- package/build/screens/conversation_screen.js +49 -2
- package/build/screens/conversation_screen.js.map +1 -1
- package/build/types/resources/message.d.ts +6 -0
- package/build/types/resources/message.d.ts.map +1 -1
- package/build/types/resources/message.js.map +1 -1
- package/build/utils/cache/optimistically_create_message.js +1 -1
- package/build/utils/cache/optimistically_create_message.js.map +1 -1
- package/build/utils/cache/optimistically_update_message.js +1 -1
- package/build/utils/cache/optimistically_update_message.js.map +1 -1
- package/build/utils/pluralize.js +1 -1
- package/build/utils/pluralize.js.map +1 -1
- package/build/utils/request/get_message.d.ts +20 -0
- package/build/utils/request/get_message.d.ts.map +1 -0
- package/build/utils/request/get_message.js +18 -0
- package/build/utils/request/get_message.js.map +1 -0
- package/build/utils/request/get_messages.d.ts +20 -0
- package/build/utils/request/get_messages.d.ts.map +1 -0
- package/build/utils/request/get_messages.js +20 -0
- package/build/utils/request/get_messages.js.map +1 -0
- package/build/utils/request/messages_data_options.d.ts +7 -0
- package/build/utils/request/messages_data_options.d.ts.map +1 -0
- package/build/utils/request/messages_data_options.js +18 -0
- package/build/utils/request/messages_data_options.js.map +1 -0
- package/package.json +2 -2
- package/src/__tests__/utils/pluralize.tsx +3 -0
- package/src/components/conversation/message.tsx +19 -6
- package/src/components/conversation/message_form.tsx +2 -2
- package/src/components/conversation/reply_connectors.tsx +62 -31
- package/src/components/conversation/{shadow_message.tsx → reply_shadow_message.tsx} +54 -5
- package/src/hooks/use_conversation_message.ts +20 -0
- package/src/hooks/use_conversation_messages.ts +3 -53
- package/src/hooks/use_conversation_messages_jolt_events.ts +1 -1
- package/src/hooks/use_message_create_or_update.ts +2 -2
- package/src/hooks/use_message_reaction_toggle.ts +1 -1
- package/src/screens/conversation_screen.tsx +77 -4
- package/src/types/resources/message.ts +6 -0
- package/src/utils/cache/optimistically_create_message.ts +1 -1
- package/src/utils/cache/optimistically_update_message.ts +1 -1
- package/src/utils/pluralize.ts +1 -1
- package/src/utils/request/get_message.ts +32 -0
- package/src/utils/request/get_messages.ts +34 -0
- package/src/utils/request/messages_data_options.ts +18 -0
- package/build/components/conversation/shadow_message.d.ts +0 -8
- package/build/components/conversation/shadow_message.d.ts.map +0 -1
- package/build/components/conversation/shadow_message.js.map +0 -1
- package/build/utils/request/messages.d.ts +0 -15
- package/build/utils/request/messages.d.ts.map +0 -1
- package/build/utils/request/messages.js +0 -22
- package/build/utils/request/messages.js.map +0 -1
- package/src/utils/request/messages.ts +0 -21
|
@@ -22,6 +22,8 @@ import { useMarkLatestMessageRead } from '../hooks/use_mark_latest_message_read'
|
|
|
22
22
|
import { CONVERSATION_MESSAGE_LIST_PADDING_HORIZONTAL } from '../utils/styles';
|
|
23
23
|
import { useConversationJoltEvents } from '../hooks/use_conversation_jolt_events';
|
|
24
24
|
import { JumpToBottomButton } from '../components/conversation/jump_to_bottom_button';
|
|
25
|
+
import { ReplyShadowMessage } from '../components/conversation/reply_shadow_message';
|
|
26
|
+
import { REPLIES_FEATURE_ENABLED } from '../utils';
|
|
25
27
|
export function ConversationScreen({ route }) {
|
|
26
28
|
const styles = useStyles();
|
|
27
29
|
const navigation = useNavigation();
|
|
@@ -35,7 +37,7 @@ export function ConversationScreen({ route }) {
|
|
|
35
37
|
useConversationMessagesJoltEvents({ conversationId: conversation_id });
|
|
36
38
|
useEnsureConversationsRouteExists();
|
|
37
39
|
useMarkLatestMessageRead({ conversation, messages });
|
|
38
|
-
const messagesWithSeparators = groupMessages(messages);
|
|
40
|
+
const messagesWithSeparators = groupMessages({ ms: messages, inReplyScreen: !!reply_root_id });
|
|
39
41
|
const noMessages = messagesWithSeparators.length === 0;
|
|
40
42
|
const { repliesDisabled, memberAbility, badges, title } = conversation;
|
|
41
43
|
const canReply = memberAbility?.canReply;
|
|
@@ -79,6 +81,9 @@ export function ConversationScreen({ route }) {
|
|
|
79
81
|
if (item.type === 'DateSeparator') {
|
|
80
82
|
return <InlineDateSeparator {...item}/>;
|
|
81
83
|
}
|
|
84
|
+
if (item.type === 'ReplyShadowMessage') {
|
|
85
|
+
return (<ReplyShadowMessage {...item} conversation_id={conversation_id} inReplyScreen={!!reply_root_id}/>);
|
|
86
|
+
}
|
|
82
87
|
return (<Message {...item} canDeleteNonAuthoredMessages={canDeleteNonAuthoredMessages} conversation_id={conversation_id} latestReadMessageSortKey={conversation?.latestReadMessageSortKey} inReplyScreen={!!reply_root_id}/>);
|
|
83
88
|
}} onEndReached={() => fetchNextPage()} ListHeaderComponent={<View style={styles.listHeader}/>}/>)}
|
|
84
89
|
<JumpToBottomButton onPress={handleReturnToBottom} visible={showJumpToBottomButton}/>
|
|
@@ -131,19 +136,30 @@ const useDateSeparatorStyles = () => {
|
|
|
131
136
|
},
|
|
132
137
|
});
|
|
133
138
|
};
|
|
134
|
-
export const groupMessages = (ms) => {
|
|
139
|
+
export const groupMessages = ({ ms, inReplyScreen }) => {
|
|
135
140
|
let enrichedMessages = [];
|
|
136
141
|
let encounteredOneOfMyMessages = false;
|
|
137
142
|
ms.forEach((message, i) => {
|
|
138
143
|
const prevMessage = ms[i + 1];
|
|
139
144
|
const nextMessage = ms[i - 1];
|
|
140
145
|
const date = moment(message.createdAt).format('YYYY-MM-DD');
|
|
146
|
+
const inThread = message.replyRootId !== null;
|
|
147
|
+
const nextMessageInThread = nextMessage?.replyRootId !== null;
|
|
148
|
+
const threadRoot = message.replyRootId === message.id;
|
|
149
|
+
const nextMessageThreadRoot = nextMessage?.replyRootId === nextMessage?.id;
|
|
150
|
+
const prevMessageDifferentThread = message.replyRootId !== prevMessage?.replyRootId;
|
|
151
|
+
const nextMessageDifferentThread = message.replyRootId !== nextMessage?.replyRootId;
|
|
141
152
|
const prevMessageDifferentAuthor = message.author?.id !== prevMessage?.author?.id;
|
|
142
153
|
const nextMessageDifferentAuthor = message.author?.id !== nextMessage?.author?.id;
|
|
143
154
|
const prevMessageMoreThan5Minutes = prevMessage &&
|
|
144
155
|
new Date(message.createdAt).getTime() - new Date(prevMessage.createdAt).getTime() > 60000 * 5;
|
|
145
156
|
const nextMessageMoreThan5Minutes = nextMessage &&
|
|
146
157
|
new Date(nextMessage.createdAt).getTime() - new Date(message.createdAt).getTime() > 60000 * 5;
|
|
158
|
+
const prevMessageIsDateSeparator = prevMessage && date !== moment(prevMessage.createdAt).format('YYYY-MM-DD');
|
|
159
|
+
const nextMessageIsDateSeparator = nextMessage && date !== moment(nextMessage.createdAt).format('YYYY-MM-DD');
|
|
160
|
+
const insertReplyShadowMessage = message.replyRootId &&
|
|
161
|
+
!threadRoot &&
|
|
162
|
+
(prevMessageDifferentThread || prevMessageIsDateSeparator);
|
|
147
163
|
if (message.mine && !encounteredOneOfMyMessages) {
|
|
148
164
|
encounteredOneOfMyMessages = true;
|
|
149
165
|
message.myLatestInConversation = true;
|
|
@@ -154,7 +170,38 @@ export const groupMessages = (ms) => {
|
|
|
154
170
|
message.lastInGroup = !nextMessage || nextMessageDifferentAuthor || nextMessageMoreThan5Minutes;
|
|
155
171
|
message.renderAuthor =
|
|
156
172
|
!message.mine && (!prevMessage || prevMessageDifferentAuthor || prevMessageMoreThan5Minutes);
|
|
173
|
+
message.threadPosition = null;
|
|
174
|
+
message.nextRendersAuthor = nextMessage?.renderAuthor;
|
|
175
|
+
message.isReplyShadowMessage = false;
|
|
176
|
+
message.nextIsReplyShadowMessage =
|
|
177
|
+
REPLIES_FEATURE_ENABLED &&
|
|
178
|
+
nextMessageInThread &&
|
|
179
|
+
!nextMessageThreadRoot &&
|
|
180
|
+
(nextMessageDifferentThread || nextMessageIsDateSeparator);
|
|
181
|
+
if (!inReplyScreen && inThread) {
|
|
182
|
+
message.prevIsMyReply = prevMessage?.mine;
|
|
183
|
+
message.nextIsMyReply = nextMessage?.mine;
|
|
184
|
+
const firstInThread = threadRoot;
|
|
185
|
+
const lastInThread = nextMessageDifferentThread || nextMessageIsDateSeparator;
|
|
186
|
+
if (firstInThread && lastInThread)
|
|
187
|
+
message.threadPosition = null; // ensures we don't render a connector for root replies that aren't immediately followed up a reply
|
|
188
|
+
else if (firstInThread)
|
|
189
|
+
message.threadPosition = 'first';
|
|
190
|
+
else if (lastInThread)
|
|
191
|
+
message.threadPosition = 'last';
|
|
192
|
+
else if (!prevMessageDifferentThread && !nextMessageDifferentThread)
|
|
193
|
+
message.threadPosition = 'center';
|
|
194
|
+
}
|
|
157
195
|
enrichedMessages.push(message);
|
|
196
|
+
if (insertReplyShadowMessage && REPLIES_FEATURE_ENABLED) {
|
|
197
|
+
enrichedMessages.push({
|
|
198
|
+
type: 'ReplyShadowMessage',
|
|
199
|
+
id: `${message.id}-${message.replyRootId}`,
|
|
200
|
+
messageId: message.replyRootId,
|
|
201
|
+
isReplyShadowMessage: true,
|
|
202
|
+
nextRendersAuthor: message?.renderAuthor,
|
|
203
|
+
});
|
|
204
|
+
}
|
|
158
205
|
if (!prevMessage || date !== moment(prevMessage.createdAt).format('YYYY-MM-DD')) {
|
|
159
206
|
enrichedMessages.push({ type: 'DateSeparator', id: `day-divider-${message.id}`, date });
|
|
160
207
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conversation_screen.js","sourceRoot":"","sources":["../../src/screens/conversation_screen.tsx"],"names":[],"mappings":"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","sourcesContent":["import { date as formatDate } from '@planningcenter/datetime-fmt'\nimport { HeaderTitle, HeaderTitleProps, PlatformPressable } from '@react-navigation/elements'\nimport {\n CommonActions,\n RouteProp,\n StaticScreenProps,\n useNavigation,\n useTheme as useNavigationTheme,\n useRoute,\n} from '@react-navigation/native'\nimport moment from 'moment'\nimport React, { useCallback, useEffect, useRef, useState } from 'react'\nimport { FlatList, Platform, StyleSheet, View } from 'react-native'\nimport { useSafeAreaInsets } from 'react-native-safe-area-context'\nimport { Badge, Icon, Text } from '../components'\nimport {\n LeaderDisabledRepliesBanner,\n MemberDisabledRepliesBanner,\n} from '../components/conversation/disabled_replies_banners'\nimport { EmptyConversationBlankState } from '../components/conversation/empty_conversation_blank_state'\nimport BlankState from '../components/primitive/blank_state_primitive'\nimport { Message } from '../components/conversation/message'\nimport { MessageForm } from '../components/conversation/message_form'\nimport { TypingIndicator } from '../components/conversation/typing_indicator'\nimport { KeyboardView } from '../components/display/keyboard_view'\nimport { useTheme } from '../hooks'\nimport { useConversation } from '../hooks/use_conversation'\nimport { useConversationMessages } from '../hooks/use_conversation_messages'\nimport { useConversationMessagesJoltEvents } from '../hooks/use_conversation_messages_jolt_events'\nimport { MessageResource } from '../types'\nimport { ConversationBadgeResource } from '../types/resources/conversation_badge'\nimport { getRelativeDateStatus } from '../utils/date'\nimport { useMarkLatestMessageRead } from '../hooks/use_mark_latest_message_read'\nimport { CONVERSATION_MESSAGE_LIST_PADDING_HORIZONTAL } from '../utils/styles'\nimport { useConversationJoltEvents } from '../hooks/use_conversation_jolt_events'\nimport { JumpToBottomButton } from '../components/conversation/jump_to_bottom_button'\n\nexport type ConversationRouteProps = {\n conversation_id: number\n reply_root_id?: string\n replyRootAuthor?: string\n chat_group_graph_id?: string\n clear_input?: boolean\n editing_message_id?: number | null\n title?: string\n subtitle?: string\n badge?: ConversationBadgeResource\n deleted?: boolean\n}\n\nexport type ConversationScreenProps = StaticScreenProps<ConversationRouteProps>\n\nexport function ConversationScreen({ route }: ConversationScreenProps) {\n const styles = useStyles()\n const navigation = useNavigation()\n const { conversation_id, editing_message_id, reply_root_id } = route.params\n const { data: conversation } = useConversation(route.params)\n const { messages, refetch, isRefetching, fetchNextPage } = useConversationMessages({\n conversation_id,\n reply_root_id,\n })\n useConversationJoltEvents({ conversationId: conversation_id })\n useConversationMessagesJoltEvents({ conversationId: conversation_id })\n useEnsureConversationsRouteExists()\n useMarkLatestMessageRead({ conversation, messages })\n const messagesWithSeparators = groupMessages(messages)\n const noMessages = messagesWithSeparators.length === 0\n\n const { repliesDisabled, memberAbility, badges, title } = conversation\n const canReply = memberAbility?.canReply\n const showLeaderDisabledReplyBanner = canReply && repliesDisabled\n const canDeleteNonAuthoredMessages = memberAbility?.canDeleteNonAuthoredMessages ?? false\n const currentlyEditingMessage = messages.find(m => String(m.id) === String(editing_message_id))\n\n const listRef = useRef<FlatList>(null)\n const [showJumpToBottomButton, setShowJumpToBottomButton] = useState(false)\n\n const trackScroll = (event: any) => {\n const offsetY = event.nativeEvent.contentOffset.y\n setShowJumpToBottomButton(offsetY > 200)\n }\n\n const handleReturnToBottom = useCallback(() => {\n listRef.current?.scrollToOffset({\n offset: 0,\n })\n }, [])\n\n useEffect(() => {\n if (reply_root_id) return\n\n navigation.setParams({\n title: title,\n badge: badges?.[0],\n deleted: conversation?.deleted,\n })\n }, [navigation, title, badges, conversation?.deleted, reply_root_id])\n\n if (!conversation || conversation.deleted) {\n return (\n <View style={styles.container}>\n <BlankState.Root>\n <BlankState.Imagery name=\"general.outlinedTextMessage\" />\n <BlankState.Content>\n <BlankState.Heading>This conversation has been deleted</BlankState.Heading>\n </BlankState.Content>\n <BlankState.Button\n onPress={navigation.goBack}\n title=\"Back to conversations\"\n accessibilityHint=\"Navigates back to the conversations list\"\n accessibilityRole=\"link\"\n />\n </BlankState.Root>\n </View>\n )\n }\n\n return (\n <View style={styles.container}>\n <KeyboardView>\n {noMessages ? (\n <EmptyConversationBlankState />\n ) : (\n <FlatList\n inverted\n ref={listRef}\n contentContainerStyle={styles.listContainer}\n refreshing={isRefetching}\n onRefresh={refetch}\n data={messagesWithSeparators}\n keyExtractor={item => item.id}\n onScroll={trackScroll}\n scrollEventThrottle={10}\n renderItem={({ item }) => {\n if (item.type === 'DateSeparator') {\n return <InlineDateSeparator {...item} />\n }\n\n return (\n <Message\n {...item}\n canDeleteNonAuthoredMessages={canDeleteNonAuthoredMessages}\n conversation_id={conversation_id}\n latestReadMessageSortKey={conversation?.latestReadMessageSortKey}\n inReplyScreen={!!reply_root_id}\n />\n )\n }}\n onEndReached={() => fetchNextPage()}\n ListHeaderComponent={<View style={styles.listHeader} />}\n />\n )}\n <JumpToBottomButton onPress={handleReturnToBottom} visible={showJumpToBottomButton} />\n {!noMessages && <TypingIndicator conversationId={conversation_id} />}\n {showLeaderDisabledReplyBanner && <LeaderDisabledRepliesBanner />}\n {canReply ? (\n <MessageForm.Root\n conversation={conversation}\n replyRootId={reply_root_id}\n currentlyEditingMessage={currentlyEditingMessage}\n // We use a separate key so that it remounts component when switching between new\n // and edit message. This simplifies internal state handling.\n key={\n currentlyEditingMessage\n ? `edit-message-form-${currentlyEditingMessage.id}`\n : 'new-message-form'\n }\n >\n <MessageForm.AttachmentPicker />\n <MessageForm.Commands />\n <MessageForm.TextInput />\n <MessageForm.SubmitButton />\n </MessageForm.Root>\n ) : (\n <MemberDisabledRepliesBanner />\n )}\n </KeyboardView>\n </View>\n )\n}\n\nexport type DateSeparator = { type: 'DateSeparator'; id: string; date: string }\n\nfunction InlineDateSeparator({ date }: DateSeparator) {\n const styles = useDateSeparatorStyles()\n const { isThisYear } = getRelativeDateStatus(date)\n const showYear = !isThisYear\n const dateStamp = formatDate(date, { style: 'long', year: showYear })\n\n return (\n <View style={styles.container}>\n <View style={styles.separator} />\n <Text variant=\"footnote\" style={styles.dateText}>\n {dateStamp}\n </Text>\n <View style={styles.separator} />\n </View>\n )\n}\n\nconst useDateSeparatorStyles = () => {\n const theme = useTheme()\n return StyleSheet.create({\n container: {\n alignItems: 'center',\n flexDirection: 'row',\n paddingHorizontal: CONVERSATION_MESSAGE_LIST_PADDING_HORIZONTAL,\n paddingVertical: 16,\n },\n separator: {\n flex: 1,\n height: 1,\n borderTopWidth: 1,\n borderTopColor: theme.colors.borderColorDefaultBase,\n },\n dateText: {\n paddingHorizontal: 8,\n },\n })\n}\n\nexport const groupMessages = (ms: MessageResource[]) => {\n let enrichedMessages: (MessageResource | DateSeparator)[] = []\n let encounteredOneOfMyMessages = false\n\n ms.forEach((message, i) => {\n const prevMessage = ms[i + 1]\n const nextMessage = ms[i - 1]\n const date = moment(message.createdAt).format('YYYY-MM-DD')\n const prevMessageDifferentAuthor = message.author?.id !== prevMessage?.author?.id\n const nextMessageDifferentAuthor = message.author?.id !== nextMessage?.author?.id\n const prevMessageMoreThan5Minutes =\n prevMessage &&\n new Date(message.createdAt).getTime() - new Date(prevMessage.createdAt).getTime() > 60000 * 5\n const nextMessageMoreThan5Minutes =\n nextMessage &&\n new Date(nextMessage.createdAt).getTime() - new Date(message.createdAt).getTime() > 60000 * 5\n\n if (message.mine && !encounteredOneOfMyMessages) {\n encounteredOneOfMyMessages = true\n message.myLatestInConversation = true\n } else {\n message.myLatestInConversation = false\n }\n message.lastInGroup = !nextMessage || nextMessageDifferentAuthor || nextMessageMoreThan5Minutes\n message.renderAuthor =\n !message.mine && (!prevMessage || prevMessageDifferentAuthor || prevMessageMoreThan5Minutes)\n\n enrichedMessages.push(message)\n if (!prevMessage || date !== moment(prevMessage.createdAt).format('YYYY-MM-DD')) {\n enrichedMessages.push({ type: 'DateSeparator', id: `day-divider-${message.id}`, date })\n }\n })\n\n return enrichedMessages\n}\ninterface ConversationScreenTitleProps extends HeaderTitleProps {\n conversation_id: number\n badge?: ConversationBadgeResource\n deleted?: boolean\n}\n\nexport const ConversationScreenTitle = ({\n conversation_id,\n badge,\n children,\n style,\n deleted,\n}: ConversationScreenTitleProps) => {\n const styles = usePressableHeaderStyle()\n const navigation = useNavigation()\n const resourceType = badge?.pcoResourceType || ''\n const productName = badge?.appName\n const name = badge?.text || undefined\n\n return (\n <PlatformPressable\n accessibilityHint=\"Opens details about members and settings\"\n style={styles.container}\n onPress={() => {\n if (deleted) return\n\n navigation.navigate('ConversationDetails', { conversation_id })\n }}\n >\n <View style={styles.titleWrapper}>\n <HeaderTitle maxFontSizeMultiplier={1} style={style}>\n {children}\n </HeaderTitle>\n {!deleted && <Icon name=\"general.downChevron\" size={12} />}\n </View>\n <Badge\n variant=\"metaSubtle\"\n productLogoName={productName}\n label={resourceType}\n metaLabel={name}\n style={styles.badge}\n maxFontSizeMultiplier={1}\n />\n </PlatformPressable>\n )\n}\n\nconst usePressableHeaderStyle = () => {\n return StyleSheet.create({\n container: {\n alignItems: Platform.select({ android: 'flex-start', default: 'center' }),\n marginRight: Platform.select({ ios: 20, default: 16 }),\n },\n titleWrapper: {\n alignItems: 'center',\n columnGap: 4,\n flexDirection: 'row',\n flexShrink: 1,\n },\n badge: {\n alignSelf: Platform.select({ android: 'flex-start', default: 'center' }),\n marginTop: 2,\n },\n })\n}\n\nconst useStyles = () => {\n const navigationTheme = useNavigationTheme()\n const { bottom } = useSafeAreaInsets()\n\n return StyleSheet.create({\n container: {\n flex: 1,\n justifyContent: 'center',\n backgroundColor: navigationTheme.colors.card,\n paddingBottom: bottom,\n },\n listContainer: {\n paddingVertical: 12,\n },\n listHeader: {\n // Just whitespace to provide space where the typing indicator can be\n height: 16,\n },\n })\n}\n\n/**\n * useEnsureConversationsRouteExists\n */\nconst useEnsureConversationsRouteExists = () => {\n const navigation = useNavigation()\n const { params } = useRoute<RouteProp<ConversationScreenProps['route']>>()\n\n useEffect(() => {\n const navigationState = navigation.getState()\n const routes = navigationState?.routes || []\n const conversationsRoute = routes.find(r => r.name === 'Conversations')\n\n if (conversationsRoute) return\n\n navigation.dispatch(state => {\n return CommonActions.reset({\n ...state,\n routes: [\n { name: 'Conversations', params: { chat_group_graph_id: params?.chat_group_graph_id } },\n ...routes,\n ],\n index: state.index + 1,\n })\n })\n }, [navigation, params?.chat_group_graph_id])\n}\n"]}
|
|
1
|
+
{"version":3,"file":"conversation_screen.js","sourceRoot":"","sources":["../../src/screens/conversation_screen.tsx"],"names":[],"mappings":"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","sourcesContent":["import { date as formatDate } from '@planningcenter/datetime-fmt'\nimport { HeaderTitle, HeaderTitleProps, PlatformPressable } from '@react-navigation/elements'\nimport {\n CommonActions,\n RouteProp,\n StaticScreenProps,\n useNavigation,\n useTheme as useNavigationTheme,\n useRoute,\n} from '@react-navigation/native'\nimport moment from 'moment'\nimport React, { useCallback, useEffect, useRef, useState } from 'react'\nimport { FlatList, Platform, StyleSheet, View } from 'react-native'\nimport { useSafeAreaInsets } from 'react-native-safe-area-context'\nimport { Badge, Icon, Text } from '../components'\nimport {\n LeaderDisabledRepliesBanner,\n MemberDisabledRepliesBanner,\n} from '../components/conversation/disabled_replies_banners'\nimport { EmptyConversationBlankState } from '../components/conversation/empty_conversation_blank_state'\nimport BlankState from '../components/primitive/blank_state_primitive'\nimport { Message } from '../components/conversation/message'\nimport { MessageForm } from '../components/conversation/message_form'\nimport { TypingIndicator } from '../components/conversation/typing_indicator'\nimport { KeyboardView } from '../components/display/keyboard_view'\nimport { useTheme } from '../hooks'\nimport { useConversation } from '../hooks/use_conversation'\nimport { useConversationMessages } from '../hooks/use_conversation_messages'\nimport { useConversationMessagesJoltEvents } from '../hooks/use_conversation_messages_jolt_events'\nimport { MessageResource } from '../types'\nimport { ConversationBadgeResource } from '../types/resources/conversation_badge'\nimport { getRelativeDateStatus } from '../utils/date'\nimport { useMarkLatestMessageRead } from '../hooks/use_mark_latest_message_read'\nimport { CONVERSATION_MESSAGE_LIST_PADDING_HORIZONTAL } from '../utils/styles'\nimport { useConversationJoltEvents } from '../hooks/use_conversation_jolt_events'\nimport { JumpToBottomButton } from '../components/conversation/jump_to_bottom_button'\nimport { ReplyShadowMessage } from '../components/conversation/reply_shadow_message'\nimport { REPLIES_FEATURE_ENABLED } from '../utils'\n\nexport type ConversationRouteProps = {\n conversation_id: number\n reply_root_id?: string | null\n replyRootAuthor?: string\n chat_group_graph_id?: string\n clear_input?: boolean\n editing_message_id?: number | null\n title?: string\n subtitle?: string\n badge?: ConversationBadgeResource\n deleted?: boolean\n}\n\nexport type ConversationScreenProps = StaticScreenProps<ConversationRouteProps>\n\nexport function ConversationScreen({ route }: ConversationScreenProps) {\n const styles = useStyles()\n const navigation = useNavigation()\n const { conversation_id, editing_message_id, reply_root_id } = route.params\n const { data: conversation } = useConversation(route.params)\n const { messages, refetch, isRefetching, fetchNextPage } = useConversationMessages({\n conversation_id,\n reply_root_id,\n })\n useConversationJoltEvents({ conversationId: conversation_id })\n useConversationMessagesJoltEvents({ conversationId: conversation_id })\n useEnsureConversationsRouteExists()\n useMarkLatestMessageRead({ conversation, messages })\n const messagesWithSeparators = groupMessages({ ms: messages, inReplyScreen: !!reply_root_id })\n const noMessages = messagesWithSeparators.length === 0\n\n const { repliesDisabled, memberAbility, badges, title } = conversation\n const canReply = memberAbility?.canReply\n const showLeaderDisabledReplyBanner = canReply && repliesDisabled\n const canDeleteNonAuthoredMessages = memberAbility?.canDeleteNonAuthoredMessages ?? false\n const currentlyEditingMessage = messages.find(m => String(m.id) === String(editing_message_id))\n\n const listRef = useRef<FlatList>(null)\n const [showJumpToBottomButton, setShowJumpToBottomButton] = useState(false)\n\n const trackScroll = (event: any) => {\n const offsetY = event.nativeEvent.contentOffset.y\n setShowJumpToBottomButton(offsetY > 200)\n }\n\n const handleReturnToBottom = useCallback(() => {\n listRef.current?.scrollToOffset({\n offset: 0,\n })\n }, [])\n\n useEffect(() => {\n if (reply_root_id) return\n\n navigation.setParams({\n title: title,\n badge: badges?.[0],\n deleted: conversation?.deleted,\n })\n }, [navigation, title, badges, conversation?.deleted, reply_root_id])\n\n if (!conversation || conversation.deleted) {\n return (\n <View style={styles.container}>\n <BlankState.Root>\n <BlankState.Imagery name=\"general.outlinedTextMessage\" />\n <BlankState.Content>\n <BlankState.Heading>This conversation has been deleted</BlankState.Heading>\n </BlankState.Content>\n <BlankState.Button\n onPress={navigation.goBack}\n title=\"Back to conversations\"\n accessibilityHint=\"Navigates back to the conversations list\"\n accessibilityRole=\"link\"\n />\n </BlankState.Root>\n </View>\n )\n }\n\n return (\n <View style={styles.container}>\n <KeyboardView>\n {noMessages ? (\n <EmptyConversationBlankState />\n ) : (\n <FlatList\n inverted\n ref={listRef}\n contentContainerStyle={styles.listContainer}\n refreshing={isRefetching}\n onRefresh={refetch}\n data={messagesWithSeparators}\n keyExtractor={item => item.id}\n onScroll={trackScroll}\n scrollEventThrottle={10}\n renderItem={({ item }) => {\n if (item.type === 'DateSeparator') {\n return <InlineDateSeparator {...item} />\n }\n\n if (item.type === 'ReplyShadowMessage') {\n return (\n <ReplyShadowMessage\n {...item}\n conversation_id={conversation_id}\n inReplyScreen={!!reply_root_id}\n />\n )\n }\n\n return (\n <Message\n {...item}\n canDeleteNonAuthoredMessages={canDeleteNonAuthoredMessages}\n conversation_id={conversation_id}\n latestReadMessageSortKey={conversation?.latestReadMessageSortKey}\n inReplyScreen={!!reply_root_id}\n />\n )\n }}\n onEndReached={() => fetchNextPage()}\n ListHeaderComponent={<View style={styles.listHeader} />}\n />\n )}\n <JumpToBottomButton onPress={handleReturnToBottom} visible={showJumpToBottomButton} />\n {!noMessages && <TypingIndicator conversationId={conversation_id} />}\n {showLeaderDisabledReplyBanner && <LeaderDisabledRepliesBanner />}\n {canReply ? (\n <MessageForm.Root\n conversation={conversation}\n replyRootId={reply_root_id}\n currentlyEditingMessage={currentlyEditingMessage}\n // We use a separate key so that it remounts component when switching between new\n // and edit message. This simplifies internal state handling.\n key={\n currentlyEditingMessage\n ? `edit-message-form-${currentlyEditingMessage.id}`\n : 'new-message-form'\n }\n >\n <MessageForm.AttachmentPicker />\n <MessageForm.Commands />\n <MessageForm.TextInput />\n <MessageForm.SubmitButton />\n </MessageForm.Root>\n ) : (\n <MemberDisabledRepliesBanner />\n )}\n </KeyboardView>\n </View>\n )\n}\n\nexport type DateSeparator = { type: 'DateSeparator'; id: string; date: string }\n\nfunction InlineDateSeparator({ date }: DateSeparator) {\n const styles = useDateSeparatorStyles()\n const { isThisYear } = getRelativeDateStatus(date)\n const showYear = !isThisYear\n const dateStamp = formatDate(date, { style: 'long', year: showYear })\n\n return (\n <View style={styles.container}>\n <View style={styles.separator} />\n <Text variant=\"footnote\" style={styles.dateText}>\n {dateStamp}\n </Text>\n <View style={styles.separator} />\n </View>\n )\n}\n\nconst useDateSeparatorStyles = () => {\n const theme = useTheme()\n return StyleSheet.create({\n container: {\n alignItems: 'center',\n flexDirection: 'row',\n paddingHorizontal: CONVERSATION_MESSAGE_LIST_PADDING_HORIZONTAL,\n paddingVertical: 16,\n },\n separator: {\n flex: 1,\n height: 1,\n borderTopWidth: 1,\n borderTopColor: theme.colors.borderColorDefaultBase,\n },\n dateText: {\n paddingHorizontal: 8,\n },\n })\n}\n\ntype ReplyShadowMessage = {\n type: 'ReplyShadowMessage'\n id: string\n messageId: string\n isReplyShadowMessage: boolean\n nextRendersAuthor: boolean\n}\n\ninterface GroupMessagesProps {\n ms: MessageResource[]\n inReplyScreen?: boolean\n}\n\nexport const groupMessages = ({ ms, inReplyScreen }: GroupMessagesProps) => {\n let enrichedMessages: (MessageResource | DateSeparator | ReplyShadowMessage)[] = []\n let encounteredOneOfMyMessages = false\n\n ms.forEach((message, i) => {\n const prevMessage = ms[i + 1]\n const nextMessage = ms[i - 1]\n const date = moment(message.createdAt).format('YYYY-MM-DD')\n const inThread = message.replyRootId !== null\n const nextMessageInThread = nextMessage?.replyRootId !== null\n const threadRoot = message.replyRootId === message.id\n const nextMessageThreadRoot = nextMessage?.replyRootId === nextMessage?.id\n const prevMessageDifferentThread = message.replyRootId !== prevMessage?.replyRootId\n const nextMessageDifferentThread = message.replyRootId !== nextMessage?.replyRootId\n const prevMessageDifferentAuthor = message.author?.id !== prevMessage?.author?.id\n const nextMessageDifferentAuthor = message.author?.id !== nextMessage?.author?.id\n const prevMessageMoreThan5Minutes =\n prevMessage &&\n new Date(message.createdAt).getTime() - new Date(prevMessage.createdAt).getTime() > 60000 * 5\n const nextMessageMoreThan5Minutes =\n nextMessage &&\n new Date(nextMessage.createdAt).getTime() - new Date(message.createdAt).getTime() > 60000 * 5\n const prevMessageIsDateSeparator =\n prevMessage && date !== moment(prevMessage.createdAt).format('YYYY-MM-DD')\n const nextMessageIsDateSeparator =\n nextMessage && date !== moment(nextMessage.createdAt).format('YYYY-MM-DD')\n const insertReplyShadowMessage =\n message.replyRootId &&\n !threadRoot &&\n (prevMessageDifferentThread || prevMessageIsDateSeparator)\n\n if (message.mine && !encounteredOneOfMyMessages) {\n encounteredOneOfMyMessages = true\n message.myLatestInConversation = true\n } else {\n message.myLatestInConversation = false\n }\n message.lastInGroup = !nextMessage || nextMessageDifferentAuthor || nextMessageMoreThan5Minutes\n message.renderAuthor =\n !message.mine && (!prevMessage || prevMessageDifferentAuthor || prevMessageMoreThan5Minutes)\n message.threadPosition = null\n message.nextRendersAuthor = nextMessage?.renderAuthor\n message.isReplyShadowMessage = false\n message.nextIsReplyShadowMessage =\n REPLIES_FEATURE_ENABLED &&\n nextMessageInThread &&\n !nextMessageThreadRoot &&\n (nextMessageDifferentThread || nextMessageIsDateSeparator)\n\n if (!inReplyScreen && inThread) {\n message.prevIsMyReply = prevMessage?.mine\n message.nextIsMyReply = nextMessage?.mine\n\n const firstInThread = threadRoot\n const lastInThread = nextMessageDifferentThread || nextMessageIsDateSeparator\n\n if (firstInThread && lastInThread)\n message.threadPosition = null // ensures we don't render a connector for root replies that aren't immediately followed up a reply\n else if (firstInThread) message.threadPosition = 'first'\n else if (lastInThread) message.threadPosition = 'last'\n else if (!prevMessageDifferentThread && !nextMessageDifferentThread)\n message.threadPosition = 'center'\n }\n\n enrichedMessages.push(message)\n\n if (insertReplyShadowMessage && REPLIES_FEATURE_ENABLED) {\n enrichedMessages.push({\n type: 'ReplyShadowMessage',\n id: `${message.id}-${message.replyRootId}`,\n messageId: message.replyRootId!,\n isReplyShadowMessage: true,\n nextRendersAuthor: message?.renderAuthor,\n })\n }\n\n if (!prevMessage || date !== moment(prevMessage.createdAt).format('YYYY-MM-DD')) {\n enrichedMessages.push({ type: 'DateSeparator', id: `day-divider-${message.id}`, date })\n }\n })\n\n return enrichedMessages\n}\ninterface ConversationScreenTitleProps extends HeaderTitleProps {\n conversation_id: number\n badge?: ConversationBadgeResource\n deleted?: boolean\n}\n\nexport const ConversationScreenTitle = ({\n conversation_id,\n badge,\n children,\n style,\n deleted,\n}: ConversationScreenTitleProps) => {\n const styles = usePressableHeaderStyle()\n const navigation = useNavigation()\n const resourceType = badge?.pcoResourceType || ''\n const productName = badge?.appName\n const name = badge?.text || undefined\n\n return (\n <PlatformPressable\n accessibilityHint=\"Opens details about members and settings\"\n style={styles.container}\n onPress={() => {\n if (deleted) return\n\n navigation.navigate('ConversationDetails', { conversation_id })\n }}\n >\n <View style={styles.titleWrapper}>\n <HeaderTitle maxFontSizeMultiplier={1} style={style}>\n {children}\n </HeaderTitle>\n {!deleted && <Icon name=\"general.downChevron\" size={12} />}\n </View>\n <Badge\n variant=\"metaSubtle\"\n productLogoName={productName}\n label={resourceType}\n metaLabel={name}\n style={styles.badge}\n maxFontSizeMultiplier={1}\n />\n </PlatformPressable>\n )\n}\n\nconst usePressableHeaderStyle = () => {\n return StyleSheet.create({\n container: {\n alignItems: Platform.select({ android: 'flex-start', default: 'center' }),\n marginRight: Platform.select({ ios: 20, default: 16 }),\n },\n titleWrapper: {\n alignItems: 'center',\n columnGap: 4,\n flexDirection: 'row',\n flexShrink: 1,\n },\n badge: {\n alignSelf: Platform.select({ android: 'flex-start', default: 'center' }),\n marginTop: 2,\n },\n })\n}\n\nconst useStyles = () => {\n const navigationTheme = useNavigationTheme()\n const { bottom } = useSafeAreaInsets()\n\n return StyleSheet.create({\n container: {\n flex: 1,\n justifyContent: 'center',\n backgroundColor: navigationTheme.colors.card,\n paddingBottom: bottom,\n },\n listContainer: {\n paddingVertical: 12,\n },\n listHeader: {\n // Just whitespace to provide space where the typing indicator can be\n height: 16,\n },\n })\n}\n\n/**\n * useEnsureConversationsRouteExists\n */\nconst useEnsureConversationsRouteExists = () => {\n const navigation = useNavigation()\n const { params } = useRoute<RouteProp<ConversationScreenProps['route']>>()\n\n useEffect(() => {\n const navigationState = navigation.getState()\n const routes = navigationState?.routes || []\n const conversationsRoute = routes.find(r => r.name === 'Conversations')\n\n if (conversationsRoute) return\n\n navigation.dispatch(state => {\n return CommonActions.reset({\n ...state,\n routes: [\n { name: 'Conversations', params: { chat_group_graph_id: params?.chat_group_graph_id } },\n ...routes,\n ],\n index: state.index + 1,\n })\n })\n }, [navigation, params?.chat_group_graph_id])\n}\n"]}
|
|
@@ -20,6 +20,12 @@ export interface MessageResource {
|
|
|
20
20
|
renderTime?: boolean;
|
|
21
21
|
myLatestInConversation?: boolean;
|
|
22
22
|
lastInGroup?: boolean;
|
|
23
|
+
threadPosition?: 'first' | 'center' | 'last' | null;
|
|
24
|
+
prevIsMyReply?: boolean;
|
|
25
|
+
nextIsMyReply?: boolean;
|
|
26
|
+
nextRendersAuthor?: boolean;
|
|
27
|
+
isReplyShadowMessage?: boolean;
|
|
28
|
+
nextIsReplyShadowMessage?: boolean;
|
|
23
29
|
pending?: boolean;
|
|
24
30
|
error?: string;
|
|
25
31
|
attachmentsForCreate?: DenormalizedAttachmentResourceForCreate[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"message.d.ts","sourceRoot":"","sources":["../../../src/types/resources/message.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,8BAA8B,EAAE,MAAM,oCAAoC,CAAA;AACnF,OAAO,EAAE,uCAAuC,EAAE,MAAM,+CAA+C,CAAA;AACvG,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAC9C,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAA;AAEvD,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,SAAS,CAAA;IACf,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,IAAI,EAAE,OAAO,CAAA;IACb,WAAW,EAAE,8BAA8B,EAAE,CAAA;IAC7C,MAAM,EAAE,cAAc,CAAA;IACtB,cAAc,EAAE,qBAAqB,EAAE,CAAA;IACvC,UAAU,EAAE,MAAM,CAAA;IAClB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAG3B,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,sBAAsB,CAAC,EAAE,OAAO,CAAA;IAChC,WAAW,CAAC,EAAE,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"message.d.ts","sourceRoot":"","sources":["../../../src/types/resources/message.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,8BAA8B,EAAE,MAAM,oCAAoC,CAAA;AACnF,OAAO,EAAE,uCAAuC,EAAE,MAAM,+CAA+C,CAAA;AACvG,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAC9C,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAA;AAEvD,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,SAAS,CAAA;IACf,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,IAAI,EAAE,OAAO,CAAA;IACb,WAAW,EAAE,8BAA8B,EAAE,CAAA;IAC7C,MAAM,EAAE,cAAc,CAAA;IACtB,cAAc,EAAE,qBAAqB,EAAE,CAAA;IACvC,UAAU,EAAE,MAAM,CAAA;IAClB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAG3B,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,sBAAsB,CAAC,EAAE,OAAO,CAAA;IAChC,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,cAAc,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,MAAM,GAAG,IAAI,CAAA;IACnD,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B,oBAAoB,CAAC,EAAE,OAAO,CAAA;IAC9B,wBAAwB,CAAC,EAAE,OAAO,CAAA;IAGlC,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,oBAAoB,CAAC,EAAE,uCAAuC,EAAE,CAAA;CACjE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"message.js","sourceRoot":"","sources":["../../../src/types/resources/message.ts"],"names":[],"mappings":"","sourcesContent":["import { DenormalizedAttachmentResource } from './denormalized_attachment_resource'\nimport { DenormalizedAttachmentResourceForCreate } from './denormalized_attachment_resource_for_create'\nimport type { PersonResource } from './person'\nimport type { ReactionCountResource } from './reaction'\n\nexport interface MessageResource {\n type: 'Message'\n id: string\n text: string | null\n html: string\n createdAt: string\n deletedAt: string | null\n textEditedAt: string | null\n mine: boolean\n attachments: DenormalizedAttachmentResource[]\n author: PersonResource\n reactionCounts: ReactionCountResource[]\n replyCount: number\n replyRootId?: string | null\n\n // Custom Local Properties we set for rendering\n renderAuthor?: boolean\n renderTime?: boolean\n myLatestInConversation?: boolean\n lastInGroup?: boolean\n\n // Properties for mutation state\n pending?: boolean // Indicates if the message is optimistically created and pending server response\n error?: string // Error message if the message failed to send\n attachmentsForCreate?: DenormalizedAttachmentResourceForCreate[]\n}\n"]}
|
|
1
|
+
{"version":3,"file":"message.js","sourceRoot":"","sources":["../../../src/types/resources/message.ts"],"names":[],"mappings":"","sourcesContent":["import { DenormalizedAttachmentResource } from './denormalized_attachment_resource'\nimport { DenormalizedAttachmentResourceForCreate } from './denormalized_attachment_resource_for_create'\nimport type { PersonResource } from './person'\nimport type { ReactionCountResource } from './reaction'\n\nexport interface MessageResource {\n type: 'Message'\n id: string\n text: string | null\n html: string\n createdAt: string\n deletedAt: string | null\n textEditedAt: string | null\n mine: boolean\n attachments: DenormalizedAttachmentResource[]\n author: PersonResource\n reactionCounts: ReactionCountResource[]\n replyCount: number\n replyRootId?: string | null\n\n // Custom Local Properties we set for rendering\n renderAuthor?: boolean\n renderTime?: boolean\n myLatestInConversation?: boolean\n lastInGroup?: boolean\n threadPosition?: 'first' | 'center' | 'last' | null\n prevIsMyReply?: boolean\n nextIsMyReply?: boolean\n nextRendersAuthor?: boolean\n isReplyShadowMessage?: boolean\n nextIsReplyShadowMessage?: boolean\n\n // Properties for mutation state\n pending?: boolean // Indicates if the message is optimistically created and pending server response\n error?: string // Error message if the message failed to send\n attachmentsForCreate?: DenormalizedAttachmentResourceForCreate[]\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getMessagesQueryKey } from '../../
|
|
1
|
+
import { getMessagesQueryKey } from '../../utils/request/get_messages';
|
|
2
2
|
import { chatQueryClient } from '../../contexts/api_provider';
|
|
3
3
|
import { updateOrCreateRecordInPagesData } from './page_mutations';
|
|
4
4
|
import { convertAttachmentsForCreate } from '../convert_attachments_for_create';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"optimistically_create_message.js","sourceRoot":"","sources":["../../../src/utils/cache/optimistically_create_message.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"optimistically_create_message.js","sourceRoot":"","sources":["../../../src/utils/cache/optimistically_create_message.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAA;AACtE,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAA;AAC7D,OAAO,EAAE,+BAA+B,EAAE,MAAM,kBAAkB,CAAA;AAClE,OAAO,EAAE,2BAA2B,EAAE,MAAM,mCAAmC,CAAA;AAG/E,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAA;AAEtE,MAAM,UAAU,2BAA2B,CAAC,EAC1C,cAAc,EACd,IAAI,EACJ,WAAW,EACX,aAAa,EACb,OAAO,GAOR;IACC,MAAM,EAAE,GAAG,OAAO,EAAE,EAAE,IAAI,qBAAqB,EAAE,CAAA;IAEjD,+DAA+D;IAC/D,MAAM,oBAAoB,GAAqC,2BAA2B,CACxF,WAAW,IAAI,EAAE,CAClB,CAAA;IAED,+BAA+B;IAC/B,MAAM,iBAAiB,GAAoB;QACzC,GAAG,OAAO;QACV,IAAI,EAAE,SAAS;QACf,EAAE;QACF,IAAI;QACJ,IAAI,EAAE,EAAE,EAAE,2BAA2B;QACrC,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,SAAS,EAAE,IAAI;QACf,YAAY,EAAE,IAAI;QAClB,IAAI,EAAE,IAAI;QACV,WAAW,EAAE,oBAAoB;QACjC,oBAAoB,EAAE,WAAW,IAAI,EAAE;QACvC,MAAM,EAAE,aAAa;QACrB,cAAc,EAAE,EAAE;QAClB,YAAY,EAAE,KAAK;QACnB,UAAU,EAAE,IAAI;QAChB,sBAAsB,EAAE,IAAI;QAC5B,WAAW,EAAE,IAAI;QACjB,OAAO,EAAE,IAAI;QACb,UAAU,EAAE,CAAC;QACb,WAAW,EAAE,IAAI;KAClB,CAAA;IAID,MAAM,QAAQ,GAAG,mBAAmB,CAAC,EAAE,eAAe,EAAE,cAAc,EAAE,CAAC,CAAA;IAEzE,eAAe,CAAC,YAAY,CAAY,QAAQ,EAAE,IAAI,CAAC,EAAE,CACvD,+BAA+B,CAAC;QAC9B,IAAI;QACJ,MAAM,EAAE,iBAAoC;KAC7C,CAAC,CACH,CAAA;IAED,OAAO,iBAAiB,CAAA;AAC1B,CAAC;AAED,MAAM,qBAAqB,GAAG,GAAG,EAAE;IACjC,0FAA0F;IAC1F,sEAAsE;IACtE,OAAO,GAAG,uBAAuB,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,OAAO,CAAA;AAC9D,CAAC,CAAA","sourcesContent":["import { InfiniteData } from '@tanstack/react-query'\nimport { ApiCollection, CurrentPersonResource, MessageResource } from '../../types'\nimport { getMessagesQueryKey } from '../../utils/request/get_messages'\nimport { chatQueryClient } from '../../contexts/api_provider'\nimport { updateOrCreateRecordInPagesData } from './page_mutations'\nimport { convertAttachmentsForCreate } from '../convert_attachments_for_create'\nimport { DenormalizedAttachmentResourceForCreate } from '../../types/resources/denormalized_attachment_resource_for_create'\nimport { DenormalizedAttachmentResource } from '../../types/resources/denormalized_attachment_resource'\nimport { generatePlaceholderUlid } from '../generate_placeholder_ulid'\n\nexport function optimisticallyCreateMessage({\n conversationId,\n text,\n attachments,\n currentPerson,\n message,\n}: {\n conversationId: number\n text: string\n attachments?: DenormalizedAttachmentResourceForCreate[]\n currentPerson: CurrentPersonResource\n message?: MessageResource\n}) {\n const id = message?.id || generateTempMessageId()\n\n // Convert attachments to denormalized format for optimistic UI\n const decoratedAttachments: DenormalizedAttachmentResource[] = convertAttachmentsForCreate(\n attachments || []\n )\n\n // Create an optimistic message\n const optimisticMessage: MessageResource = {\n ...message,\n type: 'Message',\n id,\n text,\n html: '', // Will be filled by server\n createdAt: new Date().toISOString(),\n deletedAt: null,\n textEditedAt: null,\n mine: true,\n attachments: decoratedAttachments,\n attachmentsForCreate: attachments || [],\n author: currentPerson,\n reactionCounts: [],\n renderAuthor: false,\n renderTime: true,\n myLatestInConversation: true,\n lastInGroup: true,\n pending: true,\n replyCount: 0,\n replyRootId: null,\n }\n\n // Add the optimistic message to the cache\n type QueryData = InfiniteData<ApiCollection<MessageResource>>\n const queryKey = getMessagesQueryKey({ conversation_id: conversationId })\n\n chatQueryClient.setQueryData<QueryData>(queryKey, data =>\n updateOrCreateRecordInPagesData({\n data,\n record: optimisticMessage as MessageResource,\n })\n )\n\n return optimisticMessage\n}\n\nconst generateTempMessageId = () => {\n // Put it 5 seconds in the future to account for server lag of previously created messages\n // that are still pending. This gets overwritten by the server anyway.\n return `${generatePlaceholderUlid({ offsetMs: 5000 })}-temp`\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getMessagesQueryKey } from '../../
|
|
1
|
+
import { getMessagesQueryKey } from '../../utils/request/get_messages';
|
|
2
2
|
import { chatQueryClient } from '../../contexts/api_provider';
|
|
3
3
|
import { updateOrCreateRecordInPagesData } from './page_mutations';
|
|
4
4
|
export function optimisticallyUpdateMessage({ conversationId, message, text, }) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"optimistically_update_message.js","sourceRoot":"","sources":["../../../src/utils/cache/optimistically_update_message.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"optimistically_update_message.js","sourceRoot":"","sources":["../../../src/utils/cache/optimistically_update_message.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAA;AACtE,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAA;AAC7D,OAAO,EAAE,+BAA+B,EAAE,MAAM,kBAAkB,CAAA;AAElE,MAAM,UAAU,2BAA2B,CAAC,EAC1C,cAAc,EACd,OAAO,EACP,IAAI,GAKL;IAEC,MAAM,QAAQ,GAAG,mBAAmB,CAAC,EAAE,eAAe,EAAE,cAAc,EAAE,CAAC,CAAA;IAEzE,IAAI,iBAAiB,GAAG,OAAO,CAAA;IAE/B,eAAe,CAAC,YAAY,CAAY,QAAQ,EAAE,IAAI,CAAC,EAAE,CACvD,+BAA+B,CAAC;QAC9B,IAAI;QACJ,MAAM,EAAE,OAAO;QACf,aAAa,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE;YAC5B,iBAAiB,GAAG;gBAClB,GAAG,CAAC,IAAI,IAAI,IAAI,CAAC;gBACjB,IAAI;gBACJ,OAAO,EAAE,IAAI;aACd,CAAA;YACD,OAAO,iBAAiB,CAAA;QAC1B,CAAC;KACF,CAAC,CACH,CAAA;IAED,OAAO,iBAAiB,CAAA;AAC1B,CAAC","sourcesContent":["import { InfiniteData } from '@tanstack/react-query'\nimport { ApiCollection, MessageResource } from '../../types'\nimport { getMessagesQueryKey } from '../../utils/request/get_messages'\nimport { chatQueryClient } from '../../contexts/api_provider'\nimport { updateOrCreateRecordInPagesData } from './page_mutations'\n\nexport function optimisticallyUpdateMessage({\n conversationId,\n message,\n text,\n}: {\n conversationId: number\n message: MessageResource\n text: string\n}) {\n type QueryData = InfiniteData<ApiCollection<MessageResource>>\n const queryKey = getMessagesQueryKey({ conversation_id: conversationId })\n\n let optimisticMessage = message\n\n chatQueryClient.setQueryData<QueryData>(queryKey, data =>\n updateOrCreateRecordInPagesData({\n data,\n record: message,\n processRecord: (next, prev) => {\n optimisticMessage = {\n ...(prev || next),\n text,\n pending: true,\n }\n return optimisticMessage\n },\n })\n )\n\n return optimisticMessage\n}\n"]}
|
package/build/utils/pluralize.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const irregularInflections = { person: 'people' };
|
|
1
|
+
const irregularInflections = { person: 'people', reply: 'replies' };
|
|
2
2
|
export function pluralize(count, singularWord, includeCount = true) {
|
|
3
3
|
const plural = count !== 1;
|
|
4
4
|
const pluralWord = irregularInflections[singularWord] || `${singularWord}s`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pluralize.js","sourceRoot":"","sources":["../../src/utils/pluralize.ts"],"names":[],"mappings":"AAAA,MAAM,oBAAoB,GAA2B,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAA;
|
|
1
|
+
{"version":3,"file":"pluralize.js","sourceRoot":"","sources":["../../src/utils/pluralize.ts"],"names":[],"mappings":"AAAA,MAAM,oBAAoB,GAA2B,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,CAAA;AAE3F,MAAM,UAAU,SAAS,CAAC,KAAa,EAAE,YAAoB,EAAE,YAAY,GAAG,IAAI;IAChF,MAAM,MAAM,GAAG,KAAK,KAAK,CAAC,CAAA;IAC1B,MAAM,UAAU,GAAG,oBAAoB,CAAC,YAAY,CAAC,IAAI,GAAG,YAAY,GAAG,CAAA;IAE3E,OAAO;QACL,YAAY,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE;QAChD,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,YAAY;KACnC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;AACZ,CAAC","sourcesContent":["const irregularInflections: Record<string, string> = { person: 'people', reply: 'replies' }\n\nexport function pluralize(count: number, singularWord: string, includeCount = true) {\n const plural = count !== 1\n const pluralWord = irregularInflections[singularWord] || `${singularWord}s`\n\n return [\n includeCount ? `${count.toLocaleString()} ` : '',\n plural ? pluralWord : singularWord,\n ].join('')\n}\n"]}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export declare const getMessageRequestArgs: ({ conversation_id, messageId, }: {
|
|
2
|
+
conversation_id: number;
|
|
3
|
+
messageId: string;
|
|
4
|
+
}) => {
|
|
5
|
+
url: string;
|
|
6
|
+
data: {
|
|
7
|
+
perPage: number;
|
|
8
|
+
fields: {
|
|
9
|
+
Message: string[];
|
|
10
|
+
Person: string[];
|
|
11
|
+
ReactionCount: string[];
|
|
12
|
+
};
|
|
13
|
+
include: string[];
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
export declare const getMessageQueryKey: ({ conversation_id, messageId, }: {
|
|
17
|
+
conversation_id: number;
|
|
18
|
+
messageId: string;
|
|
19
|
+
}) => import("../../hooks/use_suspense_api").RequestQueryKey;
|
|
20
|
+
//# sourceMappingURL=get_message.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get_message.d.ts","sourceRoot":"","sources":["../../../src/utils/request/get_message.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,qBAAqB,oCAG/B;IACD,eAAe,EAAE,MAAM,CAAA;IACvB,SAAS,EAAE,MAAM,CAAA;CAClB;;;;;;;;;;;CAWA,CAAA;AAED,eAAO,MAAM,kBAAkB,oCAG5B;IACD,eAAe,EAAE,MAAM,CAAA;IACvB,SAAS,EAAE,MAAM,CAAA;CAClB,2DAGA,CAAA"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { getRequestQueryKey } from '../../hooks/use_suspense_api';
|
|
2
|
+
import { getMessageFields, getMessagesInclude } from './messages_data_options';
|
|
3
|
+
export const getMessageRequestArgs = ({ conversation_id, messageId, }) => {
|
|
4
|
+
const url = `/me/conversations/${conversation_id}/messages/${messageId}`;
|
|
5
|
+
return {
|
|
6
|
+
url,
|
|
7
|
+
data: {
|
|
8
|
+
perPage: 25,
|
|
9
|
+
fields: getMessageFields,
|
|
10
|
+
include: getMessagesInclude,
|
|
11
|
+
},
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
export const getMessageQueryKey = ({ conversation_id, messageId, }) => {
|
|
15
|
+
const requestArgs = getMessageRequestArgs({ conversation_id, messageId });
|
|
16
|
+
return getRequestQueryKey(requestArgs);
|
|
17
|
+
};
|
|
18
|
+
//# sourceMappingURL=get_message.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get_message.js","sourceRoot":"","sources":["../../../src/utils/request/get_message.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAA;AACjE,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAE9E,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,EACpC,eAAe,EACf,SAAS,GAIV,EAAE,EAAE;IACH,MAAM,GAAG,GAAG,qBAAqB,eAAe,aAAa,SAAS,EAAE,CAAA;IAExE,OAAO;QACL,GAAG;QACH,IAAI,EAAE;YACJ,OAAO,EAAE,EAAE;YACX,MAAM,EAAE,gBAAgB;YACxB,OAAO,EAAE,kBAAkB;SAC5B;KACF,CAAA;AACH,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,EACjC,eAAe,EACf,SAAS,GAIV,EAAE,EAAE;IACH,MAAM,WAAW,GAAG,qBAAqB,CAAC,EAAE,eAAe,EAAE,SAAS,EAAE,CAAC,CAAA;IACzE,OAAO,kBAAkB,CAAC,WAAW,CAAC,CAAA;AACxC,CAAC,CAAA","sourcesContent":["import { getRequestQueryKey } from '../../hooks/use_suspense_api'\nimport { getMessageFields, getMessagesInclude } from './messages_data_options'\n\nexport const getMessageRequestArgs = ({\n conversation_id,\n messageId,\n}: {\n conversation_id: number\n messageId: string\n}) => {\n const url = `/me/conversations/${conversation_id}/messages/${messageId}`\n\n return {\n url,\n data: {\n perPage: 25,\n fields: getMessageFields,\n include: getMessagesInclude,\n },\n }\n}\n\nexport const getMessageQueryKey = ({\n conversation_id,\n messageId,\n}: {\n conversation_id: number\n messageId: string\n}) => {\n const requestArgs = getMessageRequestArgs({ conversation_id, messageId })\n return getRequestQueryKey(requestArgs)\n}\n"]}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export declare const getMessagesRequestArgs: ({ conversation_id, reply_root_id, }: {
|
|
2
|
+
conversation_id: number;
|
|
3
|
+
reply_root_id?: string | null;
|
|
4
|
+
}) => {
|
|
5
|
+
url: string;
|
|
6
|
+
data: {
|
|
7
|
+
perPage: number;
|
|
8
|
+
fields: {
|
|
9
|
+
Message: string[];
|
|
10
|
+
Person: string[];
|
|
11
|
+
ReactionCount: string[];
|
|
12
|
+
};
|
|
13
|
+
include: string[];
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
export declare const getMessagesQueryKey: ({ conversation_id, reply_root_id, }: {
|
|
17
|
+
conversation_id: number;
|
|
18
|
+
reply_root_id?: string | null;
|
|
19
|
+
}) => import("../../hooks/use_suspense_api").RequestQueryKey;
|
|
20
|
+
//# sourceMappingURL=get_messages.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get_messages.d.ts","sourceRoot":"","sources":["../../../src/utils/request/get_messages.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,sBAAsB,wCAGhC;IACD,eAAe,EAAE,MAAM,CAAA;IACvB,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAC9B;;;;;;;;;;;CAaA,CAAA;AAED,eAAO,MAAM,mBAAmB,wCAG7B;IACD,eAAe,EAAE,MAAM,CAAA;IACvB,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAC9B,2DAGA,CAAA"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { getRequestQueryKey } from '../../hooks/use_suspense_api';
|
|
2
|
+
import { getMessageFields, getMessagesInclude } from './messages_data_options';
|
|
3
|
+
export const getMessagesRequestArgs = ({ conversation_id, reply_root_id, }) => {
|
|
4
|
+
const url = reply_root_id
|
|
5
|
+
? `/me/conversations/${conversation_id}/messages/${reply_root_id}/replies`
|
|
6
|
+
: `/me/conversations/${conversation_id}/messages`;
|
|
7
|
+
return {
|
|
8
|
+
url,
|
|
9
|
+
data: {
|
|
10
|
+
perPage: 25,
|
|
11
|
+
fields: getMessageFields,
|
|
12
|
+
include: getMessagesInclude,
|
|
13
|
+
},
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
export const getMessagesQueryKey = ({ conversation_id, reply_root_id, }) => {
|
|
17
|
+
const requestArgs = getMessagesRequestArgs({ conversation_id, reply_root_id });
|
|
18
|
+
return getRequestQueryKey(requestArgs);
|
|
19
|
+
};
|
|
20
|
+
//# sourceMappingURL=get_messages.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get_messages.js","sourceRoot":"","sources":["../../../src/utils/request/get_messages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAA;AACjE,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAE9E,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,EACrC,eAAe,EACf,aAAa,GAId,EAAE,EAAE;IACH,MAAM,GAAG,GAAG,aAAa;QACvB,CAAC,CAAC,qBAAqB,eAAe,aAAa,aAAa,UAAU;QAC1E,CAAC,CAAC,qBAAqB,eAAe,WAAW,CAAA;IAEnD,OAAO;QACL,GAAG;QACH,IAAI,EAAE;YACJ,OAAO,EAAE,EAAE;YACX,MAAM,EAAE,gBAAgB;YACxB,OAAO,EAAE,kBAAkB;SAC5B;KACF,CAAA;AACH,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,EAClC,eAAe,EACf,aAAa,GAId,EAAE,EAAE;IACH,MAAM,WAAW,GAAG,sBAAsB,CAAC,EAAE,eAAe,EAAE,aAAa,EAAE,CAAC,CAAA;IAC9E,OAAO,kBAAkB,CAAC,WAAW,CAAC,CAAA;AACxC,CAAC,CAAA","sourcesContent":["import { getRequestQueryKey } from '../../hooks/use_suspense_api'\nimport { getMessageFields, getMessagesInclude } from './messages_data_options'\n\nexport const getMessagesRequestArgs = ({\n conversation_id,\n reply_root_id,\n}: {\n conversation_id: number\n reply_root_id?: string | null\n}) => {\n const url = reply_root_id\n ? `/me/conversations/${conversation_id}/messages/${reply_root_id}/replies`\n : `/me/conversations/${conversation_id}/messages`\n\n return {\n url,\n data: {\n perPage: 25,\n fields: getMessageFields,\n include: getMessagesInclude,\n },\n }\n}\n\nexport const getMessagesQueryKey = ({\n conversation_id,\n reply_root_id,\n}: {\n conversation_id: number\n reply_root_id?: string | null\n}) => {\n const requestArgs = getMessagesRequestArgs({ conversation_id, reply_root_id })\n return getRequestQueryKey(requestArgs)\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"messages_data_options.d.ts","sourceRoot":"","sources":["../../../src/utils/request/messages_data_options.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB;;;;CAe5B,CAAA;AAED,eAAO,MAAM,kBAAkB,UAAgC,CAAA"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export const getMessageFields = {
|
|
2
|
+
Message: [
|
|
3
|
+
'text',
|
|
4
|
+
'text_edited_at',
|
|
5
|
+
'mine',
|
|
6
|
+
'attachments',
|
|
7
|
+
'created_at',
|
|
8
|
+
'deleted_at',
|
|
9
|
+
'author',
|
|
10
|
+
'reaction_counts',
|
|
11
|
+
'reply_count',
|
|
12
|
+
'reply_root',
|
|
13
|
+
],
|
|
14
|
+
Person: ['name', 'avatar'],
|
|
15
|
+
ReactionCount: ['value', 'count', 'mine', 'message_id', 'author_ids'],
|
|
16
|
+
};
|
|
17
|
+
export const getMessagesInclude = ['author', 'reaction_counts'];
|
|
18
|
+
//# sourceMappingURL=messages_data_options.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"messages_data_options.js","sourceRoot":"","sources":["../../../src/utils/request/messages_data_options.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,OAAO,EAAE;QACP,MAAM;QACN,gBAAgB;QAChB,MAAM;QACN,aAAa;QACb,YAAY;QACZ,YAAY;QACZ,QAAQ;QACR,iBAAiB;QACjB,aAAa;QACb,YAAY;KACb;IACD,MAAM,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC;IAC1B,aAAa,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,YAAY,CAAC;CACtE,CAAA;AAED,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,QAAQ,EAAE,iBAAiB,CAAC,CAAA","sourcesContent":["export const getMessageFields = {\n Message: [\n 'text',\n 'text_edited_at',\n 'mine',\n 'attachments',\n 'created_at',\n 'deleted_at',\n 'author',\n 'reaction_counts',\n 'reply_count',\n 'reply_root',\n ],\n Person: ['name', 'avatar'],\n ReactionCount: ['value', 'count', 'mine', 'message_id', 'author_ids'],\n}\n\nexport const getMessagesInclude = ['author', 'reaction_counts']\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@planningcenter/chat-react-native",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.17.0-rc.1",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
@@ -56,5 +56,5 @@
|
|
|
56
56
|
"react-native-url-polyfill": "^2.0.0",
|
|
57
57
|
"typescript": "<5.6.0"
|
|
58
58
|
},
|
|
59
|
-
"gitHead": "
|
|
59
|
+
"gitHead": "9cc0a46532ce7bbf7f32bbb5e5873bd5c709b3f0"
|
|
60
60
|
}
|
|
@@ -14,4 +14,7 @@ describe('pluralize', () => {
|
|
|
14
14
|
it('can convert "person" to "people"', () => {
|
|
15
15
|
expect(pluralize(2, 'person', false)).toEqual('people')
|
|
16
16
|
})
|
|
17
|
+
it('can convert "reply" to "replies"', () => {
|
|
18
|
+
expect(pluralize(2, 'reply', false)).toEqual('replies')
|
|
19
|
+
})
|
|
17
20
|
})
|
|
@@ -24,8 +24,8 @@ import { useLiveRelativeTime } from '../../hooks/use_live_relative_time'
|
|
|
24
24
|
import { MessageReadReceipts } from './message_read_receipts'
|
|
25
25
|
import { isNewMessage, useMessageCreateOrUpdate } from '../../hooks/use_message_create_or_update'
|
|
26
26
|
import { Haptic } from '../../utils/native_adapters'
|
|
27
|
-
import { TheirReplyConnector, MyReplyConnector } from './reply_connectors'
|
|
28
|
-
import { REPLIES_FEATURE_ENABLED } from '../../utils'
|
|
27
|
+
import { TheirReplyConnector, MyReplyConnector, AVATAR_CONNECTOR_SPACING } from './reply_connectors'
|
|
28
|
+
import { pluralize, REPLIES_FEATURE_ENABLED } from '../../utils'
|
|
29
29
|
|
|
30
30
|
/** Message
|
|
31
31
|
* Component for display of a message within a conversation list
|
|
@@ -130,10 +130,16 @@ export function Message({
|
|
|
130
130
|
}
|
|
131
131
|
|
|
132
132
|
const renderAuthor = (!message.mine && message.renderAuthor) || false
|
|
133
|
-
const messageBottomMargin = message.lastInGroup ? 12 : hasReactions || showMessageMeta ? 8 : 4
|
|
134
133
|
const messagePendingLabel = isPersisted ? 'Saving' : 'Sending'
|
|
135
134
|
const showReplyCountButton =
|
|
136
135
|
!inReplyScreen && message.replyRootId === message.id && REPLIES_FEATURE_ENABLED
|
|
136
|
+
const replyCountText = pluralize(message.replyCount, 'reply')
|
|
137
|
+
const messageBottomMargin =
|
|
138
|
+
message.lastInGroup || message.nextIsReplyShadowMessage
|
|
139
|
+
? 16
|
|
140
|
+
: hasReactions || showMessageMeta || showReplyCountButton
|
|
141
|
+
? 8
|
|
142
|
+
: 4
|
|
137
143
|
|
|
138
144
|
return (
|
|
139
145
|
<Pressable
|
|
@@ -162,7 +168,11 @@ export function Message({
|
|
|
162
168
|
</View>
|
|
163
169
|
)}
|
|
164
170
|
<View style={[styles.messageContent, { marginBottom: messageBottomMargin }]}>
|
|
165
|
-
{renderAuthor &&
|
|
171
|
+
{renderAuthor && (
|
|
172
|
+
<Text variant="footnote" style={styles.authorName}>
|
|
173
|
+
{message.author.name}
|
|
174
|
+
</Text>
|
|
175
|
+
)}
|
|
166
176
|
<View
|
|
167
177
|
style={styles.messageBubble}
|
|
168
178
|
onLayout={e => setMessageBubbleHeight(e.nativeEvent.layout.height)}
|
|
@@ -189,7 +199,7 @@ export function Message({
|
|
|
189
199
|
accessibilityHint="Navigates to reply screen for this message"
|
|
190
200
|
accessibilityRole="link"
|
|
191
201
|
>
|
|
192
|
-
{
|
|
202
|
+
{replyCountText}
|
|
193
203
|
</TextButton>
|
|
194
204
|
)}
|
|
195
205
|
{hasReactions && (
|
|
@@ -282,11 +292,14 @@ const useMessageStyles = ({ mine }: MessageResource) => {
|
|
|
282
292
|
gap: 4,
|
|
283
293
|
},
|
|
284
294
|
avatar: {
|
|
285
|
-
marginBottom:
|
|
295
|
+
marginBottom: AVATAR_CONNECTOR_SPACING,
|
|
286
296
|
},
|
|
287
297
|
avatarPlaceholder: {
|
|
288
298
|
width: MESSAGE_AUTHOR_AVATAR_COLUMN_WIDTH, // Same width as avatar
|
|
289
299
|
},
|
|
300
|
+
authorName: {
|
|
301
|
+
fontWeight: platformFontWeightMedium,
|
|
302
|
+
},
|
|
290
303
|
messageBubble: {
|
|
291
304
|
backgroundColor: messageBubbleBackgroundColor,
|
|
292
305
|
borderRadius: 8,
|
|
@@ -59,7 +59,7 @@ export const MessageForm = {
|
|
|
59
59
|
interface MessagesFormRootProps extends ViewProps {
|
|
60
60
|
conversation: ConversationResource
|
|
61
61
|
currentlyEditingMessage?: MessageResource | null
|
|
62
|
-
replyRootId?: string
|
|
62
|
+
replyRootId?: string | null
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
const MessageFormContext = React.createContext<{
|
|
@@ -73,7 +73,7 @@ const MessageFormContext = React.createContext<{
|
|
|
73
73
|
attachmentUploader?: ReturnType<typeof useAttachmentUploader>
|
|
74
74
|
currentlyEditingMessage?: MessageResource | null
|
|
75
75
|
reset: () => void
|
|
76
|
-
replyRootId?: string
|
|
76
|
+
replyRootId?: string | null
|
|
77
77
|
}>({
|
|
78
78
|
text: '',
|
|
79
79
|
setText: (_text: string) => {},
|