@messenger-box/platform-mobile 10.0.3-alpha.23 → 10.0.3-alpha.232

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 (116) hide show
  1. package/lib/components/messages-container-ui/BuildModeView.js +428 -0
  2. package/lib/components/messages-container-ui/BuildModeView.js.map +1 -0
  3. package/lib/components/messages-container-ui/MessagesContainerUI.js +55 -0
  4. package/lib/components/messages-container-ui/MessagesContainerUI.js.map +1 -0
  5. package/lib/components/messages-container-ui/PlanModeView.js +336 -0
  6. package/lib/components/messages-container-ui/PlanModeView.js.map +1 -0
  7. package/lib/compute.js +2 -3
  8. package/lib/compute.js.map +1 -1
  9. package/lib/index.js +1 -1
  10. package/lib/index.js.map +1 -1
  11. package/lib/module.js.map +1 -1
  12. package/lib/queries/inboxQueries.js +62 -0
  13. package/lib/queries/inboxQueries.js.map +1 -0
  14. package/lib/routes.json +2 -3
  15. package/lib/screens/inbox/DialogMessages.js +8 -3
  16. package/lib/screens/inbox/DialogMessages.js.map +1 -1
  17. package/lib/screens/inbox/DialogThreadMessages.js +6 -11
  18. package/lib/screens/inbox/DialogThreadMessages.js.map +1 -1
  19. package/lib/screens/inbox/DialogThreads.js +9 -11
  20. package/lib/screens/inbox/DialogThreads.js.map +1 -1
  21. package/lib/screens/inbox/Inbox.js.map +1 -1
  22. package/lib/screens/inbox/components/CachedImage/consts.js +1 -1
  23. package/lib/screens/inbox/components/CachedImage/consts.js.map +1 -1
  24. package/lib/screens/inbox/components/CachedImage/index.js +125 -96
  25. package/lib/screens/inbox/components/CachedImage/index.js.map +1 -1
  26. package/lib/screens/inbox/components/DialogItem.js +160 -0
  27. package/lib/screens/inbox/components/DialogItem.js.map +1 -0
  28. package/lib/screens/inbox/components/GiftedChatInboxComponent.js +315 -0
  29. package/lib/screens/inbox/components/GiftedChatInboxComponent.js.map +1 -0
  30. package/lib/screens/inbox/components/SlackMessageContainer/ImageViewerModal.js +3 -1
  31. package/lib/screens/inbox/components/SlackMessageContainer/ImageViewerModal.js.map +1 -1
  32. package/lib/screens/inbox/components/SlackMessageContainer/PaymentMessage.js +194 -0
  33. package/lib/screens/inbox/components/SlackMessageContainer/PaymentMessage.js.map +1 -0
  34. package/lib/screens/inbox/components/SlackMessageContainer/SlackBubble.js +149 -36
  35. package/lib/screens/inbox/components/SlackMessageContainer/SlackBubble.js.map +1 -1
  36. package/lib/screens/inbox/components/SlackMessageContainer/SlackMessage.js +4 -5
  37. package/lib/screens/inbox/components/SlackMessageContainer/SlackMessage.js.map +1 -1
  38. package/lib/screens/inbox/components/SubscriptionHandler.js +22 -0
  39. package/lib/screens/inbox/components/SubscriptionHandler.js.map +1 -0
  40. package/lib/screens/inbox/components/ThreadsViewItem.js +2 -4
  41. package/lib/screens/inbox/components/ThreadsViewItem.js.map +1 -1
  42. package/lib/screens/inbox/config/config.js +4 -2
  43. package/lib/screens/inbox/config/config.js.map +1 -1
  44. package/lib/screens/inbox/containers/ConversationView.js +1093 -1090
  45. package/lib/screens/inbox/containers/ConversationView.js.map +1 -1
  46. package/lib/screens/inbox/containers/Dialogs.js +130 -577
  47. package/lib/screens/inbox/containers/Dialogs.js.map +1 -1
  48. package/lib/screens/inbox/containers/ThreadConversationView.js +864 -1408
  49. package/lib/screens/inbox/containers/ThreadConversationView.js.map +1 -1
  50. package/lib/screens/inbox/containers/ThreadsView.js +9 -15
  51. package/lib/screens/inbox/containers/ThreadsView.js.map +1 -1
  52. package/lib/screens/inbox/hooks/useInboxMessages.js +31 -0
  53. package/lib/screens/inbox/hooks/useInboxMessages.js.map +1 -0
  54. package/lib/screens/inbox/hooks/useSafeDialogThreadsMachine.js +1 -1
  55. package/lib/screens/inbox/hooks/useSafeDialogThreadsMachine.js.map +1 -1
  56. package/lib/screens/inbox/workflow/dialog-threads-xstate.js.map +1 -1
  57. package/package.json +10 -8
  58. package/CHANGELOG.md +0 -172
  59. package/jest.config.js +0 -24
  60. package/lib/screens/inbox/components/DialogsListItem.js +0 -548
  61. package/lib/screens/inbox/components/DialogsListItem.js.map +0 -1
  62. package/lib/screens/inbox/components/ServiceDialogsListItem.js +0 -489
  63. package/lib/screens/inbox/components/ServiceDialogsListItem.js.map +0 -1
  64. package/lib/screens/inbox/components/workflow/dialogs-list-item-xstate.js +0 -175
  65. package/lib/screens/inbox/components/workflow/dialogs-list-item-xstate.js.map +0 -1
  66. package/lib/screens/inbox/components/workflow/service-dialogs-list-item-xstate.js +0 -191
  67. package/lib/screens/inbox/components/workflow/service-dialogs-list-item-xstate.js.map +0 -1
  68. package/lib/screens/inbox/containers/workflow/conversation-xstate.js +0 -380
  69. package/lib/screens/inbox/containers/workflow/conversation-xstate.js.map +0 -1
  70. package/lib/screens/inbox/containers/workflow/dialogs-xstate.js +0 -211
  71. package/lib/screens/inbox/containers/workflow/dialogs-xstate.js.map +0 -1
  72. package/lib/screens/inbox/containers/workflow/thread-conversation-xstate.js +0 -438
  73. package/lib/screens/inbox/containers/workflow/thread-conversation-xstate.js.map +0 -1
  74. package/rollup.config.mjs +0 -45
  75. package/src/components/index.ts +0 -0
  76. package/src/compute.ts +0 -63
  77. package/src/index.ts +0 -7
  78. package/src/module.ts +0 -10
  79. package/src/navigation/InboxNavigation.tsx +0 -102
  80. package/src/navigation/index.ts +0 -1
  81. package/src/screens/inbox/DialogMessages.tsx +0 -21
  82. package/src/screens/inbox/DialogThreadMessages.tsx +0 -97
  83. package/src/screens/inbox/DialogThreads.tsx +0 -125
  84. package/src/screens/inbox/Inbox.tsx +0 -17
  85. package/src/screens/inbox/components/CachedImage/consts.ts +0 -6
  86. package/src/screens/inbox/components/CachedImage/index.tsx +0 -223
  87. package/src/screens/inbox/components/DialogsHeader.tsx +0 -30
  88. package/src/screens/inbox/components/DialogsListItem.tsx +0 -819
  89. package/src/screens/inbox/components/ServiceDialogsListItem.tsx +0 -679
  90. package/src/screens/inbox/components/SlackMessageContainer/ImageViewerModal.tsx +0 -113
  91. package/src/screens/inbox/components/SlackMessageContainer/SlackBubble.tsx +0 -313
  92. package/src/screens/inbox/components/SlackMessageContainer/SlackMessage.tsx +0 -145
  93. package/src/screens/inbox/components/SlackMessageContainer/index.ts +0 -3
  94. package/src/screens/inbox/components/SmartLoader.tsx +0 -61
  95. package/src/screens/inbox/components/SupportServiceDialogsListItem.tsx +0 -301
  96. package/src/screens/inbox/components/ThreadsViewItem.tsx +0 -233
  97. package/src/screens/inbox/components/workflow/dialogs-list-item-xstate.ts +0 -145
  98. package/src/screens/inbox/components/workflow/service-dialogs-list-item-xstate.ts +0 -159
  99. package/src/screens/inbox/config/config.ts +0 -15
  100. package/src/screens/inbox/config/index.ts +0 -1
  101. package/src/screens/inbox/containers/ConversationView.tsx +0 -1784
  102. package/src/screens/inbox/containers/Dialogs.tsx +0 -829
  103. package/src/screens/inbox/containers/SupportServiceDialogs.tsx +0 -119
  104. package/src/screens/inbox/containers/ThreadConversationView.tsx +0 -2295
  105. package/src/screens/inbox/containers/ThreadsView.tsx +0 -224
  106. package/src/screens/inbox/containers/workflow/apollo/handleResult.ts +0 -20
  107. package/src/screens/inbox/containers/workflow/conversation-xstate.ts +0 -313
  108. package/src/screens/inbox/containers/workflow/dialogs-xstate.ts +0 -196
  109. package/src/screens/inbox/containers/workflow/thread-conversation-xstate.ts +0 -401
  110. package/src/screens/inbox/hooks/useSafeDialogThreadsMachine.ts +0 -136
  111. package/src/screens/inbox/index.ts +0 -37
  112. package/src/screens/inbox/machines/threadsMachine.ts +0 -147
  113. package/src/screens/inbox/workflow/dialog-threads-xstate.ts +0 -163
  114. package/src/screens/index.ts +0 -4
  115. package/tsconfig.json +0 -13
  116. package/webpack.config.js +0 -58
