@ethora/chat-component-rn 26.8.4 → 26.8.6

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 (417) hide show
  1. package/README.md +55 -0
  2. package/lib/commonjs/assets/emojiData.js +40 -0
  3. package/lib/commonjs/assets/emojiData.js.map +1 -0
  4. package/lib/commonjs/assets/icons.js +1 -1
  5. package/lib/commonjs/assets/icons.js.map +1 -1
  6. package/lib/commonjs/components/Header/HeaderRoomList.js +12 -7
  7. package/lib/commonjs/components/Header/HeaderRoomList.js.map +1 -1
  8. package/lib/commonjs/components/MainComponents/ChatHeader.js +7 -9
  9. package/lib/commonjs/components/MainComponents/ChatHeader.js.map +1 -1
  10. package/lib/commonjs/components/MainComponents/ChatRoom.js +47 -26
  11. package/lib/commonjs/components/MainComponents/ChatRoom.js.map +1 -1
  12. package/lib/commonjs/components/MainComponents/ChatWrapper.js +58 -21
  13. package/lib/commonjs/components/MainComponents/ChatWrapper.js.map +1 -1
  14. package/lib/commonjs/components/MainComponents/KeyboardInputDock.js +40 -0
  15. package/lib/commonjs/components/MainComponents/KeyboardInputDock.js.map +1 -0
  16. package/lib/commonjs/components/MainComponents/MessageContainer.js +4 -12
  17. package/lib/commonjs/components/MainComponents/MessageContainer.js.map +1 -1
  18. package/lib/commonjs/components/MainComponents/MessageList.js +110 -35
  19. package/lib/commonjs/components/MainComponents/MessageList.js.map +1 -1
  20. package/lib/commonjs/components/MainComponents/RoomList.js +32 -29
  21. package/lib/commonjs/components/MainComponents/RoomList.js.map +1 -1
  22. package/lib/commonjs/components/MainComponents/RoomStack.js +270 -0
  23. package/lib/commonjs/components/MainComponents/RoomStack.js.map +1 -0
  24. package/lib/commonjs/components/MainComponents/SystemMessage.js +6 -2
  25. package/lib/commonjs/components/MainComponents/SystemMessage.js.map +1 -1
  26. package/lib/commonjs/components/MessageBubble/Avatar.js +5 -1
  27. package/lib/commonjs/components/MessageBubble/Avatar.js.map +1 -1
  28. package/lib/commonjs/components/MessageBubble/BottomReplyContainer.js +17 -21
  29. package/lib/commonjs/components/MessageBubble/BottomReplyContainer.js.map +1 -1
  30. package/lib/commonjs/components/MessageBubble/EmojiPickerSheet.js +447 -0
  31. package/lib/commonjs/components/MessageBubble/EmojiPickerSheet.js.map +1 -0
  32. package/lib/commonjs/components/MessageBubble/Message.js +200 -132
  33. package/lib/commonjs/components/MessageBubble/Message.js.map +1 -1
  34. package/lib/commonjs/components/MessageBubble/MessageInteractions.js +213 -12
  35. package/lib/commonjs/components/MessageBubble/MessageInteractions.js.map +1 -1
  36. package/lib/commonjs/components/MessageBubble/MessageReaction.js +113 -94
  37. package/lib/commonjs/components/MessageBubble/MessageReaction.js.map +1 -1
  38. package/lib/commonjs/components/MessageBubble/MessageReply.js +66 -24
  39. package/lib/commonjs/components/MessageBubble/MessageReply.js.map +1 -1
  40. package/lib/commonjs/components/Modals/ChatProfileModal/ChatProfileModal.js +6 -1
  41. package/lib/commonjs/components/Modals/ChatProfileModal/ChatProfileModal.js.map +1 -1
  42. package/lib/commonjs/components/Modals/Modal/Modal.js +24 -0
  43. package/lib/commonjs/components/Modals/Modal/Modal.js.map +1 -1
  44. package/lib/commonjs/components/Modals/Modal/SwipeBackLayer.js +178 -0
  45. package/lib/commonjs/components/Modals/Modal/SwipeBackLayer.js.map +1 -0
  46. package/lib/commonjs/components/Modals/ProfileHeader/ProfileHeader.js +28 -10
  47. package/lib/commonjs/components/Modals/ProfileHeader/ProfileHeader.js.map +1 -1
  48. package/lib/commonjs/components/Modals/UserProfileModal/UserProfileModal.js +9 -3
  49. package/lib/commonjs/components/Modals/UserProfileModal/UserProfileModal.js.map +1 -1
  50. package/lib/commonjs/components/RoomComponents/ChatRoomItem.js +5 -4
  51. package/lib/commonjs/components/RoomComponents/ChatRoomItem.js.map +1 -1
  52. package/lib/commonjs/components/RoomComponents/styled/LastMessageEmoji.js +8 -9
  53. package/lib/commonjs/components/RoomComponents/styled/LastMessageEmoji.js.map +1 -1
  54. package/lib/commonjs/components/Thread/ThreadWrapper.js +265 -152
  55. package/lib/commonjs/components/Thread/ThreadWrapper.js.map +1 -1
  56. package/lib/commonjs/components/styled/DateLabel.js +6 -3
  57. package/lib/commonjs/components/styled/DateLabel.js.map +1 -1
  58. package/lib/commonjs/context/MessageNotificationContext.js +188 -9
  59. package/lib/commonjs/context/MessageNotificationContext.js.map +1 -1
  60. package/lib/commonjs/context/xmppProvider.js +22 -7
  61. package/lib/commonjs/context/xmppProvider.js.map +1 -1
  62. package/lib/commonjs/helpers/createRoomFromApi.js +36 -2
  63. package/lib/commonjs/helpers/createRoomFromApi.js.map +1 -1
  64. package/lib/commonjs/helpers/emoji.js +51 -0
  65. package/lib/commonjs/helpers/emoji.js.map +1 -0
  66. package/lib/commonjs/helpers/haptics.js +29 -0
  67. package/lib/commonjs/helpers/haptics.js.map +1 -0
  68. package/lib/commonjs/helpers/historyPreloadScheduler.js +32 -66
  69. package/lib/commonjs/helpers/historyPreloadScheduler.js.map +1 -1
  70. package/lib/commonjs/helpers/insertMessageWithDelimiter.js +21 -12
  71. package/lib/commonjs/helpers/insertMessageWithDelimiter.js.map +1 -1
  72. package/lib/commonjs/helpers/keyboardLayout.js +23 -1
  73. package/lib/commonjs/helpers/keyboardLayout.js.map +1 -1
  74. package/lib/commonjs/helpers/mamReactions.js +57 -0
  75. package/lib/commonjs/helpers/mamReactions.js.map +1 -0
  76. package/lib/commonjs/helpers/parseMessageReference.js +42 -0
  77. package/lib/commonjs/helpers/parseMessageReference.js.map +1 -0
  78. package/lib/commonjs/helpers/reactionsConfig.js +17 -0
  79. package/lib/commonjs/helpers/reactionsConfig.js.map +1 -0
  80. package/lib/commonjs/helpers/updateMessagesTillLast.js +17 -2
  81. package/lib/commonjs/helpers/updateMessagesTillLast.js.map +1 -1
  82. package/lib/commonjs/hooks/useHeapSender.js +3 -1
  83. package/lib/commonjs/hooks/useHeapSender.js.map +1 -1
  84. package/lib/commonjs/hooks/useMessageHeapState.js +3 -2
  85. package/lib/commonjs/hooks/useMessageHeapState.js.map +1 -1
  86. package/lib/commonjs/hooks/useRoomInitialization.js +16 -7
  87. package/lib/commonjs/hooks/useRoomInitialization.js.map +1 -1
  88. package/lib/commonjs/hooks/useSendMessage.js +14 -8
  89. package/lib/commonjs/hooks/useSendMessage.js.map +1 -1
  90. package/lib/commonjs/hooks/useUnreadMessagesCounter.js +1 -1
  91. package/lib/commonjs/hooks/useUnreadMessagesCounter.js.map +1 -1
  92. package/lib/commonjs/networking/stanzaHandlers.js +106 -50
  93. package/lib/commonjs/networking/stanzaHandlers.js.map +1 -1
  94. package/lib/commonjs/networking/xmpp/getHistory.xmpp.js +29 -74
  95. package/lib/commonjs/networking/xmpp/getHistory.xmpp.js.map +1 -1
  96. package/lib/commonjs/networking/xmpp/handleStanzas.xmpp.js +4 -0
  97. package/lib/commonjs/networking/xmpp/handleStanzas.xmpp.js.map +1 -1
  98. package/lib/commonjs/networking/xmpp/mamRouter.js +186 -0
  99. package/lib/commonjs/networking/xmpp/mamRouter.js.map +1 -0
  100. package/lib/commonjs/networking/xmpp/presenceInRoom.xmpp.js +41 -4
  101. package/lib/commonjs/networking/xmpp/presenceInRoom.xmpp.js.map +1 -1
  102. package/lib/commonjs/networking/xmppClient.js +98 -23
  103. package/lib/commonjs/networking/xmppClient.js.map +1 -1
  104. package/lib/commonjs/roomStore/Middleware/newMessageMidlleware.js +29 -34
  105. package/lib/commonjs/roomStore/Middleware/newMessageMidlleware.js.map +1 -1
  106. package/lib/commonjs/roomStore/Middleware/perfMiddleware.js +51 -0
  107. package/lib/commonjs/roomStore/Middleware/perfMiddleware.js.map +1 -0
  108. package/lib/commonjs/roomStore/Middleware/reactionsMiddleware.js +66 -43
  109. package/lib/commonjs/roomStore/Middleware/reactionsMiddleware.js.map +1 -1
  110. package/lib/commonjs/roomStore/Middleware/unreadMidlleware.js +88 -68
  111. package/lib/commonjs/roomStore/Middleware/unreadMidlleware.js.map +1 -1
  112. package/lib/commonjs/roomStore/index.js +18 -14
  113. package/lib/commonjs/roomStore/index.js.map +1 -1
  114. package/lib/commonjs/roomStore/persistBackend.js +96 -0
  115. package/lib/commonjs/roomStore/persistBackend.js.map +1 -0
  116. package/lib/commonjs/roomStore/persistence.js +245 -50
  117. package/lib/commonjs/roomStore/persistence.js.map +1 -1
  118. package/lib/commonjs/roomStore/roomsSlice.js +282 -136
  119. package/lib/commonjs/roomStore/roomsSlice.js.map +1 -1
  120. package/lib/commonjs/theme/theme.js +3 -0
  121. package/lib/commonjs/theme/theme.js.map +1 -1
  122. package/lib/commonjs/utils/devLogger.js +14 -0
  123. package/lib/commonjs/utils/devLogger.js.map +1 -1
  124. package/lib/commonjs/version.js +1 -1
  125. package/lib/module/assets/emojiData.js +36 -0
  126. package/lib/module/assets/emojiData.js.map +1 -0
  127. package/lib/module/assets/icons.js +1 -1
  128. package/lib/module/assets/icons.js.map +1 -1
  129. package/lib/module/components/Header/HeaderRoomList.js +12 -7
  130. package/lib/module/components/Header/HeaderRoomList.js.map +1 -1
  131. package/lib/module/components/MainComponents/ChatHeader.js +8 -10
  132. package/lib/module/components/MainComponents/ChatHeader.js.map +1 -1
  133. package/lib/module/components/MainComponents/ChatRoom.js +49 -28
  134. package/lib/module/components/MainComponents/ChatRoom.js.map +1 -1
  135. package/lib/module/components/MainComponents/ChatWrapper.js +60 -23
  136. package/lib/module/components/MainComponents/ChatWrapper.js.map +1 -1
  137. package/lib/module/components/MainComponents/KeyboardInputDock.js +33 -0
  138. package/lib/module/components/MainComponents/KeyboardInputDock.js.map +1 -0
  139. package/lib/module/components/MainComponents/MessageContainer.js +7 -14
  140. package/lib/module/components/MainComponents/MessageContainer.js.map +1 -1
  141. package/lib/module/components/MainComponents/MessageList.js +110 -35
  142. package/lib/module/components/MainComponents/MessageList.js.map +1 -1
  143. package/lib/module/components/MainComponents/RoomList.js +32 -29
  144. package/lib/module/components/MainComponents/RoomList.js.map +1 -1
  145. package/lib/module/components/MainComponents/RoomStack.js +266 -0
  146. package/lib/module/components/MainComponents/RoomStack.js.map +1 -0
  147. package/lib/module/components/MainComponents/SystemMessage.js +6 -2
  148. package/lib/module/components/MainComponents/SystemMessage.js.map +1 -1
  149. package/lib/module/components/MessageBubble/Avatar.js +5 -1
  150. package/lib/module/components/MessageBubble/Avatar.js.map +1 -1
  151. package/lib/module/components/MessageBubble/BottomReplyContainer.js +18 -22
  152. package/lib/module/components/MessageBubble/BottomReplyContainer.js.map +1 -1
  153. package/lib/module/components/MessageBubble/EmojiPickerSheet.js +438 -0
  154. package/lib/module/components/MessageBubble/EmojiPickerSheet.js.map +1 -0
  155. package/lib/module/components/MessageBubble/Message.js +203 -134
  156. package/lib/module/components/MessageBubble/Message.js.map +1 -1
  157. package/lib/module/components/MessageBubble/MessageInteractions.js +215 -14
  158. package/lib/module/components/MessageBubble/MessageInteractions.js.map +1 -1
  159. package/lib/module/components/MessageBubble/MessageReaction.js +115 -94
  160. package/lib/module/components/MessageBubble/MessageReaction.js.map +1 -1
  161. package/lib/module/components/MessageBubble/MessageReply.js +65 -24
  162. package/lib/module/components/MessageBubble/MessageReply.js.map +1 -1
  163. package/lib/module/components/Modals/ChatProfileModal/ChatProfileModal.js +6 -1
  164. package/lib/module/components/Modals/ChatProfileModal/ChatProfileModal.js.map +1 -1
  165. package/lib/module/components/Modals/Modal/Modal.js +25 -1
  166. package/lib/module/components/Modals/Modal/Modal.js.map +1 -1
  167. package/lib/module/components/Modals/Modal/SwipeBackLayer.js +172 -0
  168. package/lib/module/components/Modals/Modal/SwipeBackLayer.js.map +1 -0
  169. package/lib/module/components/Modals/ProfileHeader/ProfileHeader.js +29 -11
  170. package/lib/module/components/Modals/ProfileHeader/ProfileHeader.js.map +1 -1
  171. package/lib/module/components/Modals/UserProfileModal/UserProfileModal.js +10 -4
  172. package/lib/module/components/Modals/UserProfileModal/UserProfileModal.js.map +1 -1
  173. package/lib/module/components/RoomComponents/ChatRoomItem.js +5 -4
  174. package/lib/module/components/RoomComponents/ChatRoomItem.js.map +1 -1
  175. package/lib/module/components/RoomComponents/styled/LastMessageEmoji.js +8 -9
  176. package/lib/module/components/RoomComponents/styled/LastMessageEmoji.js.map +1 -1
  177. package/lib/module/components/Thread/ThreadWrapper.js +264 -152
  178. package/lib/module/components/Thread/ThreadWrapper.js.map +1 -1
  179. package/lib/module/components/styled/DateLabel.js +6 -3
  180. package/lib/module/components/styled/DateLabel.js.map +1 -1
  181. package/lib/module/context/MessageNotificationContext.js +190 -11
  182. package/lib/module/context/MessageNotificationContext.js.map +1 -1
  183. package/lib/module/context/xmppProvider.js +22 -7
  184. package/lib/module/context/xmppProvider.js.map +1 -1
  185. package/lib/module/helpers/createRoomFromApi.js +36 -2
  186. package/lib/module/helpers/createRoomFromApi.js.map +1 -1
  187. package/lib/module/helpers/emoji.js +44 -0
  188. package/lib/module/helpers/emoji.js.map +1 -0
  189. package/lib/module/helpers/haptics.js +24 -0
  190. package/lib/module/helpers/haptics.js.map +1 -0
  191. package/lib/module/helpers/historyPreloadScheduler.js +32 -66
  192. package/lib/module/helpers/historyPreloadScheduler.js.map +1 -1
  193. package/lib/module/helpers/insertMessageWithDelimiter.js +21 -12
  194. package/lib/module/helpers/insertMessageWithDelimiter.js.map +1 -1
  195. package/lib/module/helpers/keyboardLayout.js +20 -0
  196. package/lib/module/helpers/keyboardLayout.js.map +1 -1
  197. package/lib/module/helpers/mamReactions.js +51 -0
  198. package/lib/module/helpers/mamReactions.js.map +1 -0
  199. package/lib/module/helpers/parseMessageReference.js +37 -0
  200. package/lib/module/helpers/parseMessageReference.js.map +1 -0
  201. package/lib/module/helpers/reactionsConfig.js +10 -0
  202. package/lib/module/helpers/reactionsConfig.js.map +1 -0
  203. package/lib/module/helpers/updateMessagesTillLast.js +17 -2
  204. package/lib/module/helpers/updateMessagesTillLast.js.map +1 -1
  205. package/lib/module/hooks/useHeapSender.js +3 -1
  206. package/lib/module/hooks/useHeapSender.js.map +1 -1
  207. package/lib/module/hooks/useMessageHeapState.js +3 -2
  208. package/lib/module/hooks/useMessageHeapState.js.map +1 -1
  209. package/lib/module/hooks/useRoomInitialization.js +17 -8
  210. package/lib/module/hooks/useRoomInitialization.js.map +1 -1
  211. package/lib/module/hooks/useSendMessage.js +14 -8
  212. package/lib/module/hooks/useSendMessage.js.map +1 -1
  213. package/lib/module/hooks/useUnreadMessagesCounter.js +1 -1
  214. package/lib/module/hooks/useUnreadMessagesCounter.js.map +1 -1
  215. package/lib/module/networking/stanzaHandlers.js +107 -51
  216. package/lib/module/networking/stanzaHandlers.js.map +1 -1
  217. package/lib/module/networking/xmpp/getHistory.xmpp.js +29 -74
  218. package/lib/module/networking/xmpp/getHistory.xmpp.js.map +1 -1
  219. package/lib/module/networking/xmpp/handleStanzas.xmpp.js +4 -0
  220. package/lib/module/networking/xmpp/handleStanzas.xmpp.js.map +1 -1
  221. package/lib/module/networking/xmpp/mamRouter.js +175 -0
  222. package/lib/module/networking/xmpp/mamRouter.js.map +1 -0
  223. package/lib/module/networking/xmpp/presenceInRoom.xmpp.js +38 -2
  224. package/lib/module/networking/xmpp/presenceInRoom.xmpp.js.map +1 -1
  225. package/lib/module/networking/xmppClient.js +99 -24
  226. package/lib/module/networking/xmppClient.js.map +1 -1
  227. package/lib/module/roomStore/Middleware/newMessageMidlleware.js +29 -34
  228. package/lib/module/roomStore/Middleware/newMessageMidlleware.js.map +1 -1
  229. package/lib/module/roomStore/Middleware/perfMiddleware.js +45 -0
  230. package/lib/module/roomStore/Middleware/perfMiddleware.js.map +1 -0
  231. package/lib/module/roomStore/Middleware/reactionsMiddleware.js +66 -43
  232. package/lib/module/roomStore/Middleware/reactionsMiddleware.js.map +1 -1
  233. package/lib/module/roomStore/Middleware/unreadMidlleware.js +89 -69
  234. package/lib/module/roomStore/Middleware/unreadMidlleware.js.map +1 -1
  235. package/lib/module/roomStore/index.js +19 -15
  236. package/lib/module/roomStore/index.js.map +1 -1
  237. package/lib/module/roomStore/persistBackend.js +89 -0
  238. package/lib/module/roomStore/persistBackend.js.map +1 -0
  239. package/lib/module/roomStore/persistence.js +245 -48
  240. package/lib/module/roomStore/persistence.js.map +1 -1
  241. package/lib/module/roomStore/roomsSlice.js +275 -134
  242. package/lib/module/roomStore/roomsSlice.js.map +1 -1
  243. package/lib/module/theme/theme.js +3 -0
  244. package/lib/module/theme/theme.js.map +1 -1
  245. package/lib/module/utils/devLogger.js +13 -0
  246. package/lib/module/utils/devLogger.js.map +1 -1
  247. package/lib/module/version.js +1 -1
  248. package/lib/typescript/assets/emojiData.d.ts +8 -0
  249. package/lib/typescript/assets/emojiData.d.ts.map +1 -0
  250. package/lib/typescript/components/Header/HeaderRoomList.d.ts.map +1 -1
  251. package/lib/typescript/components/MainComponents/ChatHeader.d.ts.map +1 -1
  252. package/lib/typescript/components/MainComponents/ChatRoom.d.ts.map +1 -1
  253. package/lib/typescript/components/MainComponents/ChatWrapper.d.ts.map +1 -1
  254. package/lib/typescript/components/MainComponents/KeyboardInputDock.d.ts +16 -0
  255. package/lib/typescript/components/MainComponents/KeyboardInputDock.d.ts.map +1 -0
  256. package/lib/typescript/components/MainComponents/MessageContainer.d.ts +2 -2
  257. package/lib/typescript/components/MainComponents/MessageContainer.d.ts.map +1 -1
  258. package/lib/typescript/components/MainComponents/MessageList.d.ts.map +1 -1
  259. package/lib/typescript/components/MainComponents/RoomList.d.ts.map +1 -1
  260. package/lib/typescript/components/MainComponents/RoomStack.d.ts +42 -0
  261. package/lib/typescript/components/MainComponents/RoomStack.d.ts.map +1 -0
  262. package/lib/typescript/components/MainComponents/SystemMessage.d.ts.map +1 -1
  263. package/lib/typescript/components/MessageBubble/Avatar.d.ts +2 -0
  264. package/lib/typescript/components/MessageBubble/Avatar.d.ts.map +1 -1
  265. package/lib/typescript/components/MessageBubble/BottomReplyContainer.d.ts.map +1 -1
  266. package/lib/typescript/components/MessageBubble/EmojiPickerSheet.d.ts +11 -0
  267. package/lib/typescript/components/MessageBubble/EmojiPickerSheet.d.ts.map +1 -0
  268. package/lib/typescript/components/MessageBubble/Message.d.ts +2 -2
  269. package/lib/typescript/components/MessageBubble/Message.d.ts.map +1 -1
  270. package/lib/typescript/components/MessageBubble/MessageInteractions.d.ts +2 -0
  271. package/lib/typescript/components/MessageBubble/MessageInteractions.d.ts.map +1 -1
  272. package/lib/typescript/components/MessageBubble/MessageReaction.d.ts +1 -0
  273. package/lib/typescript/components/MessageBubble/MessageReaction.d.ts.map +1 -1
  274. package/lib/typescript/components/MessageBubble/MessageReply.d.ts +7 -7
  275. package/lib/typescript/components/MessageBubble/MessageReply.d.ts.map +1 -1
  276. package/lib/typescript/components/Modals/ChatProfileModal/ChatProfileModal.d.ts.map +1 -1
  277. package/lib/typescript/components/Modals/Modal/Modal.d.ts.map +1 -1
  278. package/lib/typescript/components/Modals/Modal/SwipeBackLayer.d.ts +16 -0
  279. package/lib/typescript/components/Modals/Modal/SwipeBackLayer.d.ts.map +1 -0
  280. package/lib/typescript/components/Modals/ProfileHeader/ProfileHeader.d.ts.map +1 -1
  281. package/lib/typescript/components/Modals/UserProfileModal/UserProfileModal.d.ts.map +1 -1
  282. package/lib/typescript/components/RoomComponents/ChatRoomItem.d.ts +2 -2
  283. package/lib/typescript/components/RoomComponents/ChatRoomItem.d.ts.map +1 -1
  284. package/lib/typescript/components/RoomComponents/styled/LastMessageEmoji.d.ts +3 -6
  285. package/lib/typescript/components/RoomComponents/styled/LastMessageEmoji.d.ts.map +1 -1
  286. package/lib/typescript/components/Thread/ThreadWrapper.d.ts +7 -1
  287. package/lib/typescript/components/Thread/ThreadWrapper.d.ts.map +1 -1
  288. package/lib/typescript/components/styled/DateLabel.d.ts +1 -0
  289. package/lib/typescript/components/styled/DateLabel.d.ts.map +1 -1
  290. package/lib/typescript/context/MessageNotificationContext.d.ts.map +1 -1
  291. package/lib/typescript/context/xmppProvider.d.ts.map +1 -1
  292. package/lib/typescript/helpers/createRoomFromApi.d.ts.map +1 -1
  293. package/lib/typescript/helpers/emoji.d.ts +6 -0
  294. package/lib/typescript/helpers/emoji.d.ts.map +1 -0
  295. package/lib/typescript/helpers/haptics.d.ts +3 -0
  296. package/lib/typescript/helpers/haptics.d.ts.map +1 -0
  297. package/lib/typescript/helpers/historyPreloadScheduler.d.ts +1 -0
  298. package/lib/typescript/helpers/historyPreloadScheduler.d.ts.map +1 -1
  299. package/lib/typescript/helpers/insertMessageWithDelimiter.d.ts.map +1 -1
  300. package/lib/typescript/helpers/keyboardLayout.d.ts +6 -0
  301. package/lib/typescript/helpers/keyboardLayout.d.ts.map +1 -1
  302. package/lib/typescript/helpers/mamReactions.d.ts +13 -0
  303. package/lib/typescript/helpers/mamReactions.d.ts.map +1 -0
  304. package/lib/typescript/helpers/parseMessageReference.d.ts +16 -0
  305. package/lib/typescript/helpers/parseMessageReference.d.ts.map +1 -0
  306. package/lib/typescript/helpers/reactionsConfig.d.ts +5 -0
  307. package/lib/typescript/helpers/reactionsConfig.d.ts.map +1 -0
  308. package/lib/typescript/helpers/updateMessagesTillLast.d.ts.map +1 -1
  309. package/lib/typescript/hooks/useHeapSender.d.ts.map +1 -1
  310. package/lib/typescript/hooks/useMessageHeapState.d.ts.map +1 -1
  311. package/lib/typescript/hooks/useRoomInitialization.d.ts +2 -2
  312. package/lib/typescript/hooks/useRoomInitialization.d.ts.map +1 -1
  313. package/lib/typescript/hooks/useSendMessage.d.ts.map +1 -1
  314. package/lib/typescript/networking/stanzaHandlers.d.ts +4 -2
  315. package/lib/typescript/networking/stanzaHandlers.d.ts.map +1 -1
  316. package/lib/typescript/networking/xmpp/getHistory.xmpp.d.ts +3 -1
  317. package/lib/typescript/networking/xmpp/getHistory.xmpp.d.ts.map +1 -1
  318. package/lib/typescript/networking/xmpp/handleStanzas.xmpp.d.ts.map +1 -1
  319. package/lib/typescript/networking/xmpp/mamRouter.d.ts +23 -0
  320. package/lib/typescript/networking/xmpp/mamRouter.d.ts.map +1 -0
  321. package/lib/typescript/networking/xmpp/presenceInRoom.xmpp.d.ts +1 -0
  322. package/lib/typescript/networking/xmpp/presenceInRoom.xmpp.d.ts.map +1 -1
  323. package/lib/typescript/networking/xmppClient.d.ts +22 -1
  324. package/lib/typescript/networking/xmppClient.d.ts.map +1 -1
  325. package/lib/typescript/roomStore/Middleware/newMessageMidlleware.d.ts.map +1 -1
  326. package/lib/typescript/roomStore/Middleware/perfMiddleware.d.ts +4 -0
  327. package/lib/typescript/roomStore/Middleware/perfMiddleware.d.ts.map +1 -0
  328. package/lib/typescript/roomStore/Middleware/reactionsMiddleware.d.ts +9 -0
  329. package/lib/typescript/roomStore/Middleware/reactionsMiddleware.d.ts.map +1 -1
  330. package/lib/typescript/roomStore/Middleware/unreadMidlleware.d.ts.map +1 -1
  331. package/lib/typescript/roomStore/index.d.ts.map +1 -1
  332. package/lib/typescript/roomStore/persistBackend.d.ts +11 -0
  333. package/lib/typescript/roomStore/persistBackend.d.ts.map +1 -0
  334. package/lib/typescript/roomStore/persistence.d.ts +5 -6
  335. package/lib/typescript/roomStore/persistence.d.ts.map +1 -1
  336. package/lib/typescript/roomStore/roomsSlice.d.ts +41 -1
  337. package/lib/typescript/roomStore/roomsSlice.d.ts.map +1 -1
  338. package/lib/typescript/theme/theme.d.ts +4 -1
  339. package/lib/typescript/theme/theme.d.ts.map +1 -1
  340. package/lib/typescript/types/models/message.model.d.ts +4 -0
  341. package/lib/typescript/types/models/message.model.d.ts.map +1 -1
  342. package/lib/typescript/types/models/room.model.d.ts +16 -0
  343. package/lib/typescript/types/models/room.model.d.ts.map +1 -1
  344. package/lib/typescript/types/models/xmpp.model.d.ts +6 -1
  345. package/lib/typescript/types/models/xmpp.model.d.ts.map +1 -1
  346. package/lib/typescript/types/types.d.ts +15 -3
  347. package/lib/typescript/types/types.d.ts.map +1 -1
  348. package/lib/typescript/utils/devLogger.d.ts +8 -0
  349. package/lib/typescript/utils/devLogger.d.ts.map +1 -1
  350. package/lib/typescript/version.d.ts +1 -1
  351. package/package.json +10 -1
  352. package/src/assets/emojiData.ts +2146 -0
  353. package/src/assets/icons.tsx +5 -5
  354. package/src/components/Header/HeaderRoomList.tsx +7 -5
  355. package/src/components/MainComponents/ChatHeader.tsx +16 -7
  356. package/src/components/MainComponents/ChatRoom.tsx +64 -32
  357. package/src/components/MainComponents/ChatWrapper.tsx +73 -21
  358. package/src/components/MainComponents/KeyboardInputDock.tsx +47 -0
  359. package/src/components/MainComponents/MessageContainer.tsx +7 -15
  360. package/src/components/MainComponents/MessageList.tsx +96 -43
  361. package/src/components/MainComponents/RoomList.tsx +28 -29
  362. package/src/components/MainComponents/RoomStack.tsx +309 -0
  363. package/src/components/MainComponents/SystemMessage.tsx +6 -2
  364. package/src/components/MessageBubble/Avatar.tsx +7 -1
  365. package/src/components/MessageBubble/BottomReplyContainer.tsx +19 -21
  366. package/src/components/MessageBubble/EmojiPickerSheet.tsx +468 -0
  367. package/src/components/MessageBubble/Message.tsx +146 -87
  368. package/src/components/MessageBubble/MessageInteractions.tsx +213 -12
  369. package/src/components/MessageBubble/MessageReaction.tsx +120 -96
  370. package/src/components/MessageBubble/MessageReply.tsx +65 -32
  371. package/src/components/Modals/ChatProfileModal/ChatProfileModal.tsx +4 -0
  372. package/src/components/Modals/Modal/Modal.tsx +32 -1
  373. package/src/components/Modals/Modal/SwipeBackLayer.tsx +221 -0
  374. package/src/components/Modals/ProfileHeader/ProfileHeader.tsx +29 -8
  375. package/src/components/Modals/UserProfileModal/UserProfileModal.tsx +6 -3
  376. package/src/components/RoomComponents/ChatRoomItem.tsx +11 -4
  377. package/src/components/RoomComponents/styled/LastMessageEmoji.tsx +7 -8
  378. package/src/components/Thread/ThreadWrapper.tsx +274 -198
  379. package/src/components/styled/DateLabel.tsx +7 -3
  380. package/src/context/MessageNotificationContext.tsx +205 -7
  381. package/src/context/xmppProvider.tsx +29 -9
  382. package/src/helpers/createRoomFromApi.tsx +37 -1
  383. package/src/helpers/emoji.ts +39 -0
  384. package/src/helpers/haptics.ts +19 -0
  385. package/src/helpers/historyPreloadScheduler.ts +37 -69
  386. package/src/helpers/insertMessageWithDelimiter.ts +23 -16
  387. package/src/helpers/keyboardLayout.ts +26 -0
  388. package/src/helpers/mamReactions.ts +59 -0
  389. package/src/helpers/parseMessageReference.ts +38 -0
  390. package/src/helpers/reactionsConfig.ts +13 -0
  391. package/src/helpers/updateMessagesTillLast.tsx +14 -2
  392. package/src/hooks/useHeapSender.tsx +3 -2
  393. package/src/hooks/useMessageHeapState.tsx +6 -2
  394. package/src/hooks/useRoomInitialization.tsx +32 -15
  395. package/src/hooks/useSendMessage.tsx +18 -11
  396. package/src/hooks/useUnreadMessagesCounter.ts +1 -1
  397. package/src/networking/stanzaHandlers.ts +116 -60
  398. package/src/networking/xmpp/getHistory.xmpp.ts +44 -106
  399. package/src/networking/xmpp/handleStanzas.xmpp.ts +2 -0
  400. package/src/networking/xmpp/mamRouter.ts +176 -0
  401. package/src/networking/xmpp/presenceInRoom.xmpp.ts +46 -3
  402. package/src/networking/xmppClient.ts +105 -20
  403. package/src/roomStore/Middleware/newMessageMidlleware.tsx +35 -38
  404. package/src/roomStore/Middleware/perfMiddleware.ts +50 -0
  405. package/src/roomStore/Middleware/reactionsMiddleware.tsx +53 -52
  406. package/src/roomStore/Middleware/unreadMidlleware.tsx +92 -80
  407. package/src/roomStore/index.ts +28 -27
  408. package/src/roomStore/persistBackend.ts +96 -0
  409. package/src/roomStore/persistence.ts +280 -73
  410. package/src/roomStore/roomsSlice.ts +304 -155
  411. package/src/theme/theme.ts +10 -1
  412. package/src/types/models/message.model.ts +4 -0
  413. package/src/types/models/room.model.ts +17 -0
  414. package/src/types/models/xmpp.model.ts +4 -2
  415. package/src/types/types.ts +15 -3
  416. package/src/utils/devLogger.ts +16 -0
  417. package/src/version.ts +1 -1
