@planningcenter/chat-react-native 3.17.0-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 +33 -14
- 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 +10 -2
- package/build/screens/conversation_screen.d.ts.map +1 -1
- package/build/screens/conversation_screen.js +27 -0
- package/build/screens/conversation_screen.js.map +1 -1
- package/build/types/resources/message.d.ts +3 -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 +42 -20
- 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 +48 -2
- package/src/types/resources/message.ts +3 -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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reply_connectors.js","sourceRoot":"","sources":["../../../src/components/conversation/reply_connectors.tsx"],"names":[],"mappings":"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","sourcesContent":["import { StyleSheet, View, ViewStyle } from 'react-native'\nimport Svg, { Path } from 'react-native-svg'\nimport { useTheme } from '../../hooks'\nimport { MessageResource } from '../../types'\nimport {\n CONVERSATION_MESSAGE_LIST_PADDING_HORIZONTAL,\n MESSAGE_AUTHOR_AVATAR_COLUMN_WIDTH,\n} from '../../utils/styles'\nimport { REPLIES_FEATURE_ENABLED } from '../../utils'\n\nconst MY_REPLY_CONNECTOR_WIDTH = 38\nconst CONNECTOR_BORDER_WIDTH = 4\n\ninterface ReplyConnectorProps {\n message: MessageResource\n messageBubbleHeight: number\n}\n\nexport function TheirReplyConnector({ message, messageBubbleHeight }: ReplyConnectorProps) {\n const styles = useStyles()\n\n if (!REPLIES_FEATURE_ENABLED) return null\n\n const connectorMap: Record<string, React.ReactNode | null> = {\n shortTailCurve: <ShortTailCurveConnector height={messageBubbleHeight / 2} />,\n shortHeadCurve: <ShortHeadCurveConnector height={messageBubbleHeight / 2} />,\n verticalLine: <VerticalLineConnector />,\n default: null,\n }\n\n const getConnectorKey = () => {\n const { threadPosition, renderAuthor } = message\n\n if (threadPosition === 'first' && !renderAuthor) return 'shortHeadCurve'\n if (threadPosition === 'last' && !renderAuthor) return 'shortTailCurve'\n if ((threadPosition === 'first' && renderAuthor) || threadPosition === 'center')\n return 'verticalLine'\n return 'default'\n }\n\n const ConnectorComponent = connectorMap[getConnectorKey()]\n if (!ConnectorComponent) return null\n\n return <View style={styles.theirReplyConnectorContainer}>{ConnectorComponent}</View>\n}\n\nexport function MyReplyConnector({ message, messageBubbleHeight }: ReplyConnectorProps) {\n const styles = useStyles()\n\n if (!REPLIES_FEATURE_ENABLED) return null\n\n const connectorMap: Record<string, React.ReactNode | null> = {\n longTailCurve: (\n <LongTailCurveConnector\n height={messageBubbleHeight / 2}\n style={styles.myReplyConnectorPosition}\n />\n ),\n longHeadCurve: (\n <LongHeadCurveConnector\n height={messageBubbleHeight / 2}\n style={styles.myReplyConnectorPosition}\n />\n ),\n verticalLine: <VerticalLineConnector style={styles.myReplyConnectorPosition} />,\n swirl: <SwirlConnector style={styles.myReplyConnectorPosition} />,\n default: null,\n }\n\n const getConnectorKey = () => {\n const { threadPosition, prevIsMyReply, nextIsMyReply } = message\n\n if (threadPosition === 'first') return 'longHeadCurve'\n if (threadPosition === 'center' && prevIsMyReply && nextIsMyReply) return 'verticalLine'\n if (threadPosition === 'center' && (!prevIsMyReply || !nextIsMyReply)) return 'swirl'\n if (threadPosition === 'last') return 'longTailCurve'\n\n return 'default'\n }\n\n const ConnectorComponent = connectorMap[getConnectorKey()]\n if (!ConnectorComponent) return null\n\n return <View style={styles.myReplyConnectorContainer}>{ConnectorComponent}</View>\n}\n\nfunction VerticalLineConnector({ style }: { style?: ViewStyle }) {\n const styles = useStyles()\n return <View style={[styles.verticalLineConnector, style]} />\n}\n\nfunction LongHeadCurveConnector({ height, style }: { height: number; style?: ViewStyle }) {\n const styles = useStyles()\n return <View style={[styles.longHeadCurveConnector, { height, marginTop: height }, style]} />\n}\n\nfunction LongTailCurveConnector({ height, style }: { height: number; style?: ViewStyle }) {\n const styles = useStyles()\n return <View style={[styles.longTailCurveConnector, { height }, style]} />\n}\n\nfunction ShortHeadCurveConnector({ height }: { height: number }) {\n const styles = useStyles()\n return <View style={[styles.shortHeadCurveConnector, { marginTop: height }]} />\n}\n\nfunction ShortTailCurveConnector({ height }: { height: number }) {\n const styles = useStyles()\n return <View style={[styles.shortTailCurveConnector, { height }]} />\n}\n\nfunction SwirlConnector({ style }: { style?: ViewStyle }) {\n const styles = useStyles()\n const { colors } = useTheme()\n const borderColor = colors.borderColorDefaultBase\n\n return (\n <View style={[styles.swirlConnectorContainer, style]}>\n <View style={styles.swirlConnectorVerticalLineHead} />\n <Svg width={27} height={34} fill=\"none\">\n <Path\n stroke={borderColor}\n strokeWidth={CONNECTOR_BORDER_WIDTH}\n d=\"M2.07 34c0-6.142 1.201-12.283 3.343-17m0 0c2.305-5.075 5.699-8.5 9.857-8.5 4.86 0 8.8 3.806 8.8 8.5s-3.94 8.5-8.8 8.5c-4.158 0-7.552-3.425-9.857-8.5zm0 0C3.271 12.283 2.07 6.142 2.07 0\"\n />\n </Svg>\n <View style={styles.swirlConnectorVerticalLineTail} />\n </View>\n )\n}\n\nconst useStyles = () => {\n const { colors } = useTheme()\n const borderColor = colors.borderColorDefaultBase\n\n return StyleSheet.create({\n theirReplyConnectorContainer: {\n width: '50%',\n alignSelf: 'flex-end',\n flex: 1,\n },\n myReplyConnectorContainer: {\n width: MESSAGE_AUTHOR_AVATAR_COLUMN_WIDTH,\n position: 'absolute',\n left: CONVERSATION_MESSAGE_LIST_PADDING_HORIZONTAL,\n top: 0,\n bottom: 0,\n },\n myReplyConnectorPosition: {\n left: '50%',\n },\n verticalLineConnector: {\n flex: 1,\n borderLeftWidth: CONNECTOR_BORDER_WIDTH,\n borderLeftColor: borderColor,\n },\n longHeadCurveConnector: {\n width: MY_REPLY_CONNECTOR_WIDTH,\n borderColor: borderColor,\n borderLeftWidth: CONNECTOR_BORDER_WIDTH,\n borderTopWidth: CONNECTOR_BORDER_WIDTH,\n borderTopLeftRadius: 16,\n flex: 1,\n },\n longTailCurveConnector: {\n width: MY_REPLY_CONNECTOR_WIDTH,\n borderColor: borderColor,\n borderLeftWidth: CONNECTOR_BORDER_WIDTH,\n borderBottomWidth: CONNECTOR_BORDER_WIDTH,\n borderBottomLeftRadius: 16,\n },\n shortHeadCurveConnector: {\n borderColor: borderColor,\n borderLeftWidth: CONNECTOR_BORDER_WIDTH,\n borderTopWidth: CONNECTOR_BORDER_WIDTH,\n borderTopLeftRadius: 16,\n flex: 1,\n },\n shortTailCurveConnector: {\n borderColor: borderColor,\n borderLeftWidth: CONNECTOR_BORDER_WIDTH,\n borderBottomWidth: CONNECTOR_BORDER_WIDTH,\n borderBottomLeftRadius: 16,\n },\n swirlConnectorContainer: {\n flex: 1,\n },\n swirlConnectorVerticalLineHead: {\n backgroundColor: borderColor,\n width: CONNECTOR_BORDER_WIDTH,\n flex: 1,\n marginBottom: -1, // Ensures there is no gap between the vertical line and the swirl connector\n },\n swirlConnectorVerticalLineTail: {\n backgroundColor: borderColor,\n width: CONNECTOR_BORDER_WIDTH,\n flex: 1,\n marginTop: -1, // Ensures there is no gap between the vertical line and the swirl connector\n },\n })\n}\n"]}
|
|
1
|
+
{"version":3,"file":"reply_connectors.js","sourceRoot":"","sources":["../../../src/components/conversation/reply_connectors.tsx"],"names":[],"mappings":"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","sourcesContent":["import { StyleSheet, View, ViewStyle } from 'react-native'\nimport Svg, { Path } from 'react-native-svg'\nimport { useTheme } from '../../hooks'\nimport { MessageResource } from '../../types'\nimport {\n CONVERSATION_MESSAGE_LIST_PADDING_HORIZONTAL,\n MESSAGE_AUTHOR_AVATAR_COLUMN_WIDTH,\n} from '../../utils/styles'\nimport { REPLIES_FEATURE_ENABLED } from '../../utils'\n\nconst MY_REPLY_CONNECTOR_WIDTH = 38\nconst CONNECTOR_BORDER_WIDTH = 4\nconst OFFSET_CONNECTOR_CONTAINER = CONNECTOR_BORDER_WIDTH / 2 // Accounts for the border width ensuring the connectors are centered under the avatar\nexport const AVATAR_CONNECTOR_SPACING = 8\n\ninterface ReplyConnectorProps {\n message: MessageResource\n messageBubbleHeight: number\n}\n\nexport function TheirReplyConnector({ message, messageBubbleHeight }: ReplyConnectorProps) {\n const styles = useStyles()\n const { nextRendersAuthor, threadPosition, renderAuthor, isReplyShadowMessage } = message\n\n if (!REPLIES_FEATURE_ENABLED) return null\n if (messageBubbleHeight === 0) return null // Prevents UI shifting\n\n const connectorMap: Record<string, React.ReactNode | null> = {\n shortTailCurve: <ShortTailCurveConnector height={messageBubbleHeight / 2} />,\n shortHeadCurve: <ShortHeadCurveConnector height={messageBubbleHeight / 2} />,\n verticalLine: <VerticalLineConnector />,\n default: null,\n }\n\n const getConnectorKey = () => {\n if (threadPosition === 'first' && !renderAuthor) return 'shortHeadCurve'\n if (threadPosition === 'last' && !renderAuthor) return 'shortTailCurve'\n if (\n (threadPosition === 'first' && renderAuthor) ||\n threadPosition === 'center' ||\n isReplyShadowMessage\n )\n return 'verticalLine'\n return 'default'\n }\n\n const ConnectorComponent = connectorMap[getConnectorKey()]\n if (!ConnectorComponent) return null\n\n const spacerStyle = nextRendersAuthor ? styles.theirReplyConnectorSpacer : null\n\n return (\n <View style={[styles.theirReplyConnectorContainer, spacerStyle]}>{ConnectorComponent}</View>\n )\n}\n\nexport function MyReplyConnector({ message, messageBubbleHeight }: ReplyConnectorProps) {\n const styles = useStyles()\n const { nextRendersAuthor, threadPosition, prevIsMyReply, nextIsMyReply, isReplyShadowMessage } =\n message\n\n if (!REPLIES_FEATURE_ENABLED) return null\n if (messageBubbleHeight === 0) return null // Prevents UI shifting\n\n const connectorMap: Record<string, React.ReactNode | null> = {\n longTailCurve: (\n <LongTailCurveConnector\n height={messageBubbleHeight / 2}\n style={styles.myReplyConnectorPosition}\n />\n ),\n longHeadCurve: (\n <LongHeadCurveConnector\n height={messageBubbleHeight / 2}\n style={styles.myReplyConnectorPosition}\n />\n ),\n verticalLine: <VerticalLineConnector style={styles.myReplyConnectorPosition} />,\n swirl: <SwirlConnector style={styles.myReplyConnectorPosition} height={messageBubbleHeight} />,\n default: null,\n }\n\n const getConnectorKey = () => {\n if (threadPosition === 'first' || isReplyShadowMessage) return 'longHeadCurve'\n if (threadPosition === 'center' && prevIsMyReply && nextIsMyReply) return 'verticalLine'\n if (threadPosition === 'center' && (!prevIsMyReply || !nextIsMyReply)) return 'swirl'\n if (threadPosition === 'last') return 'longTailCurve'\n\n return 'default'\n }\n\n const ConnectorComponent = connectorMap[getConnectorKey()]\n if (!ConnectorComponent) return null\n\n const spacerStyle = nextRendersAuthor ? styles.myReplyConnectorSpacer : null\n\n return <View style={[styles.myReplyConnectorContainer, spacerStyle]}>{ConnectorComponent}</View>\n}\n\nfunction VerticalLineConnector({ style }: { style?: ViewStyle }) {\n const styles = useStyles()\n return <View style={[styles.verticalLineConnector, style]} />\n}\n\nfunction LongHeadCurveConnector({ height, style }: { height: number; style?: ViewStyle }) {\n const styles = useStyles()\n return <View style={[styles.longHeadCurveConnector, { height, marginTop: height }, style]} />\n}\n\nfunction LongTailCurveConnector({ height, style }: { height: number; style?: ViewStyle }) {\n const styles = useStyles()\n return <View style={[styles.longTailCurveConnector, { height }, style]} />\n}\n\nfunction ShortHeadCurveConnector({ height }: { height: number }) {\n const styles = useStyles()\n return <View style={[styles.shortHeadCurveConnector, { marginTop: height }]} />\n}\n\nfunction ShortTailCurveConnector({ height }: { height: number }) {\n const styles = useStyles()\n return <View style={[styles.shortTailCurveConnector, { height }]} />\n}\n\nfunction SwirlConnector({ style, height }: { style?: ViewStyle; height: number }) {\n const styles = useStyles()\n const { colors } = useTheme()\n\n return (\n <View style={[styles.swirlConnectorContainer, style]}>\n <View style={{ height }}>\n <View style={styles.swirlConnectorVerticalLineHead} />\n <Svg width={27} height={34} fill=\"none\">\n <Path\n stroke={colors.borderColorDefaultBase}\n strokeWidth={CONNECTOR_BORDER_WIDTH}\n d=\"M2.07 34c0-6.142 1.201-12.283 3.343-17m0 0c2.305-5.075 5.699-8.5 9.857-8.5 4.86 0 8.8 3.806 8.8 8.5s-3.94 8.5-8.8 8.5c-4.158 0-7.552-3.425-9.857-8.5zm0 0C3.271 12.283 2.07 6.142 2.07 0\"\n />\n </Svg>\n <View style={styles.swirlConnectorVerticalLineTail} />\n </View>\n <View style={styles.swirlConnectorVerticalLineTail} />\n </View>\n )\n}\n\nconst useStyles = () => {\n const { colors } = useTheme()\n const borderColor = colors.borderColorDefaultBase\n\n return StyleSheet.create({\n theirReplyConnectorContainer: {\n width: '50%',\n marginRight: OFFSET_CONNECTOR_CONTAINER,\n alignSelf: 'flex-end',\n flex: 1,\n },\n theirReplyConnectorSpacer: {\n paddingBottom: AVATAR_CONNECTOR_SPACING,\n },\n myReplyConnectorContainer: {\n width: MESSAGE_AUTHOR_AVATAR_COLUMN_WIDTH,\n position: 'absolute',\n left: CONVERSATION_MESSAGE_LIST_PADDING_HORIZONTAL - OFFSET_CONNECTOR_CONTAINER,\n top: 0,\n bottom: 0,\n },\n myReplyConnectorPosition: {\n left: '50%',\n },\n myReplyConnectorSpacer: {\n bottom: AVATAR_CONNECTOR_SPACING,\n },\n verticalLineConnector: {\n flex: 1,\n borderLeftWidth: CONNECTOR_BORDER_WIDTH,\n borderLeftColor: borderColor,\n },\n longHeadCurveConnector: {\n width: MY_REPLY_CONNECTOR_WIDTH,\n borderColor: borderColor,\n borderLeftWidth: CONNECTOR_BORDER_WIDTH,\n borderTopWidth: CONNECTOR_BORDER_WIDTH,\n borderTopLeftRadius: 16,\n flex: 1,\n },\n longTailCurveConnector: {\n width: MY_REPLY_CONNECTOR_WIDTH,\n borderColor: borderColor,\n borderLeftWidth: CONNECTOR_BORDER_WIDTH,\n borderBottomWidth: CONNECTOR_BORDER_WIDTH,\n borderBottomLeftRadius: 16,\n },\n shortHeadCurveConnector: {\n borderColor: borderColor,\n borderLeftWidth: CONNECTOR_BORDER_WIDTH,\n borderTopWidth: CONNECTOR_BORDER_WIDTH,\n borderTopLeftRadius: 16,\n flex: 1,\n },\n shortTailCurveConnector: {\n borderColor: borderColor,\n borderLeftWidth: CONNECTOR_BORDER_WIDTH,\n borderBottomWidth: CONNECTOR_BORDER_WIDTH,\n borderBottomLeftRadius: 16,\n },\n swirlConnectorContainer: {\n flex: 1,\n },\n swirlConnectorVerticalLineHead: {\n backgroundColor: borderColor,\n width: CONNECTOR_BORDER_WIDTH,\n flex: 1,\n marginBottom: -1, // Ensures there is no gap between the vertical line and the swirl connector\n },\n swirlConnectorVerticalLineTail: {\n backgroundColor: borderColor,\n width: CONNECTOR_BORDER_WIDTH,\n flex: 1,\n marginTop: -1, // Ensures there is no gap between the vertical line and the swirl connector\n },\n })\n}\n"]}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { MessageResource } from '../../types';
|
|
3
|
+
interface ReplyShadowMessageProps extends MessageResource {
|
|
4
|
+
messageId: string;
|
|
5
|
+
conversation_id: number;
|
|
6
|
+
inReplyScreen?: boolean;
|
|
7
|
+
isReplyShadowMessage: boolean;
|
|
8
|
+
nextRendersAuthor: boolean;
|
|
9
|
+
}
|
|
10
|
+
export declare function ReplyShadowMessage({ conversation_id, inReplyScreen, messageId, isReplyShadowMessage, nextRendersAuthor, }: ReplyShadowMessageProps): React.JSX.Element | null;
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=reply_shadow_message.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reply_shadow_message.d.ts","sourceRoot":"","sources":["../../../src/components/conversation/reply_shadow_message.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AASzB,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAmB7C,UAAU,uBAAwB,SAAQ,eAAe;IACvD,SAAS,EAAE,MAAM,CAAA;IACjB,eAAe,EAAE,MAAM,CAAA;IACvB,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,oBAAoB,EAAE,OAAO,CAAA;IAC7B,iBAAiB,EAAE,OAAO,CAAA;CAC3B;AAED,wBAAgB,kBAAkB,CAAC,EACjC,eAAe,EACf,aAAa,EACb,SAAS,EACT,oBAAoB,EACpB,iBAAiB,GAClB,EAAE,uBAAuB,4BAczB"}
|
|
@@ -5,9 +5,25 @@ import { useAnimatedMessageBackgroundColor, useFontScale, useScalableNumberOfLin
|
|
|
5
5
|
import { CONVERSATION_MESSAGE_LIST_PADDING_HORIZONTAL, MAX_FONT_SIZE_MULTIPLIER, MESSAGE_AUTHOR_AVATAR_COLUMN_WIDTH, platformFontWeightMedium, } from '../../utils/styles';
|
|
6
6
|
import Animated from 'react-native-reanimated';
|
|
7
7
|
import { TheirReplyConnector, MyReplyConnector } from './reply_connectors';
|
|
8
|
-
import { assertKeysAreNumbers } from '../../utils';
|
|
8
|
+
import { assertKeysAreNumbers, pluralize } from '../../utils';
|
|
9
9
|
import { useNavigation } from '@react-navigation/native';
|
|
10
|
-
|
|
10
|
+
import { useConversationMessage } from '../../hooks/use_conversation_message';
|
|
11
|
+
export function ReplyShadowMessage({ conversation_id, inReplyScreen, messageId, isReplyShadowMessage, nextRendersAuthor, }) {
|
|
12
|
+
const { message, isError, isLoading } = useConversationMessage({ conversation_id, messageId });
|
|
13
|
+
if (inReplyScreen)
|
|
14
|
+
return null;
|
|
15
|
+
if (isLoading)
|
|
16
|
+
return <ShadowMessageFallback text="Loading..."/>;
|
|
17
|
+
if (isError || !message)
|
|
18
|
+
return <ShadowMessageFallback text="Message not found"/>;
|
|
19
|
+
const enrichedMessage = {
|
|
20
|
+
...message,
|
|
21
|
+
isReplyShadowMessage,
|
|
22
|
+
nextRendersAuthor,
|
|
23
|
+
};
|
|
24
|
+
return <ShadowMessageContent conversation_id={conversation_id} {...enrichedMessage}/>;
|
|
25
|
+
}
|
|
26
|
+
function ShadowMessageContent({ conversation_id, ...message }) {
|
|
11
27
|
const { text } = message;
|
|
12
28
|
const styles = useStyles(message);
|
|
13
29
|
const { colors } = useTheme();
|
|
@@ -15,10 +31,11 @@ export function ShadowMessage({ conversation_id, ...message }) {
|
|
|
15
31
|
const [messageBubbleHeight, setMessageBubbleHeight] = React.useState(0);
|
|
16
32
|
const { animatedBackgroundColor, handleMessagePressIn, handleMessagePressOut } = useAnimatedMessageBackgroundColor();
|
|
17
33
|
const scalableNumberOfLines = useScalableNumberOfLines(2);
|
|
34
|
+
const replyCountText = pluralize(message.replyCount, 'reply');
|
|
18
35
|
const handleNavigateToReplies = () => {
|
|
19
36
|
navigation.navigate('ConversationReply', {
|
|
20
37
|
conversation_id,
|
|
21
|
-
reply_root_id: message.
|
|
38
|
+
reply_root_id: message.replyRootId,
|
|
22
39
|
// TODO: Add a way to pass the reply root author's name
|
|
23
40
|
});
|
|
24
41
|
};
|
|
@@ -39,7 +56,7 @@ export function ShadowMessage({ conversation_id, ...message }) {
|
|
|
39
56
|
</View>
|
|
40
57
|
<View style={styles.messageMeta}>
|
|
41
58
|
<Text variant="footnote" style={styles.replyCountText}>
|
|
42
|
-
{
|
|
59
|
+
{replyCountText}
|
|
43
60
|
</Text>
|
|
44
61
|
</View>
|
|
45
62
|
</View>
|
|
@@ -96,6 +113,19 @@ function MessageAttachmentIcon({ iconName }) {
|
|
|
96
113
|
const styles = useStyles();
|
|
97
114
|
return (<Icon name={iconName} style={styles.attachmentIcon} maxFontSizeMultiplier={MAX_FONT_SIZE_MULTIPLIER}/>);
|
|
98
115
|
}
|
|
116
|
+
// TODO: The mine prop is not used yet, but in the future we will be adding a way to find the `mine` value for this fallback.
|
|
117
|
+
function ShadowMessageFallback({ text, mine }) {
|
|
118
|
+
const styles = useStyles({ mine });
|
|
119
|
+
return (<View style={styles.message}>
|
|
120
|
+
<View style={styles.messageContent}>
|
|
121
|
+
<View style={styles.messageBubble}>
|
|
122
|
+
<Text variant="footnote" style={styles.messageText}>
|
|
123
|
+
{text}
|
|
124
|
+
</Text>
|
|
125
|
+
</View>
|
|
126
|
+
</View>
|
|
127
|
+
</View>);
|
|
128
|
+
}
|
|
99
129
|
const useStyles = ({ mine, imageWidth = 32, imageHeight = 32 } = {}) => {
|
|
100
130
|
const { colors } = useTheme();
|
|
101
131
|
const fontScale = useFontScale({ maxFontSizeMultiplier: MAX_FONT_SIZE_MULTIPLIER });
|
|
@@ -158,4 +188,4 @@ const useStyles = ({ mine, imageWidth = 32, imageHeight = 32 } = {}) => {
|
|
|
158
188
|
},
|
|
159
189
|
});
|
|
160
190
|
};
|
|
161
|
-
//# sourceMappingURL=
|
|
191
|
+
//# sourceMappingURL=reply_shadow_message.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reply_shadow_message.js","sourceRoot":"","sources":["../../../src/components/conversation/reply_shadow_message.tsx"],"names":[],"mappings":"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","sourcesContent":["import React from 'react'\nimport { Pressable, StyleSheet, useWindowDimensions, View } from 'react-native'\nimport { Avatar, Icon, IconProps, Image, Text } from '../display'\nimport {\n useAnimatedMessageBackgroundColor,\n useFontScale,\n useScalableNumberOfLines,\n useTheme,\n} from '../../hooks'\nimport { MessageResource } from '../../types'\nimport {\n DenormalizedAttachmentResource,\n DenormalizedGiphyAttachmentResource,\n DenormalizedExpandedLinkAttachmentResource,\n DenormalizedMessageAttachmentResource,\n} from '../../types/resources/denormalized_attachment_resource'\nimport {\n CONVERSATION_MESSAGE_LIST_PADDING_HORIZONTAL,\n MAX_FONT_SIZE_MULTIPLIER,\n MESSAGE_AUTHOR_AVATAR_COLUMN_WIDTH,\n platformFontWeightMedium,\n} from '../../utils/styles'\nimport Animated from 'react-native-reanimated'\nimport { TheirReplyConnector, MyReplyConnector } from './reply_connectors'\nimport { assertKeysAreNumbers, pluralize } from '../../utils'\nimport { useNavigation } from '@react-navigation/native'\nimport { useConversationMessage } from '../../hooks/use_conversation_message'\n\ninterface ReplyShadowMessageProps extends MessageResource {\n messageId: string\n conversation_id: number\n inReplyScreen?: boolean\n isReplyShadowMessage: boolean\n nextRendersAuthor: boolean\n}\n\nexport function ReplyShadowMessage({\n conversation_id,\n inReplyScreen,\n messageId,\n isReplyShadowMessage,\n nextRendersAuthor,\n}: ReplyShadowMessageProps) {\n const { message, isError, isLoading } = useConversationMessage({ conversation_id, messageId })\n\n if (inReplyScreen) return null\n if (isLoading) return <ShadowMessageFallback text=\"Loading...\" />\n if (isError || !message) return <ShadowMessageFallback text=\"Message not found\" />\n\n const enrichedMessage = {\n ...message,\n isReplyShadowMessage,\n nextRendersAuthor,\n }\n\n return <ShadowMessageContent conversation_id={conversation_id} {...enrichedMessage} />\n}\n\ninterface ShadowMessageContentProps extends MessageResource {\n conversation_id: number\n}\n\nfunction ShadowMessageContent({ conversation_id, ...message }: ShadowMessageContentProps) {\n const { text } = message\n const styles = useStyles(message)\n const { colors } = useTheme()\n const navigation = useNavigation()\n\n const [messageBubbleHeight, setMessageBubbleHeight] = React.useState(0)\n const { animatedBackgroundColor, handleMessagePressIn, handleMessagePressOut } =\n useAnimatedMessageBackgroundColor()\n const scalableNumberOfLines = useScalableNumberOfLines(2)\n const replyCountText = pluralize(message.replyCount, 'reply')\n\n const handleNavigateToReplies = () => {\n navigation.navigate('ConversationReply', {\n conversation_id,\n reply_root_id: message.replyRootId,\n // TODO: Add a way to pass the reply root author's name\n })\n }\n\n return (\n <Pressable\n android_ripple={{ color: colors.androidRippleNeutral }}\n onPress={handleNavigateToReplies}\n onPressIn={handleMessagePressIn}\n onPressOut={handleMessagePressOut}\n accessibilityHint=\"Navigate to reply screen for this message\"\n accessibilityRole=\"link\"\n >\n <Animated.View style={[styles.message, animatedBackgroundColor]}>\n {!message.mine && (\n <View>\n <View style={styles.avatarWrapper}>\n <Avatar\n size=\"xs\"\n sourceUri={message.author.avatar}\n style={styles.avatar}\n maxFontSizeMultiplier={1}\n />\n </View>\n <TheirReplyConnector message={message} messageBubbleHeight={messageBubbleHeight} />\n </View>\n )}\n <View style={styles.messageContent}>\n <View\n style={styles.messageBubble}\n onLayout={e => setMessageBubbleHeight(e.nativeEvent.layout.height)}\n >\n <MessageAttachmentImagery attachments={message.attachments} />\n {text && (\n <Text\n variant=\"footnote\"\n style={styles.messageText}\n numberOfLines={scalableNumberOfLines}\n >\n {text}\n </Text>\n )}\n </View>\n <View style={styles.messageMeta}>\n <Text variant=\"footnote\" style={styles.replyCountText}>\n {replyCountText}\n </Text>\n </View>\n </View>\n {message.mine && (\n <MyReplyConnector message={message} messageBubbleHeight={messageBubbleHeight} />\n )}\n </Animated.View>\n </Pressable>\n )\n}\n\nfunction MessageAttachmentImagery({\n attachments,\n}: {\n attachments: DenormalizedAttachmentResource[]\n}) {\n if (!attachments || attachments.length === 0) return null\n\n const attachment = attachments[0]\n\n if (attachment.type === 'giphy') {\n return <GiphyImage attachment={attachment} />\n }\n if (attachment.type === 'ExpandedLink') {\n return <ExpandedLinkImage attachment={attachment} />\n }\n if (attachment.type === 'MessageAttachment') {\n const contentType = attachment.attributes?.contentType\n const basicType = contentType?.split('/')[0]\n\n switch (basicType) {\n case 'image':\n return <MessageAttachmentImage attachment={attachment} />\n case 'video':\n return <MessageAttachmentIcon iconName=\"general.outlinedVideoFile\" />\n case 'audio':\n return <MessageAttachmentIcon iconName=\"general.outlinedMusicFile\" />\n case 'application':\n return <MessageAttachmentIcon iconName=\"general.outlinedGenericFile\" />\n default:\n return null\n }\n }\n\n return null\n}\n\nfunction GiphyImage({ attachment }: { attachment: DenormalizedGiphyAttachmentResource }) {\n const { title, giphy } = attachment\n const { url } = giphy.fixedWidth\n const { width, height } = assertKeysAreNumbers(giphy.fixedWidth)\n const styles = useStyles({ imageWidth: width, imageHeight: height })\n\n return (\n <Image\n source={{ uri: url }}\n wrapperStyle={styles.imageWrapper}\n style={styles.image}\n alt={title}\n loaderSize={16}\n />\n )\n}\n\nfunction ExpandedLinkImage({\n attachment,\n}: {\n attachment: DenormalizedExpandedLinkAttachmentResource\n}) {\n const { title = '', imageUrl, imageHeight, imageWidth } = attachment.attributes\n const styles = useStyles({ imageWidth, imageHeight })\n\n return (\n <Image\n source={{ uri: imageUrl }}\n wrapperStyle={styles.imageWrapper}\n style={styles.image}\n alt={title}\n loaderSize={16}\n />\n )\n}\n\nfunction MessageAttachmentImage({\n attachment,\n}: {\n attachment: DenormalizedMessageAttachmentResource\n}) {\n const { url, urlMedium, filename, metadata = {} } = attachment.attributes\n const styles = useStyles({ imageWidth: metadata.width, imageHeight: metadata.height })\n\n return (\n <Image\n source={{ uri: urlMedium || url }}\n style={styles.image}\n wrapperStyle={styles.imageWrapper}\n alt={filename}\n loaderSize={16}\n />\n )\n}\n\nfunction MessageAttachmentIcon({ iconName }: { iconName: IconProps['name'] }) {\n const styles = useStyles()\n return (\n <Icon\n name={iconName}\n style={styles.attachmentIcon}\n maxFontSizeMultiplier={MAX_FONT_SIZE_MULTIPLIER}\n />\n )\n}\n\n// TODO: The mine prop is not used yet, but in the future we will be adding a way to find the `mine` value for this fallback.\nfunction ShadowMessageFallback({ text, mine }: { text: string; mine?: boolean }) {\n const styles = useStyles({ mine })\n\n return (\n <View style={styles.message}>\n <View style={styles.messageContent}>\n <View style={styles.messageBubble}>\n <Text variant=\"footnote\" style={styles.messageText}>\n {text}\n </Text>\n </View>\n </View>\n </View>\n )\n}\n\ninterface StylesProps {\n imageWidth?: number\n imageHeight?: number\n mine?: boolean\n}\n\nconst useStyles = ({ mine, imageWidth = 32, imageHeight = 32 }: StylesProps = {}) => {\n const { colors } = useTheme()\n const fontScale = useFontScale({ maxFontSizeMultiplier: MAX_FONT_SIZE_MULTIPLIER })\n const { width } = useWindowDimensions()\n const tabletWidth = width >= 744 // Smallest iPad Mini's width\n\n return StyleSheet.create({\n message: {\n gap: 8,\n flexDirection: mine ? 'row-reverse' : 'row',\n paddingHorizontal: CONVERSATION_MESSAGE_LIST_PADDING_HORIZONTAL,\n },\n messageContent: {\n flex: 1,\n gap: 4,\n marginBottom: 12,\n },\n avatarWrapper: {\n width: MESSAGE_AUTHOR_AVATAR_COLUMN_WIDTH,\n alignItems: 'center',\n },\n avatar: {\n marginBottom: 8,\n opacity: 0.5,\n },\n messageBubble: {\n flexDirection: 'row',\n alignSelf: mine ? 'flex-end' : 'flex-start',\n alignItems: 'center',\n gap: 8,\n borderColor: colors.borderColorDefaultBase,\n borderWidth: 1,\n borderRadius: 8,\n maxWidth: tabletWidth ? 360 : '80%',\n paddingVertical: 6,\n paddingHorizontal: 8,\n },\n messageText: {\n color: colors.textColorDefaultPlaceholder,\n flexShrink: 1,\n },\n messageMeta: {\n flexDirection: 'row',\n justifyContent: mine ? 'flex-end' : 'flex-start',\n },\n replyCountText: {\n color: colors.interaction,\n fontWeight: platformFontWeightMedium,\n },\n imageWrapper: {\n width: 32 * fontScale,\n aspectRatio: imageWidth / imageHeight,\n opacity: 0.5,\n },\n image: {\n borderRadius: 4,\n },\n attachmentIcon: {\n color: colors.iconColorDefaultDim,\n fontSize: 16,\n },\n })\n}\n"]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { MessageResource } from '../types';
|
|
2
|
+
export declare const useConversationMessage: ({ conversation_id, messageId, }: {
|
|
3
|
+
conversation_id: number;
|
|
4
|
+
messageId: string;
|
|
5
|
+
}) => {
|
|
6
|
+
message: MessageResource | undefined;
|
|
7
|
+
isError: boolean;
|
|
8
|
+
isLoading: boolean;
|
|
9
|
+
queryKey: import("./use_suspense_api").RequestQueryKey;
|
|
10
|
+
};
|
|
11
|
+
//# sourceMappingURL=use_conversation_message.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use_conversation_message.d.ts","sourceRoot":"","sources":["../../src/hooks/use_conversation_message.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAI1C,eAAO,MAAM,sBAAsB,oCAGhC;IACD,eAAe,EAAE,MAAM,CAAA;IACvB,SAAS,EAAE,MAAM,CAAA;CAClB;;;;;CASA,CAAA"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { useApiGet } from './use_api';
|
|
2
|
+
import { getMessageRequestArgs, getMessageQueryKey } from '../utils/request/get_message';
|
|
3
|
+
export const useConversationMessage = ({ conversation_id, messageId, }) => {
|
|
4
|
+
const { data: message, isError, isLoading, } = useApiGet(getMessageRequestArgs({ conversation_id, messageId }));
|
|
5
|
+
const queryKey = getMessageQueryKey({ conversation_id, messageId });
|
|
6
|
+
return { message, isError, isLoading, queryKey };
|
|
7
|
+
};
|
|
8
|
+
//# sourceMappingURL=use_conversation_message.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use_conversation_message.js","sourceRoot":"","sources":["../../src/hooks/use_conversation_message.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AACrC,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAA;AAExF,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,EACrC,eAAe,EACf,SAAS,GAIV,EAAE,EAAE;IACH,MAAM,EACJ,IAAI,EAAE,OAAO,EACb,OAAO,EACP,SAAS,GACV,GAAG,SAAS,CAAkB,qBAAqB,CAAC,EAAE,eAAe,EAAE,SAAS,EAAE,CAAC,CAAC,CAAA;IACrF,MAAM,QAAQ,GAAG,kBAAkB,CAAC,EAAE,eAAe,EAAE,SAAS,EAAE,CAAC,CAAA;IAEnE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAA;AAClD,CAAC,CAAA","sourcesContent":["import { MessageResource } from '../types'\nimport { useApiGet } from './use_api'\nimport { getMessageRequestArgs, getMessageQueryKey } from '../utils/request/get_message'\n\nexport const useConversationMessage = ({\n conversation_id,\n messageId,\n}: {\n conversation_id: number\n messageId: string\n}) => {\n const {\n data: message,\n isError,\n isLoading,\n } = useApiGet<MessageResource>(getMessageRequestArgs({ conversation_id, messageId }))\n const queryKey = getMessageQueryKey({ conversation_id, messageId })\n\n return { message, isError, isLoading, queryKey }\n}\n"]}
|
|
@@ -2,7 +2,7 @@ import { MessageResource } from '../types';
|
|
|
2
2
|
import { SuspensePaginatorOptions } from './use_suspense_api';
|
|
3
3
|
export declare const useConversationMessages: ({ conversation_id, reply_root_id }: {
|
|
4
4
|
conversation_id: number;
|
|
5
|
-
reply_root_id?: string;
|
|
5
|
+
reply_root_id?: string | null;
|
|
6
6
|
}, opts?: SuspensePaginatorOptions) => {
|
|
7
7
|
messages: MessageResource[];
|
|
8
8
|
refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<import("@tanstack/query-core").InfiniteData<import("../types").ApiCollection<MessageResource>, unknown>, Response>>;
|
|
@@ -10,23 +10,4 @@ export declare const useConversationMessages: ({ conversation_id, reply_root_id
|
|
|
10
10
|
fetchNextPage: (options?: import("@tanstack/query-core").FetchNextPageOptions) => Promise<import("@tanstack/query-core").InfiniteQueryObserverResult<import("@tanstack/query-core").InfiniteData<import("../types").ApiCollection<MessageResource>, unknown>, Response>>;
|
|
11
11
|
queryKey: import("./use_suspense_api").RequestQueryKey;
|
|
12
12
|
};
|
|
13
|
-
export declare const getMessagesRequestArgs: ({ conversation_id, reply_root_id, }: {
|
|
14
|
-
conversation_id: number;
|
|
15
|
-
reply_root_id?: string;
|
|
16
|
-
}) => {
|
|
17
|
-
url: string;
|
|
18
|
-
data: {
|
|
19
|
-
perPage: number;
|
|
20
|
-
fields: {
|
|
21
|
-
Message: string[];
|
|
22
|
-
Person: string[];
|
|
23
|
-
ReactionCount: string[];
|
|
24
|
-
};
|
|
25
|
-
include: string[];
|
|
26
|
-
};
|
|
27
|
-
};
|
|
28
|
-
export declare const getMessagesQueryKey: ({ conversation_id, reply_root_id, }: {
|
|
29
|
-
conversation_id: number;
|
|
30
|
-
reply_root_id?: string;
|
|
31
|
-
}) => import("./use_suspense_api").RequestQueryKey;
|
|
32
13
|
//# sourceMappingURL=use_conversation_messages.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use_conversation_messages.d.ts","sourceRoot":"","sources":["../../src/hooks/use_conversation_messages.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAC1C,OAAO,
|
|
1
|
+
{"version":3,"file":"use_conversation_messages.d.ts","sourceRoot":"","sources":["../../src/hooks/use_conversation_messages.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAC1C,OAAO,EAAE,wBAAwB,EAAwB,MAAM,oBAAoB,CAAA;AAGnF,eAAO,MAAM,uBAAuB,uCACE;IAAE,eAAe,EAAE,MAAM,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,SACvF,wBAAwB;;;;;;CAkBhC,CAAA"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { useMemo } from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { useSuspensePaginator } from './use_suspense_api';
|
|
3
|
+
import { getMessagesQueryKey, getMessagesRequestArgs } from '../utils/request/get_messages';
|
|
3
4
|
export const useConversationMessages = ({ conversation_id, reply_root_id }, opts) => {
|
|
4
5
|
const { data, refetch, isRefetching, fetchNextPage } = useSuspensePaginator(getMessagesRequestArgs({ conversation_id, reply_root_id }), opts);
|
|
5
6
|
const queryKey = getMessagesQueryKey({ conversation_id, reply_root_id });
|
|
@@ -8,36 +9,4 @@ export const useConversationMessages = ({ conversation_id, reply_root_id }, opts
|
|
|
8
9
|
.sort((a, b) => -a.id.localeCompare(b.id)), [data]);
|
|
9
10
|
return { messages, refetch, isRefetching, fetchNextPage, queryKey };
|
|
10
11
|
};
|
|
11
|
-
export const getMessagesRequestArgs = ({ conversation_id, reply_root_id, }) => {
|
|
12
|
-
const url = reply_root_id
|
|
13
|
-
? `/me/conversations/${conversation_id}/messages/${reply_root_id}/replies`
|
|
14
|
-
: `/me/conversations/${conversation_id}/messages`;
|
|
15
|
-
return {
|
|
16
|
-
url,
|
|
17
|
-
data: {
|
|
18
|
-
perPage: 25,
|
|
19
|
-
fields: {
|
|
20
|
-
Message: [
|
|
21
|
-
'text',
|
|
22
|
-
'text_edited_at',
|
|
23
|
-
'mine',
|
|
24
|
-
'attachments',
|
|
25
|
-
'created_at',
|
|
26
|
-
'deleted_at',
|
|
27
|
-
'author',
|
|
28
|
-
'reaction_counts',
|
|
29
|
-
'reply_count',
|
|
30
|
-
'reply_root',
|
|
31
|
-
],
|
|
32
|
-
Person: ['name', 'avatar'],
|
|
33
|
-
ReactionCount: ['value', 'count', 'mine', 'message_id', 'author_ids'],
|
|
34
|
-
},
|
|
35
|
-
include: ['author', 'reaction_counts'],
|
|
36
|
-
},
|
|
37
|
-
};
|
|
38
|
-
};
|
|
39
|
-
export const getMessagesQueryKey = ({ conversation_id, reply_root_id, }) => {
|
|
40
|
-
const requestArgs = getMessagesRequestArgs({ conversation_id, reply_root_id });
|
|
41
|
-
return getRequestQueryKey(requestArgs);
|
|
42
|
-
};
|
|
43
12
|
//# sourceMappingURL=use_conversation_messages.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use_conversation_messages.js","sourceRoot":"","sources":["../../src/hooks/use_conversation_messages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAA;AAE/B,OAAO,
|
|
1
|
+
{"version":3,"file":"use_conversation_messages.js","sourceRoot":"","sources":["../../src/hooks/use_conversation_messages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAA;AAE/B,OAAO,EAA4B,oBAAoB,EAAE,MAAM,oBAAoB,CAAA;AACnF,OAAO,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAA;AAE3F,MAAM,CAAC,MAAM,uBAAuB,GAAG,CACrC,EAAE,eAAe,EAAE,aAAa,EAA8D,EAC9F,IAA+B,EAC/B,EAAE;IACF,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,GAAG,oBAAoB,CACzE,sBAAsB,CAAC,EAAE,eAAe,EAAE,aAAa,EAAE,CAAC,EAC1D,IAAI,CACL,CAAA;IACD,MAAM,QAAQ,GAAG,mBAAmB,CAAC,EAAE,eAAe,EAAE,aAAa,EAAE,CAAC,CAAA;IACxE,MAAM,QAAQ,GAAG,OAAO,CACtB,GAAG,EAAE,CACH,IAAI;SACD,MAAM,CACL,OAAO,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,SAAS,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,MAAM,IAAI,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CACvF;SACA,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAC9C,CAAC,IAAI,CAAC,CACP,CAAA;IAED,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,QAAQ,EAAE,CAAA;AACrE,CAAC,CAAA","sourcesContent":["import { useMemo } from 'react'\nimport { MessageResource } from '../types'\nimport { SuspensePaginatorOptions, useSuspensePaginator } from './use_suspense_api'\nimport { getMessagesQueryKey, getMessagesRequestArgs } from '../utils/request/get_messages'\n\nexport const useConversationMessages = (\n { conversation_id, reply_root_id }: { conversation_id: number; reply_root_id?: string | null },\n opts?: SuspensePaginatorOptions\n) => {\n const { data, refetch, isRefetching, fetchNextPage } = useSuspensePaginator<MessageResource>(\n getMessagesRequestArgs({ conversation_id, reply_root_id }),\n opts\n )\n const queryKey = getMessagesQueryKey({ conversation_id, reply_root_id })\n const messages = useMemo(\n () =>\n data\n .filter(\n message => !message.deletedAt && (message.attachments?.length || message.text?.length)\n )\n .sort((a, b) => -a.id.localeCompare(b.id)),\n [data]\n )\n\n return { messages, refetch, isRefetching, fetchNextPage, queryKey }\n}\n"]}
|
|
@@ -5,7 +5,7 @@ import { useCurrentPerson } from './use_current_person';
|
|
|
5
5
|
import { transformMessageEventDataToMessageResource } from '../utils/jolt/transform_message_event_data_to_message_resource';
|
|
6
6
|
import { getRequestQueryKey } from './use_suspense_api';
|
|
7
7
|
import { transformReactionEventDataToReactionCountResource } from '../utils/jolt/transform_reaction_event_data_to_reaction_count_resource';
|
|
8
|
-
import { getMessagesRequestArgs } from '../utils/request/
|
|
8
|
+
import { getMessagesRequestArgs } from '../utils/request/get_messages';
|
|
9
9
|
import { TYPING_TIMEOUT_INTERVAL, useTypingStatusCache } from './use_typing_status_cache';
|
|
10
10
|
import { isTemporaryMessageId } from './use_message_create_or_update';
|
|
11
11
|
import { completeMessageCreationTracking } from '../utils/performance_tracking';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use_conversation_messages_jolt_events.js","sourceRoot":"","sources":["../../src/hooks/use_conversation_messages_jolt_events.ts"],"names":[],"mappings":"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","sourcesContent":["import { ApiCollection, MessageResource } from '../types'\nimport { useJoltChannel, useJoltEvent } from './use_jolt'\nimport {\n deleteRecordInPagesData,\n updateOrCreateRecordInPagesData,\n updateRecordInPagesData,\n} from '../utils'\nimport { MessageCreatedEvent, MessageDeletedEvent } from '../types/jolt_events/message_events'\nimport { InfiniteData, useQueryClient } from '@tanstack/react-query'\nimport { useCurrentPerson } from './use_current_person'\nimport { transformMessageEventDataToMessageResource } from '../utils/jolt/transform_message_event_data_to_message_resource'\nimport { getRequestQueryKey } from './use_suspense_api'\nimport { JoltReactionEvent, JoltTypingEvent } from '../types/jolt_events'\nimport { transformReactionEventDataToReactionCountResource } from '../utils/jolt/transform_reaction_event_data_to_reaction_count_resource'\nimport { getMessagesRequestArgs } from '../utils/request/messages'\nimport { TYPING_TIMEOUT_INTERVAL, useTypingStatusCache } from './use_typing_status_cache'\nimport { isTemporaryMessageId } from './use_message_create_or_update'\nimport { completeMessageCreationTracking } from '../utils/performance_tracking'\nimport { useApiClient } from './use_api_client'\n\ninterface Props {\n conversationId: number\n}\n\nexport function useConversationMessagesJoltEvents({ conversationId }: Props) {\n const queryClient = useQueryClient()\n const currentPerson = useCurrentPerson()\n const joltChannel = useJoltChannel(`chat.conversations.${conversationId}`)\n const messagesRequestArgs = getMessagesRequestArgs({ conversation_id: conversationId })\n const messagesQueryKey = getRequestQueryKey(messagesRequestArgs)\n const apiClient = useApiClient()\n\n const { addTypingEvent, removeTypingEventById, removeAllTypingEventsByAuthorId } =\n useTypingStatusCache(conversationId)\n\n const handleMessageUpdateOrCreate = async (e: MessageCreatedEvent) => {\n const { data } = e.data\n const message = transformMessageEventDataToMessageResource({\n data,\n currentPersonId: currentPerson.id,\n })\n\n if (e.event === 'message.created' && data.author_id) {\n removeAllTypingEventsByAuthorId(data.author_id)\n if (data.idempotent_key && data.author_id === currentPerson.id) {\n completeMessageCreationTracking({ apiClient, idempotentKey: data.idempotent_key })\n }\n }\n\n queryClient.setQueryData<QueryData>(messagesQueryKey, prev => {\n if (e.event === 'message.created') {\n // Before adding the new message, remove any pending temporary messages\n // with matching text to prevent duplicates from race conditions\n let dataAfterTempRemoval = prev\n if (prev && message.text && message.mine) {\n dataAfterTempRemoval = deleteRecordInPagesData({\n data: prev,\n record: message,\n matchFn: (existingMessage, _record) => {\n return (\n isTemporaryMessageId(existingMessage.id) &&\n existingMessage.text === message.text &&\n existingMessage.mine\n )\n },\n })\n }\n\n return updateOrCreateRecordInPagesData({\n data: dataAfterTempRemoval,\n record: message,\n processRecord: (record, current) => {\n return { ...current, ...record }\n },\n })\n } else {\n return updateRecordInPagesData({\n data: prev,\n record: message,\n processRecord: (record, current) => {\n return { ...current, ...record }\n },\n })\n }\n })\n }\n\n const handleMessageDeleted = async (e: MessageDeletedEvent) => {\n const { data } = e.data\n const message = transformMessageEventDataToMessageResource({\n data,\n currentPersonId: currentPerson.id,\n })\n\n queryClient.setQueryData<QueryData>(messagesQueryKey, prev =>\n deleteRecordInPagesData({ data: prev, record: message })\n )\n }\n\n const handleReactionJoltEvent = async (e: JoltReactionEvent) => {\n const { data } = e.data\n const message = { id: data.message_sort_key } as MessageResource\n queryClient.setQueryData<QueryData>(messagesQueryKey, prev =>\n updateRecordInPagesData({\n data: prev,\n record: message,\n processRecord: (record, oldMessage) => {\n const reactionCounts = oldMessage.reactionCounts || []\n let foundMatch = false\n let newReactionCounts = reactionCounts.map(reactionCount => {\n if (reactionCount.value === data.value) {\n foundMatch = true\n return transformReactionEventDataToReactionCountResource({\n data,\n oldData: reactionCount,\n event: e.event,\n currentPersonId: currentPerson.id,\n })\n }\n return reactionCount\n })\n\n if (!foundMatch) {\n const newReactionCount = transformReactionEventDataToReactionCountResource({\n data,\n event: e.event,\n currentPersonId: currentPerson.id,\n })\n\n if (newReactionCount?.count) {\n newReactionCounts = [...newReactionCounts, newReactionCount]\n }\n }\n\n return { ...oldMessage, reactionCounts: newReactionCounts }\n },\n })\n )\n }\n\n const handleTypingEvent = async (e: JoltTypingEvent) => {\n const { data } = e.data\n addTypingEvent(data)\n setTimeout(() => removeTypingEventById(data.id), TYPING_TIMEOUT_INTERVAL)\n }\n\n useJoltEvent(joltChannel, 'message.created', handleMessageUpdateOrCreate)\n useJoltEvent(joltChannel, 'message.updated', handleMessageUpdateOrCreate)\n useJoltEvent(joltChannel, 'message.destroyed', handleMessageDeleted)\n useJoltEvent(joltChannel, 'reaction.*', handleReactionJoltEvent)\n useJoltEvent(joltChannel, 'typing.broadcast', handleTypingEvent)\n}\n\ntype QueryData = InfiniteData<ApiCollection<MessageResource>>\n"]}
|
|
1
|
+
{"version":3,"file":"use_conversation_messages_jolt_events.js","sourceRoot":"","sources":["../../src/hooks/use_conversation_messages_jolt_events.ts"],"names":[],"mappings":"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","sourcesContent":["import { ApiCollection, MessageResource } from '../types'\nimport { useJoltChannel, useJoltEvent } from './use_jolt'\nimport {\n deleteRecordInPagesData,\n updateOrCreateRecordInPagesData,\n updateRecordInPagesData,\n} from '../utils'\nimport { MessageCreatedEvent, MessageDeletedEvent } from '../types/jolt_events/message_events'\nimport { InfiniteData, useQueryClient } from '@tanstack/react-query'\nimport { useCurrentPerson } from './use_current_person'\nimport { transformMessageEventDataToMessageResource } from '../utils/jolt/transform_message_event_data_to_message_resource'\nimport { getRequestQueryKey } from './use_suspense_api'\nimport { JoltReactionEvent, JoltTypingEvent } from '../types/jolt_events'\nimport { transformReactionEventDataToReactionCountResource } from '../utils/jolt/transform_reaction_event_data_to_reaction_count_resource'\nimport { getMessagesRequestArgs } from '../utils/request/get_messages'\nimport { TYPING_TIMEOUT_INTERVAL, useTypingStatusCache } from './use_typing_status_cache'\nimport { isTemporaryMessageId } from './use_message_create_or_update'\nimport { completeMessageCreationTracking } from '../utils/performance_tracking'\nimport { useApiClient } from './use_api_client'\n\ninterface Props {\n conversationId: number\n}\n\nexport function useConversationMessagesJoltEvents({ conversationId }: Props) {\n const queryClient = useQueryClient()\n const currentPerson = useCurrentPerson()\n const joltChannel = useJoltChannel(`chat.conversations.${conversationId}`)\n const messagesRequestArgs = getMessagesRequestArgs({ conversation_id: conversationId })\n const messagesQueryKey = getRequestQueryKey(messagesRequestArgs)\n const apiClient = useApiClient()\n\n const { addTypingEvent, removeTypingEventById, removeAllTypingEventsByAuthorId } =\n useTypingStatusCache(conversationId)\n\n const handleMessageUpdateOrCreate = async (e: MessageCreatedEvent) => {\n const { data } = e.data\n const message = transformMessageEventDataToMessageResource({\n data,\n currentPersonId: currentPerson.id,\n })\n\n if (e.event === 'message.created' && data.author_id) {\n removeAllTypingEventsByAuthorId(data.author_id)\n if (data.idempotent_key && data.author_id === currentPerson.id) {\n completeMessageCreationTracking({ apiClient, idempotentKey: data.idempotent_key })\n }\n }\n\n queryClient.setQueryData<QueryData>(messagesQueryKey, prev => {\n if (e.event === 'message.created') {\n // Before adding the new message, remove any pending temporary messages\n // with matching text to prevent duplicates from race conditions\n let dataAfterTempRemoval = prev\n if (prev && message.text && message.mine) {\n dataAfterTempRemoval = deleteRecordInPagesData({\n data: prev,\n record: message,\n matchFn: (existingMessage, _record) => {\n return (\n isTemporaryMessageId(existingMessage.id) &&\n existingMessage.text === message.text &&\n existingMessage.mine\n )\n },\n })\n }\n\n return updateOrCreateRecordInPagesData({\n data: dataAfterTempRemoval,\n record: message,\n processRecord: (record, current) => {\n return { ...current, ...record }\n },\n })\n } else {\n return updateRecordInPagesData({\n data: prev,\n record: message,\n processRecord: (record, current) => {\n return { ...current, ...record }\n },\n })\n }\n })\n }\n\n const handleMessageDeleted = async (e: MessageDeletedEvent) => {\n const { data } = e.data\n const message = transformMessageEventDataToMessageResource({\n data,\n currentPersonId: currentPerson.id,\n })\n\n queryClient.setQueryData<QueryData>(messagesQueryKey, prev =>\n deleteRecordInPagesData({ data: prev, record: message })\n )\n }\n\n const handleReactionJoltEvent = async (e: JoltReactionEvent) => {\n const { data } = e.data\n const message = { id: data.message_sort_key } as MessageResource\n queryClient.setQueryData<QueryData>(messagesQueryKey, prev =>\n updateRecordInPagesData({\n data: prev,\n record: message,\n processRecord: (record, oldMessage) => {\n const reactionCounts = oldMessage.reactionCounts || []\n let foundMatch = false\n let newReactionCounts = reactionCounts.map(reactionCount => {\n if (reactionCount.value === data.value) {\n foundMatch = true\n return transformReactionEventDataToReactionCountResource({\n data,\n oldData: reactionCount,\n event: e.event,\n currentPersonId: currentPerson.id,\n })\n }\n return reactionCount\n })\n\n if (!foundMatch) {\n const newReactionCount = transformReactionEventDataToReactionCountResource({\n data,\n event: e.event,\n currentPersonId: currentPerson.id,\n })\n\n if (newReactionCount?.count) {\n newReactionCounts = [...newReactionCounts, newReactionCount]\n }\n }\n\n return { ...oldMessage, reactionCounts: newReactionCounts }\n },\n })\n )\n }\n\n const handleTypingEvent = async (e: JoltTypingEvent) => {\n const { data } = e.data\n addTypingEvent(data)\n setTimeout(() => removeTypingEventById(data.id), TYPING_TIMEOUT_INTERVAL)\n }\n\n useJoltEvent(joltChannel, 'message.created', handleMessageUpdateOrCreate)\n useJoltEvent(joltChannel, 'message.updated', handleMessageUpdateOrCreate)\n useJoltEvent(joltChannel, 'message.destroyed', handleMessageDeleted)\n useJoltEvent(joltChannel, 'reaction.*', handleReactionJoltEvent)\n useJoltEvent(joltChannel, 'typing.broadcast', handleTypingEvent)\n}\n\ntype QueryData = InfiniteData<ApiCollection<MessageResource>>\n"]}
|
|
@@ -3,7 +3,7 @@ import { DenormalizedAttachmentResourceForCreate } from '../types/resources/deno
|
|
|
3
3
|
interface Props {
|
|
4
4
|
conversationId: number;
|
|
5
5
|
message?: MessageResource;
|
|
6
|
-
replyRootId?: string;
|
|
6
|
+
replyRootId?: string | null;
|
|
7
7
|
}
|
|
8
8
|
export declare function useMessageCreateOrUpdate({ conversationId, message, replyRootId }: Props): import("@tanstack/react-query").UseMutationResult<ApiResource<MessageResource>, Error, {
|
|
9
9
|
text: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use_message_create_or_update.d.ts","sourceRoot":"","sources":["../../src/hooks/use_message_create_or_update.ts"],"names":[],"mappings":"AAGA,OAAO,EAAiB,WAAW,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAQtE,OAAO,EAAE,uCAAuC,EAAE,MAAM,gEAAgE,CAAA;AAMxH,UAAU,KAAK;IACb,cAAc,EAAE,MAAM,CAAA;IACtB,OAAO,CAAC,EAAE,eAAe,CAAA;IACzB,WAAW,CAAC,EAAE,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"use_message_create_or_update.d.ts","sourceRoot":"","sources":["../../src/hooks/use_message_create_or_update.ts"],"names":[],"mappings":"AAGA,OAAO,EAAiB,WAAW,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAQtE,OAAO,EAAE,uCAAuC,EAAE,MAAM,gEAAgE,CAAA;AAMxH,UAAU,KAAK;IACb,cAAc,EAAE,MAAM,CAAA;IACtB,OAAO,CAAC,EAAE,eAAe,CAAA;IACzB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAC5B;AAED,wBAAgB,wBAAwB,CAAC,EAAE,cAAc,EAAE,OAAO,EAAE,WAAW,EAAE,EAAE,KAAK;UAqD5E,MAAM;kBACE,uCAAuC,EAAE;;;GAuE5D;AAED,wBAAgB,oBAAoB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAEvE;AACD,wBAAgB,YAAY,CAAC,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAE/D"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useMutation } from '@tanstack/react-query';
|
|
2
|
-
import { getMessagesQueryKey, getMessagesRequestArgs } from '
|
|
2
|
+
import { getMessagesQueryKey, getMessagesRequestArgs } from '../utils/request/get_messages';
|
|
3
3
|
import { useApiClient } from './use_api_client';
|
|
4
4
|
import { chatQueryClient } from '../contexts/api_provider';
|
|
5
5
|
import { deleteRecordInPagesData, Haptic, updateOrCreateRecordInPagesData, updateRecordInPagesData, } from '../utils';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use_message_create_or_update.js","sourceRoot":"","sources":["../../src/hooks/use_message_create_or_update.ts"],"names":[],"mappings":"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","sourcesContent":["import { InfiniteData, useMutation } from '@tanstack/react-query'\nimport { getMessagesQueryKey, getMessagesRequestArgs } from './use_conversation_messages'\nimport { useApiClient } from './use_api_client'\nimport { ApiCollection, ApiResource, MessageResource } from '../types'\nimport { chatQueryClient } from '../contexts/api_provider'\nimport {\n deleteRecordInPagesData,\n Haptic,\n updateOrCreateRecordInPagesData,\n updateRecordInPagesData,\n} from '../utils'\nimport { DenormalizedAttachmentResourceForCreate } from '../types/resources/denormalized_attachment_resource_for_create'\nimport { useCurrentPerson } from './use_current_person'\nimport { optimisticallyUpdateMessage } from '../utils/cache/optimistically_update_message'\nimport { optimisticallyCreateMessage } from '../utils/cache/optimistically_create_message'\nimport { startMessageCreationTracking } from '../utils/performance_tracking'\n\ninterface Props {\n conversationId: number\n message?: MessageResource\n replyRootId?: string\n}\n\nexport function useMessageCreateOrUpdate({ conversationId, message, replyRootId }: Props) {\n const messageId = message?.id || null\n const isEditing = !isNewMessage(message)\n const apiClient = useApiClient()\n const currentPerson = useCurrentPerson()\n\n const mutation = useMutation({\n mutationFn: ({\n text,\n attachments,\n }: {\n text: string\n attachments?: DenormalizedAttachmentResourceForCreate[]\n }) => {\n const requestParams = getMessagesRequestArgs({ conversation_id: conversationId })\n const fieldsWithValueJoined = Object.fromEntries(\n Object.entries(requestParams.data.fields).map(([k, v]) => [k, v.join(',')])\n )\n let attributes: any = {\n text,\n ...(attachments ? { attachments } : {}),\n ...(replyRootId ? { reply_root: { id: replyRootId } } : {}),\n }\n if (!isEditing) {\n const idempotentKey = insecureUUID()\n attributes.idempotent_key = idempotentKey\n startMessageCreationTracking(idempotentKey)\n }\n const data = {\n ...requestParams.data,\n data: {\n type: 'Message',\n attributes,\n },\n fields: fieldsWithValueJoined,\n }\n\n if (isEditing) {\n return apiClient.chat.patch<ApiResource<MessageResource>>({\n url: `/me/conversations/${conversationId}/messages/${messageId}`,\n data,\n })\n } else {\n return apiClient.chat.post<ApiResource<MessageResource>>({\n url: `/me/conversations/${conversationId}/messages`,\n data,\n })\n }\n },\n onMutate: async ({\n text,\n attachments,\n }: {\n text: string\n attachments?: DenormalizedAttachmentResourceForCreate[]\n }) => {\n if (message && isEditing) {\n const optimisticMessage = optimisticallyUpdateMessage({\n conversationId,\n message,\n text,\n })\n\n return { message: optimisticMessage }\n }\n\n const optimisticMessage = optimisticallyCreateMessage({\n conversationId,\n message,\n text,\n attachments,\n currentPerson,\n })\n\n return { message: optimisticMessage }\n },\n onError: (error, variables, context) => {\n const { message: optimisticMessage } = context || {}\n Haptic.notificationError()\n\n // Add error to the optimistic message from the cache on error\n if (optimisticMessage) {\n const queryKey = getMessagesQueryKey({ conversation_id: conversationId })\n chatQueryClient.setQueryData(\n queryKey,\n (data: InfiniteData<ApiCollection<MessageResource>> | undefined) =>\n updateRecordInPagesData({\n data,\n record: optimisticMessage,\n processRecord: (_next, prev) => ({\n ...prev,\n error: error.message || 'Failed to send message',\n pending: false, // Mark as no longer pending\n }),\n })\n )\n }\n },\n onSuccess: (result: ApiResource<MessageResource>, variables, context) => {\n const { message: optimisticMessage } = context || {}\n const updatedMessage = result.data\n type QueryData = InfiniteData<ApiCollection<MessageResource>>\n const queryKey = getMessagesQueryKey({ conversation_id: conversationId })\n\n // First remove the optimistic message if it exists\n if (optimisticMessage) {\n chatQueryClient.setQueryData<QueryData>(queryKey, data =>\n deleteRecordInPagesData({\n data,\n record: optimisticMessage,\n })\n )\n }\n\n // Then add the real message\n chatQueryClient.setQueryData<QueryData>(queryKey, data =>\n updateOrCreateRecordInPagesData({\n data,\n record: updatedMessage,\n })\n )\n },\n })\n\n return mutation\n}\n\nexport function isTemporaryMessageId(messageId?: string | null): boolean {\n return !!messageId && messageId.endsWith('-temp')\n}\nexport function isNewMessage(message?: MessageResource): boolean {\n return !message?.id || isTemporaryMessageId(message.id)\n}\n\n/**\n * Generate a random UUID (v4) for idempotent keys.\n * Uses Math.random, which is not cryptographically secure.\n * An actual crypto library requires native dependencies.\n * This is OK for now since idempotent keys are not security-sensitive\n * or need to be guaranteed unique.\n * They are short lived and we use it in combination with the message's creator_id so\n * their impact is scoped only the current user.\n */\nfunction insecureUUID(): string {\n return 'xxxxxxxx-xxxx-4xxx-Nxxx-xxxxxxxxxxxx'\n .replace(/x/g, () => Math.floor(Math.random() * 16).toString(16))\n .replace(/N/g, () => (Math.floor(Math.random() * 4) + 8).toString(16))\n}\n"]}
|
|
1
|
+
{"version":3,"file":"use_message_create_or_update.js","sourceRoot":"","sources":["../../src/hooks/use_message_create_or_update.ts"],"names":[],"mappings":"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","sourcesContent":["import { InfiniteData, useMutation } from '@tanstack/react-query'\nimport { getMessagesQueryKey, getMessagesRequestArgs } from '../utils/request/get_messages'\nimport { useApiClient } from './use_api_client'\nimport { ApiCollection, ApiResource, MessageResource } from '../types'\nimport { chatQueryClient } from '../contexts/api_provider'\nimport {\n deleteRecordInPagesData,\n Haptic,\n updateOrCreateRecordInPagesData,\n updateRecordInPagesData,\n} from '../utils'\nimport { DenormalizedAttachmentResourceForCreate } from '../types/resources/denormalized_attachment_resource_for_create'\nimport { useCurrentPerson } from './use_current_person'\nimport { optimisticallyUpdateMessage } from '../utils/cache/optimistically_update_message'\nimport { optimisticallyCreateMessage } from '../utils/cache/optimistically_create_message'\nimport { startMessageCreationTracking } from '../utils/performance_tracking'\n\ninterface Props {\n conversationId: number\n message?: MessageResource\n replyRootId?: string | null\n}\n\nexport function useMessageCreateOrUpdate({ conversationId, message, replyRootId }: Props) {\n const messageId = message?.id || null\n const isEditing = !isNewMessage(message)\n const apiClient = useApiClient()\n const currentPerson = useCurrentPerson()\n\n const mutation = useMutation({\n mutationFn: ({\n text,\n attachments,\n }: {\n text: string\n attachments?: DenormalizedAttachmentResourceForCreate[]\n }) => {\n const requestParams = getMessagesRequestArgs({ conversation_id: conversationId })\n const fieldsWithValueJoined = Object.fromEntries(\n Object.entries(requestParams.data.fields).map(([k, v]) => [k, v.join(',')])\n )\n let attributes: any = {\n text,\n ...(attachments ? { attachments } : {}),\n ...(replyRootId ? { reply_root: { id: replyRootId } } : {}),\n }\n if (!isEditing) {\n const idempotentKey = insecureUUID()\n attributes.idempotent_key = idempotentKey\n startMessageCreationTracking(idempotentKey)\n }\n const data = {\n ...requestParams.data,\n data: {\n type: 'Message',\n attributes,\n },\n fields: fieldsWithValueJoined,\n }\n\n if (isEditing) {\n return apiClient.chat.patch<ApiResource<MessageResource>>({\n url: `/me/conversations/${conversationId}/messages/${messageId}`,\n data,\n })\n } else {\n return apiClient.chat.post<ApiResource<MessageResource>>({\n url: `/me/conversations/${conversationId}/messages`,\n data,\n })\n }\n },\n onMutate: async ({\n text,\n attachments,\n }: {\n text: string\n attachments?: DenormalizedAttachmentResourceForCreate[]\n }) => {\n if (message && isEditing) {\n const optimisticMessage = optimisticallyUpdateMessage({\n conversationId,\n message,\n text,\n })\n\n return { message: optimisticMessage }\n }\n\n const optimisticMessage = optimisticallyCreateMessage({\n conversationId,\n message,\n text,\n attachments,\n currentPerson,\n })\n\n return { message: optimisticMessage }\n },\n onError: (error, variables, context) => {\n const { message: optimisticMessage } = context || {}\n Haptic.notificationError()\n\n // Add error to the optimistic message from the cache on error\n if (optimisticMessage) {\n const queryKey = getMessagesQueryKey({ conversation_id: conversationId })\n chatQueryClient.setQueryData(\n queryKey,\n (data: InfiniteData<ApiCollection<MessageResource>> | undefined) =>\n updateRecordInPagesData({\n data,\n record: optimisticMessage,\n processRecord: (_next, prev) => ({\n ...prev,\n error: error.message || 'Failed to send message',\n pending: false, // Mark as no longer pending\n }),\n })\n )\n }\n },\n onSuccess: (result: ApiResource<MessageResource>, variables, context) => {\n const { message: optimisticMessage } = context || {}\n const updatedMessage = result.data\n type QueryData = InfiniteData<ApiCollection<MessageResource>>\n const queryKey = getMessagesQueryKey({ conversation_id: conversationId })\n\n // First remove the optimistic message if it exists\n if (optimisticMessage) {\n chatQueryClient.setQueryData<QueryData>(queryKey, data =>\n deleteRecordInPagesData({\n data,\n record: optimisticMessage,\n })\n )\n }\n\n // Then add the real message\n chatQueryClient.setQueryData<QueryData>(queryKey, data =>\n updateOrCreateRecordInPagesData({\n data,\n record: updatedMessage,\n })\n )\n },\n })\n\n return mutation\n}\n\nexport function isTemporaryMessageId(messageId?: string | null): boolean {\n return !!messageId && messageId.endsWith('-temp')\n}\nexport function isNewMessage(message?: MessageResource): boolean {\n return !message?.id || isTemporaryMessageId(message.id)\n}\n\n/**\n * Generate a random UUID (v4) for idempotent keys.\n * Uses Math.random, which is not cryptographically secure.\n * An actual crypto library requires native dependencies.\n * This is OK for now since idempotent keys are not security-sensitive\n * or need to be guaranteed unique.\n * They are short lived and we use it in combination with the message's creator_id so\n * their impact is scoped only the current user.\n */\nfunction insecureUUID(): string {\n return 'xxxxxxxx-xxxx-4xxx-Nxxx-xxxxxxxxxxxx'\n .replace(/x/g, () => Math.floor(Math.random() * 16).toString(16))\n .replace(/N/g, () => (Math.floor(Math.random() * 4) + 8).toString(16))\n}\n"]}
|
|
@@ -2,7 +2,7 @@ import { useMutation, useQueryClient } from '@tanstack/react-query';
|
|
|
2
2
|
import { useCallback } from 'react';
|
|
3
3
|
import { Alert } from 'react-native';
|
|
4
4
|
import { useApiClient } from './use_api_client';
|
|
5
|
-
import { getMessagesQueryKey, getMessagesRequestArgs } from '
|
|
5
|
+
import { getMessagesQueryKey, getMessagesRequestArgs } from '../utils/request/get_messages';
|
|
6
6
|
import { updateRecordInPagesData } from '../utils';
|
|
7
7
|
export function useMessageReactionToggle({ conversation_id, message, onSuccess, }) {
|
|
8
8
|
const apiClient = useApiClient();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use_message_reaction_toggle.js","sourceRoot":"","sources":["../../src/hooks/use_message_reaction_toggle.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,WAAW,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AACjF,OAAO,EAAE,WAAW,EAAE,MAAM,OAAO,CAAA;AACnC,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAA;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAC/C,OAAO,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"use_message_reaction_toggle.js","sourceRoot":"","sources":["../../src/hooks/use_message_reaction_toggle.ts"],"names":[],"mappings":"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","sourcesContent":["import { InfiniteData, useMutation, useQueryClient } from '@tanstack/react-query'\nimport { useCallback } from 'react'\nimport { Alert } from 'react-native'\nimport { useApiClient } from './use_api_client'\nimport { getMessagesQueryKey, getMessagesRequestArgs } from '../utils/request/get_messages'\nimport { ApiCollection, ApiResource, MessageResource } from '../types'\nimport { ReactionCountResource } from '../types/resources/reaction'\nimport { updateRecordInPagesData } from '../utils'\n\ntype UseMessageReactionToggleProps = {\n conversation_id: number\n message: MessageResource\n onSuccess?: () => void\n}\n\ntype ToggleReactionParams = {\n value: ReactionCountResource['value']\n mine?: boolean\n}\n\ntype QueryData = InfiniteData<ApiCollection<MessageResource>>\n\nexport function useMessageReactionToggle({\n conversation_id,\n message,\n onSuccess,\n}: UseMessageReactionToggleProps) {\n const apiClient = useApiClient()\n const queryClient = useQueryClient()\n const queryKey = getMessagesQueryKey({ conversation_id })\n const message_id = message.id\n\n const toggleReaction = useCallback(\n ({ value, mine }: ToggleReactionParams) => {\n const requestParams = getMessagesRequestArgs({ conversation_id })\n\n // If already reacted, unreact; otherwise react\n const endpoint = !mine ? 'react' : 'unreact'\n const url = `/me/conversations/${conversation_id}/messages/${message_id}/${endpoint}`\n const fieldsWithValueJoined = Object.fromEntries(\n Object.entries(requestParams.data.fields).map(([k, v]) => [k, v.join(',')])\n )\n\n return apiClient.chat.post<ApiResource<MessageResource>>({\n url,\n data: {\n ...requestParams.data,\n data: {\n type: 'Message',\n attributes: { value: value },\n },\n fields: fieldsWithValueJoined,\n },\n })\n },\n [apiClient, conversation_id, message_id]\n )\n\n const { mutate: handleReactionToggle, isPending } = useMutation({\n mutationFn: toggleReaction,\n onMutate: variables => {\n const previousData = queryClient.getQueryData<QueryData>(queryKey)\n if (previousData) {\n queryClient.setQueryData<QueryData>(queryKey, data =>\n optimisticUpdate({\n message,\n data,\n value: variables.value,\n state: !variables.mine,\n })\n )\n }\n return { previousData }\n },\n onSuccess: result => {\n const updatedMessage = result.data\n\n queryClient.setQueryData<QueryData>(queryKey, data =>\n updateRecordInPagesData({\n data,\n record: updatedMessage,\n })\n )\n\n if (onSuccess) {\n onSuccess()\n }\n },\n onError: (_data, _variables, context) => {\n if (context?.previousData) {\n queryClient.setQueryData<QueryData>(queryKey, context.previousData)\n }\n Alert.alert('Oops', 'We were unable to react to this message. Please try again.')\n },\n })\n\n return {\n handleReactionToggle,\n isPending,\n }\n}\n\nconst optimisticUpdate = ({\n message,\n data,\n value,\n state,\n}: {\n message: MessageResource\n data: QueryData | undefined\n value: ReactionCountResource['value']\n state: boolean\n}) => {\n if (!data) return data\n\n const updatedReactionCounts: ReactionCountResource[] = message.reactionCounts.map(reaction => {\n if (reaction.value === value) {\n return {\n ...reaction,\n mine: state ? 1 : 0,\n count: state ? reaction.count + 1 : reaction.count - 1,\n } as ReactionCountResource\n }\n return reaction\n })\n\n const updatedMessage: MessageResource = {\n ...message,\n reactionCounts: updatedReactionCounts,\n }\n\n return updateRecordInPagesData({\n data,\n record: updatedMessage,\n })\n}\n"]}
|
|
@@ -3,9 +3,10 @@ import { StaticScreenProps } from '@react-navigation/native';
|
|
|
3
3
|
import React from 'react';
|
|
4
4
|
import { MessageResource } from '../types';
|
|
5
5
|
import { ConversationBadgeResource } from '../types/resources/conversation_badge';
|
|
6
|
+
import { ReplyShadowMessage } from '../components/conversation/reply_shadow_message';
|
|
6
7
|
export type ConversationRouteProps = {
|
|
7
8
|
conversation_id: number;
|
|
8
|
-
reply_root_id?: string;
|
|
9
|
+
reply_root_id?: string | null;
|
|
9
10
|
replyRootAuthor?: string;
|
|
10
11
|
chat_group_graph_id?: string;
|
|
11
12
|
clear_input?: boolean;
|
|
@@ -22,11 +23,18 @@ export type DateSeparator = {
|
|
|
22
23
|
id: string;
|
|
23
24
|
date: string;
|
|
24
25
|
};
|
|
26
|
+
type ReplyShadowMessage = {
|
|
27
|
+
type: 'ReplyShadowMessage';
|
|
28
|
+
id: string;
|
|
29
|
+
messageId: string;
|
|
30
|
+
isReplyShadowMessage: boolean;
|
|
31
|
+
nextRendersAuthor: boolean;
|
|
32
|
+
};
|
|
25
33
|
interface GroupMessagesProps {
|
|
26
34
|
ms: MessageResource[];
|
|
27
35
|
inReplyScreen?: boolean;
|
|
28
36
|
}
|
|
29
|
-
export declare const groupMessages: ({ ms, inReplyScreen }: GroupMessagesProps) => (MessageResource | DateSeparator)[];
|
|
37
|
+
export declare const groupMessages: ({ ms, inReplyScreen }: GroupMessagesProps) => (MessageResource | DateSeparator | ReplyShadowMessage)[];
|
|
30
38
|
interface ConversationScreenTitleProps extends HeaderTitleProps {
|
|
31
39
|
conversation_id: number;
|
|
32
40
|
badge?: ConversationBadgeResource;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conversation_screen.d.ts","sourceRoot":"","sources":["../../src/screens/conversation_screen.tsx"],"names":[],"mappings":"AACA,OAAO,EAAe,gBAAgB,EAAqB,MAAM,4BAA4B,CAAA;AAC7F,OAAO,EAGL,iBAAiB,EAIlB,MAAM,0BAA0B,CAAA;AAEjC,OAAO,KAAmD,MAAM,OAAO,CAAA;AAkBvE,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAC1C,OAAO,EAAE,yBAAyB,EAAE,MAAM,uCAAuC,CAAA;
|
|
1
|
+
{"version":3,"file":"conversation_screen.d.ts","sourceRoot":"","sources":["../../src/screens/conversation_screen.tsx"],"names":[],"mappings":"AACA,OAAO,EAAe,gBAAgB,EAAqB,MAAM,4BAA4B,CAAA;AAC7F,OAAO,EAGL,iBAAiB,EAIlB,MAAM,0BAA0B,CAAA;AAEjC,OAAO,KAAmD,MAAM,OAAO,CAAA;AAkBvE,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAC1C,OAAO,EAAE,yBAAyB,EAAE,MAAM,uCAAuC,CAAA;AAMjF,OAAO,EAAE,kBAAkB,EAAE,MAAM,iDAAiD,CAAA;AAGpF,MAAM,MAAM,sBAAsB,GAAG;IACnC,eAAe,EAAE,MAAM,CAAA;IACvB,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAClC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,KAAK,CAAC,EAAE,yBAAyB,CAAA;IACjC,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB,CAAA;AAED,MAAM,MAAM,uBAAuB,GAAG,iBAAiB,CAAC,sBAAsB,CAAC,CAAA;AAE/E,wBAAgB,kBAAkB,CAAC,EAAE,KAAK,EAAE,EAAE,uBAAuB,qBAyIpE;AAED,MAAM,MAAM,aAAa,GAAG;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAA;AAwC/E,KAAK,kBAAkB,GAAG;IACxB,IAAI,EAAE,oBAAoB,CAAA;IAC1B,EAAE,EAAE,MAAM,CAAA;IACV,SAAS,EAAE,MAAM,CAAA;IACjB,oBAAoB,EAAE,OAAO,CAAA;IAC7B,iBAAiB,EAAE,OAAO,CAAA;CAC3B,CAAA;AAED,UAAU,kBAAkB;IAC1B,EAAE,EAAE,eAAe,EAAE,CAAA;IACrB,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB;AAED,eAAO,MAAM,aAAa,0BAA2B,kBAAkB,6DAkFtE,CAAA;AACD,UAAU,4BAA6B,SAAQ,gBAAgB;IAC7D,eAAe,EAAE,MAAM,CAAA;IACvB,KAAK,CAAC,EAAE,yBAAyB,CAAA;IACjC,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED,eAAO,MAAM,uBAAuB,0DAMjC,4BAA4B,sBAiC9B,CAAA"}
|