@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.
- package/lib/module/components/ThreadCard/ThreadCard.js +2 -0
- package/lib/module/components/ThreadCard/ThreadCard.js.map +1 -1
- package/lib/module/components/messages/ExpandableMessageText.js +112 -0
- package/lib/module/components/messages/ExpandableMessageText.js.map +1 -0
- package/lib/module/components/messages/PreviewScrollableText.js +80 -0
- package/lib/module/components/messages/PreviewScrollableText.js.map +1 -0
- package/lib/module/components/messages/fileMessage/index.js +9 -2
- package/lib/module/components/messages/fileMessage/index.js.map +1 -1
- package/lib/module/components/messages/linkMessage/index.js +21 -12
- package/lib/module/components/messages/linkMessage/index.js.map +1 -1
- package/lib/module/components/messages/quotedMessage/index.js +18 -3
- package/lib/module/components/messages/quotedMessage/index.js.map +1 -1
- package/lib/module/components/messages/textMessage/index.js +7 -1
- package/lib/module/components/messages/textMessage/index.js.map +1 -1
- package/lib/module/components/messages/types.js.map +1 -1
- package/lib/module/context/TimelinePressGuardContext.js +14 -0
- package/lib/module/context/TimelinePressGuardContext.js.map +1 -0
- package/lib/module/hooks/useConversationList.js +4 -0
- package/lib/module/hooks/useConversationList.js.map +1 -1
- package/lib/module/hooks/useDismissKeyboardFirst.js +19 -0
- package/lib/module/hooks/useDismissKeyboardFirst.js.map +1 -0
- package/lib/module/hooks/useExpandableText.js +125 -0
- package/lib/module/hooks/useExpandableText.js.map +1 -0
- package/lib/module/hooks/useGuardedPress.js +19 -0
- package/lib/module/hooks/useGuardedPress.js.map +1 -0
- package/lib/module/screens/chat-detail/ChatComposer.js +89 -498
- package/lib/module/screens/chat-detail/ChatComposer.js.map +1 -1
- package/lib/module/screens/chat-detail/ChatDetail.js +49 -20
- package/lib/module/screens/chat-detail/ChatDetail.js.map +1 -1
- package/lib/module/screens/chat-detail/ChatListLegend.js +113 -76
- package/lib/module/screens/chat-detail/ChatListLegend.js.map +1 -1
- package/lib/module/screens/chat-detail/PinnedMessagesSheet.js +7 -0
- package/lib/module/screens/chat-detail/PinnedMessagesSheet.js.map +1 -1
- package/lib/module/screens/chat-detail/components/ChatComposerAccessorySlot.js +47 -0
- package/lib/module/screens/chat-detail/components/ChatComposerAccessorySlot.js.map +1 -0
- package/lib/module/screens/chat-detail/components/ChatComposerInputArea.js +149 -0
- package/lib/module/screens/chat-detail/components/ChatComposerInputArea.js.map +1 -0
- package/lib/module/screens/chat-detail/components/ChatComposerStatusBanner.js +104 -0
- package/lib/module/screens/chat-detail/components/ChatComposerStatusBanner.js.map +1 -0
- package/lib/module/screens/chat-detail/hooks/useChatComposerAnimation.js +0 -17
- package/lib/module/screens/chat-detail/hooks/useChatComposerAnimation.js.map +1 -1
- package/lib/module/screens/chat-detail/hooks/useChatComposerState.js +16 -2
- package/lib/module/screens/chat-detail/hooks/useChatComposerState.js.map +1 -1
- package/lib/module/screens/chat-detail/hooks/useComposerBotMenu.js +122 -0
- package/lib/module/screens/chat-detail/hooks/useComposerBotMenu.js.map +1 -0
- package/lib/module/screens/chat-detail/hooks/useComposerPanelActions.js +46 -0
- package/lib/module/screens/chat-detail/hooks/useComposerPanelActions.js.map +1 -0
- package/lib/module/screens/chat-detail/hooks/useComposerPanelDismiss.js +75 -0
- package/lib/module/screens/chat-detail/hooks/useComposerPanelDismiss.js.map +1 -0
- package/lib/module/screens/chat-detail/hooks/useComposerPanels.js +136 -0
- package/lib/module/screens/chat-detail/hooks/useComposerPanels.js.map +1 -0
- package/lib/module/screens/chat-detail/hooks/useComposerSend.js +74 -0
- package/lib/module/screens/chat-detail/hooks/useComposerSend.js.map +1 -0
- package/lib/module/screens/chat-detail/legend/LegendChatMessage.js +12 -3
- package/lib/module/screens/chat-detail/legend/LegendChatMessage.js.map +1 -1
- package/lib/module/screens/chat-detail/messageToolbox/MessageToolboxOverlay.js +11 -2
- package/lib/module/screens/chat-detail/messageToolbox/MessageToolboxOverlay.js.map +1 -1
- package/lib/module/screens/chat-detail/messageToolbox/MessageToolboxWrapper.js +79 -6
- package/lib/module/screens/chat-detail/messageToolbox/MessageToolboxWrapper.js.map +1 -1
- package/lib/module/screens/chat-detail/messageToolbox/useClonePreview.js +30 -0
- package/lib/module/screens/chat-detail/messageToolbox/useClonePreview.js.map +1 -0
- package/lib/module/screens/chat-detail/types.js +5 -0
- package/lib/module/screens/chat-detail/types.js.map +1 -1
- package/lib/module/store/expandedMessage.js +28 -0
- package/lib/module/store/expandedMessage.js.map +1 -0
- package/lib/module/store/message.js +14 -0
- package/lib/module/store/message.js.map +1 -1
- package/lib/module/utils/composerPanelDismissGesture.js +52 -0
- package/lib/module/utils/composerPanelDismissGesture.js.map +1 -0
- package/lib/module/utils/expandableText.js +41 -0
- package/lib/module/utils/expandableText.js.map +1 -0
- package/lib/module/utils/inlineTruncation.js +51 -0
- package/lib/module/utils/inlineTruncation.js.map +1 -0
- package/lib/module/utils/perf-marker.js +44 -0
- package/lib/module/utils/perf-marker.js.map +1 -0
- package/lib/module/utils/truncateTextChildren.js +38 -0
- package/lib/module/utils/truncateTextChildren.js.map +1 -0
- package/lib/typescript/src/components/ThreadCard/ThreadCard.d.ts.map +1 -1
- package/lib/typescript/src/components/messages/ExpandableMessageText.d.ts +25 -0
- package/lib/typescript/src/components/messages/ExpandableMessageText.d.ts.map +1 -0
- package/lib/typescript/src/components/messages/PreviewScrollableText.d.ts +29 -0
- package/lib/typescript/src/components/messages/PreviewScrollableText.d.ts.map +1 -0
- package/lib/typescript/src/components/messages/fileMessage/index.d.ts.map +1 -1
- package/lib/typescript/src/components/messages/linkMessage/index.d.ts +1 -1
- package/lib/typescript/src/components/messages/linkMessage/index.d.ts.map +1 -1
- package/lib/typescript/src/components/messages/quotedMessage/index.d.ts.map +1 -1
- package/lib/typescript/src/components/messages/textMessage/index.d.ts +1 -1
- package/lib/typescript/src/components/messages/textMessage/index.d.ts.map +1 -1
- package/lib/typescript/src/components/messages/types.d.ts +18 -0
- package/lib/typescript/src/components/messages/types.d.ts.map +1 -1
- package/lib/typescript/src/context/TimelinePressGuardContext.d.ts +3 -0
- package/lib/typescript/src/context/TimelinePressGuardContext.d.ts.map +1 -0
- package/lib/typescript/src/hooks/useConversationList.d.ts.map +1 -1
- package/lib/typescript/src/hooks/useDismissKeyboardFirst.d.ts +8 -0
- package/lib/typescript/src/hooks/useDismissKeyboardFirst.d.ts.map +1 -0
- package/lib/typescript/src/hooks/useExpandableText.d.ts +13 -0
- package/lib/typescript/src/hooks/useExpandableText.d.ts.map +1 -0
- package/lib/typescript/src/hooks/useGuardedPress.d.ts +9 -0
- package/lib/typescript/src/hooks/useGuardedPress.d.ts.map +1 -0
- package/lib/typescript/src/screens/chat-detail/ChatComposer.d.ts +7 -3
- package/lib/typescript/src/screens/chat-detail/ChatComposer.d.ts.map +1 -1
- package/lib/typescript/src/screens/chat-detail/ChatDetail.d.ts.map +1 -1
- package/lib/typescript/src/screens/chat-detail/ChatListLegend.d.ts +5 -1
- package/lib/typescript/src/screens/chat-detail/ChatListLegend.d.ts.map +1 -1
- package/lib/typescript/src/screens/chat-detail/PinnedMessagesSheet.d.ts.map +1 -1
- package/lib/typescript/src/screens/chat-detail/components/ChatComposerAccessorySlot.d.ts +12 -0
- package/lib/typescript/src/screens/chat-detail/components/ChatComposerAccessorySlot.d.ts.map +1 -0
- package/lib/typescript/src/screens/chat-detail/components/ChatComposerInputArea.d.ts +30 -0
- package/lib/typescript/src/screens/chat-detail/components/ChatComposerInputArea.d.ts.map +1 -0
- package/lib/typescript/src/screens/chat-detail/components/ChatComposerStatusBanner.d.ts +19 -0
- package/lib/typescript/src/screens/chat-detail/components/ChatComposerStatusBanner.d.ts.map +1 -0
- package/lib/typescript/src/screens/chat-detail/hooks/useChatComposerAnimation.d.ts +0 -1
- package/lib/typescript/src/screens/chat-detail/hooks/useChatComposerAnimation.d.ts.map +1 -1
- package/lib/typescript/src/screens/chat-detail/hooks/useChatComposerState.d.ts +7 -0
- package/lib/typescript/src/screens/chat-detail/hooks/useChatComposerState.d.ts.map +1 -1
- package/lib/typescript/src/screens/chat-detail/hooks/useComposerBotMenu.d.ts +7 -0
- package/lib/typescript/src/screens/chat-detail/hooks/useComposerBotMenu.d.ts.map +1 -0
- package/lib/typescript/src/screens/chat-detail/hooks/useComposerPanelActions.d.ts +17 -0
- package/lib/typescript/src/screens/chat-detail/hooks/useComposerPanelActions.d.ts.map +1 -0
- package/lib/typescript/src/screens/chat-detail/hooks/useComposerPanelDismiss.d.ts +12 -0
- package/lib/typescript/src/screens/chat-detail/hooks/useComposerPanelDismiss.d.ts.map +1 -0
- package/lib/typescript/src/screens/chat-detail/hooks/useComposerPanels.d.ts +25 -0
- package/lib/typescript/src/screens/chat-detail/hooks/useComposerPanels.d.ts.map +1 -0
- package/lib/typescript/src/screens/chat-detail/hooks/useComposerSend.d.ts +16 -0
- package/lib/typescript/src/screens/chat-detail/hooks/useComposerSend.d.ts.map +1 -0
- package/lib/typescript/src/screens/chat-detail/legend/LegendChatMessage.d.ts +11 -1
- package/lib/typescript/src/screens/chat-detail/legend/LegendChatMessage.d.ts.map +1 -1
- package/lib/typescript/src/screens/chat-detail/messageToolbox/MessageToolboxOverlay.d.ts.map +1 -1
- package/lib/typescript/src/screens/chat-detail/messageToolbox/MessageToolboxWrapper.d.ts +14 -1
- package/lib/typescript/src/screens/chat-detail/messageToolbox/MessageToolboxWrapper.d.ts.map +1 -1
- package/lib/typescript/src/screens/chat-detail/messageToolbox/useClonePreview.d.ts +18 -0
- package/lib/typescript/src/screens/chat-detail/messageToolbox/useClonePreview.d.ts.map +1 -0
- package/lib/typescript/src/screens/chat-detail/types.d.ts +8 -0
- package/lib/typescript/src/screens/chat-detail/types.d.ts.map +1 -1
- package/lib/typescript/src/store/expandedMessage.d.ts +15 -0
- package/lib/typescript/src/store/expandedMessage.d.ts.map +1 -0
- package/lib/typescript/src/store/message.d.ts.map +1 -1
- package/lib/typescript/src/utils/composerPanelDismissGesture.d.ts +33 -0
- package/lib/typescript/src/utils/composerPanelDismissGesture.d.ts.map +1 -0
- package/lib/typescript/src/utils/expandableText.d.ts +18 -0
- package/lib/typescript/src/utils/expandableText.d.ts.map +1 -0
- package/lib/typescript/src/utils/inlineTruncation.d.ts +24 -0
- package/lib/typescript/src/utils/inlineTruncation.d.ts.map +1 -0
- package/lib/typescript/src/utils/perf-marker.d.ts +8 -0
- package/lib/typescript/src/utils/perf-marker.d.ts.map +1 -0
- package/lib/typescript/src/utils/truncateTextChildren.d.ts +3 -0
- package/lib/typescript/src/utils/truncateTextChildren.d.ts.map +1 -0
- package/package.json +2 -1
- package/src/components/ThreadCard/ThreadCard.tsx +2 -0
- package/src/components/messages/ExpandableMessageText.tsx +145 -0
- package/src/components/messages/PreviewScrollableText.tsx +98 -0
- package/src/components/messages/fileMessage/index.tsx +17 -3
- package/src/components/messages/linkMessage/index.tsx +30 -21
- package/src/components/messages/quotedMessage/index.tsx +19 -3
- package/src/components/messages/textMessage/index.tsx +11 -2
- package/src/components/messages/types.ts +18 -0
- package/src/context/TimelinePressGuardContext.tsx +15 -0
- package/src/hooks/useConversationList.ts +2 -0
- package/src/hooks/useDismissKeyboardFirst.ts +19 -0
- package/src/hooks/useExpandableText.ts +143 -0
- package/src/hooks/useGuardedPress.ts +20 -0
- package/src/screens/chat-detail/ChatComposer.tsx +105 -631
- package/src/screens/chat-detail/ChatDetail.tsx +49 -20
- package/src/screens/chat-detail/ChatListLegend.tsx +122 -71
- package/src/screens/chat-detail/PinnedMessagesSheet.tsx +8 -0
- package/src/screens/chat-detail/components/ChatComposerAccessorySlot.tsx +61 -0
- package/src/screens/chat-detail/components/ChatComposerInputArea.tsx +198 -0
- package/src/screens/chat-detail/components/ChatComposerStatusBanner.tsx +116 -0
- package/src/screens/chat-detail/hooks/useChatComposerAnimation.ts +0 -29
- package/src/screens/chat-detail/hooks/useChatComposerState.ts +25 -2
- package/src/screens/chat-detail/hooks/useComposerBotMenu.tsx +140 -0
- package/src/screens/chat-detail/hooks/useComposerPanelActions.ts +57 -0
- package/src/screens/chat-detail/hooks/useComposerPanelDismiss.ts +111 -0
- package/src/screens/chat-detail/hooks/useComposerPanels.ts +197 -0
- package/src/screens/chat-detail/hooks/useComposerSend.ts +98 -0
- package/src/screens/chat-detail/legend/LegendChatMessage.tsx +24 -2
- package/src/screens/chat-detail/messageToolbox/MessageToolboxOverlay.tsx +20 -1
- package/src/screens/chat-detail/messageToolbox/MessageToolboxWrapper.tsx +111 -5
- package/src/screens/chat-detail/messageToolbox/useClonePreview.ts +34 -0
- package/src/screens/chat-detail/types.ts +9 -0
- package/src/store/expandedMessage.ts +42 -0
- package/src/store/message.ts +14 -0
- package/src/utils/composerPanelDismissGesture.ts +72 -0
- package/src/utils/expandableText.ts +51 -0
- package/src/utils/inlineTruncation.ts +65 -0
- package/src/utils/perf-marker.ts +39 -0
- 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;
|
|
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":[]}
|