@droppii-org/chat-mobile 0.2.106 → 0.2.108

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 (187) hide show
  1. package/lib/module/components/ThreadCard/ThreadCard.js +2 -0
  2. package/lib/module/components/ThreadCard/ThreadCard.js.map +1 -1
  3. package/lib/module/components/messages/ExpandableMessageText.js +112 -0
  4. package/lib/module/components/messages/ExpandableMessageText.js.map +1 -0
  5. package/lib/module/components/messages/PreviewScrollableText.js +80 -0
  6. package/lib/module/components/messages/PreviewScrollableText.js.map +1 -0
  7. package/lib/module/components/messages/fileMessage/index.js +9 -2
  8. package/lib/module/components/messages/fileMessage/index.js.map +1 -1
  9. package/lib/module/components/messages/linkMessage/index.js +21 -12
  10. package/lib/module/components/messages/linkMessage/index.js.map +1 -1
  11. package/lib/module/components/messages/quotedMessage/index.js +18 -3
  12. package/lib/module/components/messages/quotedMessage/index.js.map +1 -1
  13. package/lib/module/components/messages/textMessage/index.js +7 -1
  14. package/lib/module/components/messages/textMessage/index.js.map +1 -1
  15. package/lib/module/components/messages/types.js.map +1 -1
  16. package/lib/module/context/TimelinePressGuardContext.js +14 -0
  17. package/lib/module/context/TimelinePressGuardContext.js.map +1 -0
  18. package/lib/module/hooks/useConversationList.js +4 -0
  19. package/lib/module/hooks/useConversationList.js.map +1 -1
  20. package/lib/module/hooks/useDismissKeyboardFirst.js +19 -0
  21. package/lib/module/hooks/useDismissKeyboardFirst.js.map +1 -0
  22. package/lib/module/hooks/useExpandableText.js +125 -0
  23. package/lib/module/hooks/useExpandableText.js.map +1 -0
  24. package/lib/module/hooks/useGuardedPress.js +19 -0
  25. package/lib/module/hooks/useGuardedPress.js.map +1 -0
  26. package/lib/module/screens/chat-detail/ChatComposer.js +89 -498
  27. package/lib/module/screens/chat-detail/ChatComposer.js.map +1 -1
  28. package/lib/module/screens/chat-detail/ChatDetail.js +49 -20
  29. package/lib/module/screens/chat-detail/ChatDetail.js.map +1 -1
  30. package/lib/module/screens/chat-detail/ChatListLegend.js +113 -76
  31. package/lib/module/screens/chat-detail/ChatListLegend.js.map +1 -1
  32. package/lib/module/screens/chat-detail/PinnedMessagesSheet.js +7 -0
  33. package/lib/module/screens/chat-detail/PinnedMessagesSheet.js.map +1 -1
  34. package/lib/module/screens/chat-detail/components/ChatComposerAccessorySlot.js +47 -0
  35. package/lib/module/screens/chat-detail/components/ChatComposerAccessorySlot.js.map +1 -0
  36. package/lib/module/screens/chat-detail/components/ChatComposerInputArea.js +149 -0
  37. package/lib/module/screens/chat-detail/components/ChatComposerInputArea.js.map +1 -0
  38. package/lib/module/screens/chat-detail/components/ChatComposerStatusBanner.js +104 -0
  39. package/lib/module/screens/chat-detail/components/ChatComposerStatusBanner.js.map +1 -0
  40. package/lib/module/screens/chat-detail/hooks/useChatComposerAnimation.js +0 -17
  41. package/lib/module/screens/chat-detail/hooks/useChatComposerAnimation.js.map +1 -1
  42. package/lib/module/screens/chat-detail/hooks/useChatComposerState.js +16 -2
  43. package/lib/module/screens/chat-detail/hooks/useChatComposerState.js.map +1 -1
  44. package/lib/module/screens/chat-detail/hooks/useComposerBotMenu.js +122 -0
  45. package/lib/module/screens/chat-detail/hooks/useComposerBotMenu.js.map +1 -0
  46. package/lib/module/screens/chat-detail/hooks/useComposerPanelActions.js +46 -0
  47. package/lib/module/screens/chat-detail/hooks/useComposerPanelActions.js.map +1 -0
  48. package/lib/module/screens/chat-detail/hooks/useComposerPanelDismiss.js +75 -0
  49. package/lib/module/screens/chat-detail/hooks/useComposerPanelDismiss.js.map +1 -0
  50. package/lib/module/screens/chat-detail/hooks/useComposerPanels.js +136 -0
  51. package/lib/module/screens/chat-detail/hooks/useComposerPanels.js.map +1 -0
  52. package/lib/module/screens/chat-detail/hooks/useComposerSend.js +74 -0
  53. package/lib/module/screens/chat-detail/hooks/useComposerSend.js.map +1 -0
  54. package/lib/module/screens/chat-detail/legend/LegendChatMessage.js +12 -3
  55. package/lib/module/screens/chat-detail/legend/LegendChatMessage.js.map +1 -1
  56. package/lib/module/screens/chat-detail/messageToolbox/MessageToolboxOverlay.js +11 -2
  57. package/lib/module/screens/chat-detail/messageToolbox/MessageToolboxOverlay.js.map +1 -1
  58. package/lib/module/screens/chat-detail/messageToolbox/MessageToolboxWrapper.js +79 -6
  59. package/lib/module/screens/chat-detail/messageToolbox/MessageToolboxWrapper.js.map +1 -1
  60. package/lib/module/screens/chat-detail/messageToolbox/useClonePreview.js +30 -0
  61. package/lib/module/screens/chat-detail/messageToolbox/useClonePreview.js.map +1 -0
  62. package/lib/module/screens/chat-detail/types.js +5 -0
  63. package/lib/module/screens/chat-detail/types.js.map +1 -1
  64. package/lib/module/store/expandedMessage.js +28 -0
  65. package/lib/module/store/expandedMessage.js.map +1 -0
  66. package/lib/module/store/message.js +14 -0
  67. package/lib/module/store/message.js.map +1 -1
  68. package/lib/module/utils/composerPanelDismissGesture.js +52 -0
  69. package/lib/module/utils/composerPanelDismissGesture.js.map +1 -0
  70. package/lib/module/utils/expandableText.js +41 -0
  71. package/lib/module/utils/expandableText.js.map +1 -0
  72. package/lib/module/utils/inlineTruncation.js +51 -0
  73. package/lib/module/utils/inlineTruncation.js.map +1 -0
  74. package/lib/module/utils/perf-marker.js +44 -0
  75. package/lib/module/utils/perf-marker.js.map +1 -0
  76. package/lib/module/utils/truncateTextChildren.js +38 -0
  77. package/lib/module/utils/truncateTextChildren.js.map +1 -0
  78. package/lib/typescript/src/components/ThreadCard/ThreadCard.d.ts.map +1 -1
  79. package/lib/typescript/src/components/messages/ExpandableMessageText.d.ts +25 -0
  80. package/lib/typescript/src/components/messages/ExpandableMessageText.d.ts.map +1 -0
  81. package/lib/typescript/src/components/messages/PreviewScrollableText.d.ts +29 -0
  82. package/lib/typescript/src/components/messages/PreviewScrollableText.d.ts.map +1 -0
  83. package/lib/typescript/src/components/messages/fileMessage/index.d.ts.map +1 -1
  84. package/lib/typescript/src/components/messages/linkMessage/index.d.ts +1 -1
  85. package/lib/typescript/src/components/messages/linkMessage/index.d.ts.map +1 -1
  86. package/lib/typescript/src/components/messages/quotedMessage/index.d.ts.map +1 -1
  87. package/lib/typescript/src/components/messages/textMessage/index.d.ts +1 -1
  88. package/lib/typescript/src/components/messages/textMessage/index.d.ts.map +1 -1
  89. package/lib/typescript/src/components/messages/types.d.ts +18 -0
  90. package/lib/typescript/src/components/messages/types.d.ts.map +1 -1
  91. package/lib/typescript/src/context/TimelinePressGuardContext.d.ts +3 -0
  92. package/lib/typescript/src/context/TimelinePressGuardContext.d.ts.map +1 -0
  93. package/lib/typescript/src/hooks/useConversationList.d.ts.map +1 -1
  94. package/lib/typescript/src/hooks/useDismissKeyboardFirst.d.ts +8 -0
  95. package/lib/typescript/src/hooks/useDismissKeyboardFirst.d.ts.map +1 -0
  96. package/lib/typescript/src/hooks/useExpandableText.d.ts +13 -0
  97. package/lib/typescript/src/hooks/useExpandableText.d.ts.map +1 -0
  98. package/lib/typescript/src/hooks/useGuardedPress.d.ts +9 -0
  99. package/lib/typescript/src/hooks/useGuardedPress.d.ts.map +1 -0
  100. package/lib/typescript/src/screens/chat-detail/ChatComposer.d.ts +7 -3
  101. package/lib/typescript/src/screens/chat-detail/ChatComposer.d.ts.map +1 -1
  102. package/lib/typescript/src/screens/chat-detail/ChatDetail.d.ts.map +1 -1
  103. package/lib/typescript/src/screens/chat-detail/ChatListLegend.d.ts +5 -1
  104. package/lib/typescript/src/screens/chat-detail/ChatListLegend.d.ts.map +1 -1
  105. package/lib/typescript/src/screens/chat-detail/PinnedMessagesSheet.d.ts.map +1 -1
  106. package/lib/typescript/src/screens/chat-detail/components/ChatComposerAccessorySlot.d.ts +12 -0
  107. package/lib/typescript/src/screens/chat-detail/components/ChatComposerAccessorySlot.d.ts.map +1 -0
  108. package/lib/typescript/src/screens/chat-detail/components/ChatComposerInputArea.d.ts +30 -0
  109. package/lib/typescript/src/screens/chat-detail/components/ChatComposerInputArea.d.ts.map +1 -0
  110. package/lib/typescript/src/screens/chat-detail/components/ChatComposerStatusBanner.d.ts +19 -0
  111. package/lib/typescript/src/screens/chat-detail/components/ChatComposerStatusBanner.d.ts.map +1 -0
  112. package/lib/typescript/src/screens/chat-detail/hooks/useChatComposerAnimation.d.ts +0 -1
  113. package/lib/typescript/src/screens/chat-detail/hooks/useChatComposerAnimation.d.ts.map +1 -1
  114. package/lib/typescript/src/screens/chat-detail/hooks/useChatComposerState.d.ts +7 -0
  115. package/lib/typescript/src/screens/chat-detail/hooks/useChatComposerState.d.ts.map +1 -1
  116. package/lib/typescript/src/screens/chat-detail/hooks/useComposerBotMenu.d.ts +7 -0
  117. package/lib/typescript/src/screens/chat-detail/hooks/useComposerBotMenu.d.ts.map +1 -0
  118. package/lib/typescript/src/screens/chat-detail/hooks/useComposerPanelActions.d.ts +17 -0
  119. package/lib/typescript/src/screens/chat-detail/hooks/useComposerPanelActions.d.ts.map +1 -0
  120. package/lib/typescript/src/screens/chat-detail/hooks/useComposerPanelDismiss.d.ts +12 -0
  121. package/lib/typescript/src/screens/chat-detail/hooks/useComposerPanelDismiss.d.ts.map +1 -0
  122. package/lib/typescript/src/screens/chat-detail/hooks/useComposerPanels.d.ts +25 -0
  123. package/lib/typescript/src/screens/chat-detail/hooks/useComposerPanels.d.ts.map +1 -0
  124. package/lib/typescript/src/screens/chat-detail/hooks/useComposerSend.d.ts +16 -0
  125. package/lib/typescript/src/screens/chat-detail/hooks/useComposerSend.d.ts.map +1 -0
  126. package/lib/typescript/src/screens/chat-detail/legend/LegendChatMessage.d.ts +11 -1
  127. package/lib/typescript/src/screens/chat-detail/legend/LegendChatMessage.d.ts.map +1 -1
  128. package/lib/typescript/src/screens/chat-detail/messageToolbox/MessageToolboxOverlay.d.ts.map +1 -1
  129. package/lib/typescript/src/screens/chat-detail/messageToolbox/MessageToolboxWrapper.d.ts +14 -1
  130. package/lib/typescript/src/screens/chat-detail/messageToolbox/MessageToolboxWrapper.d.ts.map +1 -1
  131. package/lib/typescript/src/screens/chat-detail/messageToolbox/useClonePreview.d.ts +18 -0
  132. package/lib/typescript/src/screens/chat-detail/messageToolbox/useClonePreview.d.ts.map +1 -0
  133. package/lib/typescript/src/screens/chat-detail/types.d.ts +8 -0
  134. package/lib/typescript/src/screens/chat-detail/types.d.ts.map +1 -1
  135. package/lib/typescript/src/store/expandedMessage.d.ts +15 -0
  136. package/lib/typescript/src/store/expandedMessage.d.ts.map +1 -0
  137. package/lib/typescript/src/store/message.d.ts.map +1 -1
  138. package/lib/typescript/src/utils/composerPanelDismissGesture.d.ts +33 -0
  139. package/lib/typescript/src/utils/composerPanelDismissGesture.d.ts.map +1 -0
  140. package/lib/typescript/src/utils/expandableText.d.ts +18 -0
  141. package/lib/typescript/src/utils/expandableText.d.ts.map +1 -0
  142. package/lib/typescript/src/utils/inlineTruncation.d.ts +24 -0
  143. package/lib/typescript/src/utils/inlineTruncation.d.ts.map +1 -0
  144. package/lib/typescript/src/utils/perf-marker.d.ts +8 -0
  145. package/lib/typescript/src/utils/perf-marker.d.ts.map +1 -0
  146. package/lib/typescript/src/utils/truncateTextChildren.d.ts +3 -0
  147. package/lib/typescript/src/utils/truncateTextChildren.d.ts.map +1 -0
  148. package/package.json +2 -1
  149. package/src/components/ThreadCard/ThreadCard.tsx +2 -0
  150. package/src/components/messages/ExpandableMessageText.tsx +145 -0
  151. package/src/components/messages/PreviewScrollableText.tsx +98 -0
  152. package/src/components/messages/fileMessage/index.tsx +17 -3
  153. package/src/components/messages/linkMessage/index.tsx +30 -21
  154. package/src/components/messages/quotedMessage/index.tsx +19 -3
  155. package/src/components/messages/textMessage/index.tsx +11 -2
  156. package/src/components/messages/types.ts +18 -0
  157. package/src/context/TimelinePressGuardContext.tsx +15 -0
  158. package/src/hooks/useConversationList.ts +2 -0
  159. package/src/hooks/useDismissKeyboardFirst.ts +19 -0
  160. package/src/hooks/useExpandableText.ts +143 -0
  161. package/src/hooks/useGuardedPress.ts +20 -0
  162. package/src/screens/chat-detail/ChatComposer.tsx +105 -631
  163. package/src/screens/chat-detail/ChatDetail.tsx +49 -20
  164. package/src/screens/chat-detail/ChatListLegend.tsx +122 -71
  165. package/src/screens/chat-detail/PinnedMessagesSheet.tsx +8 -0
  166. package/src/screens/chat-detail/components/ChatComposerAccessorySlot.tsx +61 -0
  167. package/src/screens/chat-detail/components/ChatComposerInputArea.tsx +198 -0
  168. package/src/screens/chat-detail/components/ChatComposerStatusBanner.tsx +116 -0
  169. package/src/screens/chat-detail/hooks/useChatComposerAnimation.ts +0 -29
  170. package/src/screens/chat-detail/hooks/useChatComposerState.ts +25 -2
  171. package/src/screens/chat-detail/hooks/useComposerBotMenu.tsx +140 -0
  172. package/src/screens/chat-detail/hooks/useComposerPanelActions.ts +57 -0
  173. package/src/screens/chat-detail/hooks/useComposerPanelDismiss.ts +111 -0
  174. package/src/screens/chat-detail/hooks/useComposerPanels.ts +197 -0
  175. package/src/screens/chat-detail/hooks/useComposerSend.ts +98 -0
  176. package/src/screens/chat-detail/legend/LegendChatMessage.tsx +24 -2
  177. package/src/screens/chat-detail/messageToolbox/MessageToolboxOverlay.tsx +20 -1
  178. package/src/screens/chat-detail/messageToolbox/MessageToolboxWrapper.tsx +111 -5
  179. package/src/screens/chat-detail/messageToolbox/useClonePreview.ts +34 -0
  180. package/src/screens/chat-detail/types.ts +9 -0
  181. package/src/store/expandedMessage.ts +42 -0
  182. package/src/store/message.ts +14 -0
  183. package/src/utils/composerPanelDismissGesture.ts +72 -0
  184. package/src/utils/expandableText.ts +51 -0
  185. package/src/utils/inlineTruncation.ts +65 -0
  186. package/src/utils/perf-marker.ts +39 -0
  187. package/src/utils/truncateTextChildren.ts +46 -0
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+
3
+ import { createContext, useContext } from 'react';
4
+ const neverSwallow = () => false;
5
+
6
+ /**
7
+ * Timeline-only press guard. ChatListLegend provides the tap-outside panel
8
+ * dismiss's `shouldSwallowPress` (useComposerPanelDismiss); every other
9
+ * surface (Pin Management, toolbox overlay) gets the no-op default.
10
+ */
11
+ const TimelinePressGuardContext = /*#__PURE__*/createContext(neverSwallow);
12
+ export const TimelinePressGuardProvider = TimelinePressGuardContext.Provider;
13
+ export const useTimelinePressGuard = () => useContext(TimelinePressGuardContext);
14
+ //# sourceMappingURL=TimelinePressGuardContext.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["createContext","useContext","neverSwallow","TimelinePressGuardContext","TimelinePressGuardProvider","Provider","useTimelinePressGuard"],"sourceRoot":"../../../src","sources":["context/TimelinePressGuardContext.tsx"],"mappings":";;AAAA,SAASA,aAAa,EAAEC,UAAU,QAAQ,OAAO;AAEjD,MAAMC,YAAY,GAAGA,CAAA,KAAM,KAAK;;AAEhC;AACA;AACA;AACA;AACA;AACA,MAAMC,yBAAyB,gBAAGH,aAAa,CAAgBE,YAAY,CAAC;AAE5E,OAAO,MAAME,0BAA0B,GAAGD,yBAAyB,CAACE,QAAQ;AAE5E,OAAO,MAAMC,qBAAqB,GAAGA,CAAA,KACnCL,UAAU,CAACE,yBAAyB,CAAC","ignoreList":[]}
@@ -5,6 +5,7 @@ import { useQuery } from '@tanstack/react-query';
5
5
  import OpenIMSDK from '@droppii/openim-rn-client-sdk';
