@planningcenter/chat-react-native 3.21.2-rc.4 → 3.22.0-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/components/conversation/attachments/attachment_card.js +1 -0
- package/build/components/conversation/attachments/attachment_card.js.map +1 -1
- package/build/components/conversation/attachments/attachment_deleting_overlay.d.ts +3 -0
- package/build/components/conversation/attachments/attachment_deleting_overlay.d.ts.map +1 -0
- package/build/components/conversation/attachments/attachment_deleting_overlay.js +29 -0
- package/build/components/conversation/attachments/attachment_deleting_overlay.js.map +1 -0
- package/build/components/conversation/attachments/audio_attachment.d.ts +2 -1
- package/build/components/conversation/attachments/audio_attachment.d.ts.map +1 -1
- package/build/components/conversation/attachments/audio_attachment.js +5 -3
- package/build/components/conversation/attachments/audio_attachment.js.map +1 -1
- package/build/components/conversation/attachments/generic_file_attachment.d.ts +2 -1
- package/build/components/conversation/attachments/generic_file_attachment.d.ts.map +1 -1
- package/build/components/conversation/attachments/generic_file_attachment.js +4 -2
- package/build/components/conversation/attachments/generic_file_attachment.js.map +1 -1
- package/build/components/conversation/attachments/image_attachment.d.ts +2 -1
- package/build/components/conversation/attachments/image_attachment.d.ts.map +1 -1
- package/build/components/conversation/attachments/image_attachment.js +9 -4
- package/build/components/conversation/attachments/image_attachment.js.map +1 -1
- package/build/components/conversation/attachments/video_attachment.d.ts +2 -1
- package/build/components/conversation/attachments/video_attachment.d.ts.map +1 -1
- package/build/components/conversation/attachments/video_attachment.js +5 -3
- package/build/components/conversation/attachments/video_attachment.js.map +1 -1
- package/build/components/conversation/message_attachments.d.ts.map +1 -1
- package/build/components/conversation/message_attachments.js +8 -6
- package/build/components/conversation/message_attachments.js.map +1 -1
- package/build/contexts/session_context.d.ts +40 -0
- package/build/contexts/session_context.d.ts.map +1 -0
- package/build/contexts/session_context.js +131 -0
- package/build/contexts/session_context.js.map +1 -0
- package/build/hooks/index.d.ts +1 -0
- package/build/hooks/index.d.ts.map +1 -1
- package/build/hooks/index.js +1 -0
- package/build/hooks/index.js.map +1 -1
- package/build/hooks/use_deleting_ids.d.ts +4 -0
- package/build/hooks/use_deleting_ids.d.ts.map +1 -0
- package/build/hooks/use_deleting_ids.js +19 -0
- package/build/hooks/use_deleting_ids.js.map +1 -0
- package/build/screens/attachment_actions/attachment_actions_screen.d.ts.map +1 -1
- package/build/screens/attachment_actions/attachment_actions_screen.js +9 -2
- package/build/screens/attachment_actions/attachment_actions_screen.js.map +1 -1
- package/build/screens/attachment_actions/hooks/useDeleteAttachment.d.ts.map +1 -1
- package/build/screens/attachment_actions/hooks/useDeleteAttachment.js +1 -3
- package/build/screens/attachment_actions/hooks/useDeleteAttachment.js.map +1 -1
- package/package.json +2 -2
- package/src/__tests__/contexts/session_context.tsx +420 -0
- package/src/components/conversation/attachments/attachment_card.tsx +1 -0
- package/src/components/conversation/attachments/attachment_deleting_overlay.tsx +34 -0
- package/src/components/conversation/attachments/audio_attachment.tsx +7 -2
- package/src/components/conversation/attachments/generic_file_attachment.tsx +6 -1
- package/src/components/conversation/attachments/image_attachment.tsx +11 -3
- package/src/components/conversation/attachments/video_attachment.tsx +7 -2
- package/src/components/conversation/message_attachments.tsx +9 -0
- package/src/contexts/session_context.tsx +234 -0
- package/src/hooks/index.ts +1 -0
- package/src/hooks/use_deleting_ids.ts +22 -0
- package/src/screens/attachment_actions/attachment_actions_screen.tsx +9 -2
- package/src/screens/attachment_actions/hooks/useDeleteAttachment.tsx +1 -3
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { DenormalizedMessageAttachmentResource } from '../../../types/resources/denormalized_attachment_resource';
|
|
3
|
-
export declare function VideoAttachment({ attachment, onMessageAttachmentLongPress, }: {
|
|
3
|
+
export declare function VideoAttachment({ attachment, onMessageAttachmentLongPress, isDeleting, }: {
|
|
4
4
|
attachment: DenormalizedMessageAttachmentResource;
|
|
5
5
|
onMessageAttachmentLongPress: (attachment: DenormalizedMessageAttachmentResource) => void;
|
|
6
|
+
isDeleting: boolean;
|
|
6
7
|
}): React.JSX.Element;
|
|
7
8
|
//# sourceMappingURL=video_attachment.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"video_attachment.d.ts","sourceRoot":"","sources":["../../../../src/components/conversation/attachments/video_attachment.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA2B,MAAM,OAAO,CAAA;AAE/C,OAAO,EAAE,qCAAqC,EAAE,MAAM,2DAA2D,CAAA;
|
|
1
|
+
{"version":3,"file":"video_attachment.d.ts","sourceRoot":"","sources":["../../../../src/components/conversation/attachments/video_attachment.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA2B,MAAM,OAAO,CAAA;AAE/C,OAAO,EAAE,qCAAqC,EAAE,MAAM,2DAA2D,CAAA;AASjH,wBAAgB,eAAe,CAAC,EAC9B,UAAU,EACV,4BAA4B,EAC5B,UAAU,GACX,EAAE;IACD,UAAU,EAAE,qCAAqC,CAAA;IACjD,4BAA4B,EAAE,CAAC,UAAU,EAAE,qCAAqC,KAAK,IAAI,CAAA;IACzF,UAAU,EAAE,OAAO,CAAA;CACpB,qBA4DA"}
|
|
@@ -6,7 +6,8 @@ import { Video } from '../../../utils/native_adapters';
|
|
|
6
6
|
import { PlatformPressable } from '@react-navigation/elements';
|
|
7
7
|
import { useTheme } from '../../../hooks';
|
|
8
8
|
import { tokens } from '../../../vendor/tapestry/tokens';
|
|
9
|
-
|
|
9
|
+
import { AttachmentDeletingOverlay } from './attachment_deleting_overlay';
|
|
10
|
+
export function VideoAttachment({ attachment, onMessageAttachmentLongPress, isDeleting, }) {
|
|
10
11
|
const { colors } = useTheme();
|
|
11
12
|
const styles = useStyles();
|
|
12
13
|
const { attributes } = attachment;
|
|
@@ -27,14 +28,15 @@ export function VideoAttachment({ attachment, onMessageAttachmentLongPress, }) {
|
|
|
27
28
|
}
|
|
28
29
|
const viewRef = useRef(null);
|
|
29
30
|
return (<View style={styles.container} ref={viewRef}>
|
|
30
|
-
<PlatformPressable onPress={openVideo} onLongPress={() => onMessageAttachmentLongPress(attachment)} android_ripple={{ color: colors.androidRippleNeutral, foreground: true }} accessibilityLabel="Play Video" accessibilityHint="Press to play video. Long press for more options">
|
|
31
|
+
<PlatformPressable onPress={openVideo} onLongPress={() => !isDeleting && onMessageAttachmentLongPress(attachment)} android_ripple={{ color: colors.androidRippleNeutral, foreground: true }} accessibilityLabel="Play Video" accessibilityHint="Press to play video. Long press for more options" disabled={isDeleting}>
|
|
31
32
|
<View style={styles.thumbnailOverlay}/>
|
|
32
33
|
<Video.Player ref={videoRef} source={{ uri: url }} aspectRatio={width / height} style={styles.video} onFullscreenPlayerWillDismiss={onFullscreenPlayerWillDismiss}/>
|
|
33
|
-
{!isOpen && (<View style={styles.playContainer}>
|
|
34
|
+
{!isOpen && !isDeleting && (<View style={styles.playContainer}>
|
|
34
35
|
<View style={styles.playCircle}>
|
|
35
36
|
<Icon name="services.play" style={styles.playIcon} accessibilityElementsHidden={true}/>
|
|
36
37
|
</View>
|
|
37
38
|
</View>)}
|
|
39
|
+
{isDeleting && <AttachmentDeletingOverlay />}
|
|
38
40
|
</PlatformPressable>
|
|
39
41
|
</View>);
|
|
40
42
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"video_attachment.js","sourceRoot":"","sources":["../../../../src/components/conversation/attachments/video_attachment.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAC/C,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAE/C,OAAO,EAAE,+BAA+B,EAAE,MAAM,aAAa,CAAA;AAC7D,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAA;AACpC,OAAO,EAAE,KAAK,EAAqB,MAAM,gCAAgC,CAAA;AACzE,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAA;AAC9D,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,iCAAiC,CAAA;
|
|
1
|
+
{"version":3,"file":"video_attachment.js","sourceRoot":"","sources":["../../../../src/components/conversation/attachments/video_attachment.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { useRef, useState } from 'react'\nimport { View, StyleSheet } from 'react-native'\nimport { DenormalizedMessageAttachmentResource } from '../../../types/resources/denormalized_attachment_resource'\nimport { MESSAGE_ATTACHMENT_WIDTH_SINGLE } from './constants'\nimport { Icon } from '../../display'\nimport { Video, VideoPlayerHandle } from '../../../utils/native_adapters'\nimport { PlatformPressable } from '@react-navigation/elements'\nimport { useTheme } from '../../../hooks'\nimport { tokens } from '../../../vendor/tapestry/tokens'\nimport { AttachmentDeletingOverlay } from './attachment_deleting_overlay'\n\nexport function VideoAttachment({\n attachment,\n onMessageAttachmentLongPress,\n isDeleting,\n}: {\n attachment: DenormalizedMessageAttachmentResource\n onMessageAttachmentLongPress: (attachment: DenormalizedMessageAttachmentResource) => void\n isDeleting: boolean\n}) {\n const { colors } = useTheme()\n const styles = useStyles()\n\n const { attributes } = attachment\n const { width = MESSAGE_ATTACHMENT_WIDTH_SINGLE, height = MESSAGE_ATTACHMENT_WIDTH_SINGLE } =\n attributes.metadata || {}\n const { url } = attributes\n\n const videoRef = useRef<VideoPlayerHandle>(null)\n const [isOpen, setIsOpen] = useState(false)\n\n function openVideo() {\n if (!isOpen && videoRef.current) {\n videoRef.current.presentFullscreenPlayer()\n videoRef.current.play()\n setIsOpen(true)\n }\n }\n\n function onFullscreenPlayerWillDismiss() {\n videoRef.current?.pause()\n setIsOpen(false)\n }\n\n const viewRef = useRef<View>(null)\n\n return (\n <View style={styles.container} ref={viewRef}>\n <PlatformPressable\n onPress={openVideo}\n onLongPress={() => !isDeleting && onMessageAttachmentLongPress(attachment)}\n android_ripple={{ color: colors.androidRippleNeutral, foreground: true }}\n accessibilityLabel=\"Play Video\"\n accessibilityHint=\"Press to play video. Long press for more options\"\n disabled={isDeleting}\n >\n <View style={styles.thumbnailOverlay} />\n <Video.Player\n ref={videoRef}\n source={{ uri: url }}\n aspectRatio={width / height}\n style={styles.video}\n onFullscreenPlayerWillDismiss={onFullscreenPlayerWillDismiss}\n />\n {!isOpen && !isDeleting && (\n <View style={styles.playContainer}>\n <View style={styles.playCircle}>\n <Icon\n name=\"services.play\"\n style={styles.playIcon}\n accessibilityElementsHidden={true}\n />\n </View>\n </View>\n )}\n {isDeleting && <AttachmentDeletingOverlay />}\n </PlatformPressable>\n </View>\n )\n}\nconst OVERLAY_Z_INDEX = 1\n\nconst useStyles = () => {\n const { colors } = useTheme()\n const overlayBackgroundColor =\n colors.name === 'light'\n ? tokens.fillColorTransparencyDark010\n : tokens.fillColorTransparencyDark030\n\n return StyleSheet.create({\n container: {\n borderRadius: 8,\n overflow: 'hidden',\n },\n video: {\n width: '100%',\n backgroundColor: colors.fillColorNeutral070,\n },\n thumbnailOverlay: {\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n backgroundColor: overlayBackgroundColor,\n zIndex: OVERLAY_Z_INDEX,\n },\n playContainer: {\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n justifyContent: 'center',\n alignItems: 'center',\n zIndex: OVERLAY_Z_INDEX + 1,\n },\n playCircle: {\n justifyContent: 'center',\n alignItems: 'center',\n width: 42,\n height: 42,\n borderRadius: 25,\n backgroundColor: colors.fillColorNeutral100Inverted,\n borderColor: colors.borderColorDefaultBase,\n borderWidth: 1,\n },\n playIcon: {\n fontSize: 20,\n },\n })\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"message_attachments.d.ts","sourceRoot":"","sources":["../../../src/components/conversation/message_attachments.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,EACL,8BAA8B,EAC9B,qCAAqC,EACtC,MAAM,wDAAwD,CAAA;AAM/D,OAAO,EAAmB,KAAK,SAAS,EAAE,MAAM,gCAAgC,CAAA;
|
|
1
|
+
{"version":3,"file":"message_attachments.d.ts","sourceRoot":"","sources":["../../../src/components/conversation/message_attachments.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,EACL,8BAA8B,EAC9B,qCAAqC,EACtC,MAAM,wDAAwD,CAAA;AAM/D,OAAO,EAAmB,KAAK,SAAS,EAAE,MAAM,gCAAgC,CAAA;AAGhF,wBAAgB,kBAAkB,CAAC,KAAK,EAAE;IACxC,WAAW,EAAE,8BAA8B,EAAE,CAAA;IAC7C,SAAS,EAAE,SAAS,CAAA;IACpB,4BAA4B,EAAE,CAAC,UAAU,EAAE,qCAAqC,KAAK,IAAI,CAAA;IACzF,kBAAkB,EAAE,MAAM,IAAI,CAAA;CAC/B,4BA8DA"}
|
|
@@ -6,9 +6,11 @@ import { GiphyAttachment } from './attachments/giphy_attachment';
|
|
|
6
6
|
import { GenericFileAttachment } from './attachments/generic_file_attachment';
|
|
7
7
|
import { ExpandedLink } from './attachments/expanded_link';
|
|
8
8
|
import { ImageAttachment } from './attachments/image_attachment';
|
|
9
|
+
import { useDeletingIds } from '../../hooks';
|
|
9
10
|
export function MessageAttachments(props) {
|
|
10
11
|
const styles = useStyles();
|
|
11
12
|
const { attachments, metaProps, onMessageAttachmentLongPress, onMessageLongPress } = props;
|
|
13
|
+
const deletingAttachmentIds = useDeletingIds('deleteAttachment');
|
|
12
14
|
if (!attachments || attachments.length === 0)
|
|
13
15
|
return null;
|
|
14
16
|
const imageAttachments = attachments.filter(attachment => attachment.type === 'MessageAttachment' &&
|
|
@@ -16,12 +18,12 @@ export function MessageAttachments(props) {
|
|
|
16
18
|
const showImageAttachmentGroup = imageAttachments.length > 0;
|
|
17
19
|
return (<View style={styles.attachmentsContainer}>
|
|
18
20
|
{showImageAttachmentGroup &&
|
|
19
|
-
imageAttachments.map((image, index) => (<ImageAttachment key={`${image.id}-${index}`} attachment={image} imageAttachments={imageAttachments} currentImageIndex={index} metaProps={metaProps} onMessageAttachmentLongPress={onMessageAttachmentLongPress}/>))}
|
|
21
|
+
imageAttachments.map((image, index) => (<ImageAttachment key={`${image.id}-${index}`} attachment={image} imageAttachments={imageAttachments} currentImageIndex={index} metaProps={metaProps} onMessageAttachmentLongPress={onMessageAttachmentLongPress} isDeleting={deletingAttachmentIds.has(image.id)}/>))}
|
|
20
22
|
|
|
21
23
|
{attachments.map((attachment, index) => {
|
|
22
24
|
switch (attachment.type) {
|
|
23
25
|
case 'MessageAttachment':
|
|
24
|
-
return (<MessageAttachment key={`${attachment.id}-${index}`} attachment={attachment} onMessageAttachmentLongPress={onMessageAttachmentLongPress}/>);
|
|
26
|
+
return (<MessageAttachment key={`${attachment.id}-${index}`} attachment={attachment} onMessageAttachmentLongPress={onMessageAttachmentLongPress} isDeleting={deletingAttachmentIds.has(attachment.id)}/>);
|
|
25
27
|
case 'giphy':
|
|
26
28
|
return (<GiphyAttachment key={`${attachment.id || attachment.titleLink}-${index}`} attachment={attachment} onMessageLongPress={onMessageLongPress}/>);
|
|
27
29
|
case 'ExpandedLink':
|
|
@@ -32,17 +34,17 @@ export function MessageAttachments(props) {
|
|
|
32
34
|
})}
|
|
33
35
|
</View>);
|
|
34
36
|
}
|
|
35
|
-
function MessageAttachment({ attachment, onMessageAttachmentLongPress, }) {
|
|
37
|
+
function MessageAttachment({ attachment, onMessageAttachmentLongPress, isDeleting, }) {
|
|
36
38
|
const { attributes } = attachment;
|
|
37
39
|
const contentType = attributes?.contentType;
|
|
38
40
|
const basicType = contentType ? contentType.split('/')[0] : '';
|
|
39
41
|
switch (basicType) {
|
|
40
42
|
case 'video':
|
|
41
|
-
return (<VideoAttachment attachment={attachment} onMessageAttachmentLongPress={onMessageAttachmentLongPress}/>);
|
|
43
|
+
return (<VideoAttachment attachment={attachment} onMessageAttachmentLongPress={onMessageAttachmentLongPress} isDeleting={isDeleting}/>);
|
|
42
44
|
case 'audio':
|
|
43
|
-
return (<AudioAttachment attachment={attachment} onMessageAttachmentLongPress={onMessageAttachmentLongPress}/>);
|
|
45
|
+
return (<AudioAttachment attachment={attachment} onMessageAttachmentLongPress={onMessageAttachmentLongPress} isDeleting={isDeleting}/>);
|
|
44
46
|
case 'application':
|
|
45
|
-
return (<GenericFileAttachment attachment={attachment} onMessageAttachmentLongPress={onMessageAttachmentLongPress}/>);
|
|
47
|
+
return (<GenericFileAttachment attachment={attachment} onMessageAttachmentLongPress={onMessageAttachmentLongPress} isDeleting={isDeleting}/>);
|
|
46
48
|
default:
|
|
47
49
|
return null;
|
|
48
50
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"message_attachments.js","sourceRoot":"","sources":["../../../src/components/conversation/message_attachments.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAK/C,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAA;AAChE,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAA;AAChE,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAA;AAChE,OAAO,EAAE,qBAAqB,EAAE,MAAM,uCAAuC,CAAA;AAC7E,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAA;AAC1D,OAAO,EAAE,eAAe,EAAkB,MAAM,gCAAgC,CAAA;
|
|
1
|
+
{"version":3,"file":"message_attachments.js","sourceRoot":"","sources":["../../../src/components/conversation/message_attachments.tsx"],"names":[],"mappings":"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","sourcesContent":["import React from 'react'\nimport { View, StyleSheet } from 'react-native'\nimport {\n DenormalizedAttachmentResource,\n DenormalizedMessageAttachmentResource,\n} from '../../types/resources/denormalized_attachment_resource'\nimport { AudioAttachment } from './attachments/audio_attachment'\nimport { VideoAttachment } from './attachments/video_attachment'\nimport { GiphyAttachment } from './attachments/giphy_attachment'\nimport { GenericFileAttachment } from './attachments/generic_file_attachment'\nimport { ExpandedLink } from './attachments/expanded_link'\nimport { ImageAttachment, type MetaProps } from './attachments/image_attachment'\nimport { useDeletingIds } from '../../hooks'\n\nexport function MessageAttachments(props: {\n attachments: DenormalizedAttachmentResource[]\n metaProps: MetaProps\n onMessageAttachmentLongPress: (attachment: DenormalizedMessageAttachmentResource) => void\n onMessageLongPress: () => void\n}) {\n const styles = useStyles()\n const { attachments, metaProps, onMessageAttachmentLongPress, onMessageLongPress } = props\n const deletingAttachmentIds = useDeletingIds('deleteAttachment')\n if (!attachments || attachments.length === 0) return null\n\n const imageAttachments = attachments.filter(\n attachment =>\n attachment.type === 'MessageAttachment' &&\n attachment.attributes?.contentType?.startsWith('image/')\n ) as DenormalizedMessageAttachmentResource[]\n\n const showImageAttachmentGroup = imageAttachments.length > 0\n\n return (\n <View style={styles.attachmentsContainer}>\n {showImageAttachmentGroup &&\n imageAttachments.map((image, index) => (\n <ImageAttachment\n key={`${image.id}-${index}`}\n attachment={image}\n imageAttachments={imageAttachments}\n currentImageIndex={index}\n metaProps={metaProps}\n onMessageAttachmentLongPress={onMessageAttachmentLongPress}\n isDeleting={deletingAttachmentIds.has(image.id)}\n />\n ))}\n\n {attachments.map((attachment, index) => {\n switch (attachment.type) {\n case 'MessageAttachment':\n return (\n <MessageAttachment\n key={`${attachment.id}-${index}`}\n attachment={attachment}\n onMessageAttachmentLongPress={onMessageAttachmentLongPress}\n isDeleting={deletingAttachmentIds.has(attachment.id)}\n />\n )\n case 'giphy':\n return (\n <GiphyAttachment\n key={`${attachment.id || attachment.titleLink}-${index}`}\n attachment={attachment}\n onMessageLongPress={onMessageLongPress}\n />\n )\n case 'ExpandedLink':\n return (\n <ExpandedLink\n key={`${attachment.id}-${index}`}\n attachment={attachment}\n onMessageLongPress={onMessageLongPress}\n />\n )\n default:\n return null\n }\n })}\n </View>\n )\n}\n\nfunction MessageAttachment({\n attachment,\n onMessageAttachmentLongPress,\n isDeleting,\n}: {\n attachment: DenormalizedMessageAttachmentResource\n onMessageAttachmentLongPress: (attachment: DenormalizedMessageAttachmentResource) => void\n isDeleting: boolean\n}) {\n const { attributes } = attachment\n const contentType = attributes?.contentType\n const basicType = contentType ? contentType.split('/')[0] : ''\n\n switch (basicType) {\n case 'video':\n return (\n <VideoAttachment\n attachment={attachment}\n onMessageAttachmentLongPress={onMessageAttachmentLongPress}\n isDeleting={isDeleting}\n />\n )\n case 'audio':\n return (\n <AudioAttachment\n attachment={attachment}\n onMessageAttachmentLongPress={onMessageAttachmentLongPress}\n isDeleting={isDeleting}\n />\n )\n case 'application':\n return (\n <GenericFileAttachment\n attachment={attachment}\n onMessageAttachmentLongPress={onMessageAttachmentLongPress}\n isDeleting={isDeleting}\n />\n )\n default:\n return null\n }\n}\n\nconst useStyles = () => {\n return StyleSheet.create({\n attachmentsContainer: {\n gap: 2,\n padding: 2,\n },\n })\n}\n"]}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Session, ENV } from '../utils';
|
|
2
|
+
import { FailedResponse, OAuthToken } from '../types';
|
|
3
|
+
import { QueryClient } from '@tanstack/react-query';
|
|
4
|
+
import React, { PropsWithChildren } from 'react';
|
|
5
|
+
import { StorageAdapter } from '../utils/native_adapters/storage_adapter';
|
|
6
|
+
export type SessionContextValue = {
|
|
7
|
+
env: ENV;
|
|
8
|
+
setEnv: (_env: ENV) => void;
|
|
9
|
+
session: Session;
|
|
10
|
+
token: OAuthToken | undefined;
|
|
11
|
+
handleUnauthorizedResponse: (_response: FailedResponse) => void;
|
|
12
|
+
logout: () => void;
|
|
13
|
+
setToken: (_token: OAuthToken) => void;
|
|
14
|
+
};
|
|
15
|
+
export declare const SessionContext: React.Context<SessionContextValue>;
|
|
16
|
+
export type SessionContextConfig = {
|
|
17
|
+
storage: StorageAdapter;
|
|
18
|
+
secureStorage: StorageAdapter;
|
|
19
|
+
refreshTokenFn: (params: {
|
|
20
|
+
refresh_token: string;
|
|
21
|
+
env: ENV;
|
|
22
|
+
}) => Promise<OAuthToken>;
|
|
23
|
+
onLogout: () => void | Promise<void>;
|
|
24
|
+
storageKeys?: {
|
|
25
|
+
env?: string;
|
|
26
|
+
sessions?: string;
|
|
27
|
+
};
|
|
28
|
+
alertConfig?: {
|
|
29
|
+
title?: string;
|
|
30
|
+
message?: string;
|
|
31
|
+
retryText?: string;
|
|
32
|
+
logoutText?: string;
|
|
33
|
+
};
|
|
34
|
+
defaultEnv?: ENV;
|
|
35
|
+
};
|
|
36
|
+
export declare function SessionContextProvider({ children, queryClient, config, }: PropsWithChildren<{
|
|
37
|
+
queryClient: QueryClient;
|
|
38
|
+
config: SessionContextConfig;
|
|
39
|
+
}>): React.JSX.Element;
|
|
40
|
+
//# sourceMappingURL=session_context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session_context.d.ts","sourceRoot":"","sources":["../../src/contexts/session_context.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA;AACvC,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AAErD,OAAO,EAAE,WAAW,EAAe,MAAM,uBAAuB,CAAA;AAChE,OAAO,KAAK,EAAE,EAEZ,iBAAiB,EAKlB,MAAM,OAAO,CAAA;AAGd,OAAO,EAAE,cAAc,EAAE,MAAM,0CAA0C,CAAA;AAEzE,MAAM,MAAM,mBAAmB,GAAG;IAChC,GAAG,EAAE,GAAG,CAAA;IACR,MAAM,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,IAAI,CAAA;IAC3B,OAAO,EAAE,OAAO,CAAA;IAChB,KAAK,EAAE,UAAU,GAAG,SAAS,CAAA;IAC7B,0BAA0B,EAAE,CAAC,SAAS,EAAE,cAAc,KAAK,IAAI,CAAA;IAC/D,MAAM,EAAE,MAAM,IAAI,CAAA;IAClB,QAAQ,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,IAAI,CAAA;CACvC,CAAA;AAED,eAAO,MAAM,cAAc,oCAQzB,CAAA;AAaF,MAAM,MAAM,oBAAoB,GAAG;IAEjC,OAAO,EAAE,cAAc,CAAA;IACvB,aAAa,EAAE,cAAc,CAAA;IAG7B,cAAc,EAAE,CAAC,MAAM,EAAE;QAAE,aAAa,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,GAAG,CAAA;KAAE,KAAK,OAAO,CAAC,UAAU,CAAC,CAAA;IACpF,QAAQ,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAGpC,WAAW,CAAC,EAAE;QACZ,GAAG,CAAC,EAAE,MAAM,CAAA;QACZ,QAAQ,CAAC,EAAE,MAAM,CAAA;KAClB,CAAA;IACD,WAAW,CAAC,EAAE;QACZ,KAAK,CAAC,EAAE,MAAM,CAAA;QACd,OAAO,CAAC,EAAE,MAAM,CAAA;QAChB,SAAS,CAAC,EAAE,MAAM,CAAA;QAClB,UAAU,CAAC,EAAE,MAAM,CAAA;KACpB,CAAA;IACD,UAAU,CAAC,EAAE,GAAG,CAAA;CACjB,CAAA;AAED,wBAAgB,sBAAsB,CAAC,EACrC,QAAQ,EACR,WAAW,EACX,MAAM,GACP,EAAE,iBAAiB,CAAC;IAAE,WAAW,EAAE,WAAW,CAAC;IAAC,MAAM,EAAE,oBAAoB,CAAA;CAAE,CAAC,qBA+J/E"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { Session } from '../utils';
|
|
2
|
+
import { chatQueryClient } from './api_provider';
|
|
3
|
+
import { useMutation } from '@tanstack/react-query';
|
|
4
|
+
import React, { createContext, useCallback, useEffect, useMemo, useState, } from 'react';
|
|
5
|
+
import { Alert } from 'react-native';
|
|
6
|
+
import { useStorage } from '../hooks/use_storage';
|
|
7
|
+
export const SessionContext = createContext({
|
|
8
|
+
env: 'production',
|
|
9
|
+
setEnv: () => null,
|
|
10
|
+
session: new Session(),
|
|
11
|
+
token: undefined,
|
|
12
|
+
handleUnauthorizedResponse: () => null,
|
|
13
|
+
logout: () => null,
|
|
14
|
+
setToken: () => null,
|
|
15
|
+
});
|
|
16
|
+
const environments = ['production', 'staging', 'development'];
|
|
17
|
+
const initialSessions = environments.reduce((acc, env) => {
|
|
18
|
+
const sessionProps = { env, token: undefined };
|
|
19
|
+
acc[env] = new Session(sessionProps).toString();
|
|
20
|
+
return acc;
|
|
21
|
+
}, {});
|
|
22
|
+
export function SessionContextProvider({ children, queryClient, config, }) {
|
|
23
|
+
const { storage, secureStorage, refreshTokenFn, onLogout, storageKeys = {}, alertConfig = {}, defaultEnv = 'production', } = config;
|
|
24
|
+
const envKey = storageKeys.env || 'env';
|
|
25
|
+
const sessionsKey = storageKeys.sessions || 'sessions-storage';
|
|
26
|
+
const [env, setEnv] = useStorage(storage, envKey, defaultEnv);
|
|
27
|
+
const [sessions, setSessions] = useStorage(secureStorage, sessionsKey, initialSessions);
|
|
28
|
+
const [alertShown, setAlertShown] = useState(false);
|
|
29
|
+
const session = useMemo(() => Session.hydrate(sessions[env]), [sessions, env]);
|
|
30
|
+
const { token } = session;
|
|
31
|
+
const { mutate: refreshToken, isPending: isRefreshingToken, isError: isRefreshError, } = useMutation({
|
|
32
|
+
mutationKey: ['refresh-token', token?.refresh_token],
|
|
33
|
+
mutationFn: () => {
|
|
34
|
+
if (!token?.refresh_token) {
|
|
35
|
+
return Promise.reject(new Error('Refresh token is required'));
|
|
36
|
+
}
|
|
37
|
+
return refreshTokenFn({ refresh_token: token.refresh_token, env: session.env }).then(handleTokenUpdate);
|
|
38
|
+
},
|
|
39
|
+
onError: (t) => {
|
|
40
|
+
handleRefreshFailed(t);
|
|
41
|
+
},
|
|
42
|
+
});
|
|
43
|
+
const handleClearQueryClient = useCallback(() => {
|
|
44
|
+
chatQueryClient.clear();
|
|
45
|
+
queryClient.clear();
|
|
46
|
+
}, [queryClient]);
|
|
47
|
+
const handleSetEnv = useCallback((_env) => {
|
|
48
|
+
setEnv(_env);
|
|
49
|
+
handleClearQueryClient();
|
|
50
|
+
}, [handleClearQueryClient, setEnv]);
|
|
51
|
+
const handleLogout = useCallback(async () => {
|
|
52
|
+
handleClearQueryClient();
|
|
53
|
+
return setSessions({
|
|
54
|
+
...sessions,
|
|
55
|
+
[env]: new Session({ env }).toString(),
|
|
56
|
+
}).then(() => onLogout());
|
|
57
|
+
}, [env, sessions, setSessions, handleClearQueryClient, onLogout]);
|
|
58
|
+
const handleTokenUpdate = useCallback((t) => {
|
|
59
|
+
if (!t || !session)
|
|
60
|
+
return t;
|
|
61
|
+
session.token = t;
|
|
62
|
+
return setSessions({
|
|
63
|
+
...sessions,
|
|
64
|
+
[env]: session?.toString(),
|
|
65
|
+
}).then(() => t);
|
|
66
|
+
}, [env, session, sessions, setSessions]);
|
|
67
|
+
const handleRefreshFailed = useCallback((t) => {
|
|
68
|
+
if (t.status !== 401)
|
|
69
|
+
return;
|
|
70
|
+
// If we didn't fail because of an unauthorized response ( 401 ),
|
|
71
|
+
// it could be because we were unable to store the token.
|
|
72
|
+
// Do not log out.
|
|
73
|
+
const { errors = [] } = t;
|
|
74
|
+
// The code for a forced logout is "capuchin"
|
|
75
|
+
const isForcedLogout = errors.some((e) => /capuchin/i.test(e.detail || ''));
|
|
76
|
+
if (isForcedLogout) {
|
|
77
|
+
handleLogout();
|
|
78
|
+
}
|
|
79
|
+
}, [handleLogout]);
|
|
80
|
+
const handleUnauthorizedResponse = useCallback(async (response) => {
|
|
81
|
+
const { errors = [] } = response;
|
|
82
|
+
const isUnauthorized = errors.some((e) => /TRASH_PANDA/i.test(e.detail || ''));
|
|
83
|
+
if (isUnauthorized)
|
|
84
|
+
return;
|
|
85
|
+
const isForcedLogout = errors.some((e) => /capuchin/i.test(e.detail || ''));
|
|
86
|
+
const isExpiredToken = errors.some((e) => /baboon/i.test(e.detail || ''));
|
|
87
|
+
if (!isRefreshingToken || isExpiredToken || isForcedLogout) {
|
|
88
|
+
refreshToken();
|
|
89
|
+
}
|
|
90
|
+
}, [refreshToken, isRefreshingToken]);
|
|
91
|
+
const sessionContextValue = {
|
|
92
|
+
env: session.env,
|
|
93
|
+
token: session.token,
|
|
94
|
+
session,
|
|
95
|
+
logout: handleLogout,
|
|
96
|
+
setToken: handleTokenUpdate,
|
|
97
|
+
handleUnauthorizedResponse,
|
|
98
|
+
setEnv: handleSetEnv,
|
|
99
|
+
};
|
|
100
|
+
const alertTitle = alertConfig.title || 'Oops';
|
|
101
|
+
const alertMessage = alertConfig.message || 'Something went wrong with your login!';
|
|
102
|
+
const retryText = alertConfig.retryText || 'Keep trying';
|
|
103
|
+
const logoutText = alertConfig.logoutText || 'Logout';
|
|
104
|
+
useEffect(() => {
|
|
105
|
+
if (isRefreshError && !alertShown && token?.refresh_token) {
|
|
106
|
+
setAlertShown(true);
|
|
107
|
+
Alert.alert(alertTitle, alertMessage, [
|
|
108
|
+
{
|
|
109
|
+
text: retryText,
|
|
110
|
+
onPress: () => {
|
|
111
|
+
refreshToken();
|
|
112
|
+
setAlertShown(false);
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
{ text: logoutText, onPress: () => handleLogout() },
|
|
116
|
+
]);
|
|
117
|
+
}
|
|
118
|
+
}, [
|
|
119
|
+
isRefreshError,
|
|
120
|
+
handleLogout,
|
|
121
|
+
alertShown,
|
|
122
|
+
refreshToken,
|
|
123
|
+
token?.refresh_token,
|
|
124
|
+
alertTitle,
|
|
125
|
+
alertMessage,
|
|
126
|
+
retryText,
|
|
127
|
+
logoutText,
|
|
128
|
+
]);
|
|
129
|
+
return <SessionContext.Provider value={sessionContextValue}>{children}</SessionContext.Provider>;
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=session_context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session_context.js","sourceRoot":"","sources":["../../src/contexts/session_context.tsx"],"names":[],"mappings":"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","sourcesContent":["import { Session, ENV } from '../utils'\nimport { FailedResponse, OAuthToken } from '../types'\nimport { chatQueryClient } from './api_provider'\nimport { QueryClient, useMutation } from '@tanstack/react-query'\nimport React, {\n createContext,\n PropsWithChildren,\n useCallback,\n useEffect,\n useMemo,\n useState,\n} from 'react'\nimport { Alert } from 'react-native'\nimport { useStorage } from '../hooks/use_storage'\nimport { StorageAdapter } from '../utils/native_adapters/storage_adapter'\n\nexport type SessionContextValue = {\n env: ENV\n setEnv: (_env: ENV) => void\n session: Session\n token: OAuthToken | undefined\n handleUnauthorizedResponse: (_response: FailedResponse) => void\n logout: () => void\n setToken: (_token: OAuthToken) => void\n}\n\nexport const SessionContext = createContext<SessionContextValue>({\n env: 'production',\n setEnv: () => null,\n session: new Session(),\n token: undefined,\n handleUnauthorizedResponse: () => null,\n logout: () => null,\n setToken: () => null,\n})\n\ntype Sessions = Record<ENV, string>\nconst environments: ENV[] = ['production', 'staging', 'development']\n\nconst initialSessions = environments.reduce((acc, env) => {\n const sessionProps = { env, token: undefined }\n\n acc[env] = new Session(sessionProps).toString()\n\n return acc\n}, {} as Sessions)\n\nexport type SessionContextConfig = {\n // Storage adapters\n storage: StorageAdapter // For non-sensitive data (env preference)\n secureStorage: StorageAdapter // For sensitive data (tokens/sessions)\n\n // Functional callbacks\n refreshTokenFn: (params: { refresh_token: string; env: ENV }) => Promise<OAuthToken>\n onLogout: () => void | Promise<void>\n\n // Optional configuration\n storageKeys?: {\n env?: string\n sessions?: string\n }\n alertConfig?: {\n title?: string\n message?: string\n retryText?: string\n logoutText?: string\n }\n defaultEnv?: ENV\n}\n\nexport function SessionContextProvider({\n children,\n queryClient,\n config,\n}: PropsWithChildren<{ queryClient: QueryClient; config: SessionContextConfig }>) {\n const {\n storage,\n secureStorage,\n refreshTokenFn,\n onLogout,\n storageKeys = {},\n alertConfig = {},\n defaultEnv = 'production',\n } = config\n\n const envKey = storageKeys.env || 'env'\n const sessionsKey = storageKeys.sessions || 'sessions-storage'\n\n const [env, setEnv] = useStorage<ENV>(storage, envKey, defaultEnv)\n const [sessions, setSessions] = useStorage<Sessions>(secureStorage, sessionsKey, initialSessions)\n const [alertShown, setAlertShown] = useState(false)\n const session = useMemo(() => Session.hydrate<OAuthToken>(sessions[env]), [sessions, env])\n const { token } = session\n\n const {\n mutate: refreshToken,\n isPending: isRefreshingToken,\n isError: isRefreshError,\n } = useMutation({\n mutationKey: ['refresh-token', token?.refresh_token],\n mutationFn: () => {\n if (!token?.refresh_token) {\n return Promise.reject(new Error('Refresh token is required'))\n }\n return refreshTokenFn({ refresh_token: token.refresh_token, env: session.env }).then(\n handleTokenUpdate\n )\n },\n onError: (t: Partial<FailedResponse>) => {\n handleRefreshFailed(t)\n },\n })\n\n const handleClearQueryClient = useCallback(() => {\n chatQueryClient.clear()\n queryClient.clear()\n }, [queryClient])\n\n const handleSetEnv = useCallback(\n (_env: ENV) => {\n setEnv(_env)\n handleClearQueryClient()\n },\n [handleClearQueryClient, setEnv]\n )\n\n const handleLogout = useCallback(async () => {\n handleClearQueryClient()\n\n return setSessions({\n ...sessions,\n [env]: new Session({ env }).toString(),\n }).then(() => onLogout())\n }, [env, sessions, setSessions, handleClearQueryClient, onLogout])\n\n const handleTokenUpdate = useCallback(\n (t: OAuthToken) => {\n if (!t || !session) return t\n\n session.token = t\n\n return setSessions({\n ...sessions,\n [env]: session?.toString(),\n }).then(() => t)\n },\n [env, session, sessions, setSessions]\n )\n\n const handleRefreshFailed = useCallback(\n (t: Partial<FailedResponse>) => {\n if (t.status !== 401) return\n // If we didn't fail because of an unauthorized response ( 401 ),\n // it could be because we were unable to store the token.\n // Do not log out.\n\n const { errors = [] } = t\n // The code for a forced logout is \"capuchin\"\n const isForcedLogout = errors.some((e: { detail?: string }) =>\n /capuchin/i.test(e.detail || '')\n )\n\n if (isForcedLogout) {\n handleLogout()\n }\n },\n [handleLogout]\n )\n\n const handleUnauthorizedResponse = useCallback(\n async (response: FailedResponse) => {\n const { errors = [] } = response\n\n const isUnauthorized = errors.some((e: { detail?: string }) =>\n /TRASH_PANDA/i.test(e.detail || '')\n )\n\n if (isUnauthorized) return\n\n const isForcedLogout = errors.some((e: { detail?: string }) =>\n /capuchin/i.test(e.detail || '')\n )\n const isExpiredToken = errors.some((e: { detail?: string }) => /baboon/i.test(e.detail || ''))\n\n if (!isRefreshingToken || isExpiredToken || isForcedLogout) {\n refreshToken()\n }\n },\n [refreshToken, isRefreshingToken]\n )\n\n const sessionContextValue: SessionContextValue = {\n env: session.env,\n token: session.token,\n session,\n logout: handleLogout,\n setToken: handleTokenUpdate,\n handleUnauthorizedResponse,\n setEnv: handleSetEnv,\n }\n\n const alertTitle = alertConfig.title || 'Oops'\n const alertMessage = alertConfig.message || 'Something went wrong with your login!'\n const retryText = alertConfig.retryText || 'Keep trying'\n const logoutText = alertConfig.logoutText || 'Logout'\n\n useEffect(() => {\n if (isRefreshError && !alertShown && token?.refresh_token) {\n setAlertShown(true)\n Alert.alert(alertTitle, alertMessage, [\n {\n text: retryText,\n onPress: () => {\n refreshToken()\n setAlertShown(false)\n },\n },\n { text: logoutText, onPress: () => handleLogout() },\n ])\n }\n }, [\n isRefreshError,\n handleLogout,\n alertShown,\n refreshToken,\n token?.refresh_token,\n alertTitle,\n alertMessage,\n retryText,\n logoutText,\n ])\n\n return <SessionContext.Provider value={sessionContextValue}>{children}</SessionContext.Provider>\n}\n"]}
|
package/build/hooks/index.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ export * from './use_animated_message_background_color';
|
|
|
3
3
|
export * from './use_theme';
|
|
4
4
|
export * from './use_suspense_api';
|
|
5
5
|
export * from './use_current_person';
|
|
6
|
+
export * from './use_deleting_ids';
|
|
6
7
|
export * from './use_font_scale';
|
|
7
8
|
export * from './use_create_android_ripple_color';
|
|
8
9
|
export * from './use_chat_permissions';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAA;AACnC,cAAc,yCAAyC,CAAA;AACvD,cAAc,aAAa,CAAA;AAC3B,cAAc,oBAAoB,CAAA;AAClC,cAAc,sBAAsB,CAAA;AACpC,cAAc,kBAAkB,CAAA;AAChC,cAAc,mCAAmC,CAAA;AACjD,cAAc,wBAAwB,CAAA;AACtC,cAAc,kBAAkB,CAAA;AAChC,cAAc,qBAAqB,CAAA;AACnC,cAAc,cAAc,CAAA;AAC5B,cAAc,WAAW,CAAA;AACzB,cAAc,kBAAkB,CAAA;AAChC,cAAc,+BAA+B,CAAA;AAC7C,cAAc,+BAA+B,CAAA;AAC7C,cAAc,gCAAgC,CAAA;AAC9C,cAAc,wBAAwB,CAAA;AACtC,cAAc,gCAAgC,CAAA;AAC9C,cAAc,wBAAwB,CAAA;AACtC,cAAc,oBAAoB,CAAA;AAClC,cAAc,yBAAyB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAA;AACnC,cAAc,yCAAyC,CAAA;AACvD,cAAc,aAAa,CAAA;AAC3B,cAAc,oBAAoB,CAAA;AAClC,cAAc,sBAAsB,CAAA;AACpC,cAAc,oBAAoB,CAAA;AAClC,cAAc,kBAAkB,CAAA;AAChC,cAAc,mCAAmC,CAAA;AACjD,cAAc,wBAAwB,CAAA;AACtC,cAAc,kBAAkB,CAAA;AAChC,cAAc,qBAAqB,CAAA;AACnC,cAAc,cAAc,CAAA;AAC5B,cAAc,WAAW,CAAA;AACzB,cAAc,kBAAkB,CAAA;AAChC,cAAc,+BAA+B,CAAA;AAC7C,cAAc,+BAA+B,CAAA;AAC7C,cAAc,gCAAgC,CAAA;AAC9C,cAAc,wBAAwB,CAAA;AACtC,cAAc,gCAAgC,CAAA;AAC9C,cAAc,wBAAwB,CAAA;AACtC,cAAc,oBAAoB,CAAA;AAClC,cAAc,yBAAyB,CAAA"}
|
package/build/hooks/index.js
CHANGED
|
@@ -3,6 +3,7 @@ export * from './use_animated_message_background_color';
|
|
|
3
3
|
export * from './use_theme';
|
|
4
4
|
export * from './use_suspense_api';
|
|
5
5
|
export * from './use_current_person';
|
|
6
|
+
export * from './use_deleting_ids';
|
|
6
7
|
export * from './use_font_scale';
|
|
7
8
|
export * from './use_create_android_ripple_color';
|
|
8
9
|
export * from './use_chat_permissions';
|
package/build/hooks/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAA;AACnC,cAAc,yCAAyC,CAAA;AACvD,cAAc,aAAa,CAAA;AAC3B,cAAc,oBAAoB,CAAA;AAClC,cAAc,sBAAsB,CAAA;AACpC,cAAc,kBAAkB,CAAA;AAChC,cAAc,mCAAmC,CAAA;AACjD,cAAc,wBAAwB,CAAA;AACtC,cAAc,kBAAkB,CAAA;AAChC,cAAc,qBAAqB,CAAA;AACnC,cAAc,cAAc,CAAA;AAC5B,cAAc,WAAW,CAAA;AACzB,cAAc,kBAAkB,CAAA;AAChC,cAAc,+BAA+B,CAAA;AAC7C,cAAc,+BAA+B,CAAA;AAC7C,cAAc,gCAAgC,CAAA;AAC9C,cAAc,wBAAwB,CAAA;AACtC,cAAc,gCAAgC,CAAA;AAC9C,cAAc,wBAAwB,CAAA;AACtC,cAAc,oBAAoB,CAAA;AAClC,cAAc,yBAAyB,CAAA","sourcesContent":["export * from './use_async_storage'\nexport * from './use_animated_message_background_color'\nexport * from './use_theme'\nexport * from './use_suspense_api'\nexport * from './use_current_person'\nexport * from './use_font_scale'\nexport * from './use_create_android_ripple_color'\nexport * from './use_chat_permissions'\nexport * from './use_api_client'\nexport * from './use_groups_groups'\nexport * from './use_groups'\nexport * from './use_api'\nexport * from './use_api_client'\nexport * from './use_message_reaction_toggle'\nexport * from './use_interaction_ghost_color'\nexport * from './use_at_font_scale_breakpoint'\nexport * from './use_qualified_by_age'\nexport * from './use_scalable_number_of_lines'\nexport * from './use_submit_age_check'\nexport * from './use_organization'\nexport * from './use_product_analytics'\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAA;AACnC,cAAc,yCAAyC,CAAA;AACvD,cAAc,aAAa,CAAA;AAC3B,cAAc,oBAAoB,CAAA;AAClC,cAAc,sBAAsB,CAAA;AACpC,cAAc,oBAAoB,CAAA;AAClC,cAAc,kBAAkB,CAAA;AAChC,cAAc,mCAAmC,CAAA;AACjD,cAAc,wBAAwB,CAAA;AACtC,cAAc,kBAAkB,CAAA;AAChC,cAAc,qBAAqB,CAAA;AACnC,cAAc,cAAc,CAAA;AAC5B,cAAc,WAAW,CAAA;AACzB,cAAc,kBAAkB,CAAA;AAChC,cAAc,+BAA+B,CAAA;AAC7C,cAAc,+BAA+B,CAAA;AAC7C,cAAc,gCAAgC,CAAA;AAC9C,cAAc,wBAAwB,CAAA;AACtC,cAAc,gCAAgC,CAAA;AAC9C,cAAc,wBAAwB,CAAA;AACtC,cAAc,oBAAoB,CAAA;AAClC,cAAc,yBAAyB,CAAA","sourcesContent":["export * from './use_async_storage'\nexport * from './use_animated_message_background_color'\nexport * from './use_theme'\nexport * from './use_suspense_api'\nexport * from './use_current_person'\nexport * from './use_deleting_ids'\nexport * from './use_font_scale'\nexport * from './use_create_android_ripple_color'\nexport * from './use_chat_permissions'\nexport * from './use_api_client'\nexport * from './use_groups_groups'\nexport * from './use_groups'\nexport * from './use_api'\nexport * from './use_api_client'\nexport * from './use_message_reaction_toggle'\nexport * from './use_interaction_ghost_color'\nexport * from './use_at_font_scale_breakpoint'\nexport * from './use_qualified_by_age'\nexport * from './use_scalable_number_of_lines'\nexport * from './use_submit_age_check'\nexport * from './use_organization'\nexport * from './use_product_analytics'\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use_deleting_ids.d.ts","sourceRoot":"","sources":["../../src/hooks/use_deleting_ids.ts"],"names":[],"mappings":"AAGA,KAAK,sBAAsB,GAAG,kBAAkB,CAAA;AAEhD,wBAAgB,cAAc,CAAC,KAAK,EAAE,sBAAsB,GAAG,GAAG,CAAC,MAAM,CAAC,CAgBzE"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { useMutationState } from '@tanstack/react-query';
|
|
2
|
+
import { useMemo } from 'react';
|
|
3
|
+
export function useDeletingIds(event) {
|
|
4
|
+
const ids = useMutationState({
|
|
5
|
+
filters: {
|
|
6
|
+
mutationKey: [event],
|
|
7
|
+
status: 'pending',
|
|
8
|
+
},
|
|
9
|
+
select: mutation => {
|
|
10
|
+
// Extract the item ID from the mutation key: [ event, id ]
|
|
11
|
+
const key = mutation.options.mutationKey;
|
|
12
|
+
return key && Array.isArray(key) && typeof key[1] === 'string' ? key[1] : null;
|
|
13
|
+
},
|
|
14
|
+
});
|
|
15
|
+
return useMemo(() => {
|
|
16
|
+
return new Set(ids.filter(id => id !== null));
|
|
17
|
+
}, [ids]);
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=use_deleting_ids.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use_deleting_ids.js","sourceRoot":"","sources":["../../src/hooks/use_deleting_ids.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AACxD,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAA;AAI/B,MAAM,UAAU,cAAc,CAAC,KAA6B;IAC1D,MAAM,GAAG,GAAG,gBAAgB,CAAC;QAC3B,OAAO,EAAE;YACP,WAAW,EAAE,CAAC,KAAK,CAAC;YACpB,MAAM,EAAE,SAAS;SAClB;QACD,MAAM,EAAE,QAAQ,CAAC,EAAE;YACjB,2DAA2D;YAC3D,MAAM,GAAG,GAAG,QAAQ,CAAC,OAAO,CAAC,WAAW,CAAA;YACxC,OAAO,GAAG,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,OAAO,GAAG,CAAC,CAAC,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;QAChF,CAAC;KACF,CAAC,CAAA;IAEF,OAAO,OAAO,CAAC,GAAG,EAAE;QAClB,OAAO,IAAI,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,IAAI,CAAC,CAAC,CAAA;IAC/C,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAA;AACX,CAAC","sourcesContent":["import { useMutationState } from '@tanstack/react-query'\nimport { useMemo } from 'react'\n\ntype DeletableResourceEvent = 'deleteAttachment'\n\nexport function useDeletingIds(event: DeletableResourceEvent): Set<string> {\n const ids = useMutationState({\n filters: {\n mutationKey: [event],\n status: 'pending',\n },\n select: mutation => {\n // Extract the item ID from the mutation key: [ event, id ]\n const key = mutation.options.mutationKey\n return key && Array.isArray(key) && typeof key[1] === 'string' ? key[1] : null\n },\n })\n\n return useMemo(() => {\n return new Set(ids.filter(id => id !== null))\n }, [ids])\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"attachment_actions_screen.d.ts","sourceRoot":"","sources":["../../../src/screens/attachment_actions/attachment_actions_screen.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAiB,MAAM,0BAA0B,CAAA;AAC3E,OAAO,KAAsB,MAAM,OAAO,CAAA;AAK1C,eAAO,MAAM,8BAA8B,uEAEzC,CAAA;AAEF,MAAM,MAAM,4BAA4B,GAAG,iBAAiB,CAAC;IAC3D,YAAY,EAAE,MAAM,CAAA;IACpB,qBAAqB,EAAE,MAAM,CAAA;IAC7B,aAAa,EAAE,MAAM,CAAA;IACrB,eAAe,EAAE,MAAM,CAAA;IACvB,4BAA4B,EAAE,OAAO,CAAA;IACrC,SAAS,EAAE,OAAO,CAAA;CACnB,CAAC,CAAA;AAEF,wBAAgB,uBAAuB,CAAC,EAAE,KAAK,EAAE,EAAE,4BAA4B,
|
|
1
|
+
{"version":3,"file":"attachment_actions_screen.d.ts","sourceRoot":"","sources":["../../../src/screens/attachment_actions/attachment_actions_screen.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAiB,MAAM,0BAA0B,CAAA;AAC3E,OAAO,KAAsB,MAAM,OAAO,CAAA;AAK1C,eAAO,MAAM,8BAA8B,uEAEzC,CAAA;AAEF,MAAM,MAAM,4BAA4B,GAAG,iBAAiB,CAAC;IAC3D,YAAY,EAAE,MAAM,CAAA;IACpB,qBAAqB,EAAE,MAAM,CAAA;IAC7B,aAAa,EAAE,MAAM,CAAA;IACrB,eAAe,EAAE,MAAM,CAAA;IACvB,4BAA4B,EAAE,OAAO,CAAA;IACrC,SAAS,EAAE,OAAO,CAAA;CACnB,CAAC,CAAA;AAEF,wBAAgB,uBAAuB,CAAC,EAAE,KAAK,EAAE,EAAE,4BAA4B,qBAgE9E"}
|
|
@@ -20,9 +20,16 @@ export function AttachmentActionsScreen({ route }) {
|
|
|
20
20
|
const handleDeleteConfirm = useCallback(() => {
|
|
21
21
|
Alert.alert(`Delete ${attachmentName}`, 'Are you sure you want to permanently delete this attachment?', [
|
|
22
22
|
{ text: 'Cancel', style: 'cancel' },
|
|
23
|
-
{
|
|
23
|
+
{
|
|
24
|
+
text: 'Delete',
|
|
25
|
+
style: 'destructive',
|
|
26
|
+
onPress: () => {
|
|
27
|
+
handleDeleteAttachment();
|
|
28
|
+
navigation.goBack();
|
|
29
|
+
},
|
|
30
|
+
},
|
|
24
31
|
]);
|
|
25
|
-
}, [attachmentName, handleDeleteAttachment]);
|
|
32
|
+
}, [attachmentName, handleDeleteAttachment, navigation]);
|
|
26
33
|
const handleOpenInBrowser = () => {
|
|
27
34
|
Linking.openURL(attachmentUrl);
|
|
28
35
|
navigation.goBack();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"attachment_actions_screen.js","sourceRoot":"","sources":["../../../src/screens/attachment_actions/attachment_actions_screen.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAqB,aAAa,EAAE,MAAM,0BAA0B,CAAA;AAC3E,OAAO,KAAK,EAAE,EAAE,WAAW,EAAE,MAAM,OAAO,CAAA;AAC1C,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AACzD,OAAO,SAAS,EAAE,EAAE,yBAAyB,EAAE,MAAM,uCAAuC,CAAA;AAC5F,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAA;AAEjE,MAAM,CAAC,MAAM,8BAA8B,GAAG,yBAAyB,CAAC;IACtE,WAAW,EAAE,oBAAoB;CAClC,CAAC,CAAA;AAWF,MAAM,UAAU,uBAAuB,CAAC,EAAE,KAAK,EAAgC;IAC7E,MAAM,UAAU,GAAG,aAAa,EAAE,CAAA;IAClC,MAAM,EACJ,YAAY,EACZ,qBAAqB,EACrB,aAAa,EACb,eAAe,EACf,4BAA4B,EAC5B,SAAS,GACV,GAAG,KAAK,CAAC,MAAM,CAAA;IAEhB,MAAM,cAAc,GAAG,sBAAsB,CAAC,qBAAqB,CAAC,CAAA;IACpE,MAAM,SAAS,GAAG,SAAS,IAAI,4BAA4B,CAAA;IAC3D,MAAM,MAAM,GAAG,SAAS,EAAE,CAAA;IAE1B,MAAM,EAAE,sBAAsB,EAAE,GAAG,mBAAmB,CAAC;QACrD,eAAe;QACf,YAAY;QACZ,cAAc;KACf,CAAC,CAAA;IAEF,MAAM,mBAAmB,GAAG,WAAW,CAAC,GAAG,EAAE;QAC3C,KAAK,CAAC,KAAK,CACT,UAAU,cAAc,EAAE,EAC1B,8DAA8D,EAC9D;YACE,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE;YACnC,
|
|
1
|
+
{"version":3,"file":"attachment_actions_screen.js","sourceRoot":"","sources":["../../../src/screens/attachment_actions/attachment_actions_screen.tsx"],"names":[],"mappings":"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","sourcesContent":["import { StaticScreenProps, useNavigation } from '@react-navigation/native'\nimport React, { useCallback } from 'react'\nimport { Alert, Linking, StyleSheet } from 'react-native'\nimport FormSheet, { getFormSheetScreenOptions } from '../../components/primitive/form_sheet'\nimport { useDeleteAttachment } from './hooks/useDeleteAttachment'\n\nexport const AttachmentActionsScreenOptions = getFormSheetScreenOptions({\n headerTitle: 'Attachment actions',\n})\n\nexport type AttachmentActionsScreenProps = StaticScreenProps<{\n attachmentId: string\n attachmentContentType: string\n attachmentUrl: string\n conversation_id: number\n canDeleteNonAuthoredMessages: boolean\n myMessage: boolean\n}>\n\nexport function AttachmentActionsScreen({ route }: AttachmentActionsScreenProps) {\n const navigation = useNavigation()\n const {\n attachmentId,\n attachmentContentType,\n attachmentUrl,\n conversation_id,\n canDeleteNonAuthoredMessages,\n myMessage,\n } = route.params\n\n const attachmentName = getAttachmentLabelName(attachmentContentType)\n const canDelete = myMessage || canDeleteNonAuthoredMessages\n const styles = useStyles()\n\n const { handleDeleteAttachment } = useDeleteAttachment({\n conversation_id,\n attachmentId,\n attachmentName,\n })\n\n const handleDeleteConfirm = useCallback(() => {\n Alert.alert(\n `Delete ${attachmentName}`,\n 'Are you sure you want to permanently delete this attachment?',\n [\n { text: 'Cancel', style: 'cancel' },\n {\n text: 'Delete',\n style: 'destructive',\n onPress: () => {\n handleDeleteAttachment()\n navigation.goBack()\n },\n },\n ]\n )\n }, [attachmentName, handleDeleteAttachment, navigation])\n\n const handleOpenInBrowser = () => {\n Linking.openURL(attachmentUrl)\n navigation.goBack()\n }\n\n return (\n <FormSheet.Root contentStyle={styles.formSheetContent}>\n <FormSheet.Action\n iconName=\"general.newWindow\"\n title=\"Open in browser\"\n accessibilityRole=\"link\"\n accessibilityLabel={`Open ${attachmentName} in browser`}\n accessibilityHint={`${attachmentName} can be downloaded and shared through the browser.`}\n onPress={handleOpenInBrowser}\n />\n {canDelete && (\n <FormSheet.Action\n appearance=\"danger\"\n iconName=\"publishing.trash\"\n title={`Delete ${attachmentName}`}\n onPress={handleDeleteConfirm}\n />\n )}\n </FormSheet.Root>\n )\n}\n\nconst useStyles = () => {\n return StyleSheet.create({\n formSheetContent: {\n paddingTop: 16,\n },\n })\n}\n\nfunction getAttachmentLabelName(contentType: string) {\n if (contentType.startsWith('image/')) return 'image'\n if (contentType.startsWith('video/')) return 'video'\n if (contentType.startsWith('audio/')) return 'audio'\n if (contentType === 'application/pdf') return 'PDF'\n if (contentType.startsWith('application/')) return 'file'\n\n return ''\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDeleteAttachment.d.ts","sourceRoot":"","sources":["../../../../src/screens/attachment_actions/hooks/useDeleteAttachment.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useDeleteAttachment.d.ts","sourceRoot":"","sources":["../../../../src/screens/attachment_actions/hooks/useDeleteAttachment.tsx"],"names":[],"mappings":"AAOA,KAAK,wBAAwB,GAAG;IAC9B,eAAe,EAAE,MAAM,CAAA;IACvB,YAAY,EAAE,MAAM,GAAG,SAAS,CAAA;IAChC,cAAc,EAAE,MAAM,CAAA;CACvB,CAAA;AAED,wBAAgB,mBAAmB,CAAC,EAClC,eAAe,EACf,YAAY,EACZ,cAAc,GACf,EAAE,wBAAwB;;EA4B1B"}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { Alert } from 'react-native';
|
|
2
|
-
import { useNavigation } from '@react-navigation/native';
|
|
3
2
|
import { useMutation } from '@tanstack/react-query';
|
|
4
3
|
import { useApiClient } from '../../../hooks/use_api_client';
|
|
5
4
|
import { useCallback } from 'react';
|
|
@@ -7,7 +6,6 @@ import { useConversationMessages } from '../../../hooks/use_conversation_message
|
|
|
7
6
|
import { Haptic } from '../../../utils/native_adapters';
|
|
8
7
|
export function useDeleteAttachment({ conversation_id, attachmentId, attachmentName, }) {
|
|
9
8
|
const apiClient = useApiClient();
|
|
10
|
-
const navigation = useNavigation();
|
|
11
9
|
const { refetch } = useConversationMessages({ conversation_id }, { refetchOnMount: false });
|
|
12
10
|
const deleteAttachment = useCallback(() => {
|
|
13
11
|
const url = `/me/conversations/${conversation_id}/message_attachments/${attachmentId}`;
|
|
@@ -15,10 +13,10 @@ export function useDeleteAttachment({ conversation_id, attachmentId, attachmentN
|
|
|
15
13
|
}, [apiClient, conversation_id, attachmentId]);
|
|
16
14
|
const { mutate: handleDeleteAttachment } = useMutation({
|
|
17
15
|
mutationFn: deleteAttachment,
|
|
16
|
+
mutationKey: ['deleteAttachment', attachmentId],
|
|
18
17
|
onSuccess: () => {
|
|
19
18
|
refetch();
|
|
20
19
|
Haptic.notificationSuccess();
|
|
21
|
-
navigation.goBack();
|
|
22
20
|
},
|
|
23
21
|
onError: () => {
|
|
24
22
|
Alert.alert('Oops', `We were unable to delete this ${attachmentName} attachment. Please try again.`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDeleteAttachment.js","sourceRoot":"","sources":["../../../../src/screens/attachment_actions/hooks/useDeleteAttachment.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAA;AACpC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"useDeleteAttachment.js","sourceRoot":"","sources":["../../../../src/screens/attachment_actions/hooks/useDeleteAttachment.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAA;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAA;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,OAAO,CAAA;AACnC,OAAO,EAAE,uBAAuB,EAAE,MAAM,0CAA0C,CAAA;AAClF,OAAO,EAAE,MAAM,EAAE,MAAM,gCAAgC,CAAA;AAQvD,MAAM,UAAU,mBAAmB,CAAC,EAClC,eAAe,EACf,YAAY,EACZ,cAAc,GACW;IACzB,MAAM,SAAS,GAAG,YAAY,EAAE,CAAA;IAChC,MAAM,EAAE,OAAO,EAAE,GAAG,uBAAuB,CAAC,EAAE,eAAe,EAAE,EAAE,EAAE,cAAc,EAAE,KAAK,EAAE,CAAC,CAAA;IAE3F,MAAM,gBAAgB,GAAG,WAAW,CAAC,GAAG,EAAE;QACxC,MAAM,GAAG,GAAG,qBAAqB,eAAe,wBAAwB,YAAY,EAAE,CAAA;QAEtF,OAAO,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC,CAAA;IACvC,CAAC,EAAE,CAAC,SAAS,EAAE,eAAe,EAAE,YAAY,CAAC,CAAC,CAAA;IAE9C,MAAM,EAAE,MAAM,EAAE,sBAAsB,EAAE,GAAG,WAAW,CAAC;QACrD,UAAU,EAAE,gBAAgB;QAC5B,WAAW,EAAE,CAAC,kBAAkB,EAAE,YAAY,CAAC;QAC/C,SAAS,EAAE,GAAG,EAAE;YACd,OAAO,EAAE,CAAA;YACT,MAAM,CAAC,mBAAmB,EAAE,CAAA;QAC9B,CAAC;QACD,OAAO,EAAE,GAAG,EAAE;YACZ,KAAK,CAAC,KAAK,CACT,MAAM,EACN,iCAAiC,cAAc,gCAAgC,CAChF,CAAA;QACH,CAAC;KACF,CAAC,CAAA;IAEF,OAAO;QACL,sBAAsB;KACvB,CAAA;AACH,CAAC","sourcesContent":["import { Alert } from 'react-native'\nimport { useMutation } from '@tanstack/react-query'\nimport { useApiClient } from '../../../hooks/use_api_client'\nimport { useCallback } from 'react'\nimport { useConversationMessages } from '../../../hooks/use_conversation_messages'\nimport { Haptic } from '../../../utils/native_adapters'\n\ntype UseDeleteAttachmentProps = {\n conversation_id: number\n attachmentId: string | undefined\n attachmentName: string\n}\n\nexport function useDeleteAttachment({\n conversation_id,\n attachmentId,\n attachmentName,\n}: UseDeleteAttachmentProps) {\n const apiClient = useApiClient()\n const { refetch } = useConversationMessages({ conversation_id }, { refetchOnMount: false })\n\n const deleteAttachment = useCallback(() => {\n const url = `/me/conversations/${conversation_id}/message_attachments/${attachmentId}`\n\n return apiClient.chat.delete({ url })\n }, [apiClient, conversation_id, attachmentId])\n\n const { mutate: handleDeleteAttachment } = useMutation({\n mutationFn: deleteAttachment,\n mutationKey: ['deleteAttachment', attachmentId],\n onSuccess: () => {\n refetch()\n Haptic.notificationSuccess()\n },\n onError: () => {\n Alert.alert(\n 'Oops',\n `We were unable to delete this ${attachmentName} attachment. Please try again.`\n )\n },\n })\n\n return {\n handleDeleteAttachment,\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@planningcenter/chat-react-native",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.22.0-rc.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
@@ -58,5 +58,5 @@
|
|
|
58
58
|
"react-native-url-polyfill": "^2.0.0",
|
|
59
59
|
"typescript": "<5.6.0"
|
|
60
60
|
},
|
|
61
|
-
"gitHead": "
|
|
61
|
+
"gitHead": "c2228e57eb9d8428f1f393cd375a548f6967e7c4"
|
|
62
62
|
}
|