@@ -1,36 +1,45 @@
1
- import { FC, useCallback, useEffect, useRef, useState } from 'react';
2
- import { IMessage, User } from '../../types/types';
1
+ import React, { FC, useCallback, useEffect, useMemo, useRef, useState } from 'react';
3
2
  import {
4
- AlsoCheckbox,
5
- AlsoContainer,
6
- ChatContainer,
7
- ThreadContainer,
8
- } from '../styled/StyledComponents';
3
+ Animated,
4
+ BackHandler,
5
+ Easing,
6
+ Keyboard,
7
+ Platform,
8
+ Pressable,
9
+ StyleSheet,
10
+ Text,
11
+ useWindowDimensions,
12
+ View,
13
+ } from 'react-native';
14
+ import { useDispatch, useSelector, useStore } from 'react-redux';
15
+ import { KeyboardAvoidingView } from 'react-native-keyboard-controller';
16
+ import { useSafeAreaInsets } from 'react-native-safe-area-context';
17
+ import { Gesture, GestureDetector } from 'react-native-gesture-handler';
18
+ import { IMessage, User } from '../../types/types';
19
+ import type { RootState } from '../../roomStore';
9
20
  import SendInput from '../styled/SendInput';
10
- import { useDispatch } from 'react-redux';
11
21
  import { useXmppClient } from '../../context/xmppProvider';
