@droppii-org/chat-mobile 0.2.81 → 0.2.82
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/MentionBadge.js +24 -0
- package/lib/module/components/ThreadCard/MentionBadge.js.map +1 -0
- package/lib/module/components/ThreadCard/ThreadCard.js +5 -1
- package/lib/module/components/ThreadCard/ThreadCard.js.map +1 -1
- package/lib/module/components/messages/linkMessage/LinkPreviewCard.js +67 -0
- package/lib/module/components/messages/linkMessage/LinkPreviewCard.js.map +1 -0
- package/lib/module/components/messages/linkMessage/index.js +21 -68
- package/lib/module/components/messages/linkMessage/index.js.map +1 -1
- package/lib/module/components/messages/quotedMessage/QuotedMessagePreviewStrip.js +152 -0
- package/lib/module/components/messages/quotedMessage/QuotedMessagePreviewStrip.js.map +1 -0
- package/lib/module/components/messages/textMessage/index.js +102 -8
- package/lib/module/components/messages/textMessage/index.js.map +1 -1
- package/lib/module/core/useChatListener.js +1 -1
- package/lib/module/core/useChatListener.js.map +1 -1
- package/lib/module/hooks/message/useSendMessage.js +64 -3
- package/lib/module/hooks/message/useSendMessage.js.map +1 -1
- package/lib/module/hooks/query-keys.js +4 -0
- package/lib/module/hooks/query-keys.js.map +1 -1
- package/lib/module/hooks/useChatCompose.js +3 -2
- package/lib/module/hooks/useChatCompose.js.map +1 -1
- package/lib/module/screens/chat-detail/ChatComposer.js +170 -48
- package/lib/module/screens/chat-detail/ChatComposer.js.map +1 -1
- package/lib/module/screens/chat-detail/ChatListLegend.js +1 -0
- package/lib/module/screens/chat-detail/ChatListLegend.js.map +1 -1
- package/lib/module/screens/chat-detail/components/ChatMessageInput.js +23 -2
- package/lib/module/screens/chat-detail/components/ChatMessageInput.js.map +1 -1
- package/lib/module/screens/chat-detail/components/MentionHighlightAdapter.js +51 -0
- package/lib/module/screens/chat-detail/components/MentionHighlightAdapter.js.map +1 -0
- package/lib/module/screens/chat-detail/components/MentionSuggestionItem.js +49 -0
- package/lib/module/screens/chat-detail/components/MentionSuggestionItem.js.map +1 -0
- package/lib/module/screens/chat-detail/components/MentionSuggestionList.js +114 -0
- package/lib/module/screens/chat-detail/components/MentionSuggestionList.js.map +1 -0
- package/lib/module/screens/chat-detail/hooks/useChatComposerState.js +8 -0
- package/lib/module/screens/chat-detail/hooks/useChatComposerState.js.map +1 -1
- package/lib/module/screens/chat-detail/hooks/useMentionComposer.js +251 -0
- package/lib/module/screens/chat-detail/hooks/useMentionComposer.js.map +1 -0
- package/lib/module/screens/chat-detail/legend/LegendChatMessage.js +5 -1
- package/lib/module/screens/chat-detail/legend/LegendChatMessage.js.map +1 -1
- package/lib/module/services/mentionSearch.js +49 -0
- package/lib/module/services/mentionSearch.js.map +1 -0
- package/lib/module/services/message.js +6 -1
- package/lib/module/services/message.js.map +1 -1
- package/lib/module/translation/resources/i18n.js +5 -0
- package/lib/module/translation/resources/i18n.js.map +1 -1
- package/lib/module/types/chat.js.map +1 -1
- package/lib/module/types/mention.js +2 -0
- package/lib/module/types/mention.js.map +1 -0
- package/lib/module/utils/mentionSerializer.js +113 -0
- package/lib/module/utils/mentionSerializer.js.map +1 -0
- package/lib/module/utils/mentions/index.js +7 -0
- package/lib/module/utils/mentions/index.js.map +1 -0
- package/lib/module/utils/mentions/mentionDetector.js +49 -0
- package/lib/module/utils/mentions/mentionDetector.js.map +1 -0
- package/lib/module/utils/mentions/mentionDiff.js +66 -0
- package/lib/module/utils/mentions/mentionDiff.js.map +1 -0
- package/lib/module/utils/mentions/mentionRange.js +188 -0
- package/lib/module/utils/mentions/mentionRange.js.map +1 -0
- package/lib/module/utils/mentions/mentionTokenize.js +50 -0
- package/lib/module/utils/mentions/mentionTokenize.js.map +1 -0
- package/lib/module/utils/messageUtils.js +6 -1
- package/lib/module/utils/messageUtils.js.map +1 -1
- package/lib/module/utils/url.js +33 -0
- package/lib/module/utils/url.js.map +1 -1
- package/lib/typescript/src/components/ThreadCard/MentionBadge.d.ts +7 -0
- package/lib/typescript/src/components/ThreadCard/MentionBadge.d.ts.map +1 -0
- package/lib/typescript/src/components/ThreadCard/ThreadCard.d.ts.map +1 -1
- package/lib/typescript/src/components/messages/linkMessage/LinkPreviewCard.d.ts +16 -0
- package/lib/typescript/src/components/messages/linkMessage/LinkPreviewCard.d.ts.map +1 -0
- package/lib/typescript/src/components/messages/linkMessage/index.d.ts.map +1 -1
- package/lib/typescript/src/components/messages/quotedMessage/QuotedMessagePreviewStrip.d.ts +13 -0
- package/lib/typescript/src/components/messages/quotedMessage/QuotedMessagePreviewStrip.d.ts.map +1 -0
- package/lib/typescript/src/components/messages/textMessage/index.d.ts +3 -1
- package/lib/typescript/src/components/messages/textMessage/index.d.ts.map +1 -1
- package/lib/typescript/src/hooks/message/useSendMessage.d.ts +5 -2
- package/lib/typescript/src/hooks/message/useSendMessage.d.ts.map +1 -1
- package/lib/typescript/src/hooks/query-keys.d.ts +4 -0
- package/lib/typescript/src/hooks/query-keys.d.ts.map +1 -1
- package/lib/typescript/src/hooks/useChatCompose.d.ts +2 -1
- package/lib/typescript/src/hooks/useChatCompose.d.ts.map +1 -1
- package/lib/typescript/src/screens/chat-detail/ChatComposer.d.ts.map +1 -1
- package/lib/typescript/src/screens/chat-detail/ChatListLegend.d.ts.map +1 -1
- package/lib/typescript/src/screens/chat-detail/components/ChatMessageInput.d.ts +10 -2
- package/lib/typescript/src/screens/chat-detail/components/ChatMessageInput.d.ts.map +1 -1
- package/lib/typescript/src/screens/chat-detail/components/MentionHighlightAdapter.d.ts +29 -0
- package/lib/typescript/src/screens/chat-detail/components/MentionHighlightAdapter.d.ts.map +1 -0
- package/lib/typescript/src/screens/chat-detail/components/MentionSuggestionItem.d.ts +8 -0
- package/lib/typescript/src/screens/chat-detail/components/MentionSuggestionItem.d.ts.map +1 -0
- package/lib/typescript/src/screens/chat-detail/components/MentionSuggestionList.d.ts +12 -0
- package/lib/typescript/src/screens/chat-detail/components/MentionSuggestionList.d.ts.map +1 -0
- package/lib/typescript/src/screens/chat-detail/hooks/useChatComposerState.d.ts +1 -1
- package/lib/typescript/src/screens/chat-detail/hooks/useChatComposerState.d.ts.map +1 -1
- package/lib/typescript/src/screens/chat-detail/hooks/useMentionComposer.d.ts +48 -0
- package/lib/typescript/src/screens/chat-detail/hooks/useMentionComposer.d.ts.map +1 -0
- package/lib/typescript/src/screens/chat-detail/legend/LegendChatMessage.d.ts.map +1 -1
- package/lib/typescript/src/services/mentionSearch.d.ts +15 -0
- package/lib/typescript/src/services/mentionSearch.d.ts.map +1 -0
- package/lib/typescript/src/services/message.d.ts +1 -1
- package/lib/typescript/src/services/message.d.ts.map +1 -1
- package/lib/typescript/src/translation/resources/i18n.d.ts.map +1 -1
- package/lib/typescript/src/types/chat.d.ts +23 -0
- package/lib/typescript/src/types/chat.d.ts.map +1 -1
- package/lib/typescript/src/types/mention.d.ts +65 -0
- package/lib/typescript/src/types/mention.d.ts.map +1 -0
- package/lib/typescript/src/utils/mentionSerializer.d.ts +78 -0
- package/lib/typescript/src/utils/mentionSerializer.d.ts.map +1 -0
- package/lib/typescript/src/utils/mentions/index.d.ts +5 -0
- package/lib/typescript/src/utils/mentions/index.d.ts.map +1 -0
- package/lib/typescript/src/utils/mentions/mentionDetector.d.ts +18 -0
- package/lib/typescript/src/utils/mentions/mentionDetector.d.ts.map +1 -0
- package/lib/typescript/src/utils/mentions/mentionDiff.d.ts +20 -0
- package/lib/typescript/src/utils/mentions/mentionDiff.d.ts.map +1 -0
- package/lib/typescript/src/utils/mentions/mentionRange.d.ts +86 -0
- package/lib/typescript/src/utils/mentions/mentionRange.d.ts.map +1 -0
- package/lib/typescript/src/utils/mentions/mentionTokenize.d.ts +29 -0
- package/lib/typescript/src/utils/mentions/mentionTokenize.d.ts.map +1 -0
- package/lib/typescript/src/utils/messageUtils.d.ts.map +1 -1
- package/lib/typescript/src/utils/url.d.ts +12 -0
- package/lib/typescript/src/utils/url.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/ThreadCard/MentionBadge.tsx +28 -0
- package/src/components/ThreadCard/ThreadCard.tsx +3 -0
- package/src/components/messages/linkMessage/LinkPreviewCard.tsx +92 -0
- package/src/components/messages/linkMessage/index.tsx +25 -89
- package/src/components/messages/quotedMessage/QuotedMessagePreviewStrip.tsx +168 -0
- package/src/components/messages/textMessage/index.tsx +124 -4
- package/src/core/useChatListener.ts +1 -1
- package/src/hooks/message/useSendMessage.ts +60 -1
- package/src/hooks/query-keys.ts +6 -0
- package/src/hooks/useChatCompose.ts +115 -107
- package/src/screens/chat-detail/ChatComposer.tsx +201 -67
- package/src/screens/chat-detail/ChatListLegend.tsx +1 -0
- package/src/screens/chat-detail/components/ChatMessageInput.tsx +35 -2
- package/src/screens/chat-detail/components/MentionHighlightAdapter.tsx +57 -0
- package/src/screens/chat-detail/components/MentionSuggestionItem.tsx +53 -0
- package/src/screens/chat-detail/components/MentionSuggestionList.tsx +133 -0
- package/src/screens/chat-detail/hooks/useChatComposerState.ts +7 -1
- package/src/screens/chat-detail/hooks/useMentionComposer.ts +344 -0
- package/src/screens/chat-detail/legend/LegendChatMessage.tsx +7 -1
- package/src/services/mentionSearch.ts +57 -0
- package/src/services/message.ts +9 -1
- package/src/translation/resources/i18n.ts +6 -0
- package/src/types/chat.ts +22 -0
- package/src/types/mention.ts +70 -0
- package/src/utils/mentionSerializer.ts +155 -0
- package/src/utils/mentions/index.ts +16 -0
- package/src/utils/mentions/mentionDetector.ts +58 -0
- package/src/utils/mentions/mentionDiff.ts +95 -0
- package/src/utils/mentions/mentionRange.ts +207 -0
- package/src/utils/mentions/mentionTokenize.ts +53 -0
- package/src/utils/messageUtils.ts +6 -1
- package/src/utils/url.ts +30 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { memo, useMemo } from 'react';
|
|
4
|
+
import { Text } from 'react-native';
|
|
5
|
+
import { KColors } from '@droppii/libs';
|
|
6
|
+
import { tokenize } from "../../../utils/mentions/index.js";
|
|
7
|
+
import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
8
|
+
/**
|
|
9
|
+
* Renders `text` as nested styled `<Text>` children for a TextInput's
|
|
10
|
+
* "undocumented" rich-text-via-children capability — the same primitive
|
|
11
|
+
* `react-native-controlled-mentions` and Bluesky's social-app both use.
|
|
12
|
+
*
|
|
13
|
+
* Deliberately STATELESS: every render calls tokenize() fresh and rebuilds
|
|
14
|
+
* the whole children tree from scratch — no attempt to preserve/diff span
|
|
15
|
+
* identity across renders. This is the Bluesky-informed choice (see the
|
|
16
|
+
* mention plan's Phase A3): react-native-controlled-mentions instead tries
|
|
17
|
+
* to maintain *stateful* span identity across renders, and its known
|
|
18
|
+
* Android bugs (#34668 duplicate input, #41647 broken selection, #50731
|
|
19
|
+
* "spans recreated on every render") read like that statefulness fighting
|
|
20
|
+
* itself — Bluesky ships live-colored nested-Text in production by never
|
|
21
|
+
* attempting to preserve identity in the first place. Only tokenize()
|
|
22
|
+
* itself is memoized (on [text, mentions]); the resulting element tree is
|
|
23
|
+
* not further diffed or cached.
|
|
24
|
+
*
|
|
25
|
+
* Only mounted when mentions.length > 0 (see ChatMessageInput) — a plain
|
|
26
|
+
* `value`-controlled TextInput is used otherwise, so the vast majority of
|
|
27
|
+
* messages (no mentions) never pay for this at all.
|
|
28
|
+
*/
|
|
29
|
+
export const MentionHighlightAdapter = /*#__PURE__*/memo(({
|
|
30
|
+
text,
|
|
31
|
+
mentions
|
|
32
|
+
}) => {
|
|
33
|
+
const segments = useMemo(() => tokenize(text, mentions), [text, mentions]);
|
|
34
|
+
return /*#__PURE__*/_jsx(_Fragment, {
|
|
35
|
+
children: segments.map((segment, index) => segment.type === 'mention' ? /*#__PURE__*/_jsx(Text, {
|
|
36
|
+
style: mentionTextStyle,
|
|
37
|
+
children: `@${segment.mention.displayName}`
|
|
38
|
+
}, segment.mention.id) :
|
|
39
|
+
/*#__PURE__*/
|
|
40
|
+
// Plain-text runs have no stable identity of their own — index
|
|
41
|
+
// is fine for a tree rebuilt from scratch every render.
|
|
42
|
+
_jsx(Text, {
|
|
43
|
+
children: segment.text
|
|
44
|
+
}, `text-${index}`))
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
MentionHighlightAdapter.displayName = 'MentionHighlightAdapter';
|
|
48
|
+
const mentionTextStyle = {
|
|
49
|
+
color: KColors.palette.primary.w400
|
|
50
|
+
};
|
|
51
|
+
//# sourceMappingURL=MentionHighlightAdapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["memo","useMemo","Text","KColors","tokenize","jsx","_jsx","Fragment","_Fragment","MentionHighlightAdapter","text","mentions","segments","children","map","segment","index","type","style","mentionTextStyle","mention","displayName","id","color","palette","primary","w400"],"sourceRoot":"../../../../../src","sources":["screens/chat-detail/components/MentionHighlightAdapter.tsx"],"mappings":";;AAAA,SAASA,IAAI,EAAEC,OAAO,QAAQ,OAAO;AACrC,SAASC,IAAI,QAAQ,cAAc;AACnC,SAASC,OAAO,QAAQ,eAAe;AACvC,SAASC,QAAQ,QAAQ,kCAAyB;AAAC,SAAAC,GAAA,IAAAC,IAAA,EAAAC,QAAA,IAAAC,SAAA;AAQnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,uBAAuB,gBAAGT,IAAI,CACzC,CAAC;EAAEU,IAAI;EAAEC;AAAuC,CAAC,KAAK;EACpD,MAAMC,QAAQ,GAAGX,OAAO,CAAC,MAAMG,QAAQ,CAACM,IAAI,EAAEC,QAAQ,CAAC,EAAE,CAACD,IAAI,EAAEC,QAAQ,CAAC,CAAC;EAE1E,oBACEL,IAAA,CAAAE,SAAA;IAAAK,QAAA,EACGD,QAAQ,CAACE,GAAG,CAAC,CAACC,OAAO,EAAEC,KAAK,KAC3BD,OAAO,CAACE,IAAI,KAAK,SAAS,gBACxBX,IAAA,CAACJ,IAAI;MAA0BgB,KAAK,EAAEC,gBAAiB;MAAAN,QAAA,EACpD,IAAIE,OAAO,CAACK,OAAO,CAACC,WAAW;IAAE,GADzBN,OAAO,CAACK,OAAO,CAACE,EAErB,CAAC;IAAA;IAEP;IACA;IACAhB,IAAA,CAACJ,IAAI;MAAAW,QAAA,EAAwBE,OAAO,CAACL;IAAI,GAA9B,QAAQM,KAAK,EAAwB,CAEpD;EAAC,CACD,CAAC;AAEP,CACF,CAAC;AAEDP,uBAAuB,CAACY,WAAW,GAAG,yBAAyB;AAE/D,MAAMF,gBAAgB,GAAG;EAAEI,KAAK,EAAEpB,OAAO,CAACqB,OAAO,CAACC,OAAO,CAACC;AAAK,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { memo, useCallback } from 'react';
|
|
4
|
+
import { KContainer, KLabel, KColors, KImage } from '@droppii/libs';
|
|
5
|
+
import Avatar from "../../../components/Avatar/Avatar.js";
|
|
6
|
+
import { trans } from "../../../translation/index.js";
|
|
7
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
8
|
+
const ALL_MEMBERS_USER_ID = 'ALL';
|
|
9
|
+
export const MentionSuggestionItem = /*#__PURE__*/memo(({
|
|
10
|
+
item,
|
|
11
|
+
onPress
|
|
12
|
+
}) => {
|
|
13
|
+
const isAllOption = item.userId === ALL_MEMBERS_USER_ID;
|
|
14
|
+
const handlePress = useCallback(() => onPress(item), [onPress, item]);
|
|
15
|
+
return /*#__PURE__*/_jsxs(KContainer.Touchable, {
|
|
16
|
+
row: true,
|
|
17
|
+
alignItems: true,
|
|
18
|
+
onPress: handlePress,
|
|
19
|
+
children: [isAllOption ? /*#__PURE__*/_jsx(KContainer.View, {
|
|
20
|
+
width: 40,
|
|
21
|
+
height: 40,
|
|
22
|
+
center: true,
|
|
23
|
+
children: /*#__PURE__*/_jsx(KImage.VectorIcons, {
|
|
24
|
+
name: "user-three-b",
|
|
25
|
+
size: 24,
|
|
26
|
+
color: KColors.palette.gray.w900
|
|
27
|
+
})
|
|
28
|
+
}) : /*#__PURE__*/_jsx(Avatar, {
|
|
29
|
+
source: item.avatar,
|
|
30
|
+
fullName: item.displayName,
|
|
31
|
+
size: "nm"
|
|
32
|
+
}), /*#__PURE__*/_jsxs(KContainer.View, {
|
|
33
|
+
flex: true,
|
|
34
|
+
marginL: "0.75rem",
|
|
35
|
+
children: [/*#__PURE__*/_jsx(KLabel.Text, {
|
|
36
|
+
typo: "TextMdMedium",
|
|
37
|
+
numberOfLines: 1,
|
|
38
|
+
children: item.displayName
|
|
39
|
+
}), isAllOption && /*#__PURE__*/_jsx(KLabel.Text, {
|
|
40
|
+
typo: "TextXsNormal",
|
|
41
|
+
color: KColors.palette.gray.w600,
|
|
42
|
+
numberOfLines: 1,
|
|
43
|
+
children: trans('group:tag_all_desc')
|
|
44
|
+
})]
|
|
45
|
+
})]
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
MentionSuggestionItem.displayName = 'MentionSuggestionItem';
|
|
49
|
+
//# sourceMappingURL=MentionSuggestionItem.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["memo","useCallback","KContainer","KLabel","KColors","KImage","Avatar","trans","jsx","_jsx","jsxs","_jsxs","ALL_MEMBERS_USER_ID","MentionSuggestionItem","item","onPress","isAllOption","userId","handlePress","Touchable","row","alignItems","children","View","width","height","center","VectorIcons","name","size","color","palette","gray","w900","source","avatar","fullName","displayName","flex","marginL","Text","typo","numberOfLines","w600"],"sourceRoot":"../../../../../src","sources":["screens/chat-detail/components/MentionSuggestionItem.tsx"],"mappings":";;AAAA,SAASA,IAAI,EAAEC,WAAW,QAAQ,OAAO;AACzC,SAASC,UAAU,EAAEC,MAAM,EAAEC,OAAO,EAAEC,MAAM,QAAQ,eAAe;AACnE,OAAOC,MAAM,MAAM,sCAAmC;AACtD,SAASC,KAAK,QAAQ,+BAAsB;AAAC,SAAAC,GAAA,IAAAC,IAAA,EAAAC,IAAA,IAAAC,KAAA;AAG7C,MAAMC,mBAAmB,GAAG,KAAK;AAOjC,OAAO,MAAMC,qBAAqB,gBAAGb,IAAI,CACvC,CAAC;EAAEc,IAAI;EAAEC;AAAoC,CAAC,KAAK;EACjD,MAAMC,WAAW,GAAGF,IAAI,CAACG,MAAM,KAAKL,mBAAmB;EAEvD,MAAMM,WAAW,GAAGjB,WAAW,CAAC,MAAMc,OAAO,CAACD,IAAI,CAAC,EAAE,CAACC,OAAO,EAAED,IAAI,CAAC,CAAC;EAErE,oBACEH,KAAA,CAACT,UAAU,CAACiB,SAAS;IAACC,GAAG;IAACC,UAAU;IAACN,OAAO,EAAEG,WAAY;IAAAI,QAAA,GACvDN,WAAW,gBACVP,IAAA,CAACP,UAAU,CAACqB,IAAI;MAACC,KAAK,EAAE,EAAG;MAACC,MAAM,EAAE,EAAG;MAACC,MAAM;MAAAJ,QAAA,eAC5Cb,IAAA,CAACJ,MAAM,CAACsB,WAAW;QACjBC,IAAI,EAAC,cAAc;QACnBC,IAAI,EAAE,EAAG;QACTC,KAAK,EAAE1B,OAAO,CAAC2B,OAAO,CAACC,IAAI,CAACC;MAAK,CAClC;IAAC,CACa,CAAC,gBAElBxB,IAAA,CAACH,MAAM;MAAC4B,MAAM,EAAEpB,IAAI,CAACqB,MAAO;MAACC,QAAQ,EAAEtB,IAAI,CAACuB,WAAY;MAACR,IAAI,EAAC;IAAI,CAAE,CACrE,eAEDlB,KAAA,CAACT,UAAU,CAACqB,IAAI;MAACe,IAAI;MAACC,OAAO,EAAC,SAAS;MAAAjB,QAAA,gBACrCb,IAAA,CAACN,MAAM,CAACqC,IAAI;QAACC,IAAI,EAAC,cAAc;QAACC,aAAa,EAAE,CAAE;QAAApB,QAAA,EAC/CR,IAAI,CAACuB;MAAW,CACN,CAAC,EACbrB,WAAW,iBACVP,IAAA,CAACN,MAAM,CAACqC,IAAI;QACVC,IAAI,EAAC,cAAc;QACnBX,KAAK,EAAE1B,OAAO,CAAC2B,OAAO,CAACC,IAAI,CAACW,IAAK;QACjCD,aAAa,EAAE,CAAE;QAAApB,QAAA,EAEhBf,KAAK,CAAC,oBAAoB;MAAC,CACjB,CACd;IAAA,CACc,CAAC;EAAA,CACE,CAAC;AAE3B,CACF,CAAC;AAEDM,qBAAqB,CAACwB,WAAW,GAAG,uBAAuB","ignoreList":[]}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { memo, useCallback } from 'react';
|
|
4
|
+
import { ActivityIndicator, StyleSheet } from 'react-native';
|
|
5
|
+
import { LegendList } from '@legendapp/list/react-native';
|
|
6
|
+
import { KContainer, KLabel, KColors, KSpacingValue } from '@droppii/libs';
|
|
7
|
+
import { MentionSuggestionItem } from "./MentionSuggestionItem.js";
|
|
8
|
+
import { trans } from "../../../translation/index.js";
|
|
9
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
10
|
+
// Figma (node 15066-319156): regular rows are 40px (single line, avatar
|
|
11
|
+
// height defines it), the "Tất cả" row is 45px (title + subtitle) — 40 is
|
|
12
|
+
// used as the shared estimate since most rows are the single-line kind.
|
|
13
|
+
const ROW_HEIGHT = 40;
|
|
14
|
+
const ROW_GAP = 8;
|
|
15
|
+
const MAX_VISIBLE_ROWS = 6;
|
|
16
|
+
const MAX_PANEL_HEIGHT = ROW_HEIGHT * MAX_VISIBLE_ROWS + ROW_GAP * (MAX_VISIBLE_ROWS - 1);
|
|
17
|
+
export const MentionSuggestionList = /*#__PURE__*/memo(({
|
|
18
|
+
suggestions,
|
|
19
|
+
isSearching,
|
|
20
|
+
isLoadingMore,
|
|
21
|
+
hasMore,
|
|
22
|
+
onLoadMore,
|
|
23
|
+
onSelect
|
|
24
|
+
}) => {
|
|
25
|
+
const renderItem = useCallback(({
|
|
26
|
+
item
|
|
27
|
+
}) => /*#__PURE__*/_jsx(MentionSuggestionItem, {
|
|
28
|
+
item: item,
|
|
29
|
+
onPress: onSelect
|
|
30
|
+
}), [onSelect]);
|
|
31
|
+
const keyExtractor = useCallback(item => item.userId, []);
|
|
32
|
+
const renderFooter = useCallback(() => {
|
|
33
|
+
if (!isLoadingMore) return null;
|
|
34
|
+
return /*#__PURE__*/_jsx(KContainer.View, {
|
|
35
|
+
paddingV: "0.5rem",
|
|
36
|
+
center: true,
|
|
37
|
+
children: /*#__PURE__*/_jsx(ActivityIndicator, {
|
|
38
|
+
color: KColors.palette.primary.w400
|
|
39
|
+
})
|
|
40
|
+
});
|
|
41
|
+
}, [isLoadingMore]);
|
|
42
|
+
const renderSeparator = useCallback(() => /*#__PURE__*/_jsx(KContainer.View, {
|
|
43
|
+
style: styles.separator
|
|
44
|
+
}), []);
|
|
45
|
+
return /*#__PURE__*/_jsx(KContainer.View, {
|
|
46
|
+
style: styles.shadowWrapper,
|
|
47
|
+
children: /*#__PURE__*/_jsxs(KContainer.View, {
|
|
48
|
+
background: KColors.white,
|
|
49
|
+
style: styles.container,
|
|
50
|
+
children: [/*#__PURE__*/_jsx(KLabel.Text, {
|
|
51
|
+
typo: "TextNmBold",
|
|
52
|
+
color: KColors.palette.gray.w600,
|
|
53
|
+
paddingH: "0.75rem",
|
|
54
|
+
paddingV: "0.5rem",
|
|
55
|
+
children: trans('group:tag_title')
|
|
56
|
+
}), suggestions.length === 0 && !isSearching ? /*#__PURE__*/_jsx(KLabel.Text, {
|
|
57
|
+
typo: "TextSmNormal",
|
|
58
|
+
color: KColors.palette.gray.w600,
|
|
59
|
+
paddingH: "0.75rem",
|
|
60
|
+
paddingB: "0.75rem",
|
|
61
|
+
children: trans('group:tag_no_member_found')
|
|
62
|
+
}) : suggestions.length === 0 && isSearching ? /*#__PURE__*/_jsx(KContainer.View, {
|
|
63
|
+
paddingV: "0.75rem",
|
|
64
|
+
center: true,
|
|
65
|
+
children: /*#__PURE__*/_jsx(ActivityIndicator, {
|
|
66
|
+
color: KColors.palette.primary.w400
|
|
67
|
+
})
|
|
68
|
+
}) : /*#__PURE__*/_jsx(KContainer.View, {
|
|
69
|
+
style: styles.listWrapper,
|
|
70
|
+
padding: "0.5rem",
|
|
71
|
+
children: /*#__PURE__*/_jsx(LegendList, {
|
|
72
|
+
data: suggestions,
|
|
73
|
+
renderItem: renderItem,
|
|
74
|
+
keyExtractor: keyExtractor,
|
|
75
|
+
estimatedItemSize: ROW_HEIGHT,
|
|
76
|
+
keyboardShouldPersistTaps: "handled",
|
|
77
|
+
onEndReached: hasMore ? onLoadMore : undefined,
|
|
78
|
+
onEndReachedThreshold: 0.5,
|
|
79
|
+
ListFooterComponent: renderFooter,
|
|
80
|
+
ItemSeparatorComponent: renderSeparator
|
|
81
|
+
})
|
|
82
|
+
})]
|
|
83
|
+
})
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
MentionSuggestionList.displayName = 'MentionSuggestionList';
|
|
87
|
+
const styles = StyleSheet.create({
|
|
88
|
+
// Shadow lives on its own, non-clipping wrapper — a single view can't
|
|
89
|
+
// both clip to a rounded corner (overflow:'hidden', required below) and
|
|
90
|
+
// cast a shadow, since the clip cuts the shadow off too.
|
|
91
|
+
shadowWrapper: {
|
|
92
|
+
shadowColor: KColors.black,
|
|
93
|
+
shadowOffset: {
|
|
94
|
+
width: 0,
|
|
95
|
+
height: -8
|
|
96
|
+
},
|
|
97
|
+
shadowOpacity: 0.08,
|
|
98
|
+
shadowRadius: 16,
|
|
99
|
+
elevation: 4
|
|
100
|
+
},
|
|
101
|
+
container: {
|
|
102
|
+
borderRadius: KSpacingValue['0.75rem'],
|
|
103
|
+
borderTopLeftRadius: KSpacingValue['0.75rem'],
|
|
104
|
+
borderTopRightRadius: KSpacingValue['0.75rem'],
|
|
105
|
+
overflow: 'hidden'
|
|
106
|
+
},
|
|
107
|
+
listWrapper: {
|
|
108
|
+
maxHeight: MAX_PANEL_HEIGHT
|
|
109
|
+
},
|
|
110
|
+
separator: {
|
|
111
|
+
height: ROW_GAP
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
//# sourceMappingURL=MentionSuggestionList.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["memo","useCallback","ActivityIndicator","StyleSheet","LegendList","KContainer","KLabel","KColors","KSpacingValue","MentionSuggestionItem","trans","jsx","_jsx","jsxs","_jsxs","ROW_HEIGHT","ROW_GAP","MAX_VISIBLE_ROWS","MAX_PANEL_HEIGHT","MentionSuggestionList","suggestions","isSearching","isLoadingMore","hasMore","onLoadMore","onSelect","renderItem","item","onPress","keyExtractor","userId","renderFooter","View","paddingV","center","children","color","palette","primary","w400","renderSeparator","style","styles","separator","shadowWrapper","background","white","container","Text","typo","gray","w600","paddingH","length","paddingB","listWrapper","padding","data","estimatedItemSize","keyboardShouldPersistTaps","onEndReached","undefined","onEndReachedThreshold","ListFooterComponent","ItemSeparatorComponent","displayName","create","shadowColor","black","shadowOffset","width","height","shadowOpacity","shadowRadius","elevation","borderRadius","borderTopLeftRadius","borderTopRightRadius","overflow","maxHeight"],"sourceRoot":"../../../../../src","sources":["screens/chat-detail/components/MentionSuggestionList.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
import { useState, useMemo, useRef } from 'react';
|
|
4
|
+
|
|
5
|
+
// 'mention' is used only for mutual-exclusion (closing attachment/sticker
|
|
6
|
+
// when the mention picker opens) — the mention picker itself renders as its
|
|
7
|
+
// own absolutely-positioned sibling in ChatComposer, not through this
|
|
8
|
+
// state's render slot, since it must float above the input while the
|
|
9
|
+
// keyboard stays open (attachment/sticker intentionally take over the
|
|
10
|
+
// keyboard area, which the mention picker must not do).
|
|
11
|
+
|
|
4
12
|
export const useChatComposerState = value => {
|
|
5
13
|
const [activePanelType, setActivePanelType] = useState(null);
|
|
6
14
|
const [isAttachmentOpen, setIsAttachmentOpen] = useState(false);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["useState","useMemo","useRef","useChatComposerState","value","activePanelType","setActivePanelType","isAttachmentOpen","setIsAttachmentOpen","isInputFocused","setIsInputFocused","isInputWrapped","setIsInputWrapped","inputRef","isMultilineInput","includes"],"sourceRoot":"../../../../../src","sources":["screens/chat-detail/hooks/useChatComposerState.ts"],"mappings":";;AAAA,SAASA,QAAQ,EAAEC,OAAO,EAAEC,MAAM,QAAQ,OAAO;
|
|
1
|
+
{"version":3,"names":["useState","useMemo","useRef","useChatComposerState","value","activePanelType","setActivePanelType","isAttachmentOpen","setIsAttachmentOpen","isInputFocused","setIsInputFocused","isInputWrapped","setIsInputWrapped","inputRef","isMultilineInput","includes"],"sourceRoot":"../../../../../src","sources":["screens/chat-detail/hooks/useChatComposerState.ts"],"mappings":";;AAAA,SAASA,QAAQ,EAAEC,OAAO,EAAEC,MAAM,QAAQ,OAAO;;AAEjD;AACA;AACA;AACA;AACA;AACA;;AAgBA,OAAO,MAAMC,oBAAoB,GAC/BC,KAAa,IACkB;EAC/B,MAAM,CAACC,eAAe,EAAEC,kBAAkB,CAAC,GAAGN,QAAQ,CAAkB,IAAI,CAAC;EAC7E,MAAM,CAACO,gBAAgB,EAAEC,mBAAmB,CAAC,GAAGR,QAAQ,CAAC,KAAK,CAAC;EAC/D,MAAM,CAACS,cAAc,EAAEC,iBAAiB,CAAC,GAAGV,QAAQ,CAAC,KAAK,CAAC;EAC3D,MAAM,CAACW,cAAc,EAAEC,iBAAiB,CAAC,GAAGZ,QAAQ,CAAC,KAAK,CAAC;EAC3D,MAAMa,QAAQ,GAAGX,MAAM,CAAM,IAAI,CAAC;EAElC,MAAMY,gBAAgB,GAAGb,OAAO,CAAC,MAAM;IACrC,IAAI,CAACG,KAAK,EAAE;MACV,OAAO,KAAK;IACd;IAEA,OAAOA,KAAK,CAACW,QAAQ,CAAC,IAAI,CAAC,IAAIJ,cAAc;EAC/C,CAAC,EAAE,CAACA,cAAc,EAAEP,KAAK,CAAC,CAAC;EAE3B,OAAO;IACLC,eAAe;IACfC,kBAAkB;IAClBC,gBAAgB;IAChBC,mBAAmB;IACnBC,cAAc;IACdC,iBAAiB;IACjBC,cAAc;IACdC,iBAAiB;IACjBE,gBAAgB;IAChBD;EACF,CAAC;AACH,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
4
|
+
import { useInfiniteQuery } from '@tanstack/react-query';
|
|
5
|
+
import debounce from 'lodash/debounce';
|
|
6
|
+
import { applyTextChange, findActiveMention, insertMention } from "../../../utils/mentions/index.js";
|
|
7
|
+
import { trans } from "../../../translation/index.js";
|
|
8
|
+
import { mentionQueryKeys } from "../../../hooks/query-keys.js";
|
|
9
|
+
const SEARCH_DEBOUNCE_MS = 200;
|
|
10
|
+
// Matches MentionSuggestionList's MAX_VISIBLE_ROWS — one page fills exactly
|
|
11
|
+
// one screenful of the panel, so scrolling further triggers loadMore instead
|
|
12
|
+
// of over-fetching members the user hasn't scrolled to yet.
|
|
13
|
+
const SEARCH_LIMIT = 4;
|
|
14
|
+
const ALL_MEMBERS_USER_ID = 'ALL';
|
|
15
|
+
const allMembersSuggestion = () => ({
|
|
16
|
+
userId: ALL_MEMBERS_USER_ID,
|
|
17
|
+
displayName: trans('group:tag_all')
|
|
18
|
+
});
|
|
19
|
+
/**
|
|
20
|
+
* Orchestrates the @mention composer: wires the pure Phase A1 logic
|
|
21
|
+
* (findActiveMention / applyTextChange / insertMention) and an injected
|
|
22
|
+
* MentionSearchSource into the live TextInput event loop.
|
|
23
|
+
*
|
|
24
|
+
* `text` stays owned by useChatCompose (the existing composer state) — this
|
|
25
|
+
* hook doesn't duplicate it, only mirrors it into a ref for synchronous
|
|
26
|
+
* access within its own event handlers (see textRef below).
|
|
27
|
+
*/
|
|
28
|
+
export function useMentionComposer({
|
|
29
|
+
text,
|
|
30
|
+
setText,
|
|
31
|
+
searchSource,
|
|
32
|
+
groupID,
|
|
33
|
+
enabled = true,
|
|
34
|
+
inputRef
|
|
35
|
+
}) {
|
|
36
|
+
const [mentions, setMentions] = useState([]);
|
|
37
|
+
const [activeMention, setActiveMention] = useState(null);
|
|
38
|
+
// The keyword actually being searched for — distinct from
|
|
39
|
+
// activeMention.keyword, which updates on every keystroke. This only
|
|
40
|
+
// changes 200ms after typing pauses (see debouncedSetKeywordRef below),
|
|
41
|
+
// and IS the react-query key: typing further characters within the debounce
|
|
42
|
+
// window never touches the query at all, so the previous page's results
|
|
43
|
+
// stay on screen with zero flicker until the debounce actually fires.
|
|
44
|
+
// null means "no active search" (panel closed) — distinct from '' (an
|
|
45
|
+
// active search for the empty keyword, which also lists all members).
|
|
46
|
+
const [debouncedKeyword, setDebouncedKeyword] = useState(null);
|
|
47
|
+
|
|
48
|
+
// Synchronous mirrors of the externally-owned `text` and internally-owned
|
|
49
|
+
// `mentions` state. React state updates aren't visible until the next
|
|
50
|
+
// render, but applyTextChange needs the *actual* latest committed values
|
|
51
|
+
// within the same tick a keystroke is processed — these refs are updated
|
|
52
|
+
// in lockstep with every setText/setMentions call below so they never lag.
|
|
53
|
+
const textRef = useRef(text);
|
|
54
|
+
const mentionsRef = useRef([]);
|
|
55
|
+
const activeMentionRef = useRef(null);
|
|
56
|
+
const searchSourceRef = useRef(searchSource);
|
|
57
|
+
searchSourceRef.current = searchSource;
|
|
58
|
+
const enabledRef = useRef(enabled);
|
|
59
|
+
enabledRef.current = enabled;
|
|
60
|
+
useEffect(() => {
|
|
61
|
+
// External text changes not driven by this hook (e.g. clearing the
|
|
62
|
+
// composer after send) — keep the mirror and mention state in sync.
|
|
63
|
+
if (text !== textRef.current) {
|
|
64
|
+
textRef.current = text;
|
|
65
|
+
if (text === '') {
|
|
66
|
+
mentionsRef.current = [];
|
|
67
|
+
setMentions([]);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}, [text]);
|
|
71
|
+
const debouncedSetKeywordRef = useRef(debounce(keyword => setDebouncedKeyword(keyword), SEARCH_DEBOUNCE_MS, {
|
|
72
|
+
leading: false,
|
|
73
|
+
trailing: true
|
|
74
|
+
}));
|
|
75
|
+
useEffect(() => () => debouncedSetKeywordRef.current.cancel(), []);
|
|
76
|
+
const isActiveSearch = debouncedKeyword !== null;
|
|
77
|
+
const {
|
|
78
|
+
data,
|
|
79
|
+
isFetching,
|
|
80
|
+
isFetchingNextPage,
|
|
81
|
+
hasNextPage,
|
|
82
|
+
fetchNextPage
|
|
83
|
+
} = useInfiniteQuery({
|
|
84
|
+
queryKey: mentionQueryKeys.search(groupID ?? '', debouncedKeyword ?? ''),
|
|
85
|
+
queryFn: ({
|
|
86
|
+
pageParam
|
|
87
|
+
}) => searchSourceRef.current.search({
|
|
88
|
+
keyword: debouncedKeyword ?? '',
|
|
89
|
+
limit: SEARCH_LIMIT,
|
|
90
|
+
offset: pageParam
|
|
91
|
+
}),
|
|
92
|
+
// Neither getGroupMemberList nor searchGroupMembers returns a total, so
|
|
93
|
+
// "is there a next page" is inferred from page size (see
|
|
94
|
+
// MentionSearchResult.hasMore's doc comment) instead of an exact count.
|
|
95
|
+
getNextPageParam: (lastPage, allPages) => lastPage.hasMore ? allPages.reduce((sum, p) => sum + p.items.length, 0) : undefined,
|
|
96
|
+
initialPageParam: 0,
|
|
97
|
+
enabled: isActiveSearch
|
|
98
|
+
// Deliberately no maxPages cap — this is a scrolling picker, not a
|
|
99
|
+
// one-shot search; capping pages would drop already-loaded members as
|
|
100
|
+
// the user scrolls further, which is a worse experience than the memory
|
|
101
|
+
// cost of keeping them.
|
|
102
|
+
});
|
|
103
|
+
const includeAll = debouncedKeyword === '';
|
|
104
|
+
const suggestions = useMemo(() => {
|
|
105
|
+
const items = data?.pages.flatMap(page => page.items) ?? [];
|
|
106
|
+
return includeAll ? [allMembersSuggestion(), ...items] : items;
|
|
107
|
+
}, [data, includeAll]);
|
|
108
|
+
const loadMore = useCallback(() => {
|
|
109
|
+
if (!isActiveSearch || !hasNextPage || isFetchingNextPage) return;
|
|
110
|
+
fetchNextPage();
|
|
111
|
+
}, [isActiveSearch, hasNextPage, isFetchingNextPage, fetchNextPage]);
|
|
112
|
+
const updateActiveMentionAndSearch = useCallback((currentText, cursor) => {
|
|
113
|
+
// Non-group conversation — "@" is a plain character, never a trigger.
|
|
114
|
+
// Checked here (not just left to the search source returning empty)
|
|
115
|
+
// so the picker UI never opens at all in this case.
|
|
116
|
+
const active = enabledRef.current ? findActiveMention(currentText, cursor) : null;
|
|
117
|
+
activeMentionRef.current = active;
|
|
118
|
+
setActiveMention(active);
|
|
119
|
+
if (!active) {
|
|
120
|
+
debouncedSetKeywordRef.current.cancel();
|
|
121
|
+
// Functional updater so an already-null value doesn't force a
|
|
122
|
+
// render on every ordinary keystroke (the common case).
|
|
123
|
+
setDebouncedKeyword(prev => prev === null ? prev : null);
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
debouncedSetKeywordRef.current(active.keyword);
|
|
127
|
+
}, []);
|
|
128
|
+
|
|
129
|
+
// Simplified from an earlier microtask-buffered design (see git history /
|
|
130
|
+
// plan doc for why that existed) after it caused a real, reproduced
|
|
131
|
+
// "Maximum update depth exceeded" loop in production testing. Root cause
|
|
132
|
+
// wasn't fully isolated without device logs, but the buffering added a
|
|
133
|
+
// second, redundant path (onSelectionChange re-running mention detection
|
|
134
|
+
// with native selection data that could be stale relative to the edit
|
|
135
|
+
// onChangeText had just processed) that could set state back and forth.
|
|
136
|
+
// applyTextChange already derives an authoritative cursor from the text
|
|
137
|
+
// diff itself — it never needed to wait for onSelectionChange for the
|
|
138
|
+
// edit case, so handling each event directly, synchronously, removes an
|
|
139
|
+
// entire dimension of timing uncertainty instead of trying to patch it.
|
|
140
|
+
const handleChangeText = useCallback(nextText => {
|
|
141
|
+
const nextTextRaw = nextText ?? '';
|
|
142
|
+
const previousText = textRef.current;
|
|
143
|
+
if (nextTextRaw === previousText) return;
|
|
144
|
+
const result = applyTextChange(previousText, mentionsRef.current, nextTextRaw);
|
|
145
|
+
textRef.current = result.text;
|
|
146
|
+
mentionsRef.current = result.mentions;
|
|
147
|
+
setText(result.text);
|
|
148
|
+
setMentions(result.mentions);
|
|
149
|
+
if (result.mentionRemoved) {
|
|
150
|
+
// The native buffer currently shows nextTextRaw, not our corrected
|
|
151
|
+
// result.text — force the cursor back to a position that's valid
|
|
152
|
+
// once React re-renders the controlled value.
|
|
153
|
+
requestAnimationFrame(() => {
|
|
154
|
+
inputRef.current?.setSelection(result.cursor, result.cursor);
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
updateActiveMentionAndSearch(result.text, result.cursor);
|
|
158
|
+
}, [inputRef, setText, updateActiveMentionAndSearch]);
|
|
159
|
+
|
|
160
|
+
// Only meaningful for a pure cursor move with NO accompanying text change
|
|
161
|
+
// (tap elsewhere in the draft, arrow keys) — an edit's cursor is already
|
|
162
|
+
// handled authoritatively inside handleChangeText above. Deliberately
|
|
163
|
+
// does not re-run search/active-mention detection here to avoid the
|
|
164
|
+
// redundant double-handling that caused the loop this replaced.
|
|
165
|
+
const handleSelectionChange = useCallback(event => {
|
|
166
|
+
const selection = event.nativeEvent.selection;
|
|
167
|
+
if (selection.start !== selection.end) return;
|
|
168
|
+
if (selection.start === textRef.current.length) return; // typical post-edit echo, already handled
|
|
169
|
+
|
|
170
|
+
updateActiveMentionAndSearch(textRef.current, selection.start);
|
|
171
|
+
}, [updateActiveMentionAndSearch]);
|
|
172
|
+
const selectSuggestion = useCallback(item => {
|
|
173
|
+
const active = activeMentionRef.current;
|
|
174
|
+
if (!active) return;
|
|
175
|
+
const result = insertMention(textRef.current, mentionsRef.current, active, {
|
|
176
|
+
userId: item.userId,
|
|
177
|
+
displayName: item.displayName
|
|
178
|
+
});
|
|
179
|
+
textRef.current = result.text;
|
|
180
|
+
mentionsRef.current = result.mentions;
|
|
181
|
+
setText(result.text);
|
|
182
|
+
setMentions(result.mentions);
|
|
183
|
+
activeMentionRef.current = null;
|
|
184
|
+
setActiveMention(null);
|
|
185
|
+
debouncedSetKeywordRef.current.cancel();
|
|
186
|
+
setDebouncedKeyword(null);
|
|
187
|
+
requestAnimationFrame(() => {
|
|
188
|
+
inputRef.current?.setSelection(result.cursor, result.cursor);
|
|
189
|
+
});
|
|
190
|
+
}, [inputRef, setText]);
|
|
191
|
+
|
|
192
|
+
// Called by ChatComposer when the user explicitly opens the
|
|
193
|
+
// attachment/sticker panel while a mention query is active — the mutual
|
|
194
|
+
// exclusion works both directions: opening mention closes attachment/
|
|
195
|
+
// sticker (ChatComposer's own handlers already do that reactively, see
|
|
196
|
+
// the effect wired there), and this closes mention when the user
|
|
197
|
+
// deliberately switches to a different panel.
|
|
198
|
+
const closeMentionPanel = useCallback(() => {
|
|
199
|
+
activeMentionRef.current = null;
|
|
200
|
+
setActiveMention(null);
|
|
201
|
+
debouncedSetKeywordRef.current.cancel();
|
|
202
|
+
setDebouncedKeyword(null);
|
|
203
|
+
}, []);
|
|
204
|
+
|
|
205
|
+
// Defensive: if `enabled` ever flips false while a mention query happens
|
|
206
|
+
// to be open (e.g. conversation type resolves after mount), close it
|
|
207
|
+
// immediately rather than leaving a stale picker for a thread that
|
|
208
|
+
// shouldn't have one at all.
|
|
209
|
+
useEffect(() => {
|
|
210
|
+
if (!enabled) closeMentionPanel();
|
|
211
|
+
// closeMentionPanel is stable ([] deps) — listing it here doesn't cause
|
|
212
|
+
// extra runs, it just keeps the deps array honest instead of suppressing
|
|
213
|
+
// the lint rule.
|
|
214
|
+
}, [enabled, closeMentionPanel]);
|
|
215
|
+
|
|
216
|
+
// Called explicitly by ChatComposer right when it clears the composer
|
|
217
|
+
// after send. The existing `useEffect` watching the `text` prop *would*
|
|
218
|
+
// eventually sync mentions to [] once `compose.setText('')` propagates
|
|
219
|
+
// down as a new `text` prop — but that's a render later, and in between
|
|
220
|
+
// there's a real transient bug: `value` is already '' while `mentions`
|
|
221
|
+
// still holds the old (now-stale) entries, and tokenize('', oldMentions)
|
|
222
|
+
// happily emits a mention segment anchored past the end of an empty
|
|
223
|
+
// string — a "ghost" mention with no surrounding text. Clearing
|
|
224
|
+
// synchronously here, in the same tick as setText(''), removes that
|
|
225
|
+
// window entirely instead of just shrinking it.
|
|
226
|
+
const clear = useCallback(() => {
|
|
227
|
+
textRef.current = '';
|
|
228
|
+
mentionsRef.current = [];
|
|
229
|
+
activeMentionRef.current = null;
|
|
230
|
+
setMentions([]);
|
|
231
|
+
setActiveMention(null);
|
|
232
|
+
debouncedSetKeywordRef.current.cancel();
|
|
233
|
+
setDebouncedKeyword(null);
|
|
234
|
+
}, []);
|
|
235
|
+
return {
|
|
236
|
+
mentions,
|
|
237
|
+
activeMention,
|
|
238
|
+
suggestions,
|
|
239
|
+
isSearching: isActiveSearch && isFetching && !isFetchingNextPage,
|
|
240
|
+
isLoadingMore: isFetchingNextPage,
|
|
241
|
+
hasMore: !!hasNextPage,
|
|
242
|
+
loadMore,
|
|
243
|
+
isPanelOpen: activeMention !== null,
|
|
244
|
+
handleChangeText,
|
|
245
|
+
handleSelectionChange,
|
|
246
|
+
selectSuggestion,
|
|
247
|
+
closeMentionPanel,
|
|
248
|
+
clear
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
//# sourceMappingURL=useMentionComposer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["useCallback","useEffect","useMemo","useRef","useState","useInfiniteQuery","debounce","applyTextChange","findActiveMention","insertMention","trans","mentionQueryKeys","SEARCH_DEBOUNCE_MS","SEARCH_LIMIT","ALL_MEMBERS_USER_ID","allMembersSuggestion","userId","displayName","useMentionComposer","text","setText","searchSource","groupID","enabled","inputRef","mentions","setMentions","activeMention","setActiveMention","debouncedKeyword","setDebouncedKeyword","textRef","mentionsRef","activeMentionRef","searchSourceRef","current","enabledRef","debouncedSetKeywordRef","keyword","leading","trailing","cancel","isActiveSearch","data","isFetching","isFetchingNextPage","hasNextPage","fetchNextPage","queryKey","search","queryFn","pageParam","limit","offset","getNextPageParam","lastPage","allPages","hasMore","reduce","sum","p","items","length","undefined","initialPageParam","includeAll","suggestions","pages","flatMap","page","loadMore","updateActiveMentionAndSearch","currentText","cursor","active","prev","handleChangeText","nextText","nextTextRaw","previousText","result","mentionRemoved","requestAnimationFrame","setSelection","handleSelectionChange","event","selection","nativeEvent","start","end","selectSuggestion","item","closeMentionPanel","clear","isSearching","isLoadingMore","isPanelOpen"],"sourceRoot":"../../../../../src","sources":["screens/chat-detail/hooks/useMentionComposer.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -77,7 +77,11 @@ export const LegendChatMessage = /*#__PURE__*/memo(({
|
|
|
77
77
|
}
|
|
78
78
|
const MessageComponent = messageComponentMap[message?.contentType] ?? TextMessage;
|
|
79
79
|
const hasMediaPress = MEDIA_TYPES.includes(message?.contentType) && onMediaPress;
|
|
80
|
-
|
|
80
|
+
// AtTextMessage included: mention+URL combo attaches its link-preview
|
|
81
|
+
// card via ex.urlMetadata on an AtTextMessage (see TextMessage's doc
|
|
82
|
+
// comment) instead of a dedicated UrlTextMessage — the card still needs
|
|
83
|
+
// a tap handler.
|
|
84
|
+
const hasUrlPress = onPressUrl && (message?.contentType === MessageType.UrlTextMessage || message?.contentType === MessageType.AtTextMessage);
|
|
81
85
|
return /*#__PURE__*/_jsxs(KContainer.View, {
|
|
82
86
|
style: messageStyles.wrapper,
|
|
83
87
|
row: true,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["KContainer","KImage","KColors","KLabel","KSpacingValue","StyleSheet","memo","useCallback","useMemo","MessageType","Gesture","GestureDetector","runOnJS","TextMessage","ImageMessage","VideoMessage","FileMessage","LinkMessage","MergedMessage","RevokedMessage","GroupNotificationMessage","MessageStatusIndicator","messageStyles","QuotedMessage","StickerMessage","GROUP_NOTIFICATION_TYPES","Avatar","TAIL_WIDTH","jsx","_jsx","jsxs","_jsxs","messageComponentMap","AtTextMessage","QuoteMessage","UrlTextMessage","PictureMessage","MergeMessage","RevokeMessage","Object","fromEntries","map","type","MEDIA_TYPES","SYSTEM_MESSAGE_TYPES","LegendChatMessage","message","isOutgoing","createdAtTime","onMediaPress","onPressUrl","onRetry","onPress","onLongPress","customMessageItemFactory","isHighlighted","showName","showAvatar","showSenderGutter","groupPosition","handlePress","handleLongPress","customNode","includes","contentType","SystemMessageComponent","View","center","style","styles","systemMessageWrapper","children","MessageComponent","hasMediaPress","hasUrlPress","wrapper","row","alignItems","avatarGutter","size","source","senderFaceUrl","fullName","senderNickname","content","Text","typo","color","gray","normal","numberOfLines","marginB","senderName","LongPressWrapper","undefined","isPinned","pinBadge","VectorIcons","name","primary","displayName","AVATAR_SIZE","create","position","marginLeft","width","marginRight","alignSelf","marginVertical","top","right","height","borderRadius","justifyContent","backgroundColor","pageBackground","shadowColor","black","shadowOffset","shadowOpacity","shadowRadius","elevation","borderWidth","borderColor","white","zIndex","Number","MAX_SAFE_INTEGER","gesture","gestures","LongPress","onStart","Tap","filter","Boolean","length","Race"],"sourceRoot":"../../../../../src","sources":["screens/chat-detail/legend/LegendChatMessage.tsx"],"mappings":";;AAAA,SACEA,UAAU,EACVC,MAAM,EACNC,OAAO,EACPC,MAAM,EACNC,aAAa,QACR,eAAe;AACtB,SAASC,UAAU,QAAQ,cAAc;AACzC,SAASC,IAAI,EAAEC,WAAW,EAAEC,OAAO,QAAQ,OAAO;AAElD,SAASC,WAAW,QAAQ,+BAA+B;AAE3D,SAASC,OAAO,EAAEC,eAAe,QAAQ,8BAA8B;AACvE,SAASC,OAAO,QAAQ,yBAAyB;AAEjD,SAASC,WAAW,QAAQ,mDAA0C;AACtE,SAASC,YAAY,QAAQ,oDAA2C;AACxE,SAASC,YAAY,QAAQ,oDAA2C;AACxE,SAASC,WAAW,QAAQ,mDAA0C;AACtE,SAASC,WAAW,QAAQ,mDAA0C;AACtE,SAASC,aAAa,QAAQ,qDAA4C;AAC1E,SAASC,cAAc,QAAQ,sDAA6C;AAC5E,SAASC,wBAAwB,QAAQ,gEAAuD;AAChG,SAASC,sBAAsB,QAAQ,wDAAqD;AAE5F,SAASC,aAAa,QAAQ,mBAAgB;AAC9C,OAAOC,aAAa,MAAM,qDAA4C;AACtE,SAASC,cAAc,QAAQ,sDAA6C;AAC5E,SAASC,wBAAwB,QAAQ,gCAA6B;AAEtE,SAASC,MAAM,QAAQ,qCAA4B;AACnD,SAASC,UAAU,QAAQ,4CAAyC;AAAC,SAAAC,GAAA,IAAAC,IAAA,EAAAC,IAAA,IAAAC,KAAA;AAgCrE,MAAMC,mBAEL,GAAG;EACF,CAACvB,WAAW,CAACI,WAAW,GAAGA,WAAW;EACtC,CAACJ,WAAW,CAACwB,aAAa,GAAGpB,WAAW;EACxC,CAACJ,WAAW,CAACyB,YAAY,GAAGX,aAAa;EACzC,CAACd,WAAW,CAAC0B,cAAc,GAAGlB,WAAW;EACzC,CAACR,WAAW,CAAC2B,cAAc,GAAGtB,YAAY;EAC1C,CAACL,WAAW,CAACM,YAAY,GAAGA,YAAY;EACxC,CAACN,WAAW,CAACO,WAAW,GAAGA,WAAW;EACtC,CAACP,WAAW,CAAC4B,YAAY,GAAGnB,aAAa;EACzC,CAACT,WAAW,CAAC6B,aAAa,GAAGnB,cAAc;EAC3C,CAACV,WAAW,CAACe,cAAc,GAAGA,cAAc;EAC5C,GAAGe,MAAM,CAACC,WAAW,CACnBf,wBAAwB,CAACgB,GAAG,CAAEC,IAAI,IAAK,CAACA,IAAI,EAAEtB,wBAAwB,CAAC,CACzE;AACF,CAAC;AAED,MAAMuB,WAAqB,GAAG,CAC5BlC,WAAW,CAAC2B,cAAc,EAC1B3B,WAAW,CAACM,YAAY,EACxBN,WAAW,CAAC4B,YAAY,CACzB;AAED,MAAMO,oBAA8B,GAAGnB,wBAAwB;AAE/D,OAAO,MAAMoB,iBAAiB,gBAAGvC,IAAI,CACnC,CAAC;EACCwC,OAAO;EACPC,UAAU;EACVC,aAAa;EACbC,YAAY;EACZC,UAAU;EACVC,OAAO;EACPC,OAAO;EACPC,WAAW;EACXC,wBAAwB;EACxBC,aAAa;EACbC,QAAQ,GAAG,KAAK;EAChBC,UAAU,GAAG,KAAK;EAClBC,gBAAgB,GAAG,KAAK;EACxBC;AACsB,CAAC,KAAK;EAC5B,MAAMC,WAAW,GAAGrD,WAAW,CAAC,MAAM;IACpC6C,OAAO,GAAGN,OAAO,CAAC;EACpB,CAAC,EAAE,CAACM,OAAO,EAAEN,OAAO,CAAC,CAAC;EAEtB,MAAMe,eAAe,GAAGtD,WAAW,CAAC,MAAM;IACxC8C,WAAW,GAAG,CAAC;EACjB,CAAC,EAAE,CAACA,WAAW,CAAC,CAAC;EAEjB,MAAMS,UAAU,GAAGR,wBAAwB,GAAGR,OAAO,CAAC;EAEtD,IAAIgB,UAAU,EAAE;IACd,OAAOA,UAAU;EACnB;EAEA,IAAIlB,oBAAoB,CAACmB,QAAQ,CAACjB,OAAO,EAAEkB,WAAW,CAAC,EAAE;IACvD,MAAMC,sBAAsB,GAC1BjC,mBAAmB,CAACc,OAAO,CAACkB,WAAW,CAAC,IAAInD,WAAW;IACzD,oBACEgB,IAAA,CAAC7B,UAAU,CAACkE,IAAI;MAACC,MAAM;MAACC,KAAK,EAAEC,MAAM,CAACC,oBAAqB;MAAAC,QAAA,eACzD1C,IAAA,CAACoC,sBAAsB;QACrBnB,OAAO,EAAEA,OAAQ;QACjBC,UAAU,EAAEA,UAAW;QACvBC,aAAa,EAAEA;MAAc,CAC9B;IAAC,CACa,CAAC;EAEtB;EAEA,MAAMwB,gBAA6C,GACjDxC,mBAAmB,CAACc,OAAO,EAAEkB,WAAW,CAAC,IAAInD,WAAW;EAE1D,MAAM4D,aAAa,GACjB9B,WAAW,CAACoB,QAAQ,CAACjB,OAAO,EAAEkB,WAAW,CAAC,IAAIf,YAAY;EAC5D,MAAMyB,WAAW,GACfxB,UAAU,
|
|
1
|
+
{"version":3,"names":["KContainer","KImage","KColors","KLabel","KSpacingValue","StyleSheet","memo","useCallback","useMemo","MessageType","Gesture","GestureDetector","runOnJS","TextMessage","ImageMessage","VideoMessage","FileMessage","LinkMessage","MergedMessage","RevokedMessage","GroupNotificationMessage","MessageStatusIndicator","messageStyles","QuotedMessage","StickerMessage","GROUP_NOTIFICATION_TYPES","Avatar","TAIL_WIDTH","jsx","_jsx","jsxs","_jsxs","messageComponentMap","AtTextMessage","QuoteMessage","UrlTextMessage","PictureMessage","MergeMessage","RevokeMessage","Object","fromEntries","map","type","MEDIA_TYPES","SYSTEM_MESSAGE_TYPES","LegendChatMessage","message","isOutgoing","createdAtTime","onMediaPress","onPressUrl","onRetry","onPress","onLongPress","customMessageItemFactory","isHighlighted","showName","showAvatar","showSenderGutter","groupPosition","handlePress","handleLongPress","customNode","includes","contentType","SystemMessageComponent","View","center","style","styles","systemMessageWrapper","children","MessageComponent","hasMediaPress","hasUrlPress","wrapper","row","alignItems","avatarGutter","size","source","senderFaceUrl","fullName","senderNickname","content","Text","typo","color","gray","normal","numberOfLines","marginB","senderName","LongPressWrapper","undefined","isPinned","pinBadge","VectorIcons","name","primary","displayName","AVATAR_SIZE","create","position","marginLeft","width","marginRight","alignSelf","marginVertical","top","right","height","borderRadius","justifyContent","backgroundColor","pageBackground","shadowColor","black","shadowOffset","shadowOpacity","shadowRadius","elevation","borderWidth","borderColor","white","zIndex","Number","MAX_SAFE_INTEGER","gesture","gestures","LongPress","onStart","Tap","filter","Boolean","length","Race"],"sourceRoot":"../../../../../src","sources":["screens/chat-detail/legend/LegendChatMessage.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import OpenIMSDK, { GroupMemberFilter } from '@droppii/openim-rn-client-sdk';
|
|
4
|
+
const toSuggestion = member => ({
|
|
5
|
+
userId: member.userID,
|
|
6
|
+
displayName: member.nickname,
|
|
7
|
+
avatar: member.faceURL
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Concrete MentionSearchSource implementation for Part A's mention
|
|
12
|
+
* composer, wrapping the OpenIM SDK's group-member primitives — 0 call
|
|
13
|
+
* sites anywhere else in this repo before this feature. Empty keyword ->
|
|
14
|
+
* the full/initial member list (getGroupMemberList); non-empty keyword ->
|
|
15
|
+
* server-backed search (searchGroupMembers), purpose-built for this case.
|
|
16
|
+
*
|
|
17
|
+
* Neither SDK call returns a total count, so `hasMore` is inferred from
|
|
18
|
+
* page size (a full page *might* mean there's another one) — the same
|
|
19
|
+
* heuristic every offset/count-paginated list in this codebase already
|
|
20
|
+
* relies on, since OpenIM doesn't expose a cheaper alternative here.
|
|
21
|
+
*/
|
|
22
|
+
export function createOpenIMMentionSearchSource(groupID) {
|
|
23
|
+
return {
|
|
24
|
+
async search({
|
|
25
|
+
keyword,
|
|
26
|
+
limit,
|
|
27
|
+
offset
|
|
28
|
+
}) {
|
|
29
|
+
const members = keyword === '' ? await OpenIMSDK.getGroupMemberList({
|
|
30
|
+
groupID,
|
|
31
|
+
filter: GroupMemberFilter.All,
|
|
32
|
+
offset,
|
|
33
|
+
count: limit
|
|
34
|
+
}) : await OpenIMSDK.searchGroupMembers({
|
|
35
|
+
groupID,
|
|
36
|
+
keywordList: [keyword],
|
|
37
|
+
isSearchUserID: false,
|
|
38
|
+
isSearchMemberNickname: true,
|
|
39
|
+
offset,
|
|
40
|
+
count: limit
|
|
41
|
+
});
|
|
42
|
+
return {
|
|
43
|
+
items: members.map(toSuggestion),
|
|
44
|
+
hasMore: members.length === limit
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=mentionSearch.js.map
|