@droppii-org/chat-mobile 0.2.81 → 0.2.83

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 (175) hide show
  1. package/lib/module/components/ThreadCard/MentionBadge.js +24 -0
  2. package/lib/module/components/ThreadCard/MentionBadge.js.map +1 -0
  3. package/lib/module/components/ThreadCard/ThreadCard.js +5 -1
  4. package/lib/module/components/ThreadCard/ThreadCard.js.map +1 -1
  5. package/lib/module/components/messages/linkMessage/LinkPreviewCard.js +67 -0
  6. package/lib/module/components/messages/linkMessage/LinkPreviewCard.js.map +1 -0
  7. package/lib/module/components/messages/linkMessage/index.js +49 -92
  8. package/lib/module/components/messages/linkMessage/index.js.map +1 -1
  9. package/lib/module/components/messages/quotedMessage/QuotedMessagePreviewStrip.js +152 -0
  10. package/lib/module/components/messages/quotedMessage/QuotedMessagePreviewStrip.js.map +1 -0
  11. package/lib/module/components/messages/quotedMessage/index.js +79 -55
  12. package/lib/module/components/messages/quotedMessage/index.js.map +1 -1
  13. package/lib/module/components/messages/stickerMessage/index.js +38 -13
  14. package/lib/module/components/messages/stickerMessage/index.js.map +1 -1
  15. package/lib/module/components/messages/textMessage/index.js +126 -13
  16. package/lib/module/components/messages/textMessage/index.js.map +1 -1
  17. package/lib/module/components/messages/types.js.map +1 -1
  18. package/lib/module/core/useChatListener.js +1 -1
  19. package/lib/module/core/useChatListener.js.map +1 -1
  20. package/lib/module/hooks/message/useSendMessage.js +64 -3
  21. package/lib/module/hooks/message/useSendMessage.js.map +1 -1
  22. package/lib/module/hooks/query-keys.js +4 -0
  23. package/lib/module/hooks/query-keys.js.map +1 -1
  24. package/lib/module/hooks/useChatCompose.js +3 -2
  25. package/lib/module/hooks/useChatCompose.js.map +1 -1
  26. package/lib/module/screens/chat-detail/ChatComposer.js +170 -48
  27. package/lib/module/screens/chat-detail/ChatComposer.js.map +1 -1
  28. package/lib/module/screens/chat-detail/ChatListLegend.js +16 -7
  29. package/lib/module/screens/chat-detail/ChatListLegend.js.map +1 -1
  30. package/lib/module/screens/chat-detail/components/ChatMessageInput.js +23 -2
  31. package/lib/module/screens/chat-detail/components/ChatMessageInput.js.map +1 -1
  32. package/lib/module/screens/chat-detail/components/MentionHighlightAdapter.js +51 -0
  33. package/lib/module/screens/chat-detail/components/MentionHighlightAdapter.js.map +1 -0
  34. package/lib/module/screens/chat-detail/components/MentionSuggestionItem.js +49 -0
  35. package/lib/module/screens/chat-detail/components/MentionSuggestionItem.js.map +1 -0
  36. package/lib/module/screens/chat-detail/components/MentionSuggestionList.js +114 -0
  37. package/lib/module/screens/chat-detail/components/MentionSuggestionList.js.map +1 -0
  38. package/lib/module/screens/chat-detail/hooks/useChatComposerState.js +8 -0
  39. package/lib/module/screens/chat-detail/hooks/useChatComposerState.js.map +1 -1
  40. package/lib/module/screens/chat-detail/hooks/useMentionComposer.js +251 -0
  41. package/lib/module/screens/chat-detail/hooks/useMentionComposer.js.map +1 -0
  42. package/lib/module/screens/chat-detail/legend/LegendChatDay.js +4 -9
  43. package/lib/module/screens/chat-detail/legend/LegendChatDay.js.map +1 -1
  44. package/lib/module/screens/chat-detail/legend/LegendChatMessage.js +14 -2
  45. package/lib/module/screens/chat-detail/legend/LegendChatMessage.js.map +1 -1
  46. package/lib/module/services/mentionSearch.js +49 -0
  47. package/lib/module/services/mentionSearch.js.map +1 -0
  48. package/lib/module/services/message.js +6 -1
  49. package/lib/module/services/message.js.map +1 -1
  50. package/lib/module/translation/resources/i18n.js +5 -0
  51. package/lib/module/translation/resources/i18n.js.map +1 -1
  52. package/lib/module/types/chat.js.map +1 -1
  53. package/lib/module/types/mention.js +2 -0
  54. package/lib/module/types/mention.js.map +1 -0
  55. package/lib/module/utils/legendListMessage.js +9 -1
  56. package/lib/module/utils/legendListMessage.js.map +1 -1
  57. package/lib/module/utils/mentionSerializer.js +113 -0
  58. package/lib/module/utils/mentionSerializer.js.map +1 -0
  59. package/lib/module/utils/mentions/index.js +7 -0
  60. package/lib/module/utils/mentions/index.js.map +1 -0
  61. package/lib/module/utils/mentions/mentionDetector.js +49 -0
  62. package/lib/module/utils/mentions/mentionDetector.js.map +1 -0
  63. package/lib/module/utils/mentions/mentionDiff.js +66 -0
  64. package/lib/module/utils/mentions/mentionDiff.js.map +1 -0
  65. package/lib/module/utils/mentions/mentionRange.js +188 -0
  66. package/lib/module/utils/mentions/mentionRange.js.map +1 -0
  67. package/lib/module/utils/mentions/mentionTokenize.js +50 -0
  68. package/lib/module/utils/mentions/mentionTokenize.js.map +1 -0
  69. package/lib/module/utils/messageUtils.js +6 -1
  70. package/lib/module/utils/messageUtils.js.map +1 -1
  71. package/lib/module/utils/url.js +33 -0
  72. package/lib/module/utils/url.js.map +1 -1
  73. package/lib/typescript/src/components/ThreadCard/MentionBadge.d.ts +7 -0
  74. package/lib/typescript/src/components/ThreadCard/MentionBadge.d.ts.map +1 -0
  75. package/lib/typescript/src/components/ThreadCard/ThreadCard.d.ts.map +1 -1
  76. package/lib/typescript/src/components/messages/linkMessage/LinkPreviewCard.d.ts +16 -0
  77. package/lib/typescript/src/components/messages/linkMessage/LinkPreviewCard.d.ts.map +1 -0
  78. package/lib/typescript/src/components/messages/linkMessage/index.d.ts +2 -2
  79. package/lib/typescript/src/components/messages/linkMessage/index.d.ts.map +1 -1
  80. package/lib/typescript/src/components/messages/quotedMessage/QuotedMessagePreviewStrip.d.ts +13 -0
  81. package/lib/typescript/src/components/messages/quotedMessage/QuotedMessagePreviewStrip.d.ts.map +1 -0
  82. package/lib/typescript/src/components/messages/quotedMessage/index.d.ts.map +1 -1
  83. package/lib/typescript/src/components/messages/stickerMessage/index.d.ts +2 -2
  84. package/lib/typescript/src/components/messages/stickerMessage/index.d.ts.map +1 -1
  85. package/lib/typescript/src/components/messages/textMessage/index.d.ts +4 -2
  86. package/lib/typescript/src/components/messages/textMessage/index.d.ts.map +1 -1
  87. package/lib/typescript/src/components/messages/types.d.ts +1 -0
  88. package/lib/typescript/src/components/messages/types.d.ts.map +1 -1
  89. package/lib/typescript/src/hooks/message/useSendMessage.d.ts +5 -2
  90. package/lib/typescript/src/hooks/message/useSendMessage.d.ts.map +1 -1
  91. package/lib/typescript/src/hooks/query-keys.d.ts +4 -0
  92. package/lib/typescript/src/hooks/query-keys.d.ts.map +1 -1
  93. package/lib/typescript/src/hooks/useChatCompose.d.ts +2 -1
  94. package/lib/typescript/src/hooks/useChatCompose.d.ts.map +1 -1
  95. package/lib/typescript/src/screens/chat-detail/ChatComposer.d.ts.map +1 -1
  96. package/lib/typescript/src/screens/chat-detail/ChatListLegend.d.ts.map +1 -1
  97. package/lib/typescript/src/screens/chat-detail/components/ChatMessageInput.d.ts +10 -2
  98. package/lib/typescript/src/screens/chat-detail/components/ChatMessageInput.d.ts.map +1 -1
  99. package/lib/typescript/src/screens/chat-detail/components/MentionHighlightAdapter.d.ts +29 -0
  100. package/lib/typescript/src/screens/chat-detail/components/MentionHighlightAdapter.d.ts.map +1 -0
  101. package/lib/typescript/src/screens/chat-detail/components/MentionSuggestionItem.d.ts +8 -0
  102. package/lib/typescript/src/screens/chat-detail/components/MentionSuggestionItem.d.ts.map +1 -0
  103. package/lib/typescript/src/screens/chat-detail/components/MentionSuggestionList.d.ts +12 -0
  104. package/lib/typescript/src/screens/chat-detail/components/MentionSuggestionList.d.ts.map +1 -0
  105. package/lib/typescript/src/screens/chat-detail/hooks/useChatComposerState.d.ts +1 -1
  106. package/lib/typescript/src/screens/chat-detail/hooks/useChatComposerState.d.ts.map +1 -1
  107. package/lib/typescript/src/screens/chat-detail/hooks/useMentionComposer.d.ts +48 -0
  108. package/lib/typescript/src/screens/chat-detail/hooks/useMentionComposer.d.ts.map +1 -0
  109. package/lib/typescript/src/screens/chat-detail/legend/LegendChatDay.d.ts.map +1 -1
  110. package/lib/typescript/src/screens/chat-detail/legend/LegendChatMessage.d.ts +2 -1
  111. package/lib/typescript/src/screens/chat-detail/legend/LegendChatMessage.d.ts.map +1 -1
  112. package/lib/typescript/src/services/mentionSearch.d.ts +15 -0
  113. package/lib/typescript/src/services/mentionSearch.d.ts.map +1 -0
  114. package/lib/typescript/src/services/message.d.ts +1 -1
  115. package/lib/typescript/src/services/message.d.ts.map +1 -1
  116. package/lib/typescript/src/translation/resources/i18n.d.ts.map +1 -1
  117. package/lib/typescript/src/types/chat.d.ts +23 -0
  118. package/lib/typescript/src/types/chat.d.ts.map +1 -1
  119. package/lib/typescript/src/types/mention.d.ts +65 -0
  120. package/lib/typescript/src/types/mention.d.ts.map +1 -0
  121. package/lib/typescript/src/utils/legendListMessage.d.ts +4 -3
  122. package/lib/typescript/src/utils/legendListMessage.d.ts.map +1 -1
  123. package/lib/typescript/src/utils/mentionSerializer.d.ts +78 -0
  124. package/lib/typescript/src/utils/mentionSerializer.d.ts.map +1 -0
  125. package/lib/typescript/src/utils/mentions/index.d.ts +5 -0
  126. package/lib/typescript/src/utils/mentions/index.d.ts.map +1 -0
  127. package/lib/typescript/src/utils/mentions/mentionDetector.d.ts +18 -0
  128. package/lib/typescript/src/utils/mentions/mentionDetector.d.ts.map +1 -0
  129. package/lib/typescript/src/utils/mentions/mentionDiff.d.ts +20 -0
  130. package/lib/typescript/src/utils/mentions/mentionDiff.d.ts.map +1 -0
  131. package/lib/typescript/src/utils/mentions/mentionRange.d.ts +86 -0
  132. package/lib/typescript/src/utils/mentions/mentionRange.d.ts.map +1 -0
  133. package/lib/typescript/src/utils/mentions/mentionTokenize.d.ts +29 -0
  134. package/lib/typescript/src/utils/mentions/mentionTokenize.d.ts.map +1 -0
  135. package/lib/typescript/src/utils/messageUtils.d.ts.map +1 -1
  136. package/lib/typescript/src/utils/url.d.ts +12 -0
  137. package/lib/typescript/src/utils/url.d.ts.map +1 -1
  138. package/package.json +1 -1
  139. package/src/components/ThreadCard/MentionBadge.tsx +28 -0
  140. package/src/components/ThreadCard/ThreadCard.tsx +3 -0
  141. package/src/components/messages/linkMessage/LinkPreviewCard.tsx +92 -0
  142. package/src/components/messages/linkMessage/index.tsx +64 -121
  143. package/src/components/messages/quotedMessage/QuotedMessagePreviewStrip.tsx +168 -0
  144. package/src/components/messages/quotedMessage/index.tsx +95 -64
  145. package/src/components/messages/stickerMessage/index.tsx +40 -11
  146. package/src/components/messages/textMessage/index.tsx +159 -17
  147. package/src/components/messages/types.ts +1 -0
  148. package/src/core/useChatListener.ts +1 -1
  149. package/src/hooks/message/useSendMessage.ts +60 -1
  150. package/src/hooks/query-keys.ts +6 -0
  151. package/src/hooks/useChatCompose.ts +115 -107
  152. package/src/screens/chat-detail/ChatComposer.tsx +201 -67
  153. package/src/screens/chat-detail/ChatListLegend.tsx +19 -4
  154. package/src/screens/chat-detail/components/ChatMessageInput.tsx +35 -2
  155. package/src/screens/chat-detail/components/MentionHighlightAdapter.tsx +57 -0
  156. package/src/screens/chat-detail/components/MentionSuggestionItem.tsx +53 -0
  157. package/src/screens/chat-detail/components/MentionSuggestionList.tsx +133 -0
  158. package/src/screens/chat-detail/hooks/useChatComposerState.ts +7 -1
  159. package/src/screens/chat-detail/hooks/useMentionComposer.ts +344 -0
  160. package/src/screens/chat-detail/legend/LegendChatDay.tsx +6 -9
  161. package/src/screens/chat-detail/legend/LegendChatMessage.tsx +25 -2
  162. package/src/services/mentionSearch.ts +57 -0
  163. package/src/services/message.ts +9 -1
  164. package/src/translation/resources/i18n.ts +6 -0
  165. package/src/types/chat.ts +22 -0
  166. package/src/types/mention.ts +70 -0
  167. package/src/utils/legendListMessage.ts +13 -4
  168. package/src/utils/mentionSerializer.ts +155 -0
  169. package/src/utils/mentions/index.ts +16 -0
  170. package/src/utils/mentions/mentionDetector.ts +58 -0
  171. package/src/utils/mentions/mentionDiff.ts +95 -0
  172. package/src/utils/mentions/mentionRange.ts +207 -0
  173. package/src/utils/mentions/mentionTokenize.ts +53 -0
  174. package/src/utils/messageUtils.ts +6 -1
  175. package/src/utils/url.ts +30 -0