12
22
  import MessageList from '../MainComponents/MessageList';
13
23
  import ModalHeaderComponent from '../Modals/ModalHeaderComponent';
14
- import {
15
- deleteRoomMessage,
16
- setCloseActiveMessage,
17
- setEditAction,
18
- setLastViewedTimestamp,
19
- } from '../../roomStore/roomsSlice';
24
+ import { setCloseActiveMessage, setEditAction } from '../../roomStore/roomsSlice';
20
25
  import { EditWrapper } from '../MainComponents/EditWrapper';
21
26
  import { useSendMessage } from '../../hooks/useSendMessage';
22
27
  import { createMainMessageForThread } from '../../helpers/createMainMessageForThread';
23
- import { useRoomState } from '../../hooks/useRoomState';
24
28
  import { useChatSettingState } from '../../hooks/useChatSettingState';
25
29
  import { useTheme } from '../../hooks/useTheme';
26
- import {
27
- Animated,
28
- Text,
29
- TouchableOpacity,
30
- StyleSheet,
31
- PanResponder,
32
- } from 'react-native';
33
30
  import CustomTypingIndicator from '../styled/StyledInputComponents/CustomTypingIndicator';
31
+ import { KeyboardInputDock } from '../MainComponents/KeyboardInputDock';
32
+ import {
33
+ getInputDockKeyboardPadding,
34
+ getInputDockPaddingBottom,
35
+ } from '../../helpers/keyboardLayout';
36
+ import {
37
+ COMPLETE_DISTANCE,
38
+ COMPLETE_VELOCITY,
39
+ EDGE_WIDTH,
40
+ POP,
41
+ PUSH,
42
+ } from '../MainComponents/RoomStack';
34
43
 
