@droppii-org/chat-mobile 0.2.78 → 0.2.80

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 (140) hide show
  1. package/lib/module/components/messages/BubbleTail.js +31 -0
  2. package/lib/module/components/messages/BubbleTail.js.map +1 -0
  3. package/lib/module/components/messages/BubbleTailRow.js +46 -0
  4. package/lib/module/components/messages/BubbleTailRow.js.map +1 -0
  5. package/lib/module/components/messages/bubbleTail.utils.js +19 -0
  6. package/lib/module/components/messages/bubbleTail.utils.js.map +1 -0
  7. package/lib/module/components/messages/fileMessage/index.js +72 -65
  8. package/lib/module/components/messages/fileMessage/index.js.map +1 -1
  9. package/lib/module/components/messages/imageMessage/index.js +23 -17
  10. package/lib/module/components/messages/imageMessage/index.js.map +1 -1
  11. package/lib/module/components/messages/linkMessage/index.js +11 -23
  12. package/lib/module/components/messages/linkMessage/index.js.map +1 -1
  13. package/lib/module/components/messages/mergedMessage/index.js +14 -7
  14. package/lib/module/components/messages/mergedMessage/index.js.map +1 -1
  15. package/lib/module/components/messages/quotedMessage/index.js +11 -23
  16. package/lib/module/components/messages/quotedMessage/index.js.map +1 -1
  17. package/lib/module/components/messages/revokedMessage/index.js +14 -7
  18. package/lib/module/components/messages/revokedMessage/index.js.map +1 -1
  19. package/lib/module/components/messages/stickerMessage/index.js +13 -7
  20. package/lib/module/components/messages/stickerMessage/index.js.map +1 -1
  21. package/lib/module/components/messages/textMessage/index.js +11 -26
  22. package/lib/module/components/messages/textMessage/index.js.map +1 -1
  23. package/lib/module/components/messages/types.js.map +1 -1
  24. package/lib/module/components/messages/videoMessage/index.js +16 -8
  25. package/lib/module/components/messages/videoMessage/index.js.map +1 -1
  26. package/lib/module/core/useChatListener.js +11 -0
  27. package/lib/module/core/useChatListener.js.map +1 -1
  28. package/lib/module/hooks/groups/useDismissGroup.js +2 -1
  29. package/lib/module/hooks/groups/useDismissGroup.js.map +1 -1
  30. package/lib/module/hooks/groups/useGroupAccessGuard.js +145 -0
  31. package/lib/module/hooks/groups/useGroupAccessGuard.js.map +1 -0
  32. package/lib/module/screens/ChatInfo/ChatInfoDescriptionRow.js +4 -1
  33. package/lib/module/screens/ChatInfo/ChatInfoDescriptionRow.js.map +1 -1
  34. package/lib/module/screens/chat-detail/ChatDetail.js +12 -10
  35. package/lib/module/screens/chat-detail/ChatDetail.js.map +1 -1
  36. package/lib/module/screens/chat-detail/ChatDetailHeader.js +3 -9
  37. package/lib/module/screens/chat-detail/ChatDetailHeader.js.map +1 -1
  38. package/lib/module/screens/chat-detail/ChatListLegend.js +71 -21
  39. package/lib/module/screens/chat-detail/ChatListLegend.js.map +1 -1
  40. package/lib/module/screens/chat-detail/legend/LegendChatDay.js +8 -2
  41. package/lib/module/screens/chat-detail/legend/LegendChatDay.js.map +1 -1
  42. package/lib/module/screens/chat-detail/legend/LegendChatMessage.js +38 -13
  43. package/lib/module/screens/chat-detail/legend/LegendChatMessage.js.map +1 -1
  44. package/lib/module/screens/inbox/CommunityTab.js +5 -2
  45. package/lib/module/screens/inbox/CommunityTab.js.map +1 -1
  46. package/lib/module/screens/inbox/MessagesTab.js +2 -2
  47. package/lib/module/screens/inbox/MessagesTab.js.map +1 -1
  48. package/lib/module/store/conversation.js +18 -20
  49. package/lib/module/store/conversation.js.map +1 -1
  50. package/lib/module/translation/resources/i18n.js +4 -1
  51. package/lib/module/translation/resources/i18n.js.map +1 -1
  52. package/lib/module/utils/conversation.js +4 -1
  53. package/lib/module/utils/conversation.js.map +1 -1
  54. package/lib/module/utils/legendListMessage.js +86 -12
  55. package/lib/module/utils/legendListMessage.js.map +1 -1
  56. package/lib/module/utils/message.js +19 -1
  57. package/lib/module/utils/message.js.map +1 -1
  58. package/lib/module/utils/messageUtils.js +7 -1
  59. package/lib/module/utils/messageUtils.js.map +1 -1
  60. package/lib/typescript/src/components/messages/BubbleTail.d.ts +13 -0
  61. package/lib/typescript/src/components/messages/BubbleTail.d.ts.map +1 -0
  62. package/lib/typescript/src/components/messages/BubbleTailRow.d.ts +25 -0
  63. package/lib/typescript/src/components/messages/BubbleTailRow.d.ts.map +1 -0
  64. package/lib/typescript/src/components/messages/bubbleTail.utils.d.ts +11 -0
  65. package/lib/typescript/src/components/messages/bubbleTail.utils.d.ts.map +1 -0
  66. package/lib/typescript/src/components/messages/fileMessage/index.d.ts +1 -1
  67. package/lib/typescript/src/components/messages/fileMessage/index.d.ts.map +1 -1
  68. package/lib/typescript/src/components/messages/imageMessage/index.d.ts +1 -1
  69. package/lib/typescript/src/components/messages/imageMessage/index.d.ts.map +1 -1
  70. package/lib/typescript/src/components/messages/linkMessage/index.d.ts +1 -1
  71. package/lib/typescript/src/components/messages/linkMessage/index.d.ts.map +1 -1
  72. package/lib/typescript/src/components/messages/mergedMessage/index.d.ts +1 -1
  73. package/lib/typescript/src/components/messages/mergedMessage/index.d.ts.map +1 -1
  74. package/lib/typescript/src/components/messages/quotedMessage/index.d.ts.map +1 -1
  75. package/lib/typescript/src/components/messages/revokedMessage/index.d.ts +1 -1
  76. package/lib/typescript/src/components/messages/revokedMessage/index.d.ts.map +1 -1
  77. package/lib/typescript/src/components/messages/stickerMessage/index.d.ts +1 -1
  78. package/lib/typescript/src/components/messages/stickerMessage/index.d.ts.map +1 -1
  79. package/lib/typescript/src/components/messages/textMessage/index.d.ts +1 -1
  80. package/lib/typescript/src/components/messages/textMessage/index.d.ts.map +1 -1
  81. package/lib/typescript/src/components/messages/types.d.ts +3 -0
  82. package/lib/typescript/src/components/messages/types.d.ts.map +1 -1
  83. package/lib/typescript/src/components/messages/videoMessage/index.d.ts +1 -1
  84. package/lib/typescript/src/components/messages/videoMessage/index.d.ts.map +1 -1
  85. package/lib/typescript/src/core/useChatListener.d.ts.map +1 -1
  86. package/lib/typescript/src/hooks/groups/useDismissGroup.d.ts.map +1 -1
  87. package/lib/typescript/src/hooks/groups/useGroupAccessGuard.d.ts +10 -0
  88. package/lib/typescript/src/hooks/groups/useGroupAccessGuard.d.ts.map +1 -0
  89. package/lib/typescript/src/screens/ChatInfo/ChatInfoDescriptionRow.d.ts.map +1 -1
  90. package/lib/typescript/src/screens/chat-detail/ChatDetail.d.ts.map +1 -1
  91. package/lib/typescript/src/screens/chat-detail/ChatDetailHeader.d.ts +1 -1
  92. package/lib/typescript/src/screens/chat-detail/ChatDetailHeader.d.ts.map +1 -1
  93. package/lib/typescript/src/screens/chat-detail/ChatListLegend.d.ts.map +1 -1
  94. package/lib/typescript/src/screens/chat-detail/legend/LegendChatDay.d.ts +6 -1
  95. package/lib/typescript/src/screens/chat-detail/legend/LegendChatDay.d.ts.map +1 -1
  96. package/lib/typescript/src/screens/chat-detail/legend/LegendChatMessage.d.ts +14 -1
  97. package/lib/typescript/src/screens/chat-detail/legend/LegendChatMessage.d.ts.map +1 -1
  98. package/lib/typescript/src/screens/chat-detail/types.d.ts +0 -1
  99. package/lib/typescript/src/screens/chat-detail/types.d.ts.map +1 -1
  100. package/lib/typescript/src/store/conversation.d.ts.map +1 -1
  101. package/lib/typescript/src/translation/resources/i18n.d.ts.map +1 -1
  102. package/lib/typescript/src/utils/conversation.d.ts.map +1 -1
  103. package/lib/typescript/src/utils/legendListMessage.d.ts +19 -4
  104. package/lib/typescript/src/utils/legendListMessage.d.ts.map +1 -1
  105. package/lib/typescript/src/utils/message.d.ts +17 -0
  106. package/lib/typescript/src/utils/message.d.ts.map +1 -1
  107. package/lib/typescript/src/utils/messageUtils.d.ts +1 -0
  108. package/lib/typescript/src/utils/messageUtils.d.ts.map +1 -1
  109. package/package.json +1 -1
  110. package/src/components/messages/BubbleTail.tsx +35 -0
  111. package/src/components/messages/BubbleTailRow.tsx +64 -0
  112. package/src/components/messages/bubbleTail.utils.ts +21 -0
  113. package/src/components/messages/fileMessage/index.tsx +90 -83
  114. package/src/components/messages/imageMessage/index.tsx +26 -23
  115. package/src/components/messages/linkMessage/index.tsx +6 -18
  116. package/src/components/messages/mergedMessage/index.tsx +27 -15
  117. package/src/components/messages/quotedMessage/index.tsx +7 -19
  118. package/src/components/messages/revokedMessage/index.tsx +23 -14
  119. package/src/components/messages/stickerMessage/index.tsx +16 -11
  120. package/src/components/messages/textMessage/index.tsx +6 -22
  121. package/src/components/messages/types.ts +3 -0
  122. package/src/components/messages/videoMessage/index.tsx +13 -10
  123. package/src/core/useChatListener.ts +14 -0
  124. package/src/hooks/groups/useDismissGroup.tsx +1 -0
  125. package/src/hooks/groups/useGroupAccessGuard.ts +182 -0
  126. package/src/screens/ChatInfo/ChatInfoDescriptionRow.tsx +5 -1
  127. package/src/screens/chat-detail/ChatDetail.tsx +11 -13
  128. package/src/screens/chat-detail/ChatDetailHeader.tsx +2 -6
  129. package/src/screens/chat-detail/ChatListLegend.tsx +97 -28
  130. package/src/screens/chat-detail/legend/LegendChatDay.tsx +25 -15
  131. package/src/screens/chat-detail/legend/LegendChatMessage.tsx +62 -12
  132. package/src/screens/chat-detail/types.ts +0 -1
  133. package/src/screens/inbox/CommunityTab.tsx +2 -2
  134. package/src/screens/inbox/MessagesTab.tsx +1 -1
  135. package/src/store/conversation.ts +14 -18
  136. package/src/translation/resources/i18n.ts +4 -0
  137. package/src/utils/conversation.ts +6 -3
  138. package/src/utils/legendListMessage.ts +123 -14
  139. package/src/utils/message.ts +19 -1
  140. package/src/utils/messageUtils.ts +9 -1