@@ -1 +1 @@
1
- {"version":3,"file":"DialogThreadMessages.js","sources":["../../../src/screens/inbox/DialogThreadMessages.tsx"],"sourcesContent":["import * as React from 'react';\nimport { Box, Spinner, Text } from '@admin-layout/gluestack-ui-mobile';\nimport { ThreadConversationView } from './containers/ThreadConversationView';\nimport { ThreadsView } from './containers/ThreadsView';\nimport { useViewChannelDetailQuery, useSendThreadMessageMutation } from 'common/graphql';\nimport { useFocusEffect } from '@react-navigation/native';\n// import { useSelector } from 'react-redux';\nimport colors from 'tailwindcss/colors';\n\nexport function DialogThreadMessages({ channelId, postParentId, isPostParentIdThread, role }) {\n const {\n data,\n loading: channelLoading,\n refetch,\n } = useViewChannelDetailQuery({\n variables: {\n id: channelId?.toString(),\n },\n });\n\n const [sendThreadMessage] = useSendThreadMessageMutation();\n const [loading, setLoading] = React.useState<boolean>(true);\n const [channel, setChannel] = React.useState<any>(null);\n const [parentId, setParentId] = React.useState<any>(postParentId);\n\n const refetchChannelDetail = React.useCallback(\n (id: string) => {\n return refetch({ id: id?.toString() });\n },\n [channelId],\n );\n\n useFocusEffect(\n React.useCallback(() => {\n // Do something when the screen is focused\n if (channelId) refetch({ id: channelId?.toString() });\n return () => {};\n }, [channelId]),\n );\n\n React.useEffect(() => {\n setParentId(postParentId);\n }, [postParentId]);\n\n React.useEffect(() => {\n if (data?.viewChannelDetail) {\n setChannel(data?.viewChannelDetail);\n setLoading(false);\n }\n }, [data]);\n\n // React.useEffect(() => {\n // async function sendInitialMessage(channel: any) {\n // const content = `Welcome to ${channel?.title}`;\n // const createdBy = channel?.creator?.id;\n // await sendThreadMessage({\n // variables: {\n // channelId,\n // threadMessageInput: {\n // content,\n // role,\n // },\n // responderId: createdBy,\n // },\n // update: (cache, { data, errors }: any) => {\n // if (!data) {\n // return;\n // }\n // setParentId(data?.sendThreadMessage?.lastMessage?.id);\n // },\n // });\n // }\n // if ((!parentId || parentId == 0) && channel) {\n // sendInitialMessage(channel);\n // }\n\n // if (parentId) setLoading(false);\n // }, [parentId, channel]);\n\n return (\n <Box className=\"bg-white flex-1\">\n {/* {loading && !parentId ? ( */}\n {loading ? (\n <Spinner color={colors.blue[500]} />\n ) : (\n <ThreadConversationView\n channelId={channelId}\n postParentId={parentId}\n isPostParentIdThread={isPostParentIdThread}\n role={role}\n />\n )}\n </Box>\n );\n}\n\nexport default DialogThreadMessages;\n"],"names":[],"mappings":"qVAQO,SAAS,oBAAqB,CAAA;AAAA,EACnC,SAAA;AAAA,EACA,YAAA;AAAA,EACA,oBAAA;AAAA,EACA;AACF,CAAG,EAAA;AACD,EAAM,MAAA;AAAA,IACJ,IAAA;AAAA,IACA,OAAS,EAAA,cAAA;AAAA,IACT;AAAA,MACE,yBAA0B,CAAA;AAAA,IAC5B,SAAW,EAAA;AAAA,MACT,IAAI,SAAW,IAAA,IAAA,GAAA,MAAA,GAAA,SAAA,CAAA,QAAA;AAAA;AACjB,GACD,CAAA;AACD,EAAM,MAAA,CAAC,iBAAiB,CAAA,GAAI,4BAA6B,EAAA;AACzD,EAAA,MAAM,CAAC,OAAS,EAAA,UAAU,CAAI,GAAA,KAAA,CAAM,SAAkB,IAAI,CAAA;AAC1D,EAAA,MAAM,CAAC,OAAS,EAAA,UAAU,CAAI,GAAA,KAAA,CAAM,SAAc,IAAI,CAAA;AACtD,EAAA,MAAM,CAAC,QAAU,EAAA,WAAW,CAAI,GAAA,KAAA,CAAM,SAAc,YAAY,CAAA;AAChE,EAA6B,KAAA,CAAM,WAAY,CAAA,CAAC,EAAe,KAAA;AAC7D,IAAA,OAAO,OAAQ,CAAA;AAAA,MACb,IAAI,EAAI,IAAA,IAAA,GAAA,MAAA,GAAA,EAAA,CAAA,QAAA;AAAA,KACT,CAAA;AAAA,GACH,EAAG,CAAC,SAAS,CAAC;AACd,EAAe,cAAA,CAAA,KAAA,CAAM,YAAY,MAAM;AAErC,IAAI,IAAA,SAAA;AAAW,MAAQ,OAAA,CAAA;AAAA,QACrB,IAAI,SAAW,IAAA,IAAA,GAAA,MAAA,GAAA,SAAA,CAAA,QAAA;AAAA,OAChB,CAAA;AACD,IAAA,OAAO,MAAM;AAAA,KAAC;AAAA,GACb,EAAA,CAAC,SAAS,CAAC,CAAC,CAAA;AACf,EAAA,KAAA,CAAM,UAAU,MAAM;AACpB,IAAA,WAAA,CAAY,YAAY,CAAA;AAAA,GAC1B,EAAG,CAAC,YAAY,CAAC,CAAA;AACjB,EAAA,KAAA,CAAM,UAAU,MAAM;AACpB,IAAA,IAAI,6BAAM,iBAAmB,EAAA;AAC3B,MAAA,UAAA,CAAW,6BAAM,iBAAiB,CAAA;AAClC,MAAA,UAAA,CAAW,KAAK,CAAA;AAAA;AAClB,GACF,EAAG,CAAC,IAAI,CAAC,CAAA;AA8BT,EAAA,2CAAQ,GAAI,EAAA,EAAA,SAAA,EAAU,qBAEX,OAAU,mBAAA,KAAA,CAAA,aAAA,CAAC,WAAQ,KAAO,EAAA,MAAA,CAAO,KAAK,GAAM,CAAA,EAAA,CAAA,uCAAM,sBAAuB,EAAA,EAAA,SAAA,EAAsB,cAAc,QAAU,EAAA,oBAAA,EAA4C,MAAY,CACpL,CAAA;AACR"}
1
+ {"version":3,"file":"DialogThreadMessages.js","sources":["../../../src/screens/inbox/DialogThreadMessages.tsx"],"sourcesContent":["import * as React from 'react';\nimport { Box, Spinner, Text } from '@admin-layout/gluestack-ui-mobile';\nimport { ThreadConversationView } from './containers/ThreadConversationView';\nimport { ThreadsView } from './containers/ThreadsView';\nimport { useChannelDetailQuery, useSendThreadMessage } from '../../queries/inboxQueries';\nimport { useFocusEffect } from '@react-navigation/native';\n// import { useSelector } from 'react-redux';\nimport colors from 'tailwindcss/colors';\n\nexport function DialogThreadMessages({ channelId, postParentId, isPostParentIdThread, role }) {\n const { data, loading: channelLoading, refetch } = useChannelDetailQuery(channelId?.toString(), {});\n\n const [sendThreadMessage] = useSendThreadMessage();\n const [loading, setLoading] = React.useState<boolean>(true);\n const [channel, setChannel] = React.useState<any>(null);\n const [parentId, setParentId] = React.useState<any>(postParentId);\n\n const refetchChannelDetail = React.useCallback(\n (id: string) => {\n return refetch({ id: id?.toString() });\n },\n [channelId],\n );\n\n useFocusEffect(\n React.useCallback(() => {\n // Do something when the screen is focused\n if (channelId) refetch({ id: channelId?.toString() });\n return () => {};\n }, [channelId]),\n );\n\n React.useEffect(() => {\n setParentId(postParentId);\n }, [postParentId]);\n\n React.useEffect(() => {\n if (data?.viewChannelDetail) {\n setChannel(data?.viewChannelDetail);\n setLoading(false);\n }\n }, [data]);\n\n // React.useEffect(() => {\n // async function sendInitialMessage(channel: any) {\n // const content = `Welcome to ${channel?.title}`;\n // const createdBy = channel?.creator?.id;\n // await sendThreadMessage({\n // variables: {\n // channelId,\n // threadMessageInput: {\n // content,\n // role,\n // },\n // responderId: createdBy,\n // },\n // update: (cache, { data, errors }: any) => {\n // if (!data) {\n // return;\n // }\n // setParentId(data?.sendThreadMessage?.lastMessage?.id);\n // },\n // });\n // }\n // if ((!parentId || parentId == 0) && channel) {\n // sendInitialMessage(channel);\n // }\n\n // if (parentId) setLoading(false);\n // }, [parentId, channel]);\n\n return (\n <Box className=\"bg-white flex-1\">\n {/* {loading && !parentId ? ( */}\n {loading ? (\n <Spinner color={colors.blue[500]} />\n ) : (\n <ThreadConversationView\n channelId={channelId}\n postParentId={parentId}\n isPostParentIdThread={isPostParentIdThread}\n role={role}\n />\n )}\n </Box>\n );\n}\n\nexport default DialogThreadMessages;\n"],"names":[],"mappings":"wVAQO,SAAS,oBAAA,CAAqB;AAAA,EACnC,SAAA;AAAA,EACA,YAAA;AAAA,EACA,oBAAA;AAAA,EACA;AACF,CAAA,EAAG;AACD,EAAA,MAAM;AAAA,IACJ,IAAA;AAAA,IACA,OAAA,EAAS,cAAA;AAAA,IACT;AAAA,GACF,GAAI,qBAAA,CAAsB,SAAA,IAAA,IAAA,GAAA,MAAA,GAAA,SAAA,CAAW,QAAA,EAAA,EAAY,EAAE,CAAA;AACnD,EAAA,MAAM,CAAC,iBAAiB,CAAA,GAAI,oBAAA,EAAqB;AACjD,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAI,KAAA,CAAM,SAAkB,IAAI,CAAA;AAC1D,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAI,KAAA,CAAM,SAAc,IAAI,CAAA;AACtD,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAI,KAAA,CAAM,SAAc,YAAY,CAAA;AAChE,EAA6B,KAAA,CAAM,WAAA,CAAY,CAAC,EAAA,KAAe;AAC7D,IAAA,OAAO,OAAA,CAAQ;AAAA,MACb,IAAI,EAAA,IAAA,IAAA,GAAA,MAAA,GAAA,EAAA,CAAI,QAAA;AAAA,KACT,CAAA;AAAA,EACH,CAAA,EAAG,CAAC,SAAS,CAAC;AACd,EAAA,cAAA,CAAe,KAAA,CAAM,YAAY,MAAM;AAErC,IAAA,IAAI,WAAW,OAAA,CAAQ;AAAA,MACrB,IAAI,SAAA,IAAA,IAAA,GAAA,MAAA,GAAA,SAAA,CAAW,QAAA;AAAA,KAChB,CAAA;AACD,IAAA,OAAO,MAAM;AAAA,IAAC,CAAA;AAAA,EAChB,CAAA,EAAG,CAAC,SAAS,CAAC,CAAC,CAAA;AACf,EAAA,KAAA,CAAM,UAAU,MAAM;AACpB,IAAA,WAAA,CAAY,YAAY,CAAA;AAAA,EAC1B,CAAA,EAAG,CAAC,YAAY,CAAC,CAAA;AACjB,EAAA,KAAA,CAAM,UAAU,MAAM;AACpB,IAAA,IAAI,6BAAM,iBAAA,EAAmB;AAC3B,MAAA,UAAA,CAAW,6BAAM,iBAAiB,CAAA;AAClC,MAAA,UAAA,CAAW,KAAK,CAAA;AAAA,IAClB;AAAA,EACF,CAAA,EAAG,CAAC,IAAI,CAAC,CAAA;AA8BT,EAAA,uBAAO,KAAA,CAAA,aAAA,CAAC,OAAI,SAAA,EAAU,iBAAA,EAAA,EAEX,0BAAU,KAAA,CAAA,aAAA,CAAC,OAAA,EAAA,EAAQ,OAAO,MAAA,CAAO,IAAA,CAAK,GAAG,CAAA,EAAG,CAAA,uCAAM,sBAAA,EAAA,EAAuB,SAAA,EAAsB,cAAc,QAAA,EAAU,oBAAA,EAA4C,MAAY,CACpL,CAAA;AACR"}
@@ -1,4 +1,4 @@
1
- import*as React from'react';import {Spinner,Box}from'@admin-layout/gluestack-ui-mobile';import {ThreadsView}from'./containers/ThreadsView.js';import {useViewChannelDetailQuery,useThreadMessagesQuery}from'common/graphql';import {useFocusEffect}from'@react-navigation/native';import {config}from'./config/config.js';import colors from'tailwindcss/colors';import {useSafeDialogThreadsMachine}from'./hooks/useSafeDialogThreadsMachine.js';import {Actions,BaseState}from'./workflow/dialog-threads-xstate.js';const {
1
+ import*as React from'react';import {Spinner,Box}from'@admin-layout/gluestack-ui-mobile';import {ThreadsView}from'./containers/ThreadsView.js';import {useChannelDetailQuery,useThreadMessagesQueryWithOptions}from'../../queries/inboxQueries.js';import {useFocusEffect}from'@react-navigation/native';import {config}from'./config/config.js';import colors from'tailwindcss/colors';import {useSafeDialogThreadsMachine}from'./hooks/useSafeDialogThreadsMachine.js';import {Actions,BaseState}from'./workflow/dialog-threads-xstate.js';const {
2
2
  MESSAGES_PER_PAGE
3
3
  } = config;
4
4
  function DialogThreads({
@@ -6,6 +6,7 @@ function DialogThreads({
6
6
  postParentId,
7
7
  role
8
8
  }) {
9
+ var _a;
9
10
  const [state, send] = useSafeDialogThreadsMachine();
10
11
  const {
11
12
  context,
@@ -20,18 +21,14 @@ function DialogThreads({
20
21
  data: channelData,
21
22
  loading: channelLoading,
22
23
  refetch: channelRefetch
23
- } = useViewChannelDetailQuery({
24
- variables: {
25
- id: channelId == null ? void 0 : channelId.toString()
26
- }
27
- });
24
+ } = useChannelDetailQuery(channelId == null ? void 0 : channelId.toString(), {});
28
25
  const {
29
26
  data: threadsData,
30
27
  loading: threadLoading,
31
28
  error: threadsError,
32
29
  refetch: threadsRefetch,
33
30
  subscribeToMore: threadsSubscribeToMore
34
- } = useThreadMessagesQuery({
31
+ } = useThreadMessagesQueryWithOptions({
35
32
  variables: {
36
33
  channelId: channelId == null ? void 0 : channelId.toString(),
37
34
  role: role == null ? void 0 : role.toString(),
@@ -39,6 +36,8 @@ function DialogThreads({
39
36
  repliesLimit2: 5
40
37
  }
41
38
  });
39
+ console.log("threadsData", (_a = threadsData == null ? void 0 : threadsData.threadMessages) == null ? void 0 : _a.totalCount);
40
+ console.log("channelid", channelId);
42
41
  React.useEffect(() => {
43
42
  send({
44
43
  type: Actions.INITIALIZE,
@@ -60,12 +59,12 @@ function DialogThreads({
60
59
  }
61
60
  }, [channelData]);
62
61
  React.useEffect(() => {
63
- var _a;
62
+ var _a2;
64
63
  if (threadsData) {
65
64
  send({
66
65
  type: Actions.SET_THREADS,
67
66
  data: {
68
- threadData: ((_a = threadsData == null ? void 0 : threadsData.threadMessages) == null ? void 0 : _a.data) || []
67
+ threadData: ((_a2 = threadsData == null ? void 0 : threadsData.threadMessages) == null ? void 0 : _a2.data) || []
69
68
  }
70
69
  });
71
70
  }
@@ -86,8 +85,7 @@ function DialogThreads({
86
85
  });
87
86
  }, [channelId]);
88
87
  useFocusEffect(React.useCallback(() => {
89
- if (channelId)
90
- refetchChannelDetail(channelId);
88
+ if (channelId) refetchChannelDetail(channelId);
91
89
  return () => {
92
90
  };
93
91
  }, []));
@@ -1 +1 @@
1
- {"version":3,"file":"DialogThreads.js","sources":["../../../src/screens/inbox/DialogThreads.tsx"],"sourcesContent":["import * as React from 'react';\nimport { Box, Spinner, Text } from '@admin-layout/gluestack-ui-mobile';\nimport { ThreadConversationView } from './containers/ThreadConversationView';\nimport { ThreadsView } from './containers/ThreadsView';\nimport { useViewChannelDetailQuery, useThreadMessagesQuery } from 'common/graphql';\nimport { useFocusEffect } from '@react-navigation/native';\nimport { useSelector } from 'react-redux';\nimport { config } from './config';\nimport colors from 'tailwindcss/colors';\nimport { useSafeDialogThreadsMachine } from './hooks/useSafeDialogThreadsMachine';\nimport { Actions, BaseState } from './workflow/dialog-threads-xstate';\nconst { MESSAGES_PER_PAGE } = config;\n\nexport function DialogThreads({ channelId, postParentId, role }) {\n // Use the XState machine for state management\n const [state, send] = useSafeDialogThreadsMachine();\n const { context, value } = state;\n const { channelsDetail, loading, error } = context;\n\n // Fetch channel details\n const {\n data: channelData,\n loading: channelLoading,\n refetch: channelRefetch,\n } = useViewChannelDetailQuery({\n variables: {\n id: channelId?.toString(),\n },\n });\n\n // Fetch thread messages\n const {\n data: threadsData,\n loading: threadLoading,\n error: threadsError,\n refetch: threadsRefetch,\n subscribeToMore: threadsSubscribeToMore,\n } = useThreadMessagesQuery({\n variables: {\n channelId: channelId?.toString(),\n role: role?.toString(),\n limit: MESSAGES_PER_PAGE,\n repliesLimit2: 5,\n },\n });\n\n // Initialize the machine with props\n React.useEffect(() => {\n send({\n type: Actions.INITIALIZE,\n data: { channelId, postParentId, role },\n });\n }, [channelId, postParentId, role]);\n\n // Update channel detail in state when data changes\n React.useEffect(() => {\n if (channelData?.viewChannelDetail) {\n send({\n type: Actions.SET_CHANNEL_DETAIL,\n data: { channelsDetail: channelData.viewChannelDetail },\n });\n }\n }, [channelData]);\n\n // Update thread data in state when data changes\n React.useEffect(() => {\n if (threadsData) {\n send({\n type: Actions.SET_THREADS,\n data: { threadData: threadsData?.threadMessages?.data || [] },\n });\n }\n }, [threadsData]);\n\n // Handle errors\n React.useEffect(() => {\n if (threadsError) {\n send({\n type: Actions.ERROR,\n data: { error: threadsError },\n });\n }\n }, [threadsError]);\n\n const refetchChannelDetail = React.useCallback(\n (id: string) => {\n return channelRefetch({ id: id?.toString() });\n },\n [channelId],\n );\n\n useFocusEffect(\n React.useCallback(() => {\n // Do something when the screen is focused\n if (channelId) refetchChannelDetail(channelId);\n return () => {};\n }, []),\n );\n\n return (\n <>\n {state.matches(BaseState.LoadingChannel) || channelLoading ? (\n <Spinner color={colors.blue[500]} />\n ) : (\n <>\n <Box className=\"flex-1 bg-gray-200 dark:border-gray-500 dark:bg-gray-500\">\n <ThreadsView\n data={threadsData}\n loading={threadLoading || state.matches(BaseState.LoadingThreads)}\n refetch={threadsRefetch}\n subscribeToMore={threadsSubscribeToMore}\n error={error || threadsError}\n channelId={channelId}\n role={role}\n channelsDetail={channelsDetail}\n refetchChannelDetail={refetchChannelDetail}\n />\n </Box>\n </>\n )}\n </>\n );\n}\n\nexport default DialogThreads;\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"DialogThreads.js","sources":["../../../src/screens/inbox/DialogThreads.tsx"],"sourcesContent":["import * as React from 'react';\nimport { Box, Spinner, Text } from '@admin-layout/gluestack-ui-mobile';\nimport { ThreadConversationView } from './containers/ThreadConversationView';\nimport { ThreadsView } from './containers/ThreadsView';\nimport { useChannelDetailQuery, useThreadMessagesQueryWithOptions } from '../../queries/inboxQueries';\nimport { useFocusEffect } from '@react-navigation/native';\nimport { useSelector } from 'react-redux';\nimport { config } from './config';\nimport colors from 'tailwindcss/colors';\nimport { useSafeDialogThreadsMachine } from './hooks/useSafeDialogThreadsMachine';\nimport { Actions, BaseState } from './workflow/dialog-threads-xstate';\nconst { MESSAGES_PER_PAGE } = config;\n\nexport function DialogThreads({ channelId, postParentId, role }) {\n // Use the XState machine for state management\n const [state, send] = useSafeDialogThreadsMachine();\n const { context, value } = state;\n const { channelsDetail, loading, error } = context;\n\n // Fetch channel details\n const {\n data: channelData,\n loading: channelLoading,\n refetch: channelRefetch,\n } = useChannelDetailQuery(channelId?.toString(), {});\n\n // Fetch thread messages\n const {\n data: threadsData,\n loading: threadLoading,\n error: threadsError,\n refetch: threadsRefetch,\n subscribeToMore: threadsSubscribeToMore,\n } = useThreadMessagesQueryWithOptions({\n variables: {\n channelId: channelId?.toString(),\n role: role?.toString(),\n limit: MESSAGES_PER_PAGE,\n repliesLimit2: 5,\n },\n });\n console.log('threadsData', threadsData?.threadMessages?.totalCount);\n console.log('channelid', channelId);\n // Initialize the machine with props\n React.useEffect(() => {\n send({\n type: Actions.INITIALIZE,\n data: { channelId, postParentId, role },\n });\n }, [channelId, postParentId, role]);\n\n // Update channel detail in state when data changes\n React.useEffect(() => {\n if (channelData?.viewChannelDetail) {\n send({\n type: Actions.SET_CHANNEL_DETAIL,\n data: { channelsDetail: channelData.viewChannelDetail },\n });\n }\n }, [channelData]);\n\n // Update thread data in state when data changes\n React.useEffect(() => {\n if (threadsData) {\n send({\n type: Actions.SET_THREADS,\n data: { threadData: threadsData?.threadMessages?.data || [] },\n });\n }\n }, [threadsData]);\n\n // Handle errors\n React.useEffect(() => {\n if (threadsError) {\n send({\n type: Actions.ERROR,\n data: { error: threadsError },\n });\n }\n }, [threadsError]);\n\n const refetchChannelDetail = React.useCallback(\n (id: string) => {\n return channelRefetch({ id: id?.toString() });\n },\n [channelId],\n );\n\n useFocusEffect(\n React.useCallback(() => {\n // Do something when the screen is focused\n if (channelId) refetchChannelDetail(channelId);\n return () => {};\n }, []),\n );\n\n return (\n <>\n {state.matches(BaseState.LoadingChannel) || channelLoading ? (\n <Spinner color={colors.blue[500]} />\n ) : (\n <>\n <Box className=\"flex-1 bg-gray-200 dark:border-gray-500 dark:bg-gray-500\">\n <ThreadsView\n data={threadsData}\n loading={threadLoading || state.matches(BaseState.LoadingThreads)}\n refetch={threadsRefetch}\n subscribeToMore={threadsSubscribeToMore}\n error={error || threadsError}\n channelId={channelId}\n role={role}\n channelsDetail={channelsDetail}\n refetchChannelDetail={refetchChannelDetail}\n />\n </Box>\n </>\n )}\n </>\n );\n}\n\nexport default DialogThreads;\n"],"names":["_a"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"Inbox.js","sources":["../../../src/screens/inbox/Inbox.tsx"],"sourcesContent":["import * as React from 'react';\nimport { Box, Text } from '@admin-layout/gluestack-ui-mobile';\n\nimport { Dialogs } from './containers/Dialogs';\n// import { SupportServiceDialogs } from './containers/SupportServiceDialogs';\n\nexport const Inbox = (props: any) => {\n const { channelFilters, channelRole, supportServices } = props;\n return (\n <Box className=\"flex-1 bg-white\">\n {/* {supportServices && (\n <SupportServiceDialogs channelFilters={channelFilters} channelRole={channelRole} {...props} />\n )} */}\n <Dialogs channelFilters={channelFilters} channelRole={channelRole} {...props} />\n </Box>\n );\n};\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAKa,MAAA,KAAA,GAAQ,CAAC,KAAe,KAAA;AACnC,EAAM,MAAA;AAAA,IACJ,cAAA;AAAA,IACA,WAAA;AAAA,IACA;AAAA,GACE,GAAA,KAAA;AACJ,EAAO,uBAAA,KAAA,CAAA,aAAA,CAAC,OAAI,SAAU,EAAA,iBAAA,EAAA,sCAIX,OAAQ,EAAA,cAAA,CAAA,EAAA,cAAA,EAAgC,WAA8B,EAAA,EAAA,KAAA,CAAO,CAClF,CAAA;AACR"}
1
+ {"version":3,"file":"Inbox.js","sources":["../../../src/screens/inbox/Inbox.tsx"],"sourcesContent":["import * as React from 'react';\nimport { Box, Text } from '@admin-layout/gluestack-ui-mobile';\n\nimport { Dialogs } from './containers/Dialogs';\n// import { SupportServiceDialogs } from './containers/SupportServiceDialogs';\n\nexport const Inbox = (props: any) => {\n const { channelFilters, channelRole, supportServices } = props;\n return (\n <Box className=\"flex-1 bg-white\">\n {/* {supportServices && (\n <SupportServiceDialogs channelFilters={channelFilters} channelRole={channelRole} {...props} />\n )} */}\n <Dialogs channelFilters={channelFilters} channelRole={channelRole} {...props} />\n </Box>\n );\n};\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAKO,MAAM,KAAA,GAAQ,CAAC,KAAA,KAAe;AACnC,EAAA,MAAM;AAAA,IACJ,cAAA;AAAA,IACA,WAAA;AAAA,IACA;AAAA,GACF,GAAI,KAAA;AACJ,EAAA,uBAAO,KAAA,CAAA,aAAA,CAAC,OAAI,SAAA,EAAU,iBAAA,EAAA,sCAIX,OAAA,EAAA,cAAA,CAAA,EAAQ,cAAA,EAAgC,WAAA,EAAA,EAA8B,KAAA,CAAO,CAClF,CAAA;AACR"}
@@ -1 +1 @@
1
- import*as FileSystem from'expo-file-system';const IMAGE_CACHE_FOLDER = `${FileSystem.cacheDirectory}/image-cache/`;export{IMAGE_CACHE_FOLDER,IMAGE_CACHE_FOLDER as default};//# sourceMappingURL=consts.js.map
1
+ import*as FileSystem from'expo-file-system';const IMAGE_CACHE_FOLDER = `${FileSystem.cacheDirectory}/image-cache/`;export{IMAGE_CACHE_FOLDER};//# sourceMappingURL=consts.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"consts.js","sources":["../../../../../src/screens/inbox/components/CachedImage/consts.ts"],"sourcesContent":["import * as FileSystem from 'expo-file-system';\n\n// Make sure cache directory path ends with a slash\nexport const IMAGE_CACHE_FOLDER = `${FileSystem.cacheDirectory}/image-cache/`;\n// export const IMAGE_CACHE_FOLDER = `${FileSystem.documentDirectory}images/`\nexport default IMAGE_CACHE_FOLDER;\n"],"names":[],"mappings":"4CAGa,MAAA,kBAAA,GAAqB,GAAG,UAAW,CAAA,cAAA,CAAA,aAAA"}
1
+ {"version":3,"file":"consts.js","sources":["../../../../../src/screens/inbox/components/CachedImage/consts.ts"],"sourcesContent":["import * as FileSystem from 'expo-file-system';\n\n// Make sure cache directory path ends with a slash\nexport const IMAGE_CACHE_FOLDER = `${FileSystem.cacheDirectory}/image-cache/`;\n// export const IMAGE_CACHE_FOLDER = `${FileSystem.documentDirectory}images/`\nexport default IMAGE_CACHE_FOLDER;\n"],"names":[],"mappings":"4CAGO,MAAM,kBAAA,GAAqB,CAAA,EAAG,UAAA,CAAW,cAAc,CAAA,aAAA"}
@@ -1,4 +1,4 @@
1
- import React__default,{useState,useRef,useEffect}from'react';import {Image,View,Text}from'react-native';import*as FileSystem from'expo-file-system';import {IMAGE_CACHE_FOLDER}from'./consts.js';var __defProp = Object.defineProperty;
1
+ import React__default,{useState,useRef,useCallback,useEffect,useMemo}from'react';import {View,Text,Image}from'react-native';import*as FileSystem from'expo-file-system';import {IMAGE_CACHE_FOLDER}from'./consts.js';var __defProp = Object.defineProperty;
2
2
  var __defProps = Object.defineProperties;
3
3
  var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
4
4
  var __getOwnPropSymbols = Object.getOwnPropertySymbols;
@@ -17,163 +17,192 @@ var __spreadValues = (a, b) => {
17
17
  return a;
18
18
  };
19
19
  var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
20
+ var __objRest = (source, exclude) => {
21
+ var target = {};
22
+ for (var prop in source)
23
+ if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
24
+ target[prop] = source[prop];
25
+ if (source != null && __getOwnPropSymbols)
26
+ for (var prop of __getOwnPropSymbols(source)) {
27
+ if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
28
+ target[prop] = source[prop];
29
+ }
30
+ return target;
31
+ };
32
+ const downloadTracker = /* @__PURE__ */ new Map();
20
33
  const ensureCacheDirectory = async () => {
21
34
  try {
22
35
  const dirInfo = await FileSystem.getInfoAsync(IMAGE_CACHE_FOLDER);
23
36
  if (!dirInfo.exists) {
24
- console.log("Creating cache directory:", IMAGE_CACHE_FOLDER);
25
37
  await FileSystem.makeDirectoryAsync(IMAGE_CACHE_FOLDER, {
26
38
  intermediates: true
27
39
  });
28
40
  }
41
+ return true;
29
42
  } catch (error) {
30
- console.error("Failed to create cache directory:", error);
43
+ return false;
31
44
  }
32
45
  };
33
46
  const validateImageUri = (uri) => {
34
- if (!uri)
35
- return null;
47
+ if (!uri) return null;
36
48
  uri = uri.trim();
37
49
  try {
38
50
  new URL(uri);
39
51
  } catch (e) {
40
- console.log("Invalid URL format:", uri);
41
52
  return null;
42
53
  }
43
54
  return uri;
44
55
  };
45
- const CachedImage = (props) => {
46
- const {
56
+ const CachedImage = React__default.memo((props) => {
57
+ const _a = props, {
47
58
  source,
48
59
  cacheKey,
49
- placeholderContent
50
- } = props;
60
+ placeholderContent,
61
+ style,
62
+ resizeMode,
63
+ alt
64
+ } = _a, restProps = __objRest(_a, [
65
+ "source",
66
+ "cacheKey",
67
+ "placeholderContent",
68
+ "style",
69
+ "resizeMode",
70
+ "alt"
71
+ ]);
51
72
  const {
52
73
  uri: originalUri,
53
74
  headers,
54
- expiresIn
75
+ expiresIn = 86400
55
76
  } = source;
56
77
  const uri = validateImageUri(originalUri);
57
78
  const fileURI = `${IMAGE_CACHE_FOLDER}${cacheKey}`;
58
- const [imgUri, setImgUri] = useState(fileURI);
79
+ const [imgUri, setImgUri] = useState(null);
59
80
  const [loadError, setLoadError] = useState(false);
60
81
  const [useFallbackUri, setUseFallbackUri] = useState(false);
82
+ const [isLoading, setIsLoading] = useState(true);
61
83
  const componentIsMounted = useRef(true);
84
+ const hasAttemptedLoad = useRef(false);
62
85
  const requestOption = headers ? {
63
86
  headers
64
87
  } : {};
65
- const _callback = (downloadProgress) => {
66
- var _a;
88
+ const downloadCallback = useCallback((downloadProgress) => {
89
+ var _a2;
67
90
  if (componentIsMounted.current === false) {
68
- (_a = downloadResumableRef.current) == null ? void 0 : _a.pauseAsync();
91
+ downloadTracker.delete(cacheKey);
92
+ (_a2 = downloadResumableRef.current) == null ? void 0 : _a2.pauseAsync();
69
93
  FileSystem.deleteAsync(fileURI, {
70
94
  idempotent: true
71
95
  });
72
96
  }
73
- };
74
- const downloadResumableRef = useRef(uri ? FileSystem.createDownloadResumable(uri, fileURI, requestOption, _callback) : null);
75
- useEffect(() => {
76
- const initCache = async () => {
77
- await ensureCacheDirectory();
78
- if (uri) {
79
- loadImage();
80
- } else {
81
- console.log("Image URI is invalid, not loading");
82
- setLoadError(true);
83
- }
84
- };
85
- console.log("Cache key:", cacheKey);
86
- initCache();
87
- return () => {
88
- componentIsMounted.current = false;
89
- };
90
- }, []);
91
- const loadImage = async () => {
97
+ }, [fileURI, cacheKey]);
98
+ const downloadResumableRef = useRef(uri ? FileSystem.createDownloadResumable(uri, fileURI, requestOption, downloadCallback) : null);
99
+ const loadImage = useCallback(async () => {
100
+ if (!uri || hasAttemptedLoad.current) return;
101
+ hasAttemptedLoad.current = true;
102
+ setIsLoading(true);
92
103
  try {
104
+ if (downloadTracker.has(cacheKey)) {
105
+ await downloadTracker.get(cacheKey);
106
+ if (componentIsMounted.current) {
107
+ setImgUri(fileURI);
108
+ setIsLoading(false);
109
+ }
110
+ return;
111
+ }
93
112
  const metadata = await FileSystem.getInfoAsync(fileURI);
94
- const expired = expiresIn && new Date().getTime() / 1e3 - (metadata == null ? void 0 : metadata.modificationTime) > expiresIn;
95
- console.log({
96
- expiresIn,
97
- expired
98
- });
113
+ const expired = expiresIn && (/* @__PURE__ */ new Date()).getTime() / 1e3 - (metadata == null ? void 0 : metadata.modificationTime) > expiresIn;
99
114
  if (!metadata.exists || (metadata == null ? void 0 : metadata.size) === 0 || expired) {
100
- if (componentIsMounted.current) {
101
- setImgUri(null);
102
- if (expired) {
103
- await FileSystem.deleteAsync(fileURI, {
104
- idempotent: true
105
- });
106
- }
107
- setImgUri(null);
108
- if (!uri) {
109
- setLoadError(true);
110
- return;
111
- }
112
- if (!downloadResumableRef.current) {
113
- console.log("Download resumable is null");
114
- setUseFallbackUri(true);
115
- setImgUri(uri);
116
- return;
117
- }
118
- try {
119
- const response = await downloadResumableRef.current.downloadAsync();
120
- if (componentIsMounted.current && response && response.status === 200) {
121
- setImgUri(`${fileURI}?`);
115
+ if (!componentIsMounted.current) return;
116
+ if (expired && metadata.exists) {
117
+ await FileSystem.deleteAsync(fileURI, {
118
+ idempotent: true
119
+ });
120
+ }
121
+ if (!uri) {
122
+ setLoadError(true);
123
+ setIsLoading(false);
124
+ return;
125
+ }
126
+ if (!downloadResumableRef.current) {
127
+ setUseFallbackUri(true);
128
+ setImgUri(uri);
129
+ setIsLoading(false);
130
+ return;
131
+ }
132
+ try {
133
+ const downloadPromise = downloadResumableRef.current.downloadAsync();
134
+ downloadTracker.set(cacheKey, downloadPromise);
135
+ const response = await downloadPromise;
136
+ downloadTracker.delete(cacheKey);
137
+ if (componentIsMounted.current) {
138
+ if (response && response.status === 200) {
139
+ setImgUri(fileURI);
122
140
  } else {
123
- console.log("Failed to download image, status:", response == null ? void 0 : response.status);
124
- console.log("Falling back to original URI");
125
141
  setUseFallbackUri(true);
126
142
  setImgUri(uri);
127
143
  FileSystem.deleteAsync(fileURI, {
128
144
  idempotent: true
129
145
  });
130
146
  }
131
- } catch (downloadError) {
132
- console.log("Error downloading image:", downloadError);
133
- console.log("Falling back to original URI");
147
+ setIsLoading(false);
148
+ }
149
+ } catch (downloadError) {
150
+ downloadTracker.delete(cacheKey);
151
+ if (componentIsMounted.current) {
134
152
  setUseFallbackUri(true);
135
153
  setImgUri(uri);
154
+ setIsLoading(false);
136
155
  }
137
156
  }
138
157
  } else {
158
+ setImgUri(fileURI);
159
+ setIsLoading(false);
139
160
  }
140
161
  } catch (err) {
141
- console.log({
142
- err
143
- });
144
- console.log("Falling back to original URI");
145
- setUseFallbackUri(true);
146
- setImgUri(uri);
162
+ if (componentIsMounted.current) {
163
+ setUseFallbackUri(true);
164
+ setImgUri(uri);
165
+ setIsLoading(false);
166
+ }
147
167
  }
148
- };
149
- const defaultPlaceholder = /* @__PURE__ */ React__default.createElement(View, { style: {
168
+ }, [uri, fileURI, cacheKey, expiresIn]);
169
+ useEffect(() => {
170
+ const setup = async () => {
171
+ const directoryExists = await ensureCacheDirectory();
172
+ if (directoryExists && uri) {
173
+ loadImage();
174
+ } else {
175
+ setLoadError(true);
176
+ setIsLoading(false);
177
+ }
178
+ };
179
+ setup();
180
+ return () => {
181
+ componentIsMounted.current = false;
182
+ };
183
+ }, [uri, loadImage]);
184
+ const defaultPlaceholder = useMemo(() => /* @__PURE__ */ React__default.createElement(View, { style: [{
150
185
  width: "100%",
151
186
  height: "100%",
152
187
  backgroundColor: "#e1e1e1",
153
188
  justifyContent: "center",
154
189
  alignItems: "center",
155
190
  borderRadius: 3
156
- } }, /* @__PURE__ */ React__default.createElement(Text, null, "Image not available"));
157
- if (!imgUri) {
191
+ }, style] }, /* @__PURE__ */ React__default.createElement(Text, null, "Image not available")), [style]);
192
+ if (isLoading || loadError || !imgUri) {
158
193
  return placeholderContent || defaultPlaceholder;
159
194
  }
160
- return /* @__PURE__ */ React__default.createElement(
161
- Image,
162
- __spreadProps(__spreadValues({}, props), {
163
- source: __spreadProps(__spreadValues({}, source), {
164
- uri: useFallbackUri ? uri : imgUri
165
- }),
166
- onError: (e) => {
167
- console.log("Image loading error:", e.nativeEvent.error);
168
- if (useFallbackUri) {
169
- setLoadError(true);
170
- setImgUri(null);
171
- } else {
172
- console.log("Falling back to original URI after onError");
173
- setUseFallbackUri(true);
174
- setImgUri(uri);
175
- }
176
- }
177
- })
178
- );
179
- };export{CachedImage as default};//# sourceMappingURL=index.js.map
195
+ return /* @__PURE__ */ React__default.createElement(Image, __spreadProps(__spreadValues({}, restProps), { style, source: __spreadProps(__spreadValues({}, source), {
196
+ uri: useFallbackUri ? uri : imgUri
197
+ }), resizeMode, onError: (e) => {
198
+ if (useFallbackUri) {
199
+ setLoadError(true);
200
+ setImgUri(null);
201
+ } else {
202
+ setUseFallbackUri(true);
203
+ setImgUri(uri);
204
+ }
205
+ } }));
206
+ }, (prevProps, nextProps) => {
207
+ return prevProps.cacheKey === nextProps.cacheKey && prevProps.source.uri === nextProps.source.uri && prevProps.style === nextProps.style;
208
+ });export{CachedImage as default};//# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../../../src/screens/inbox/components/CachedImage/index.tsx"],"sourcesContent":["import React, { useEffect, useState, useRef } from 'react';\nimport { Image, View, Text } from 'react-native';\n// import { Image } from \"react-native\"\nimport * as FileSystem from 'expo-file-system';\n\nimport * as CONST from './consts';\n\n// Ensure the cache directory exists\nconst ensureCacheDirectory = async () => {\n try {\n const dirInfo = await FileSystem.getInfoAsync(CONST.IMAGE_CACHE_FOLDER);\n if (!dirInfo.exists) {\n console.log('Creating cache directory:', CONST.IMAGE_CACHE_FOLDER);\n await FileSystem.makeDirectoryAsync(CONST.IMAGE_CACHE_FOLDER, { intermediates: true });\n }\n } catch (error) {\n console.error('Failed to create cache directory:', error);\n }\n};\n\n// Validate and sanitize the image URL\nconst validateImageUri = (uri: string): string | null => {\n if (!uri) return null;\n\n // Trim whitespace\n uri = uri.trim();\n\n // Check if it's a valid URL format\n try {\n new URL(uri);\n } catch (e) {\n console.log('Invalid URL format:', uri);\n return null;\n }\n\n // Add more validation as needed for your specific case\n return uri;\n};\n\nconst CachedImage = (props: any) => {\n const { source, cacheKey, placeholderContent } = props;\n const { uri: originalUri, headers, expiresIn } = source;\n\n // Validate and sanitize the URI\n const uri = validateImageUri(originalUri);\n\n const fileURI = `${CONST.IMAGE_CACHE_FOLDER}${cacheKey}`;\n\n const [imgUri, setImgUri] = useState<any>(fileURI);\n const [loadError, setLoadError] = useState<boolean>(false);\n const [useFallbackUri, setUseFallbackUri] = useState<boolean>(false);\n\n const componentIsMounted = useRef(true);\n const requestOption = headers ? { headers } : {};\n\n const _callback = (downloadProgress: any) => {\n if (componentIsMounted.current === false) {\n downloadResumableRef.current?.pauseAsync();\n FileSystem.deleteAsync(fileURI, { idempotent: true }); // delete file locally if it was not downloaded properly\n }\n };\n\n const downloadResumableRef = useRef(\n uri ? FileSystem.createDownloadResumable(uri, fileURI, requestOption, _callback) : null,\n );\n\n useEffect(() => {\n const initCache = async () => {\n await ensureCacheDirectory();\n if (uri) {\n loadImage();\n } else {\n console.log('Image URI is invalid, not loading');\n setLoadError(true);\n }\n };\n\n // console.log('CachedImage loading with URI:', uri);\n console.log('Cache key:', cacheKey);\n\n initCache();\n\n return () => {\n componentIsMounted.current = false;\n };\n }, []); // eslint-disable-line react-hooks/exhaustive-deps\n\n const loadImage = async () => {\n try {\n // Use the cached image if it exists\n const metadata: any = await FileSystem.getInfoAsync(fileURI);\n const expired = expiresIn && new Date().getTime() / 1000 - metadata?.modificationTime > expiresIn;\n console.log({ expiresIn, expired });\n\n // console.log({ modificationTime: metadata.modificationTime, currentTime: new Date().getTime() / 1000 });\n // console.log({ metadata });\n\n if (!metadata.exists || metadata?.size === 0 || expired) {\n if (componentIsMounted.current) {\n setImgUri(null);\n\n if (expired) {\n await FileSystem.deleteAsync(fileURI, { idempotent: true });\n }\n // download to cache\n setImgUri(null);\n\n // console.log('Downloading image from URI:', uri);\n if (!uri) {\n // console.log('Image URI is undefined or null');\n setLoadError(true);\n return;\n }\n\n if (!downloadResumableRef.current) {\n console.log('Download resumable is null');\n setUseFallbackUri(true);\n setImgUri(uri);\n return;\n }\n\n try {\n const response: any = await downloadResumableRef.current.downloadAsync();\n // console.log('Download response:', response);\n\n if (componentIsMounted.current && response && response.status === 200) {\n setImgUri(`${fileURI}?`); // deep clone to force re-render\n // console.log('Image cached successfully, new URI:', `${fileURI}?`);\n } else {\n console.log('Failed to download image, status:', response?.status);\n console.log('Falling back to original URI');\n setUseFallbackUri(true);\n setImgUri(uri);\n FileSystem.deleteAsync(fileURI, { idempotent: true }); // delete file locally if it was not downloaded properly\n }\n } catch (downloadError) {\n console.log('Error downloading image:', downloadError);\n console.log('Falling back to original URI');\n setUseFallbackUri(true);\n setImgUri(uri);\n }\n }\n } else {\n //console.log('Using cached image at:', fileURI);\n }\n } catch (err) {\n console.log({ err });\n console.log('Falling back to original URI');\n setUseFallbackUri(true);\n setImgUri(uri);\n }\n };\n\n //console.log({ placeholderContent, imgUri, loadError, useFallbackUri });\n\n // Default placeholder if none is provided\n const defaultPlaceholder = (\n <View\n style={{\n width: '100%',\n height: '100%',\n backgroundColor: '#e1e1e1',\n justifyContent: 'center',\n alignItems: 'center',\n borderRadius: 3,\n }}\n >\n <Text>Image not available</Text>\n </View>\n );\n\n if (!imgUri) {\n return placeholderContent || defaultPlaceholder;\n }\n\n return (\n <Image\n // eslint-disable-next-line react/jsx-props-no-spreading\n {...props}\n source={{\n ...source,\n uri: useFallbackUri ? uri : imgUri,\n }}\n onError={(e) => {\n console.log('Image loading error:', e.nativeEvent.error);\n // If we're already using the fallback URI and still getting an error,\n // then show the placeholder\n if (useFallbackUri) {\n setLoadError(true);\n setImgUri(null);\n } else {\n console.log('Falling back to original URI after onError');\n setUseFallbackUri(true);\n setImgUri(uri);\n }\n }}\n />\n );\n};\n\nexport const CacheManager = {\n addToCache: async ({ file, key }: any) => {\n await FileSystem.copyAsync({\n from: file,\n to: `${CONST.IMAGE_CACHE_FOLDER}${key}`,\n });\n // const uri = await FileSystem.getContentUriAsync(`${CONST.IMAGE_CACHE_FOLDER}${key}`)\n // return uri\n const uri = await CacheManager.getCachedUri({ key });\n return uri;\n },\n\n getCachedUri: async ({ key }: any) => {\n const uri = await FileSystem.getContentUriAsync(`${CONST.IMAGE_CACHE_FOLDER}${key}`);\n return uri;\n },\n\n downloadAsync: async ({ uri, key, options }: any) => {\n return await FileSystem.downloadAsync(uri, `${CONST.IMAGE_CACHE_FOLDER}${key}`, options);\n },\n};\n\nexport default CachedImage;\n"],"names":["CONST.IMAGE_CACHE_FOLDER","React"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../../../../../src/screens/inbox/components/CachedImage/index.tsx"],"sourcesContent":["import React, { useEffect, useState, useRef, useMemo, useCallback } from 'react';\nimport { Image, View, Text } from 'react-native';\n// import { Image } from \"react-native\"\nimport * as FileSystem from 'expo-file-system';\n\nimport * as CONST from './consts';\n\n// Global download tracking to prevent duplicate downloads\nconst downloadTracker = new Map();\n\n// Ensure the cache directory exists\nconst ensureCacheDirectory = async () => {\n try {\n const dirInfo = await FileSystem.getInfoAsync(CONST.IMAGE_CACHE_FOLDER);\n if (!dirInfo.exists) {\n // console.log('Creating cache directory:', CONST.IMAGE_CACHE_FOLDER);\n await FileSystem.makeDirectoryAsync(CONST.IMAGE_CACHE_FOLDER, { intermediates: true });\n }\n return true;\n } catch (error) {\n // console.error('Failed to create cache directory:', error);\n return false;\n }\n};\n\n// Validate and sanitize the image URL\nconst validateImageUri = (uri: string): string | null => {\n if (!uri) return null;\n\n // Trim whitespace\n uri = uri.trim();\n\n // Check if it's a valid URL format\n try {\n new URL(uri);\n } catch (e) {\n // console.log('Invalid URL format:', uri);\n return null;\n }\n\n // Add more validation as needed for your specific case\n return uri;\n};\n\nconst CachedImage = React.memo(\n (props: any) => {\n const { source, cacheKey, placeholderContent, style, resizeMode, alt, ...restProps } = props;\n const { uri: originalUri, headers, expiresIn = 86400 } = source;\n\n // Validate and sanitize the URI\n const uri = validateImageUri(originalUri);\n const fileURI = `${CONST.IMAGE_CACHE_FOLDER}${cacheKey}`;\n\n const [imgUri, setImgUri] = useState<string | null>(null);\n const [loadError, setLoadError] = useState<boolean>(false);\n const [useFallbackUri, setUseFallbackUri] = useState<boolean>(false);\n const [isLoading, setIsLoading] = useState<boolean>(true);\n\n const componentIsMounted = useRef(true);\n const hasAttemptedLoad = useRef(false);\n const requestOption = headers ? { headers } : {};\n\n // Create a memoized download callback\n const downloadCallback = useCallback(\n (downloadProgress: any) => {\n if (componentIsMounted.current === false) {\n downloadTracker.delete(cacheKey);\n downloadResumableRef.current?.pauseAsync();\n FileSystem.deleteAsync(fileURI, { idempotent: true });\n }\n },\n [fileURI, cacheKey],\n );\n\n // Create a memoized download resumable\n const downloadResumableRef = useRef(\n uri ? FileSystem.createDownloadResumable(uri, fileURI, requestOption, downloadCallback) : null,\n );\n\n // Memoized load image function to avoid recreating on every render\n const loadImage = useCallback(async () => {\n if (!uri || hasAttemptedLoad.current) return;\n\n hasAttemptedLoad.current = true;\n setIsLoading(true);\n\n try {\n // Check if this image is already being downloaded\n if (downloadTracker.has(cacheKey)) {\n // Wait for the existing download to complete\n await downloadTracker.get(cacheKey);\n if (componentIsMounted.current) {\n setImgUri(fileURI);\n setIsLoading(false);\n }\n return;\n }\n\n // Use the cached image if it exists\n const metadata: any = await FileSystem.getInfoAsync(fileURI);\n const expired = expiresIn && new Date().getTime() / 1000 - metadata?.modificationTime > expiresIn;\n\n if (!metadata.exists || metadata?.size === 0 || expired) {\n if (!componentIsMounted.current) return;\n\n if (expired && metadata.exists) {\n await FileSystem.deleteAsync(fileURI, { idempotent: true });\n }\n\n if (!uri) {\n setLoadError(true);\n setIsLoading(false);\n return;\n }\n\n if (!downloadResumableRef.current) {\n setUseFallbackUri(true);\n setImgUri(uri);\n setIsLoading(false);\n return;\n }\n\n try {\n // Record this download in the global tracker\n const downloadPromise = downloadResumableRef.current.downloadAsync();\n downloadTracker.set(cacheKey, downloadPromise);\n\n const response: any = await downloadPromise;\n\n // Remove from tracker when done\n downloadTracker.delete(cacheKey);\n\n if (componentIsMounted.current) {\n if (response && response.status === 200) {\n setImgUri(fileURI);\n } else {\n setUseFallbackUri(true);\n setImgUri(uri);\n FileSystem.deleteAsync(fileURI, { idempotent: true });\n }\n setIsLoading(false);\n }\n } catch (downloadError) {\n downloadTracker.delete(cacheKey);\n if (componentIsMounted.current) {\n setUseFallbackUri(true);\n setImgUri(uri);\n setIsLoading(false);\n }\n }\n } else {\n // Use cached version\n setImgUri(fileURI);\n setIsLoading(false);\n }\n } catch (err) {\n if (componentIsMounted.current) {\n setUseFallbackUri(true);\n setImgUri(uri);\n setIsLoading(false);\n }\n }\n }, [uri, fileURI, cacheKey, expiresIn]);\n\n // Setup effect\n useEffect(() => {\n const setup = async () => {\n const directoryExists = await ensureCacheDirectory();\n if (directoryExists && uri) {\n loadImage();\n } else {\n setLoadError(true);\n setIsLoading(false);\n }\n };\n\n setup();\n\n return () => {\n componentIsMounted.current = false;\n };\n }, [uri, loadImage]);\n\n // Default placeholder\n const defaultPlaceholder = useMemo(\n () => (\n <View\n style={[\n {\n width: '100%',\n height: '100%',\n backgroundColor: '#e1e1e1',\n justifyContent: 'center',\n alignItems: 'center',\n borderRadius: 3,\n },\n style,\n ]}\n >\n <Text>Image not available</Text>\n </View>\n ),\n [style],\n );\n\n // Show placeholder while loading or if there's an error\n if (isLoading || loadError || !imgUri) {\n return placeholderContent || defaultPlaceholder;\n }\n\n // Actual image component\n return (\n <Image\n {...restProps}\n style={style}\n source={{\n ...source,\n uri: useFallbackUri ? uri : imgUri,\n }}\n resizeMode={resizeMode}\n onError={(e) => {\n if (useFallbackUri) {\n setLoadError(true);\n setImgUri(null);\n } else {\n setUseFallbackUri(true);\n setImgUri(uri);\n }\n }}\n />\n );\n },\n (prevProps, nextProps) => {\n // Custom comparison function for memoization\n return (\n prevProps.cacheKey === nextProps.cacheKey &&\n prevProps.source.uri === nextProps.source.uri &&\n prevProps.style === nextProps.style\n );\n },\n);\n\nexport const CacheManager = {\n addToCache: async ({ file, key }: any) => {\n await ensureCacheDirectory();\n await FileSystem.copyAsync({\n from: file,\n to: `${CONST.IMAGE_CACHE_FOLDER}${key}`,\n });\n const uri = await CacheManager.getCachedUri({ key });\n return uri;\n },\n\n getCachedUri: async ({ key }: any) => {\n const uri = await FileSystem.getContentUriAsync(`${CONST.IMAGE_CACHE_FOLDER}${key}`);\n return uri;\n },\n\n downloadAsync: async ({ uri, key, options }: any) => {\n await ensureCacheDirectory();\n return await FileSystem.downloadAsync(uri, `${CONST.IMAGE_CACHE_FOLDER}${key}`, options);\n },\n\n clearCache: async () => {\n try {\n await FileSystem.deleteAsync(CONST.IMAGE_CACHE_FOLDER, { idempotent: true });\n await ensureCacheDirectory();\n } catch (error) {\n console.error('Error clearing cache:', error);\n }\n },\n};\n\nexport default CachedImage;\n"],"names":["CONST.IMAGE_CACHE_FOLDER","React","_a"],"mappings":"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"}