35
44
  interface ThreadWrapperProps {
36
45
  activeMessage: IMessage;
@@ -42,6 +51,12 @@ interface ThreadWrapperProps {
42
51
  }>;
43
52
  }
44
53
 
54
+ /**
55
+ * The thread of one message, over the room: slides in from the right,
56
+ * closes with the header's back button, Android back or a swipe from the
57
+ * left edge (same feel as leaving a room). Replies go to the thread;
58
+ * "Also send to <room>" posts them in the channel too.
59
+ */
45
60
  const ThreadWrapper: FC<ThreadWrapperProps> = ({
46
61
  activeMessage,
47
62
  user,
@@ -49,70 +64,102 @@ const ThreadWrapper: FC<ThreadWrapperProps> = ({
49
64
  }) => {
50
65
  const { client } = useXmppClient();
51
66
  const dispatch = useDispatch();
52
-
53
- const { loading, roomsList, editAction, activeRoomJID } = useRoomState();
67
+ const reduxStore = useStore<RootState>();
54
68
  const { config } = useChatSettingState();
55
69
  const theme = useTheme();
56
- const { sendMessage: sendMs, sendMedia: sendMessageMedia, sendEditMessage, isLastMessageFromUserAndProcessing } = useSendMessage();
70
+ const insets = useSafeAreaInsets();
71
+ const { width: windowWidth } = useWindowDimensions();
72
+ const roomJid = activeMessage.roomJid;
73
+
74
+ const room = useSelector((state: RootState) => state.rooms.rooms?.[roomJid]);
75
+ const editAction = useSelector((state: RootState) => state.rooms.editAction);
76
+ const {
77
+ sendMessage: sendMs,
78
+ sendMedia: sendMessageMedia,
79
+ sendEditMessage,
80
+ isLastMessageFromUserAndProcessing,
81
+ } = useSendMessage();
82
+
83
+ // `name` is often the room's JID local part (an id) — the title is the
84
+ // human name.
85
+ // Same field the room header and the list show (`name` can be the id).
86
+ const roomDisplayName = String(room?.title || room?.name || 'chat').trim();
57
87
 
58
- const [isLoadingMore, setIsLoadingMore] = useState<boolean>(false);
59
- const [isChecked, setIsChecked] = useState<boolean>(false);
88
+ const [isLoadingMore, setIsLoadingMore] = useState(false);
89
+ const [isChecked, setIsChecked] = useState(false);
90
+
91
+ // 0 = in place, windowWidth = off-screen to the right.
92
+ const x = useRef(new Animated.Value(windowWidth)).current;
93
+ const closing = useRef(false);
94
+
95
+ useEffect(() => {
96
+ Animated.timing(x, { toValue: 0, ...PUSH, useNativeDriver: true }).start();
97
+ }, [x]);
98
+
99
+ const close = useCallback(() => {
100
+ if (closing.current) {return;}
101
+ closing.current = true;
102
+ Keyboard.dismiss();
103
+ Animated.timing(x, { toValue: windowWidth, ...POP, useNativeDriver: true }).start(
104
+ () => {
105
+ dispatch(setCloseActiveMessage({ chatJID: roomJid }));
106
+ dispatch(setEditAction({ isEdit: false }));
107
+ }
108
+ );
109
+ }, [dispatch, roomJid, windowWidth, x]);
60
110
 
61
- const slideAnim = useRef(new Animated.Value(300)).current;
111
+ useEffect(() => {
112
+ const sub = BackHandler.addEventListener('hardwareBackPress', () => {
113
+ close();
114
+ return true;
115
+ });
116
+ return () => sub.remove();
117
+ }, [close]);
62
118
 
63
- const panResponder = useRef(
64
- PanResponder.create({
65
- onStartShouldSetPanResponder: (e, gestureState) => {
66
- return gestureState.x0 <= 100;
67
- },
68
- onMoveShouldSetPanResponder: (e, gestureState) => {
69
- return gestureState.x0 <= 100 && gestureState.dx > 0;
70
- },
71
- onPanResponderMove: (e, gestureState) => {
72
- if (gestureState.x0 <= 100 && gestureState.dx > 0) {
73
- slideAnim.setValue(gestureState.dx);
74
- }
75
- },
76
- onPanResponderRelease: (e, gestureState) => {
77
- if (gestureState.x0 <= 100 && gestureState.dx > 150) {
78
- closeThread();
79
- } else {
80
- Animated.spring(slideAnim, {
81
- toValue: 0,
82
- useNativeDriver: true,
83
- }).start();
84
- }
85
- },
86
- })
87
- ).current;
119
+ const swipeBack = useMemo(
120
+ () =>
121
+ Gesture.Pan()
122
+ .runOnJS(true)
123
+ .hitSlop({ left: 0, width: EDGE_WIDTH })
124
+ .activeOffsetX(12)
125
+ .failOffsetY([-16, 16])
126
+ .onStart(() => Keyboard.dismiss())
127
+ .onUpdate((e) => {
128
+ if (!closing.current) {x.setValue(Math.max(0, e.translationX));}
129
+ })
130
+ .onEnd((e) => {
131
+ if (closing.current) {return;}
132
+ if (e.translationX > windowWidth * COMPLETE_DISTANCE || e.velocityX > COMPLETE_VELOCITY) {
133
+ close();
134
+ } else {
135
+ Animated.timing(x, { toValue: 0, ...POP, useNativeDriver: true }).start();
136
+ }
137
+ }),
138
+ [close, windowWidth, x]
139
+ );
88
140
 
141
+ // Thread history IS the room's history (replies live in the room).
89
142
  const loadMoreMessages = useCallback(
90
143
  async (chatJID: string, max: number, idOfMessageBefore?: number) => {
91
- if (!isLoadingMore) {
92
- client?.getHistoryStanza(chatJID, max, idOfMessageBefore)
93
- .then(() => {
94
- setIsLoadingMore(false);
95
- })
96
- .catch((err: unknown) => {
97
- console.warn('getHistoryStanza failed', err);
98
- setIsLoadingMore(false);
99
- });
144
+ if (isLoadingMore) {return;}
145
+ if (reduxStore.getState().rooms.rooms?.[chatJID]?.historyComplete) {return;}
146
+ setIsLoadingMore(true);
147
+ try {
148
+ await client?.getHistoryStanza(chatJID, max, idOfMessageBefore);
149
+ } catch (err) {
150
+ console.warn('getHistoryStanza failed', err);
151
+ } finally {
152
+ setIsLoadingMore(false);
100
153
  }
101
154
  },
102
- [client]
155
+ [client, isLoadingMore, reduxStore]
103
156
  );
104
157
 
105
158
  const sendMessage = useCallback(
106
159
  (message: string) => {
107
- sendMs(
108
- message,
109
- activeMessage.roomJid,
110
- true,
111
- isChecked,
112
- createMainMessageForThread(activeMessage)
113
- );
160
+ sendMs(message, roomJid, true, isChecked, createMainMessageForThread(activeMessage));
114
161
  },
115
- [activeMessage, isChecked]
162
+ [activeMessage, isChecked, roomJid, sendMs]
116
163
  );
117
164
 
118
165
  const sendMedia = useCallback(
@@ -120,157 +167,186 @@ const ThreadWrapper: FC<ThreadWrapperProps> = ({
120
167
  sendMessageMedia(
121
168
  data,
122
169
  type,
123
- activeMessage.roomJid,
170
+ roomJid,
124
171
  true,
125
172
  isChecked,
126
173
  createMainMessageForThread(activeMessage)
127
174
  );
128
175
  },
129
- [activeMessage, isChecked]
176
+ [activeMessage, isChecked, roomJid, sendMessageMedia]
130
177
  );
131
178
 
179
+ const fullName = `${user.firstName || ''} ${user.lastName || ''}`.trim();
132
180
  const sendStartComposing = useCallback(() => {
133
- if (config?.disableTypingIndicator) {
134
- return;
135
- }
136
- client?.sendTypingRequestStanza(
137
- activeMessage.roomJid,
138
- `${user.firstName} ${user.lastName}`,
139
- true
140
- );
141
- }, []);
142
-
181
+ if (config?.disableTypingIndicator) {return;}
182
+ client?.sendTypingRequestStanza(roomJid, fullName, true);
183
+ }, [client, config?.disableTypingIndicator, fullName, roomJid]);
143
184
  const sendEndComposing = useCallback(() => {
144
- if (config?.disableTypingIndicator) {
145
- return;
146
- }
147
- client?.sendTypingRequestStanza(
148
- activeMessage.roomJid,
149
- `${user.firstName} ${user.lastName}`,
150
- false
151
- );
152
- }, []);
153
-
154
- const onCloseEdit = () => {
155
- dispatch(setEditAction({ isEdit: false }));
156
- };
185
+ if (config?.disableTypingIndicator) {return;}
186
+ client?.sendTypingRequestStanza(roomJid, fullName, false);
187
+ }, [client, config?.disableTypingIndicator, fullName, roomJid]);
157
188
 
158
- const closeThread = () => {
159
- dispatch(setCloseActiveMessage({ chatJID: activeMessage.roomJid }));
160
- dispatch(setEditAction({ isEdit: false }));
161
- };
162
-
163
- useEffect(() => {
164
- if (activeMessage?.activeMessage) {
165
- Animated.timing(slideAnim, {
166
- toValue: 0,
167
- duration: 300,
168
- useNativeDriver: true,
169
- }).start();
170
- } else {
171
- Animated.timing(slideAnim, {
172
- toValue: 300,
173
- duration: 300,
174
- useNativeDriver: true,
175
- }).start();
176
- }
177
- }, [activeMessage?.activeMessage]);
189
+ const dockPadding = getInputDockPaddingBottom({
190
+ platform: Platform.OS,
191
+ bottomInset: insets.bottom,
192
+ configuredPadding: config?.inputDockPaddingBottom,
193
+ });
194
+ const dockKeyboardPadding = getInputDockKeyboardPadding({
195
+ platform: Platform.OS,
196
+ inputDockPaddingBottom: dockPadding,
197
+ });
198
+ const DockTag: React.ComponentType<any> =
199
+ dockKeyboardPadding !== dockPadding ? KeyboardInputDock : View;
178
200
 
179
201
  return (
180
- <Animated.View
181
- {...panResponder.panHandlers}
182
- style={[
183
- styles.threadContainer,
184
- { backgroundColor: theme.chatBackground },
185
- { transform: [{ translateX: slideAnim }] },
186
- // ...config?.chatRoomStyles,
187
- ]}
188
- >
189
- <ModalHeaderComponent
190
- headerTitle="Thread"
191
- handleCloseModal={closeThread}
192
- />
193
- <MessageList
194
- loadMoreMessages={loadMoreMessages}
195
- CustomMessage={CustomMessageComponent}
196
- user={user}
197
- roomJID={activeMessage.roomJid}
198
- config={config}
199
- loading={isLoadingMore}
200
- activeMessage={activeMessage}
201
- isReply
202
- />
203
- <AlsoContainer onPress={() => setIsChecked((prev) => !prev)}>
204
- <AlsoCheckbox
205
- accentColor={isChecked ? theme.primary : theme.surface}
206
- // checked={isChecked}
207
- // onPress={() => setIsChecked(!isChecked)}
208
- />
209
- <Text style={{ color: theme.text }}>Also send to</Text>
210
- <TouchableOpacity onPress={closeThread}>
211
- <Text
212
- style={{
213
- color: theme.primary,
214
- fontWeight: 500,
215
- }}
202
+ <GestureDetector gesture={swipeBack}>
203
+ <Animated.View
204
+ style={[
205
+ styles.thread,
206
+ { backgroundColor: theme.chatBackground, transform: [{ translateX: x }] },
207
+ ]}
208
+ >
209
+ <KeyboardAvoidingView
210
+ behavior="padding"
211
+ style={[styles.fill, { backgroundColor: theme.surface }]}
212
+ >
213
+ <View style={[styles.fill, { backgroundColor: theme.chatBackground }]}>
214
+ <ModalHeaderComponent headerTitle="Thread" handleCloseModal={close} />
215
+ <MessageList
216
+ loadMoreMessages={loadMoreMessages}
217
+ CustomMessage={CustomMessageComponent}
218
+ user={user}
219
+ roomJID={roomJid}
220
+ config={config}
221
+ loading={isLoadingMore}
222
+ activeMessage={activeMessage}
223
+ isReply
224
+ />
225
+ </View>
226
+ <DockTag
227
+ {...(DockTag === View
228
+ ? {}
229
+ : { closedPadding: dockPadding, openedPadding: dockKeyboardPadding })}
230
+ style={[
231
+ styles.dock,
232
+ { backgroundColor: theme.surface, shadowColor: theme.shadow },
233
+ DockTag === View ? { paddingBottom: dockPadding } : null,
234
+ ]}
216
235
  >
217
- {roomsList[activeMessage.roomJid].name}
218
- </Text>
219
- </TouchableOpacity>
220
- </AlsoContainer>
221
- {editAction && editAction.isEdit && (
222
- <EditWrapper text={editAction.text || ''} onClose={onCloseEdit} />
223
- )}
224
- <SendInput
225
- editMessage={editAction && editAction.text}
226
- sendMedia={sendMedia}
227
- sendMessage={editAction && editAction.isEdit ? sendEditMessage : sendMessage}
228
- config={config}
229
- onFocus={sendStartComposing}
230
- onBlur={sendEndComposing}
231
- isLoading={loading}
232
- isMessageProcessing={isLastMessageFromUserAndProcessing(
233
- activeMessage.roomJid
234
- )}
235
- />
236
+ <Pressable
237
+ testID="thread-also-send"
238
+ accessibilityRole="checkbox"
239
+ accessibilityState={{ checked: isChecked }}
240
+ onPress={() => setIsChecked((prev) => !prev)}
241
+ style={styles.also}
242
+ >
243
+ <View
244
+ style={[
245
+ styles.checkbox,
246
+ {
247
+ borderColor: isChecked ? theme.primary : theme.textMuted,
248
+ backgroundColor: isChecked ? theme.primary : 'transparent',
249
+ },
250
+ ]}
251
+ >
252
+ {isChecked && (
253
+ <Text style={[styles.check, { color: theme.textOnPrimary }]}>✓</Text>
254
+ )}
255
+ </View>
256
+ <Text
257
+ numberOfLines={1}
258
+ style={[styles.alsoText, { color: theme.textSecondary }]}
259
+ >
260
+ Also send to{' '}
261
+ <Text style={{ color: theme.primary, fontWeight: '600' }}>
262
+ {roomDisplayName}
263
+ </Text>
264
+ </Text>
265
+ </Pressable>
266
+ {editAction?.isEdit && (
267
+ <EditWrapper
268
+ text={editAction.text || ''}
269
+ onClose={() => dispatch(setEditAction({ isEdit: false }))}
270
+ />
271
+ )}
272
+ <SendInput
273
+ editMessage={editAction && editAction.text}
274
+ sendMedia={sendMedia}
275
+ sendMessage={editAction?.isEdit ? sendEditMessage : sendMessage}
276
+ config={config}
277
+ onFocus={sendStartComposing}
278
+ onBlur={sendEndComposing}
279
+ isLoading={!!room?.isLoading}
280
+ isMessageProcessing={isLastMessageFromUserAndProcessing(roomJid)}
281
+ />
282
+ </DockTag>
283
+ </KeyboardAvoidingView>
236
284
 
237
- {config?.customTypingIndicator?.enabled &&
238
- (config.customTypingIndicator.position === 'overlay' ||
239
- config.customTypingIndicator.position === 'floating') &&
240
- roomsList[activeMessage.roomJid]?.composing && (
241
- <CustomTypingIndicator
242
- usersTyping={
243
- roomsList[activeMessage.roomJid]?.composingList || ['User']
244
- }
245
- text={config.customTypingIndicator.text}
246
- position={config.customTypingIndicator.position}
247
- styles={config.customTypingIndicator.styles}
248
- customComponent={config.customTypingIndicator.customComponent}
249
- isVisible={roomsList[activeMessage.roomJid]?.composing || false}
250
- />
251
- )}
252
- </Animated.View>
285
+ {config?.customTypingIndicator?.enabled &&
286
+ (config.customTypingIndicator.position === 'overlay' ||
287
+ config.customTypingIndicator.position === 'floating') &&
288
+ room?.composing && (
289
+ <CustomTypingIndicator
290
+ usersTyping={room?.composingList || ['User']}
291
+ text={config.customTypingIndicator.text}
292
+ position={config.customTypingIndicator.position}
293
+ styles={config.customTypingIndicator.styles}
294
+ customComponent={config.customTypingIndicator.customComponent}
295
+ isVisible={!!room?.composing}
296
+ />
297
+ )}
298
+ </Animated.View>
299
+ </GestureDetector>
253
300
  );
254
301
  };
