@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.
Files changed (57) hide show
  1. package/build/components/conversation/attachments/attachment_card.js +1 -0
  2. package/build/components/conversation/attachments/attachment_card.js.map +1 -1
  3. package/build/components/conversation/attachments/attachment_deleting_overlay.d.ts +3 -0
  4. package/build/components/conversation/attachments/attachment_deleting_overlay.d.ts.map +1 -0
  5. package/build/components/conversation/attachments/attachment_deleting_overlay.js +29 -0
  6. package/build/components/conversation/attachments/attachment_deleting_overlay.js.map +1 -0
  7. package/build/components/conversation/attachments/audio_attachment.d.ts +2 -1
  8. package/build/components/conversation/attachments/audio_attachment.d.ts.map +1 -1
  9. package/build/components/conversation/attachments/audio_attachment.js +5 -3
  10. package/build/components/conversation/attachments/audio_attachment.js.map +1 -1
  11. package/build/components/conversation/attachments/generic_file_attachment.d.ts +2 -1
  12. package/build/components/conversation/attachments/generic_file_attachment.d.ts.map +1 -1
  13. package/build/components/conversation/attachments/generic_file_attachment.js +4 -2
  14. package/build/components/conversation/attachments/generic_file_attachment.js.map +1 -1
  15. package/build/components/conversation/attachments/image_attachment.d.ts +2 -1
  16. package/build/components/conversation/attachments/image_attachment.d.ts.map +1 -1
  17. package/build/components/conversation/attachments/image_attachment.js +9 -4
  18. package/build/components/conversation/attachments/image_attachment.js.map +1 -1
  19. package/build/components/conversation/attachments/video_attachment.d.ts +2 -1
  20. package/build/components/conversation/attachments/video_attachment.d.ts.map +1 -1
  21. package/build/components/conversation/attachments/video_attachment.js +5 -3
  22. package/build/components/conversation/attachments/video_attachment.js.map +1 -1
  23. package/build/components/conversation/message_attachments.d.ts.map +1 -1
  24. package/build/components/conversation/message_attachments.js +8 -6
  25. package/build/components/conversation/message_attachments.js.map +1 -1
  26. package/build/contexts/session_context.d.ts +40 -0
  27. package/build/contexts/session_context.d.ts.map +1 -0
  28. package/build/contexts/session_context.js +131 -0
  29. package/build/contexts/session_context.js.map +1 -0
  30. package/build/hooks/index.d.ts +1 -0
  31. package/build/hooks/index.d.ts.map +1 -1
  32. package/build/hooks/index.js +1 -0
  33. package/build/hooks/index.js.map +1 -1
  34. package/build/hooks/use_deleting_ids.d.ts +4 -0
  35. package/build/hooks/use_deleting_ids.d.ts.map +1 -0
  36. package/build/hooks/use_deleting_ids.js +19 -0
  37. package/build/hooks/use_deleting_ids.js.map +1 -0
  38. package/build/screens/attachment_actions/attachment_actions_screen.d.ts.map +1 -1
  39. package/build/screens/attachment_actions/attachment_actions_screen.js +9 -2
  40. package/build/screens/attachment_actions/attachment_actions_screen.js.map +1 -1
  41. package/build/screens/attachment_actions/hooks/useDeleteAttachment.d.ts.map +1 -1
  42. package/build/screens/attachment_actions/hooks/useDeleteAttachment.js +1 -3
  43. package/build/screens/attachment_actions/hooks/useDeleteAttachment.js.map +1 -1
  44. package/package.json +2 -2
  45. package/src/__tests__/contexts/session_context.tsx +420 -0
  46. package/src/components/conversation/attachments/attachment_card.tsx +1 -0
  47. package/src/components/conversation/attachments/attachment_deleting_overlay.tsx +34 -0
  48. package/src/components/conversation/attachments/audio_attachment.tsx +7 -2
  49. package/src/components/conversation/attachments/generic_file_attachment.tsx +6 -1
  50. package/src/components/conversation/attachments/image_attachment.tsx +11 -3
  51. package/src/components/conversation/attachments/video_attachment.tsx +7 -2
  52. package/src/components/conversation/message_attachments.tsx +9 -0
  53. package/src/contexts/session_context.tsx +234 -0
  54. package/src/hooks/index.ts +1 -0
  55. package/src/hooks/use_deleting_ids.ts +22 -0
  56. package/src/screens/attachment_actions/attachment_actions_screen.tsx +9 -2
  57. 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;AAQjH,wBAAgB,eAAe,CAAC,EAC9B,UAAU,EACV,4BAA4B,GAC7B,EAAE;IACD,UAAU,EAAE,qCAAqC,CAAA;IACjD,4BAA4B,EAAE,CAAC,UAAU,EAAE,qCAAqC,KAAK,IAAI,CAAA;CAC1F,qBA0DA"}
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
- export function VideoAttachment({ attachment, onMessageAttachmentLongPress, }) {
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;AAExD,MAAM,UAAU,eAAe,CAAC,EAC9B,UAAU,EACV,4BAA4B,GAI7B;IACC,MAAM,EAAE,MAAM,EAAE,GAAG,QAAQ,EAAE,CAAA;IAC7B,MAAM,MAAM,GAAG,SAAS,EAAE,CAAA;IAE1B,MAAM,EAAE,UAAU,EAAE,GAAG,UAAU,CAAA;IACjC,MAAM,EAAE,KAAK,GAAG,+BAA+B,EAAE,MAAM,GAAG,+BAA+B,EAAE,GACzF,UAAU,CAAC,QAAQ,IAAI,EAAE,CAAA;IAC3B,MAAM,EAAE,GAAG,EAAE,GAAG,UAAU,CAAA;IAE1B,MAAM,QAAQ,GAAG,MAAM,CAAoB,IAAI,CAAC,CAAA;IAChD,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;IAE3C,SAAS,SAAS;QAChB,IAAI,CAAC,MAAM,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;YAChC,QAAQ,CAAC,OAAO,CAAC,uBAAuB,EAAE,CAAA;YAC1C,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,CAAA;YACvB,SAAS,CAAC,IAAI,CAAC,CAAA;QACjB,CAAC;IACH,CAAC;IAED,SAAS,6BAA6B;QACpC,QAAQ,CAAC,OAAO,EAAE,KAAK,EAAE,CAAA;QACzB,SAAS,CAAC,KAAK,CAAC,CAAA;IAClB,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,CAAO,IAAI,CAAC,CAAA;IAElC,OAAO,CACL,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAC1C;MAAA,CAAC,iBAAiB,CAChB,OAAO,CAAC,CAAC,SAAS,CAAC,CACnB,WAAW,CAAC,CAAC,GAAG,EAAE,CAAC,4BAA4B,CAAC,UAAU,CAAC,CAAC,CAC5D,cAAc,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,oBAAoB,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CACzE,kBAAkB,CAAC,YAAY,CAC/B,iBAAiB,CAAC,kDAAkD,CAEpE;QAAA,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,gBAAgB,CAAC,EACrC;QAAA,CAAC,KAAK,CAAC,MAAM,CACX,GAAG,CAAC,CAAC,QAAQ,CAAC,CACd,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CACrB,WAAW,CAAC,CAAC,KAAK,GAAG,MAAM,CAAC,CAC5B,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CACpB,6BAA6B,CAAC,CAAC,6BAA6B,CAAC,EAE/D;QAAA,CAAC,CAAC,MAAM,IAAI,CACV,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,CAChC;YAAA,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAC7B;cAAA,CAAC,IAAI,CACH,IAAI,CAAC,eAAe,CACpB,KAAK,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CACvB,2BAA2B,CAAC,CAAC,IAAI,CAAC,EAEtC;YAAA,EAAE,IAAI,CACR;UAAA,EAAE,IAAI,CAAC,CACR,CACH;MAAA,EAAE,iBAAiB,CACrB;IAAA,EAAE,IAAI,CAAC,CACR,CAAA;AACH,CAAC;AACD,MAAM,eAAe,GAAG,CAAC,CAAA;AAEzB,MAAM,SAAS,GAAG,GAAG,EAAE;IACrB,MAAM,EAAE,MAAM,EAAE,GAAG,QAAQ,EAAE,CAAA;IAC7B,MAAM,sBAAsB,GAC1B,MAAM,CAAC,IAAI,KAAK,OAAO;QACrB,CAAC,CAAC,MAAM,CAAC,4BAA4B;QACrC,CAAC,CAAC,MAAM,CAAC,4BAA4B,CAAA;IAEzC,OAAO,UAAU,CAAC,MAAM,CAAC;QACvB,SAAS,EAAE;YACT,YAAY,EAAE,CAAC;YACf,QAAQ,EAAE,QAAQ;SACnB;QACD,KAAK,EAAE;YACL,KAAK,EAAE,MAAM;YACb,eAAe,EAAE,MAAM,CAAC,mBAAmB;SAC5C;QACD,gBAAgB,EAAE;YAChB,QAAQ,EAAE,UAAU;YACpB,GAAG,EAAE,CAAC;YACN,IAAI,EAAE,CAAC;YACP,KAAK,EAAE,CAAC;YACR,MAAM,EAAE,CAAC;YACT,eAAe,EAAE,sBAAsB;YACvC,MAAM,EAAE,eAAe;SACxB;QACD,aAAa,EAAE;YACb,QAAQ,EAAE,UAAU;YACpB,GAAG,EAAE,CAAC;YACN,IAAI,EAAE,CAAC;YACP,KAAK,EAAE,CAAC;YACR,MAAM,EAAE,CAAC;YACT,cAAc,EAAE,QAAQ;YACxB,UAAU,EAAE,QAAQ;YACpB,MAAM,EAAE,eAAe,GAAG,CAAC;SAC5B;QACD,UAAU,EAAE;YACV,cAAc,EAAE,QAAQ;YACxB,UAAU,EAAE,QAAQ;YACpB,KAAK,EAAE,EAAE;YACT,MAAM,EAAE,EAAE;YACV,YAAY,EAAE,EAAE;YAChB,eAAe,EAAE,MAAM,CAAC,2BAA2B;YACnD,WAAW,EAAE,MAAM,CAAC,sBAAsB;YAC1C,WAAW,EAAE,CAAC;SACf;QACD,QAAQ,EAAE;YACR,QAAQ,EAAE,EAAE;SACb;KACF,CAAC,CAAA;AACJ,CAAC,CAAA","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'\n\nexport function VideoAttachment({\n attachment,\n onMessageAttachmentLongPress,\n}: {\n attachment: DenormalizedMessageAttachmentResource\n onMessageAttachmentLongPress: (attachment: DenormalizedMessageAttachmentResource) => void\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={() => 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 >\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 && (\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 </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
+ {"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;AAEhF,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,4BA2DA"}
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":"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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'\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 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 />\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 />\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}: {\n attachment: DenormalizedMessageAttachmentResource\n onMessageAttachmentLongPress: (attachment: DenormalizedMessageAttachmentResource) => void\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 />\n )\n case 'audio':\n return (\n <AudioAttachment\n attachment={attachment}\n onMessageAttachmentLongPress={onMessageAttachmentLongPress}\n />\n )\n case 'application':\n return (\n <GenericFileAttachment\n attachment={attachment}\n onMessageAttachmentLongPress={onMessageAttachmentLongPress}\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"]}
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"]}
@@ -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"}
@@ -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.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,4 @@
1
+ type DeletableResourceEvent = 'deleteAttachment';
2
+ export declare function useDeletingIds(event: DeletableResourceEvent): Set<string>;
3
+ export {};
4
+ //# sourceMappingURL=use_deleting_ids.d.ts.map
@@ -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,qBAyD9E"}
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
- { text: 'Delete', style: 'destructive', onPress: () => handleDeleteAttachment() },
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,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,sBAAsB,EAAE,EAAE;SAClF,CACF,CAAA;IACH,CAAC,EAAE,CAAC,cAAc,EAAE,sBAAsB,CAAC,CAAC,CAAA;IAE5C,MAAM,mBAAmB,GAAG,GAAG,EAAE;QAC/B,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC,CAAA;QAC9B,UAAU,CAAC,MAAM,EAAE,CAAA;IACrB,CAAC,CAAA;IAED,OAAO,CACL,CAAC,SAAS,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,gBAAgB,CAAC,CACpD;MAAA,CAAC,SAAS,CAAC,MAAM,CACf,QAAQ,CAAC,mBAAmB,CAC5B,KAAK,CAAC,iBAAiB,CACvB,iBAAiB,CAAC,MAAM,CACxB,kBAAkB,CAAC,CAAC,QAAQ,cAAc,aAAa,CAAC,CACxD,iBAAiB,CAAC,CAAC,GAAG,cAAc,oDAAoD,CAAC,CACzF,OAAO,CAAC,CAAC,mBAAmB,CAAC,EAE/B;MAAA,CAAC,SAAS,IAAI,CACZ,CAAC,SAAS,CAAC,MAAM,CACf,UAAU,CAAC,QAAQ,CACnB,QAAQ,CAAC,kBAAkB,CAC3B,KAAK,CAAC,CAAC,UAAU,cAAc,EAAE,CAAC,CAClC,OAAO,CAAC,CAAC,mBAAmB,CAAC,EAC7B,CACH,CACH;IAAA,EAAE,SAAS,CAAC,IAAI,CAAC,CAClB,CAAA;AACH,CAAC;AAED,MAAM,SAAS,GAAG,GAAG,EAAE;IACrB,OAAO,UAAU,CAAC,MAAM,CAAC;QACvB,gBAAgB,EAAE;YAChB,UAAU,EAAE,EAAE;SACf;KACF,CAAC,CAAA;AACJ,CAAC,CAAA;AAED,SAAS,sBAAsB,CAAC,WAAmB;IACjD,IAAI,WAAW,CAAC,UAAU,CAAC,QAAQ,CAAC;QAAE,OAAO,OAAO,CAAA;IACpD,IAAI,WAAW,CAAC,UAAU,CAAC,QAAQ,CAAC;QAAE,OAAO,OAAO,CAAA;IACpD,IAAI,WAAW,CAAC,UAAU,CAAC,QAAQ,CAAC;QAAE,OAAO,OAAO,CAAA;IACpD,IAAI,WAAW,KAAK,iBAAiB;QAAE,OAAO,KAAK,CAAA;IACnD,IAAI,WAAW,CAAC,UAAU,CAAC,cAAc,CAAC;QAAE,OAAO,MAAM,CAAA;IAEzD,OAAO,EAAE,CAAA;AACX,CAAC","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 { text: 'Delete', style: 'destructive', onPress: () => handleDeleteAttachment() },\n ]\n )\n }, [attachmentName, handleDeleteAttachment])\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
+ {"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":"AAQA,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;;EA6B1B"}
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,aAAa,EAAE,MAAM,0BAA0B,CAAA;AACxD,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,UAAU,GAAG,aAAa,EAAE,CAAA;IAClC,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,SAAS,EAAE,GAAG,EAAE;YACd,OAAO,EAAE,CAAA;YACT,MAAM,CAAC,mBAAmB,EAAE,CAAA;YAC5B,UAAU,CAAC,MAAM,EAAE,CAAA;QACrB,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 { useNavigation } from '@react-navigation/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 navigation = useNavigation()\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 onSuccess: () => {\n refetch()\n Haptic.notificationSuccess()\n navigation.goBack()\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"]}
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.21.2-rc.4",
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": "243ecc2da2b0a74b66db045af3f30655ea57a55c"
61
+ "gitHead": "c2228e57eb9d8428f1f393cd375a548f6967e7c4"
62
62
  }