@@ -0,0 +1,53 @@
1
+ import type { Mention } from '../../types/mention';
2
+
3
+ export type Segment =
4
+ | { type: 'text'; text: string; start: number; end: number }
5
+ | { type: 'mention'; mention: Mention };
6
+
7
+ /**
8
+ * Converts edit-time state (flat string + Mention[] ranges) into an
9
+ * ordered list of plain-text runs and mention tokens — the shape both the
10
+ * composer's highlight renderer (Phase A3) and the sent-message bubble
11
+ * renderer (Phase B3) need to produce their styled `<Text>` children.
12
+ * Shared by both so the segment-splitting logic exists exactly once.
13
+ *
14
+ * O(m log m) sort + O(n) slicing (m = mention count, n = text length) —
15
+ * trivial at the sizes this feature targets (≤50 mentions, ≤2000 chars).
16
+ *
17
+ * Precondition: `mentions` is non-overlapping, guaranteed by Phase A1's own
18
+ * pipeline (insertMention/reconcileMentions never produce overlaps). The
19
+ * `m.start < cursor` skip below is a defensive backstop for
20
+ * externally-sourced data (a message loaded for editing, or an `ex` blob
21
+ * serialized by an older app version) — not a correctness dependency for
22
+ * the live composer.
23
+ */
24
+ export function tokenize(text: string, mentions: Mention[]): Segment[] {
25
+ const sorted = [...mentions].sort((a, b) => a.start - b.start);
26
+ const segments: Segment[] = [];
27
+ let cursor = 0;
28
+
29
+ for (const m of sorted) {
30
+ if (m.start < cursor) continue; // overlapping/malformed entry — skip rather than produce a negative-length slice
31
+ if (m.start > cursor) {
32
+ segments.push({
33
+ type: 'text',
34
+ text: text.slice(cursor, m.start),
35
+ start: cursor,
36
+ end: m.start,
37
+ });
38
+ }
39
+ segments.push({ type: 'mention', mention: m });
40
+ cursor = m.end;
41
+ }
42
+
43
+ if (cursor < text.length) {
44
+ segments.push({
45
+ type: 'text',
46
+ text: text.slice(cursor),
47
+ start: cursor,
48
+ end: text.length,
49
+ });
50
+ }
51
+
52
+ return segments;
53
+ }
@@ -272,7 +272,12 @@ export const getMessagePreview = (message?: MessageItem): string => {
272
272
  return urlText ? urlText : '';
273
273
 
274
274
  case MessageType.AtTextMessage:
275
- return extractTextContent(message);
275
+ // Bug: was calling extractTextContent(message) directly, which only
276
+ // checks message.textElem?.content (wrong elem for this type — always
277
+ // undefined here) before falling back to JSON.parse(message.content).
278
+ // atTextElem.text is the actual plain text for this message type —
279
+ // read it first, matching the QuoteMessage case right below.
280
+ return message?.atTextElem?.text || extractTextContent(message) || '';
276
281
 
277
282
  case MessageType.QuoteMessage:
278
283
  return message?.quoteElem?.text || extractTextContent(message) || '';
package/src/utils/url.ts CHANGED
@@ -33,6 +33,36 @@ export function extractUrls(text: string): string[] {
33
33
  return text.match(URL_REGEX) ?? [];
34
34
  }
35
35
 
36
+ export interface TextUrlPart {
37
+ text: string;
38
+ isUrl: boolean;
39
+ }
40
+
41
+ /**
42
+ * Splits `text` into an ordered run of plain/URL parts — pure data, no
43
+ * JSX, so both LinkMessage (a whole message that's just text+URLs) and
44
+ * TextMessage (a mention message whose plain-text *segments* may also
45
+ * contain a URL) can render URL styling from the same source instead of
46
+ * two divergent implementations.
47
+ */
48
+ export function splitTextByUrls(text: string, urls: string[]): TextUrlPart[] {
49
+ if (!urls.length) return [{ text, isUrl: false }];
50
+
51
+ const parts: TextUrlPart[] = [];
52
+ let remaining = text;
53
+
54
+ for (const url of urls) {
55
+ const idx = remaining.indexOf(url);
56
+ if (idx === -1) continue;
57
+ if (idx > 0) parts.push({ text: remaining.slice(0, idx), isUrl: false });
58
+ parts.push({ text: url, isUrl: true });
59
+ remaining = remaining.slice(idx + url.length);
60
+ }
61
+
62
+ if (remaining) parts.push({ text: remaining, isUrl: false });
63
+ return parts;
64
+ }
65
+
36
66
  export function normalizeUrl(url: string) {
37
67
  if (!/^https?:\/\//i.test(url)) {
38
68
  return `https://${url}`;