@@ -1,6 +1,7 @@
1
1
  import type { ReactNode } from 'react';
2
2
  import type { MessageItem } from '@droppii/openim-rn-client-sdk';
3
3
  import type { MediaItem } from '../../../hooks/useMediaViewer';
4
+ import type { GroupPosition } from '../../../utils/legendListMessage';
4
5
  interface LegendChatMessageProps {
5
6
  message: MessageItem;
6
7
  isOutgoing: boolean;
@@ -12,7 +13,19 @@ interface LegendChatMessageProps {
12
13
  onLongPress?: () => void;
13
14
  customMessageItemFactory?: (m: MessageItem) => ReactNode;
14
15
  isHighlighted?: boolean;
16
+ /** Sender name above the bubble — first message of an incoming cluster. */
17
+ showName?: boolean;
18
+ /** Sender avatar beside the bubble — last message of an incoming cluster. */
19
+ showAvatar?: boolean;
20
+ /**
21
+ * Reserve the avatar column. True for every incoming message in a group
22
+ * conversation, not just the one carrying the avatar, so that the middle of
23
+ * a cluster stays aligned with its last message.
24
+ */
25
+ showSenderGutter?: boolean;
26
+ /** Position within its same-sender cluster — drives the bubble tail. */
27
+ groupPosition?: GroupPosition;
15
28
  }
16
- export declare const LegendChatMessage: import("react").MemoExoticComponent<({ message, isOutgoing, createdAtTime, onMediaPress, onPressUrl, onRetry, onPress, onLongPress, customMessageItemFactory, isHighlighted, }: LegendChatMessageProps) => string | number | bigint | true | Iterable<ReactNode> | Promise<string | number | bigint | boolean | import("react").ReactPortal | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<ReactNode>> | import("react").JSX.Element>;
29
+ export declare const LegendChatMessage: import("react").MemoExoticComponent<({ message, isOutgoing, createdAtTime, onMediaPress, onPressUrl, onRetry, onPress, onLongPress, customMessageItemFactory, isHighlighted, showName, showAvatar, showSenderGutter, groupPosition, }: LegendChatMessageProps) => string | number | bigint | true | Iterable<ReactNode> | Promise<string | number | bigint | boolean | import("react").ReactPortal | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<ReactNode>> | import("react").JSX.Element>;
17
30
  export {};
18
31
  //# sourceMappingURL=LegendChatMessage.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"LegendChatMessage.d.ts","sourceRoot":"","sources":["../../../../../../src/screens/chat-detail/legend/LegendChatMessage.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAoC,SAAS,EAAE,MAAM,OAAO,CAAC;AAEzE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAGjE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAqB/D,UAAU,sBAAsB;IAC9B,OAAO,EAAE,WAAW,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5D,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,IAAI,CAAC;IACzC,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,IAAI,CAAC;IACzC,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IACzB,wBAAwB,CAAC,EAAE,CAAC,CAAC,EAAE,WAAW,KAAK,SAAS,CAAC;IACzD,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAsCD,eAAO,MAAM,iBAAiB,kLAYzB,sBAAsB,wRAqE1B,CAAC"}
1
+ {"version":3,"file":"LegendChatMessage.d.ts","sourceRoot":"","sources":["../../../../../../src/screens/chat-detail/legend/LegendChatMessage.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAoC,SAAS,EAAE,MAAM,OAAO,CAAC;AAEzE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAGjE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAe/D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAC;AAStE,UAAU,sBAAsB;IAC9B,OAAO,EAAE,WAAW,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5D,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,IAAI,CAAC;IACzC,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,IAAI,CAAC;IACzC,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IACzB,wBAAwB,CAAC,EAAE,CAAC,CAAC,EAAE,WAAW,KAAK,SAAS,CAAC;IACzD,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,6EAA6E;IAC7E,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,wEAAwE;IACxE,aAAa,CAAC,EAAE,aAAa,CAAC;CAC/B;AA4BD,eAAO,MAAM,iBAAiB,yOAgBzB,sBAAsB,wRA4F1B,CAAC"}
@@ -40,7 +40,6 @@ export interface ChatDetailHeaderProps {
40
40
  onPressAvatar?: () => void;
41
41
  conversationId: string;
42
42
  targetUserId?: string;
43
- targetGroupId?: string;
44
43
  }
45
44
  export interface ChatQuickActionsRenderParams {
46
45
  actions: DChatQuickAction[];
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../src/screens/chat-detail/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../src/screens/chat-detail/types.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"conversation.d.ts","sourceRoot":"","sources":["../../../../src/store/conversation.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAEtE,KAAK,cAAc,GAAG,MAAM,CAAC;AAE7B,MAAM,WAAW,iBAAiB;IAChC,qBAAqB,CAAC,EAAE,cAAc,CAAC;IACvC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,sBAAsB,CACpB,EAAE,CAAC,EAAE,cAAc,EACnB,MAAM,CAAC,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,MAAM,GACf,IAAI,CAAC;IACR,sBAAsB,IAAI,gBAAgB,GAAG,SAAS,CAAC;IACvD,IAAI,EAAE,cAAc,EAAE,CAAC;IACvB,GAAG,EAAE,MAAM,CAAC,cAAc,EAAE,gBAAgB,CAAC,CAAC;IAC9C,6FAA6F;IAC7F,qBAAqB,EAAE,MAAM,CAAC;IAC9B,kBAAkB,CAAC,EAAE,EAAE,cAAc,EAAE,IAAI,EAAE,OAAO,CAAC,gBAAgB,CAAC,GAAG,IAAI,CAAC;IAC9E,mBAAmB,CAAC,aAAa,EAAE,gBAAgB,EAAE,GAAG,IAAI,CAAC;IAC7D;;;OAGG;IACH,kBAAkB,CAAC,EAAE,EAAE,cAAc,GAAG,IAAI,CAAC;IAC7C,sCAAsC;IACtC,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/C,KAAK,IAAI,IAAI,CAAC;CACf;AAED,eAAO,MAAM,oBAAoB,gFAwE9B,CAAC;AAEJ,eAAO,MAAM,eAAe,GAAI,IAAI,MAAM,KAAG,gBAAgB,GAAG,SAE/D,CAAC"}
1
+ {"version":3,"file":"conversation.d.ts","sourceRoot":"","sources":["../../../../src/store/conversation.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAEtE,KAAK,cAAc,GAAG,MAAM,CAAC;AAE7B,MAAM,WAAW,iBAAiB;IAChC,qBAAqB,CAAC,EAAE,cAAc,CAAC;IACvC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,sBAAsB,CACpB,EAAE,CAAC,EAAE,cAAc,EACnB,MAAM,CAAC,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,MAAM,GACf,IAAI,CAAC;IACR,sBAAsB,IAAI,gBAAgB,GAAG,SAAS,CAAC;IACvD,IAAI,EAAE,cAAc,EAAE,CAAC;IACvB,GAAG,EAAE,MAAM,CAAC,cAAc,EAAE,gBAAgB,CAAC,CAAC;IAC9C,6FAA6F;IAC7F,qBAAqB,EAAE,MAAM,CAAC;IAC9B,kBAAkB,CAAC,EAAE,EAAE,cAAc,EAAE,IAAI,EAAE,OAAO,CAAC,gBAAgB,CAAC,GAAG,IAAI,CAAC;IAC9E,mBAAmB,CAAC,aAAa,EAAE,gBAAgB,EAAE,GAAG,IAAI,CAAC;IAC7D;;;OAGG;IACH,kBAAkB,CAAC,EAAE,EAAE,cAAc,GAAG,IAAI,CAAC;IAC7C,sCAAsC;IACtC,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/C,KAAK,IAAI,IAAI,CAAC;CACf;AAED,eAAO,MAAM,oBAAoB,gFAoE9B,CAAC;AAEJ,eAAO,MAAM,eAAe,GAAI,IAAI,MAAM,KAAG,gBAAgB,GAAG,SAE/D,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"i18n.d.ts","sourceRoot":"","sources":["../../../../../src/translation/resources/i18n.ts"],"names":[],"mappings":";;;AAqNA,wBAEE"}
1
+ {"version":3,"file":"i18n.d.ts","sourceRoot":"","sources":["../../../../../src/translation/resources/i18n.ts"],"names":[],"mappings":";;;AAyNA,wBAEE"}
@@ -1 +1 @@
1
- {"version":3,"file":"conversation.d.ts","sourceRoot":"","sources":["../../../../src/utils/conversation.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,WAAW,EACX,KAAK,gBAAgB,EACtB,MAAM,+BAA+B,CAAC;AAEvC,eAAO,MAAM,mBAAmB,GAC9B,GAAG,gBAAgB,EACnB,GAAG,gBAAgB,WAcpB,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAC5B,aAAa,WAAW,EACxB,WAAW,MAAM,EACjB,aAAa,MAAM,WAUpB,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAI,KAAK,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC;;;CAKrE,CAAC;AAEF,eAAO,MAAM,QAAQ,GAAI,eAAe,gBAAgB,QAWvD,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAC9B,eAAe,IAAI,CAAC,gBAAgB,EAAE,kBAAkB,GAAG,UAAU,CAAC,YAGvE,CAAC"}
1
+ {"version":3,"file":"conversation.d.ts","sourceRoot":"","sources":["../../../../src/utils/conversation.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,WAAW,EACX,KAAK,gBAAgB,EACtB,MAAM,+BAA+B,CAAC;AAEvC,eAAO,MAAM,mBAAmB,GAC9B,GAAG,gBAAgB,EACnB,GAAG,gBAAgB,WAcpB,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAC5B,aAAa,WAAW,EACxB,WAAW,MAAM,EACjB,aAAa,MAAM,WAUpB,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAI,KAAK,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC;;;CAQrE,CAAC;AAEF,eAAO,MAAM,QAAQ,GAAI,eAAe,gBAAgB,QAWvD,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAC9B,eAAe,IAAI,CAAC,gBAAgB,EAAE,kBAAkB,GAAG,UAAU,CAAC,YAGvE,CAAC"}
@@ -3,18 +3,33 @@ import { type MessageItem } from '@droppii/openim-rn-client-sdk';
3
3
  * Extract message text based on content type
4
4
  */
5
5
  export declare const getMessageText: (message: MessageItem) => string;
6
+ /** Where a message sits inside its run of consecutive same-sender messages. */
7
+ export type GroupPosition = 'first' | 'middle' | 'last' | 'solo';
6
8
  export interface PrecomputedMessageData {
7
9
  messageId: string;
8
10
  dayStart: boolean;
11
+ /**
12
+ * More than GROUP_TIME_GAP has passed since the previous message. The list
13
+ * marks these with a time label: the cluster break is real but, unlike a day
14
+ * change, nothing else on screen would show why the run stopped.
15
+ */
16
+ timeBreak: boolean;
9
17
  createdAt: number;
18
+ groupPosition: GroupPosition;
19
+ }
20
+ export interface PrecomputeOptions {
21
+ isBotConversation?: boolean;
22
+ currentUserId?: string;
10
23
  }
11
24
  /**
12
- * Precompute all message rendering data in single pass O(n)
13
- * Eliminates redundant Date creation and type resolution during render
25
+ * Precompute per-message render data (day dividers + cluster position) so
26
+ * renderItem stays allocation-free.
14
27
  *
15
- * Returns: Map of messageId -> {dayStart, messageType, createdAt}
28
+ * Runs in two passes: day starts first, because cluster boundaries depend on
29
+ * them — a divider between two messages separates them however close in time
30
+ * they are.
16
31
  */
17
- export declare const precomputeLegendListData: (messages: MessageItem[]) => Map<string, PrecomputedMessageData>;
32
+ export declare const precomputeLegendListData: (messages: MessageItem[], { isBotConversation, currentUserId }?: PrecomputeOptions) => Map<string, PrecomputedMessageData>;
18
33
  /**
19
34
  * Legacy: Use precomputeLegendListData instead
20
35
  * Kept for backward compatibility
@@ -1 +1 @@
1
- {"version":3,"file":"legendListMessage.d.ts","sourceRoot":"","sources":["../../../../src/utils/legendListMessage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAE9E;;GAEG;AACH,eAAO,MAAM,cAAc,GAAI,SAAS,WAAW,KAAG,MAkCrD,CAAC;AAEF,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB,GACnC,UAAU,WAAW,EAAE,KACtB,GAAG,CAAC,MAAM,EAAE,sBAAsB,CAwBpC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,gBAAgB,GAC3B,UAAU,WAAW,EAAE,KACtB,GAAG,CAAC,MAAM,EAAE,OAAO,CAYrB,CAAC"}
1
+ {"version":3,"file":"legendListMessage.d.ts","sourceRoot":"","sources":["../../../../src/utils/legendListMessage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAI9E;;GAEG;AACH,eAAO,MAAM,cAAc,GAAI,SAAS,WAAW,KAAG,MAkCrD,CAAC;AAEF,+EAA+E;AAC/E,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,GAAG,MAAM,CAAC;AAEjE,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;IAClB;;;;OAIG;IACH,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,aAAa,CAAC;CAC9B;AAsCD,MAAM,WAAW,iBAAiB;IAChC,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,wBAAwB,GACnC,UAAU,WAAW,EAAE,EACvB,uCAA8C,iBAAsB,KACnE,GAAG,CAAC,MAAM,EAAE,sBAAsB,CA6EpC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,gBAAgB,GAC3B,UAAU,WAAW,EAAE,KACtB,GAAG,CAAC,MAAM,EAAE,OAAO,CAYrB,CAAC"}
@@ -1,4 +1,21 @@
1
1
  import { type ConversationItem, type MessageItem } from '@droppii/openim-rn-client-sdk';
2
+ /**
3
+ * Canonical timestamp for a message. `sendTime` is 0 until the SDK stamps an
4
+ * outgoing message, so `createTime` covers the in-flight window. This is the
5
+ * key the list is sorted by — anything reasoning about message order must use
6
+ * it too, or it will disagree with the order actually rendered.
7
+ */
8
+ export declare const getMessageTime: (message: MessageItem) => number;
9
+ /**
10
+ * Stable id for a message inside a rendered list.
11
+ *
12
+ * A message that has not round-tripped through the server yet may carry
13
+ * neither id, so position and timestamp stand in. Every consumer that looks a
14
+ * message up by id must derive it the same way — the precompute map is keyed
15
+ * on this, so a divergent formula silently misses and the message renders
16
+ * without its day divider or cluster position.
17
+ */
18
+ export declare const getMessageRenderId: (message: MessageItem, index: number) => string;
2
19
  export declare const mergeMessages: (current: MessageItem[], incoming: MessageItem[]) => MessageItem[];
3
20
  export declare const normalizeCreatedMessage: (message: MessageItem | string) => MessageItem;
4
21
  export type HistoryPaginationAnchor = {
@@ -1 +1 @@
1
- {"version":3,"file":"message.d.ts","sourceRoot":"","sources":["../../../../src/utils/message.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,gBAAgB,EACrB,KAAK,WAAW,EACjB,MAAM,+BAA+B,CAAC;AASvC,eAAO,MAAM,aAAa,GACxB,SAAS,WAAW,EAAE,EACtB,UAAU,WAAW,EAAE,KACtB,WAAW,EAab,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAClC,SAAS,WAAW,GAAG,MAAM,KAC5B,WAYF,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,eAAO,MAAM,wBAAwB,GACnC,SAAS;IAAE,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,EAChC,kBAAkB,WAAW,KAC5B,MAMF,CAAC;AAEF,eAAO,MAAM,0BAA0B,GACrC,UAAU,WAAW,EAAE,KACtB,uBAAuB,GAAG,IAkB5B,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAChC,SAAS,WAAW,EAAE,EACtB,UAAU,WAAW,EAAE,KACtB,OASF,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAChC,SAAS,WAAW,EACpB,iBAAiB,MAAM,EACvB,eAAe,MAAM,KACpB,OA2BF,CAAC;AAEF,eAAO,MAAM,aAAa,GAAI,eAAe,gBAAgB;;;CAW5D,CAAC"}
1
+ {"version":3,"file":"message.d.ts","sourceRoot":"","sources":["../../../../src/utils/message.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,gBAAgB,EACrB,KAAK,WAAW,EACjB,MAAM,+BAA+B,CAAC;AAGvC;;;;;GAKG;AACH,eAAO,MAAM,cAAc,GAAI,SAAS,WAAW,WACN,CAAC;AAK9C;;;;;;;;GAQG;AACH,eAAO,MAAM,kBAAkB,GAAI,SAAS,WAAW,EAAE,OAAO,MAAM,WACA,CAAC;AAEvE,eAAO,MAAM,aAAa,GACxB,SAAS,WAAW,EAAE,EACtB,UAAU,WAAW,EAAE,KACtB,WAAW,EAab,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAClC,SAAS,WAAW,GAAG,MAAM,KAC5B,WAYF,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,eAAO,MAAM,wBAAwB,GACnC,SAAS;IAAE,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,EAChC,kBAAkB,WAAW,KAC5B,MAMF,CAAC;AAEF,eAAO,MAAM,0BAA0B,GACrC,UAAU,WAAW,EAAE,KACtB,uBAAuB,GAAG,IAkB5B,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAChC,SAAS,WAAW,EAAE,EACtB,UAAU,WAAW,EAAE,KACtB,OASF,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAChC,SAAS,WAAW,EACpB,iBAAiB,MAAM,EACvB,eAAe,MAAM,KACpB,OA2BF,CAAC;AAEF,eAAO,MAAM,aAAa,GAAI,eAAe,gBAAgB;;;CAW5D,CAAC"}
@@ -9,6 +9,7 @@ export declare const GROUP_NOTIFICATION_TEXT: Partial<Record<MessageType, {
9
9
  previewKey: string;
10
10
  bySenderKey: string;
11
11
  }>>;
12
+ export declare const GROUP_NOTIFICATION_TYPES: MessageType[];
12
13
  export interface ResolvedNotificationText {
13
14
  previewKey: string;
14
15
  bySenderKey: string;
@@ -1 +1 @@
1
- {"version":3,"file":"messageUtils.d.ts","sourceRoot":"","sources":["../../../../src/utils/messageUtils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,WAAW,EAEX,KAAK,gBAAgB,EACrB,KAAK,WAAW,EACjB,MAAM,+BAA+B,CAAC;AAIvC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,eAAO,MAAM,gBAAgB,GAAI,SAAS,WAAW,KAAG,OACL,CAAC;AAKpD,eAAO,MAAM,uBAAuB,EAAE,OAAO,CAC3C,MAAM,CAAC,WAAW,EAAE;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC,CAqEjE,CAAC;AA2BF,MAAM,WAAW,wBAAwB;IACvC,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAQD,eAAO,MAAM,uBAAuB,GAClC,SAAS,WAAW,KACnB,wBAAwB,GAAG,SA8D7B,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAAI,SAAS,WAAW,KAAG,MAYzD,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAI,UAAU,WAAW,KAAG,MAyFzD,CAAC;AAEF,eAAO,MAAM,0BAA0B,GACrC,UAAU,WAAW,KACpB,SAUF,CAAC;AAEF,eAAO,MAAM,sBAAsB,GACjC,UAAU,WAAW,KACpB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,SAAS,CAAA;CAGrC,CAAC;AAEH,MAAM,MAAM,sBAAsB,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;AAEzE,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,sBAAsB,CAAC;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAmBD,eAAO,MAAM,uBAAuB,GAClC,SAAS,WAAW,KACnB,oBA0DF,CAAC;AAKF,eAAO,MAAM,6BAA6B,GACxC,SAAS,WAAW,KACnB,MAAM,GAAG,SAaX,CAAC;AAEF,eAAO,MAAM,aAAa,GACxB,SAAS,WAAW,EACpB,gBAAgB,MAAM,EACtB,eAAe,gBAAgB,KAC9B,MAUF,CAAC;AAEF,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,WAAW,GAAG,SAAS,CAAC;IACjC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,gBAAgB,CAAC;IAChC,6BAA6B,CAAC,EAAE,OAAO,CAAC;CACzC;AAED,eAAO,MAAM,kBAAkB,GAAI,0EAKhC,wBAAwB,KAAG,MAyB7B,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAC7B,UAAU,WAAW,EACrB,gBAAgB,MAAM,EACtB,eAAe,gBAAgB,EAC/B,SAAS,OAAO,KACf,MAOF,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAI,KAAK,MAAM,KAAG,YAAY,GAAG,SAS7D,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,MAAM,MAAM,EAAE,WAAW,MAAM,KAAG,MAUhE,CAAC"}
1
+ {"version":3,"file":"messageUtils.d.ts","sourceRoot":"","sources":["../../../../src/utils/messageUtils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,WAAW,EAEX,KAAK,gBAAgB,EACrB,KAAK,WAAW,EACjB,MAAM,+BAA+B,CAAC;AAIvC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,eAAO,MAAM,gBAAgB,GAAI,SAAS,WAAW,KAAG,OACL,CAAC;AAKpD,eAAO,MAAM,uBAAuB,EAAE,OAAO,CAC3C,MAAM,CAAC,WAAW,EAAE;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC,CAqEjE,CAAC;AAMF,eAAO,MAAM,wBAAwB,EAEpB,WAAW,EAAE,CAAC;AA2B/B,MAAM,WAAW,wBAAwB;IACvC,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAQD,eAAO,MAAM,uBAAuB,GAClC,SAAS,WAAW,KACnB,wBAAwB,GAAG,SA8D7B,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAAI,SAAS,WAAW,KAAG,MAYzD,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAI,UAAU,WAAW,KAAG,MAyFzD,CAAC;AAEF,eAAO,MAAM,0BAA0B,GACrC,UAAU,WAAW,KACpB,SAUF,CAAC;AAEF,eAAO,MAAM,sBAAsB,GACjC,UAAU,WAAW,KACpB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,SAAS,CAAA;CAGrC,CAAC;AAEH,MAAM,MAAM,sBAAsB,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;AAEzE,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,sBAAsB,CAAC;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAmBD,eAAO,MAAM,uBAAuB,GAClC,SAAS,WAAW,KACnB,oBA0DF,CAAC;AAKF,eAAO,MAAM,6BAA6B,GACxC,SAAS,WAAW,KACnB,MAAM,GAAG,SAaX,CAAC;AAEF,eAAO,MAAM,aAAa,GACxB,SAAS,WAAW,EACpB,gBAAgB,MAAM,EACtB,eAAe,gBAAgB,KAC9B,MAUF,CAAC;AAEF,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,WAAW,GAAG,SAAS,CAAC;IACjC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,gBAAgB,CAAC;IAChC,6BAA6B,CAAC,EAAE,OAAO,CAAC;CACzC;AAED,eAAO,MAAM,kBAAkB,GAAI,0EAKhC,wBAAwB,KAAG,MAyB7B,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAC7B,UAAU,WAAW,EACrB,gBAAgB,MAAM,EACtB,eAAe,gBAAgB,EAC/B,SAAS,OAAO,KACf,MAOF,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAI,KAAK,MAAM,KAAG,YAAY,GAAG,SAS7D,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,MAAM,MAAM,EAAE,WAAW,MAAM,KAAG,MAUhE,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@droppii-org/chat-mobile",
3
- "version": "0.2.78",
3
+ "version": "0.2.80",
4
4
  "description": "Droppii chat mobile",
5
5
  "keywords": [
6
6
  "react-native",
@@ -0,0 +1,35 @@
1
+ import { memo } from 'react';
2
+ import Svg, { Path } from 'react-native-svg';
3
+
4
+ export const TAIL_WIDTH = 4;
5
+ const TAIL_HEIGHT = 18;
6
+
7
+ // Traced from the design export (Vector 2.svg): a straight vertical edge that
8
+ // continues the bubble's side, flaring outward toward the bottom.
9
+ const TAIL_PATH =
10
+ 'M2.6202 18H0V0C0.482375 4.5 0.657308 10.5 3.03348 14C4.56838 16.2608 4.15936 18 2.6202 18Z';
11
+
12
+ export interface BubbleTailProps {
13
+ /**
14
+ * Solid bubble colour. The export carries fill-opacity 0.1, but
15
+ * CHAT_BUBBLE_COLORS is already flattened — reusing the translucent fill here
16
+ * would render the tail a different shade from the bubble it joins.
17
+ */
18
+ color: string;
19
+ /** Side of the bubble the tail hangs off. */
20
+ side: 'left' | 'right';
21
+ }
22
+
23
+ export const BubbleTail = memo(({ color, side }: BubbleTailProps) => (
24
+ <Svg
25
+ width={TAIL_WIDTH}
26
+ height={TAIL_HEIGHT}
27
+ viewBox={`0 0 ${TAIL_WIDTH} ${TAIL_HEIGHT}`}
28
+ fill="none"
29
+ style={side === 'left' ? { transform: [{ scaleX: -1 }] } : undefined}
30
+ >
31
+ <Path d={TAIL_PATH} fill={color} />
32
+ </Svg>
33
+ ));
34
+
35
+ BubbleTail.displayName = 'BubbleTail';
@@ -0,0 +1,64 @@
1
+ import { memo, type PropsWithChildren } from 'react';
2
+ import { StyleSheet } from 'react-native';
3
+ import { KContainer } from '@droppii/libs';
4
+ import { BubbleTail, TAIL_WIDTH } from './BubbleTail';
5
+ import { hasBubbleTail } from './bubbleTail.utils';
6
+ import { CHAT_BUBBLE_COLORS } from '../../screens/chat-detail/constants';
7
+ import type { GroupPosition } from '../../utils/legendListMessage';
8
+
9
+ export type BubbleTailRowProps = PropsWithChildren<{
10
+ isOutgoing: boolean;
11
+ groupPosition?: GroupPosition;
12
+ /**
13
+ * Set false for media bubbles, which carry no tail but still need the gutter
14
+ * so they line up with the text bubbles around them.
15
+ */
16
+ withTail?: boolean;
17
+ }>;
18
+
19
+ /**
20
+ * Places the tail beside the bubble that closes a cluster.
21
+ *
22
+ * The gutter on the tail side is always TAIL_WIDTH wide, whether or not it
23
+ * actually holds a tail. That keeps every bubble in a cluster starting at the
24
+ * same offset while leaving the row's own padding intact — the tail occupies
25
+ * reserved space rather than overhanging into the margin.
26
+ *
27
+ * The tail is a real sibling rather than an absolutely positioned overlay: it
28
+ * sits outside the bubble's edge, and `overflow: visible` is unreliable on
29
+ * Android for views carrying elevation — which the neighbouring pin badge does.
30
+ */
31
+ export const BubbleTailRow = memo(
32
+ ({
33
+ isOutgoing,
34
+ groupPosition,
35
+ withTail = true,
36
+ children,
37
+ }: BubbleTailRowProps) => {
38
+ const gutter =
39
+ withTail && hasBubbleTail(groupPosition) ? (
40
+ <BubbleTail
41
+ side={isOutgoing ? 'right' : 'left'}
42
+ color={
43
+ isOutgoing ? CHAT_BUBBLE_COLORS.sent : CHAT_BUBBLE_COLORS.received
44
+ }
45
+ />
46
+ ) : (
47
+ <KContainer.View style={styles.gutter} />
48
+ );
49
+
50
+ return (
51
+ <KContainer.View row alignItems="flex-end">
52
+ {!isOutgoing && gutter}
53
+ {children}
54
+ {isOutgoing && gutter}
55
+ </KContainer.View>
56
+ );
57
+ }
58
+ );
59
+
60
+ BubbleTailRow.displayName = 'BubbleTailRow';
61
+
62
+ const styles = StyleSheet.create({
63
+ gutter: { width: TAIL_WIDTH },
64
+ });
@@ -0,0 +1,21 @@
1
+ import type { ViewStyle } from 'react-native';
2
+ import type { GroupPosition } from '../../utils/legendListMessage';
3
+
4
+ /** Only the message closing a cluster carries a tail. */
5
+ export const hasBubbleTail = (position?: GroupPosition): boolean =>
6
+ position === 'last' || position === 'solo';
7
+
8
+ /**
9
+ * The corner the tail hangs off must be square, otherwise the tail's straight
10
+ * 18px edge meets the bubble's rounded corner and leaves a visible notch.
11
+ * Every other corner keeps its normal radius.
12
+ */
13
+ export const getTailCornerStyle = (
14
+ isOutgoing: boolean,
15
+ position?: GroupPosition
16
+ ): ViewStyle | undefined => {
17
+ if (!hasBubbleTail(position)) return undefined;
18
+ return isOutgoing
19
+ ? { borderBottomRightRadius: 0 }
20
+ : { borderBottomLeftRadius: 0 };
21
+ };
@@ -3,6 +3,8 @@ import { StyleSheet } from 'react-native';
3
3
  import { KContainer, KImage, KLabel, KColors } from '@droppii/libs';
4
4
  import { CHAT_BUBBLE_COLORS } from '../../../screens/chat-detail/constants';
5
5
  import { messageStyles } from '../styles';
6
+ import { getTailCornerStyle } from '../bubbleTail.utils';
7
+ import { BubbleTailRow } from '../BubbleTailRow';
6
8
  import type { BaseLegendMessageProps } from '../types';
7
9
  import { useFileDownload } from '../../../hooks/useFileDownload';
8
10
  import {
@@ -12,7 +14,7 @@ import {
12
14
  } from '../../../utils/imageUtils';
13
15
  import { trans } from '../../../translation';
14
16
  export const FileMessage = memo(
15
- ({ message, isOutgoing }: BaseLegendMessageProps) => {
17
+ ({ message, isOutgoing, groupPosition }: BaseLegendMessageProps) => {
16
18
  const fileName = message.fileElem?.fileName || '[File]';
17
19
  const fileSize = message.fileElem?.fileSize ?? 0;
18
20
  const url =
@@ -49,97 +51,102 @@ export const FileMessage = memo(
49
51
  const isDownloading = state.status === 'downloading';
50
52
 
51
53
  return (
52
- <KContainer.View
53
- padding={'0.5rem'}
54
- style={[
55
- styles.wrapper,
56
- isOutgoing ? messageStyles.bubbleSent : messageStyles.bubbleReceived,
57
- ]}
58
- >
54
+ <BubbleTailRow isOutgoing={isOutgoing} groupPosition={groupPosition}>
59
55
  <KContainer.View
60
- row
61
- alignItems
62
- br={'3x'}
63
- paddingR={'0.75rem'}
64
- paddingV={'0.25rem'}
65
- background={KColors.white}
56
+ padding={'0.5rem'}
57
+ style={[
58
+ styles.wrapper,
59
+ isOutgoing
60
+ ? messageStyles.bubbleSent
61
+ : messageStyles.bubbleReceived,
62
+ getTailCornerStyle(isOutgoing, groupPosition),
63
+ ]}
66
64
  >
67
- <KContainer.VisibleView visible={isDownloading}>
68
- <KContainer.Touchable
69
- center
70
- br="round"
71
- style={styles.cancelBtn}
72
- width={32}
73
- height={32}
74
- onPress={handleDownload}
75
- >
76
- <KContainer.View
65
+ <KContainer.View
66
+ row
67
+ alignItems
68
+ br={'3x'}
69
+ paddingR={'0.75rem'}
70
+ paddingV={'0.25rem'}
71
+ background={KColors.white}
72
+ >
73
+ <KContainer.VisibleView visible={isDownloading}>
74
+ <KContainer.Touchable
77
75
  center
78
76
  br="round"
79
- style={styles.cancelBtnIconContainer}
80
- width={26}
81
- height={26}
77
+ style={styles.cancelBtn}
78
+ width={32}
79
+ height={32}
80
+ onPress={handleDownload}
82
81
  >
83
- <KImage.VectorIcons
84
- name="close"
85
- provider="MaterialCommunityIcons"
86
- size={24}
87
- color={KColors.white}
88
- />
89
- </KContainer.View>
90
- </KContainer.Touchable>
91
- </KContainer.VisibleView>
92
- <KContainer.VisibleView visible={!isDownloading}>
93
- <KImage.Base
94
- uri={iconSource}
95
- style={styles.fileIcon}
96
- resizeMode="contain"
97
- />
98
- </KContainer.VisibleView>
82
+ <KContainer.View
83
+ center
84
+ br="round"
85
+ style={styles.cancelBtnIconContainer}
86
+ width={26}
87
+ height={26}
88
+ >
89
+ <KImage.VectorIcons
90
+ name="close"
91
+ provider="MaterialCommunityIcons"
92
+ size={24}
93
+ color={KColors.white}
94
+ />
95
+ </KContainer.View>
96
+ </KContainer.Touchable>
97
+ </KContainer.VisibleView>
98
+ <KContainer.VisibleView visible={!isDownloading}>
99
+ <KImage.Base
100
+ uri={iconSource}
101
+ style={styles.fileIcon}
102
+ resizeMode="contain"
103
+ />
104
+ </KContainer.VisibleView>
99
105
 
100
- {/* File name + size/progress */}
101
- <KContainer.View flexS={1}>
102
- <KLabel.Text
103
- typo="TextSmMedium"
104
- color={CHAT_BUBBLE_COLORS.text}
105
- numberOfLines={1}
106
- ellipsizeMode="middle"
107
- >
108
- {fileName}
109
- </KLabel.Text>
110
- <KLabel.Text
111
- typo="TextXsNormal"
112
- color={subtitleColor}
113
- numberOfLines={1}
114
- >
115
- {subtitle}
116
- </KLabel.Text>
117
- </KContainer.View>
106
+ {/* File name + size/progress */}
107
+ <KContainer.View flexS={1}>
108
+ <KLabel.Text
109
+ typo="TextSmMedium"
110
+ color={CHAT_BUBBLE_COLORS.text}
111
+ numberOfLines={1}
112
+ ellipsizeMode="middle"
113
+ >
114
+ {fileName}
115
+ </KLabel.Text>
116
+ <KLabel.Text
117
+ typo="TextXsNormal"
118
+ color={subtitleColor}
119
+ numberOfLines={1}
120
+ >
121
+ {subtitle}
122
+ </KLabel.Text>
123
+ </KContainer.View>
118
124
 
119
- {/* Eye (view) button */}
120
- <KImage.VectorIcons
121
- name="eye-outline"
122
- provider="MaterialCommunityIcons"
123
- onPress={handleView}
124
- size={20}
125
- color={KColors.palette.gray.w600}
126
- containerStyle={styles.viewIcon}
127
- />
125
+ {/* Eye (view) button */}
126
+ <KImage.VectorIcons
127
+ name="eye-outline"
128
+ provider="MaterialCommunityIcons"
129
+ onPress={handleView}
130
+ size={20}
131
+ color={KColors.palette.gray.w600}
132
+ containerStyle={styles.viewIcon}
133
+ />
128
134
 
129
- <KImage.VectorIcons
130
- name={'download-o'}
131
- provider="DroppiiNew"
132
- onPress={isDownloading ? undefined : handleDownload}
133
- size={20}
134
- color={
135
- state.status === 'error'
136
- ? (KColors.palette.danger?.w400 ?? '#FF3B30')
137
- : KColors.palette.gray.w600
138
- }
139
- containerStyle={isDownloading ? styles.disabledIcon : undefined}
140
- />
135
+ <KImage.VectorIcons
136
+ name={'download-o'}
137
+ provider="DroppiiNew"
138
+ onPress={isDownloading ? undefined : handleDownload}
139
+ size={20}
140
+ color={
141
+ state.status === 'error'
142
+ ? (KColors.palette.danger?.w400 ?? '#FF3B30')
143
+ : KColors.palette.gray.w600
144
+ }
145
+ containerStyle={isDownloading ? styles.disabledIcon : undefined}
146
+ />
147
+ </KContainer.View>
141
148
  </KContainer.View>
142
- </KContainer.View>
149
+ </BubbleTailRow>
143
150
  );
144
151
  }
145
152
  );
@@ -3,6 +3,7 @@ import { StyleSheet, useWindowDimensions } from 'react-native';
3
3
  import { KContainer, KImage } from '@droppii/libs';
4
4
  import ChatImageDimens from '../../../utils/chatImageDimens';
5
5
  import { messageStyles } from '../styles';
6
+ import { BubbleTailRow } from '../BubbleTailRow';
6
7
  import type { BaseLegendMessageProps } from '../types';
7
8
  const DEFAULT_DIMS = { width: 300, height: 300 };
8
9
 
@@ -72,7 +73,7 @@ export const resolveImageDisplayDims = (
72
73
  };
73
74
 
74
75
  export const ImageMessage = memo(
75
- ({ message, onMediaPress }: BaseLegendMessageProps) => {
76
+ ({ message, isOutgoing, onMediaPress }: BaseLegendMessageProps) => {
76
77
  const windowWidth = useWindowDimensions().width;
77
78
  const [isLoading, setIsLoading] = useState(true);
78
79
  const pictureElem = (message as any).pictureElem;
@@ -130,28 +131,30 @@ export const ImageMessage = memo(
130
131
  );
131
132
 
132
133
  return (
133
- <KContainer.View style={styles.wrapper}>
134
- <KContainer.Touchable
135
- onPress={handlePress}
136
- style={[
137
- messageStyles.imageBubble,
138
- styles.imageContainer,
139
- {
140
- width: imageDimensions.width,
141
- height: imageDimensions.height,
142
- },
143
- ]}
144
- >
145
- <KImage.Base
146
- uri={optimizedUrl}
147
- width={imageDimensions.width}
148
- height={imageDimensions.height}
149
- style={[messageStyles.imageBubble]}
150
- onLoad={handleLoad}
151
- />
152
- {isLoading && <KContainer.View style={styles.skeleton} />}
153
- </KContainer.Touchable>
154
- </KContainer.View>
134
+ <BubbleTailRow isOutgoing={isOutgoing} withTail={false}>
135
+ <KContainer.View style={styles.wrapper}>
136
+ <KContainer.Touchable
137
+ onPress={handlePress}
138
+ style={[
139
+ messageStyles.imageBubble,
140
+ styles.imageContainer,
141
+ {
142
+ width: imageDimensions.width,
143
+ height: imageDimensions.height,
144
+ },
145
+ ]}
146
+ >
147
+ <KImage.Base
148
+ uri={optimizedUrl}
149
+ width={imageDimensions.width}
150
+ height={imageDimensions.height}
151
+ style={[messageStyles.imageBubble]}
152
+ onLoad={handleLoad}
153
+ />
154
+ {isLoading && <KContainer.View style={styles.skeleton} />}
155
+ </KContainer.Touchable>
156
+ </KContainer.View>
157
+ </BubbleTailRow>
155
158
  );
156
159
  }
157
160
  );