255
302
 
256
303
  export default ThreadWrapper;
257
304
 
258
305
  const styles = StyleSheet.create({
259
- threadContainer: {
260
- zIndex: 999,
306
+ thread: {
261
307
  position: 'absolute',
262
308
  top: 0,
263
- bottom: 0,
264
309
  right: 0,
265
- width: '100%',
266
- height: '100%',
267
- backgroundColor: '#f3f6fc',
268
- flexDirection: 'column',
269
- justifyContent: 'space-between',
310
+ bottom: 0,
311
+ left: 0,
312
+ zIndex: 999,
313
+ shadowColor: '#000',
314
+ shadowOffset: { width: -4, height: 0 },
315
+ shadowOpacity: 0.18,
316
+ shadowRadius: 12,
317
+ },
318
+ fill: {
270
319
  flex: 1,
271
320
  },
272
- text: {
273
- color: '#fff',
274
- fontSize: 18,
321
+ dock: {
322
+ borderTopLeftRadius: 20,
323
+ borderTopRightRadius: 20,
324
+ shadowOffset: { width: 0, height: -4 },
325
+ shadowOpacity: 0.06,
326
+ shadowRadius: 12,
327
+ elevation: 8,
328
+ },
329
+ also: {
330
+ flexDirection: 'row',
331
+ alignItems: 'center',
332
+ paddingHorizontal: 20,
333
+ paddingTop: 10,
334
+ gap: 8,
335
+ },
336
+ checkbox: {
337
+ width: 18,
338
+ height: 18,
339
+ borderRadius: 5,
340
+ borderWidth: 1.5,
341
+ alignItems: 'center',
342
+ justifyContent: 'center',
343
+ },
344
+ check: {
345
+ fontSize: 12,
346
+ fontWeight: '700',
347
+ lineHeight: 14,
348
+ },
349
+ alsoText: {
350
+ fontSize: 14,
275
351
  },
276
352
  });
@@ -7,6 +7,7 @@ import { useT, useUiLocale } from '../../i18n/useT';
7
7
 
8
8
  interface DateLabelProps {
9
9
  date: Date;
10
+ /** Unused since the theme carries these; kept for callers' signatures. */
10
11
  colors?: { primary?: string; secondary?: string; dateLabel?: string };
11
12
  }
12
13
 
@@ -71,11 +72,14 @@ const DateLabel: React.FC<DateLabelProps> = ({ date, colors }) => {
71
72
  label = date.toLocaleDateString(uiLocale, options);
72
73
  }
73
74
 
74
- // Theme-aware: dark mode ignores the light-only `colors` knobs (the
75
- // theme already folds `colors.dateLabel` / `colors.primary` in light).
75
+ // Both colours come from the theme: the host's `colors.dateLabel` /
76
+ // `colors.dateLabelBackground` (light) and `darkColors.*` (dark) are
77
+ // already folded in there, with the palette defaults underneath. The
78
+ // pill no longer borrows `colors.secondary` — that is the accent for
79
+ // text on primary, and hosts set it to near-black.
76
80
  const theme = useTheme();
77
81
  const textColor = theme.dateLabel;
78
- const bgColor = theme.dark ? theme.surfaceSecondary : colors?.secondary;
82
+ const bgColor = theme.dateLabelBackground;
79
83
 
80
84
  return (
81
85
  <Container>