6
6
  import { conversationQueryKeys } from "./query-keys.js";
7
7
  import { useConversationStore } from "../store/index.js";
8
+ import { perfMark } from "../utils/perf-marker.js";
8
9
  export function useConversationList({
9
10
  applicationType,
10
11
  page = 1,
@@ -24,6 +25,9 @@ export function useConversationList({
24
25
  applicationType
25
26
  });
26
27
  useConversationStore.getState().updateConversations(conversations);
28
+ perfMark('conversation_list_loaded', {
29
+ count: conversations.length
30
+ });
27
31
  return conversations;
28
32
  }
29
33
  });
@@ -1 +1 @@
1
- {"version":3,"names":["useEffect","useQuery","OpenIMSDK","conversationQueryKeys","useConversationStore","useConversationList","applicationType","page","enabled","newConversationSignal","s","query","queryKey","list","staleTime","queryFn","offset","conversations","getConversationListSplitApp","count","getState","updateConversations","refetch"],"sourceRoot":"../../../src","sources":["hooks/useConversationList.ts"],"mappings":";;AAAA,SAASA,SAAS,QAAQ,OAAO;AACjC,SAASC,QAAQ,QAAQ,uBAAuB;AAChD,OAAOC,SAAS,MAAM,+BAA+B;AACrD,SAASC,qBAAqB,QAAQ,iBAAc;AACpD,SAASC,oBAAoB,QAAQ,mBAAU;AAS/C,OAAO,SAASC,mBAAmBA,CAAC;EAClCC,eAAe;EACfC,IAAI,GAAG,CAAC;EACRC,OAAO,GAAG;AACJ,CAAC,EAAE;EACT,MAAMC,qBAAqB,GAAGL,oBAAoB,CAC/CM,CAAC,IAAKA,CAAC,CAACD,qBACX,CAAC;EAED,MAAME,KAAK,GAAGV,QAAQ,CAAC;IACrBW,QAAQ,EAAE,CAAC,GAAGT,qBAAqB,CAACU,IAAI,CAACP,eAAe,CAAC,EAAEC,IAAI,CAAC;IAChEC,OAAO,EAAEA,OAAO,KAAK,KAAK;IAC1BM,SAAS,EAAE,IAAI,GAAG,EAAE,GAAG,CAAC;IAAE;IAC1BC,OAAO,EAAE,MAAAA,CAAA,KAAY;MACnB,MAAMC,MAAM,GAAG,CAACT,IAAI,GAAG,CAAC,IAAI,GAAG;MAC/B,MAAMU,aAAa,GAAG,MAAMf,SAAS,CAACgB,2BAA2B,CAAC;QAChEF,MAAM;QACNG,KAAK,EAAE,GAAG;QACVb;MACF,CAAC,CAAC;MAEFF,oBAAoB,CAACgB,QAAQ,CAAC,CAAC,CAACC,mBAAmB,CAACJ,aAAa,CAAC;MAClE,OAAOA,aAAa;IACtB;EACF,CAAC,CAAC;;EAEF;EACA;EACAjB,SAAS,CAAC,MAAM;IACd,IAAIS,qBAAqB,GAAG,CAAC,EAAE;MAC7BE,KAAK,CAACW,OAAO,CAAC,CAAC;IACjB;IACA;EACF,CAAC,EAAE,CAACb,qBAAqB,CAAC,CAAC;EAE3B,OAAOE,KAAK;AACd","ignoreList":[]}
1
+ {"version":3,"names":["useEffect","useQuery","OpenIMSDK","conversationQueryKeys","useConversationStore","perfMark","useConversationList","applicationType","page","enabled","newConversationSignal","s","query","queryKey","list","staleTime","queryFn","offset","conversations","getConversationListSplitApp","count","getState","updateConversations","length","refetch"],"sourceRoot":"../../../src","sources":["hooks/useConversationList.ts"],"mappings":";;AAAA,SAASA,SAAS,QAAQ,OAAO;AACjC,SAASC,QAAQ,QAAQ,uBAAuB;AAChD,OAAOC,SAAS,MAAM,+BAA+B;AACrD,SAASC,qBAAqB,QAAQ,iBAAc;AACpD,SAASC,oBAAoB,QAAQ,mBAAU;AAE/C,SAASC,QAAQ,QAAQ,yBAAsB;AAQ/C,OAAO,SAASC,mBAAmBA,CAAC;EAClCC,eAAe;EACfC,IAAI,GAAG,CAAC;EACRC,OAAO,GAAG;AACJ,CAAC,EAAE;EACT,MAAMC,qBAAqB,GAAGN,oBAAoB,CAC/CO,CAAC,IAAKA,CAAC,CAACD,qBACX,CAAC;EAED,MAAME,KAAK,GAAGX,QAAQ,CAAC;IACrBY,QAAQ,EAAE,CAAC,GAAGV,qBAAqB,CAACW,IAAI,CAACP,eAAe,CAAC,EAAEC,IAAI,CAAC;IAChEC,OAAO,EAAEA,OAAO,KAAK,KAAK;IAC1BM,SAAS,EAAE,IAAI,GAAG,EAAE,GAAG,CAAC;IAAE;IAC1BC,OAAO,EAAE,MAAAA,CAAA,KAAY;MACnB,MAAMC,MAAM,GAAG,CAACT,IAAI,GAAG,CAAC,IAAI,GAAG;MAC/B,MAAMU,aAAa,GAAG,MAAMhB,SAAS,CAACiB,2BAA2B,CAAC;QAChEF,MAAM;QACNG,KAAK,EAAE,GAAG;QACVb;MACF,CAAC,CAAC;MAEFH,oBAAoB,CAACiB,QAAQ,CAAC,CAAC,CAACC,mBAAmB,CAACJ,aAAa,CAAC;MAClEb,QAAQ,CAAC,0BAA0B,EAAE;QAAEe,KAAK,EAAEF,aAAa,CAACK;MAAO,CAAC,CAAC;MACrE,OAAOL,aAAa;IACtB;EACF,CAAC,CAAC;;EAEF;EACA;EACAlB,SAAS,CAAC,MAAM;IACd,IAAIU,qBAAqB,GAAG,CAAC,EAAE;MAC7BE,KAAK,CAACY,OAAO,CAAC,CAAC;IACjB;IACA;EACF,CAAC,EAAE,CAACd,qBAAqB,CAAC,CAAC;EAE3B,OAAOE,KAAK;AACd","ignoreList":[]}
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+
3
+ import { useMemo } from 'react';
4
+ import { Keyboard } from 'react-native';
5
+
6
+ /**
7
+ * Wraps a press that leaves the timeline (media viewer, link, file viewer) so
8
+ * the keyboard is dismissed first. The timeline uses
9
+ * `keyboardShouldPersistTaps="handled"`, so the keyboard would otherwise stay
10
+ * up over the screen the press opens. An absent handler stays absent.
11
+ */
12
+ export const useDismissKeyboardFirst = handler => useMemo(() => {
13
+ if (!handler) return handler;
14
+ return (...args) => {
15
+ Keyboard.dismiss();
16
+ handler(...args);
17
+ };
18
+ }, [handler]);
19
+ //# sourceMappingURL=useDismissKeyboardFirst.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["useMemo","Keyboard","useDismissKeyboardFirst","handler","args","dismiss"],"sourceRoot":"../../../src","sources":["hooks/useDismissKeyboardFirst.ts"],"mappings":";;AAAA,SAASA,OAAO,QAAQ,OAAO;AAC/B,SAASC,QAAQ,QAAQ,cAAc;;AAEvC;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,uBAAuB,GAClCC,OAA8C,IAE9CH,OAAO,CAAC,MAAM;EACZ,IAAI,CAACG,OAAO,EAAE,OAAOA,OAAO;EAC5B,OAAO,CAAC,GAAGC,IAAO,KAAK;IACrBH,QAAQ,CAACI,OAAO,CAAC,CAAC;IAClBF,OAAO,CAAC,GAAGC,IAAI,CAAC;EAClB,CAAC;AACH,CAAC,EAAE,CAACD,OAAO,CAAC,CAAC","ignoreList":[]}
@@ -0,0 +1,125 @@
1
+ "use strict";
2
+
3
+ import { useCallback, useState } from 'react';
4
+ import { useWindowDimensions } from 'react-native';
5
+ import { useExpandedMessageStore } from "../store/expandedMessage.js";
6
+ import { useTimelinePressGuard } from "../context/TimelinePressGuardContext.js";
7
+ import { COLLAPSED_LINES, expandedKey, isMeasurementCandidate } from "../utils/expandableText.js";
8
+ import { initialCut, joinLines, shrinkCut } from "../utils/inlineTruncation.js";
9
+ export { COLLAPSED_LINES };
10
+ // Each pass is one extra layout; in practice the suffix fits by the second.
11
+ // Past this the suffix may sit on a sixth line — still visible and tappable.
12
+ const MAX_FIT_PASSES = 4;
13
+
14
+ /**
15
+ * Truncation is a pure function of (text, available width, typography), so it
16
+ * belongs to the message — not to the list row that happens to render it.
17
+ * `recycleItems` reuses row instances, so a verdict held in component state
18
+ * bleeds onto the next message in that slot. Keyed here, a recycled row reads
19
+ * the right answer during render and pays no measurement for a message seen.
20
+ */
21
+ const verdictCache = new Map();
22
+ export const clearExpandableTextCache = () => verdictCache.clear();
23
+
24
+ // Window width, not the bubble's: the bubble shrinks to its content, and the
25
+ // content changes when the suffix is appended, so keying on it would re-measure
26
+ // in a loop. Surface is in the key because the pin sheet is a different width.
27
+ // Text length makes a body that mutates in place (TextMessage re-derives its
28
+ // runs when `ex` arrives) miss the cache rather than reuse a stale cut.
29
+ const verdictKey = (surface, messageId, windowWidth, text) => `${surface}:${messageId}:${Math.round(windowWidth)}:${text.length}`;
30
+ export function useExpandableText(messageId, text, surface) {
31
+ const expanded = useExpandedMessageStore(s => !!s.expanded[expandedKey(surface, messageId)]);
32
+ const expandInStore = useExpandedMessageStore(s => s.expand);
33
+ const {
34
+ width: windowWidth
35
+ } = useWindowDimensions();
36
+ const key = messageId ? verdictKey(surface, messageId, windowWidth, text) : null;
37
+
38
+ // Reset during render rather than in an effect: an effect lands after paint,
39
+ // so a recycled row would show one frame with the previous message's cut.
40
+ const [fit, setFit] = useState({
41
+ key,
42
+ passes: 0
43
+ });
44
+ const current = fit.key === key ? fit : {
45
+ key,
46
+ passes: 0
47
+ };
48
+ if (fit.key !== key) setFit(current);
49
+
50
+ // Without an id there is nowhere to record an expansion, so the control
51
+ // would do nothing. Never collapse those.
52
+ const isCandidate = !!messageId && !expanded && isMeasurementCandidate(text);
53
+ const verdict = key && verdictCache.get(key) || current.verdict;
54
+ let mode = 'plain';
55
+ if (isCandidate) {
56
+ if (verdict) mode = verdict.truncated ? 'collapsed' : 'plain';else mode = current.cut == null ? 'measuring' : 'fitting';
57
+ }
58
+ const cut = verdict?.truncated ? verdict.cut : current.cut ?? 0;
59
+ const settle = useCallback(next => {
60
+ if (key) verdictCache.set(key, next);
61
+ setFit(prev => prev.key === key ? {
62
+ ...prev,
63
+ verdict: next
64
+ } : prev);
65
+ }, [key]);
66
+
67
+ // Full, unclamped copy: how many lines, and where line N ends.
68
+ const onMeasureTextLayout = useCallback(({
69
+ nativeEvent: {
70
+ lines
71
+ }
72
+ }) => {
73
+ if (lines.length <= COLLAPSED_LINES) {
74
+ settle({
75
+ truncated: false
76
+ });
77
+ return;
78
+ }
79
+ const full = joinLines(lines);
80
+ const first = initialCut(lines, COLLAPSED_LINES);
81
+ setFit(prev => prev.key === key ? {
82
+ ...prev,
83
+ full,
84
+ cut: first,
85
+ passes: 0
86
+ } : prev);
87
+ }, [key, settle]);
88
+
89
+ // The visible copy with the suffix appended: accept once it fits in N lines.
90
+ const onFitTextLayout = useCallback(({
91
+ nativeEvent: {
92
+ lines
93
+ }
94
+ }) => {
95
+ if (fit.key !== key || fit.full == null || fit.cut == null) return;
96
+ if (lines.length <= COLLAPSED_LINES || fit.passes >= MAX_FIT_PASSES) {
97
+ settle({
98
+ truncated: true,
99
+ cut: fit.cut
100
+ });
101
+ return;
102
+ }
103
+ const next = shrinkCut(fit.full, fit.cut, lines, COLLAPSED_LINES);
104
+ setFit({
105
+ ...fit,
106
+ cut: next,
107
+ passes: fit.passes + 1
108
+ });
109
+ }, [fit, key, settle]);
110
+
111
+ // Skipped for the tap that dismisses a composer panel (timeline only).
112
+ const shouldSwallowPress = useTimelinePressGuard();
113
+ const expand = useCallback(() => {
114
+ if (shouldSwallowPress()) return;
115
+ expandInStore(surface, messageId);
116
+ }, [expandInStore, surface, messageId, shouldSwallowPress]);
117
+ return {
118
+ mode,
119
+ cut,
120
+ expand,
121
+ onMeasureTextLayout,
122
+ onFitTextLayout
123
+ };
124
+ }
125
+ //# sourceMappingURL=useExpandableText.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["useCallback","useState","useWindowDimensions","useExpandedMessageStore","useTimelinePressGuard","COLLAPSED_LINES","expandedKey","isMeasurementCandidate","initialCut","joinLines","shrinkCut","MAX_FIT_PASSES","verdictCache","Map","clearExpandableTextCache","clear","verdictKey","surface","messageId","windowWidth","text","Math","round","length","useExpandableText","expanded","s","expandInStore","expand","width","key","fit","setFit","passes","current","isCandidate","verdict","get","mode","truncated","cut","settle","next","set","prev","onMeasureTextLayout","nativeEvent","lines","full","first","onFitTextLayout","shouldSwallowPress"],"sourceRoot":"../../../src","sources":["hooks/useExpandableText.ts"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+
3
+ import { useMemo } from 'react';
4
+
5
+ /**
6
+ * Wraps a timeline press handler so it is skipped while `shouldSwallow()` is
7
+ * true — the tap-outside panel dismiss (useComposerPanelDismiss) swallows the
8
+ * press of a touch that began with a composer panel open. An absent handler
9
+ * stays absent, so "not tappable" rows keep behaving as before. The wrapper's
10
+ * return value is dropped: press handlers are fire-and-forget.
11
+ */
12
+ export const useGuardedPress = (handler, shouldSwallow) => useMemo(() => {
13
+ if (!handler || !shouldSwallow) return handler;
14
+ return (...args) => {
15
+ if (shouldSwallow()) return;
16
+ handler(...args);
17
+ };
18
+ }, [handler, shouldSwallow]);
19
+ //# sourceMappingURL=useGuardedPress.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["useMemo","useGuardedPress","handler","shouldSwallow","args"],"sourceRoot":"../../../src","sources":["hooks/useGuardedPress.ts"],"mappings":";;AAAA,SAASA,OAAO,QAAQ,OAAO;;AAE/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,eAAe,GAAGA,CAC7BC,OAA8C,EAC9CC,aAA0C,KAE1CH,OAAO,CAAC,MAAM;EACZ,IAAI,CAACE,OAAO,IAAI,CAACC,aAAa,EAAE,OAAOD,OAAO;EAC9C,OAAO,CAAC,GAAGE,IAAO,KAAK;IACrB,IAAID,aAAa,CAAC,CAAC,EAAE;IACrBD,OAAO,CAAC,GAAGE,IAAI,CAAC;EAClB,CAAC;AACH,CAAC,EAAE,CAACF,OAAO,EAAEC,aAAa,CAAC,CAAC","ignoreList":[]}