@ethora/chat-component-rn 26.8.5 → 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 (373) 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/MainComponents/ChatHeader.js +7 -9
  7. package/lib/commonjs/components/MainComponents/ChatHeader.js.map +1 -1
  8. package/lib/commonjs/components/MainComponents/ChatRoom.js +24 -23
  9. package/lib/commonjs/components/MainComponents/ChatRoom.js.map +1 -1
  10. package/lib/commonjs/components/MainComponents/ChatWrapper.js +22 -16
  11. package/lib/commonjs/components/MainComponents/ChatWrapper.js.map +1 -1
  12. package/lib/commonjs/components/MainComponents/MessageContainer.js +4 -12
  13. package/lib/commonjs/components/MainComponents/MessageContainer.js.map +1 -1
  14. package/lib/commonjs/components/MainComponents/MessageList.js +110 -35
  15. package/lib/commonjs/components/MainComponents/MessageList.js.map +1 -1
  16. package/lib/commonjs/components/MainComponents/RoomList.js +32 -29
  17. package/lib/commonjs/components/MainComponents/RoomList.js.map +1 -1
  18. package/lib/commonjs/components/MainComponents/RoomStack.js +133 -65
  19. package/lib/commonjs/components/MainComponents/RoomStack.js.map +1 -1
  20. package/lib/commonjs/components/MainComponents/SystemMessage.js +6 -2
  21. package/lib/commonjs/components/MainComponents/SystemMessage.js.map +1 -1
  22. package/lib/commonjs/components/MessageBubble/Avatar.js +5 -1
  23. package/lib/commonjs/components/MessageBubble/Avatar.js.map +1 -1
  24. package/lib/commonjs/components/MessageBubble/BottomReplyContainer.js +17 -21
  25. package/lib/commonjs/components/MessageBubble/BottomReplyContainer.js.map +1 -1
  26. package/lib/commonjs/components/MessageBubble/EmojiPickerSheet.js +447 -0
  27. package/lib/commonjs/components/MessageBubble/EmojiPickerSheet.js.map +1 -0
  28. package/lib/commonjs/components/MessageBubble/Message.js +200 -132
  29. package/lib/commonjs/components/MessageBubble/Message.js.map +1 -1
  30. package/lib/commonjs/components/MessageBubble/MessageInteractions.js +213 -12
  31. package/lib/commonjs/components/MessageBubble/MessageInteractions.js.map +1 -1
  32. package/lib/commonjs/components/MessageBubble/MessageReaction.js +113 -94
  33. package/lib/commonjs/components/MessageBubble/MessageReaction.js.map +1 -1
  34. package/lib/commonjs/components/MessageBubble/MessageReply.js +66 -24
  35. package/lib/commonjs/components/MessageBubble/MessageReply.js.map +1 -1
  36. package/lib/commonjs/components/Modals/Modal/SwipeBackLayer.js +76 -44
  37. package/lib/commonjs/components/Modals/Modal/SwipeBackLayer.js.map +1 -1
  38. package/lib/commonjs/components/RoomComponents/ChatRoomItem.js +5 -4
  39. package/lib/commonjs/components/RoomComponents/ChatRoomItem.js.map +1 -1
  40. package/lib/commonjs/components/RoomComponents/styled/LastMessageEmoji.js +8 -9
  41. package/lib/commonjs/components/RoomComponents/styled/LastMessageEmoji.js.map +1 -1
  42. package/lib/commonjs/components/Thread/ThreadWrapper.js +265 -152
  43. package/lib/commonjs/components/Thread/ThreadWrapper.js.map +1 -1
  44. package/lib/commonjs/components/styled/DateLabel.js +6 -3
  45. package/lib/commonjs/components/styled/DateLabel.js.map +1 -1
  46. package/lib/commonjs/context/MessageNotificationContext.js +188 -9
  47. package/lib/commonjs/context/MessageNotificationContext.js.map +1 -1
  48. package/lib/commonjs/context/xmppProvider.js +22 -7
  49. package/lib/commonjs/context/xmppProvider.js.map +1 -1
  50. package/lib/commonjs/helpers/createRoomFromApi.js +36 -2
  51. package/lib/commonjs/helpers/createRoomFromApi.js.map +1 -1
  52. package/lib/commonjs/helpers/emoji.js +51 -0
  53. package/lib/commonjs/helpers/emoji.js.map +1 -0
  54. package/lib/commonjs/helpers/haptics.js +29 -0
  55. package/lib/commonjs/helpers/haptics.js.map +1 -0
  56. package/lib/commonjs/helpers/historyPreloadScheduler.js +32 -66
  57. package/lib/commonjs/helpers/historyPreloadScheduler.js.map +1 -1
  58. package/lib/commonjs/helpers/insertMessageWithDelimiter.js +21 -12
  59. package/lib/commonjs/helpers/insertMessageWithDelimiter.js.map +1 -1
  60. package/lib/commonjs/helpers/mamReactions.js +57 -0
  61. package/lib/commonjs/helpers/mamReactions.js.map +1 -0
  62. package/lib/commonjs/helpers/parseMessageReference.js +42 -0
  63. package/lib/commonjs/helpers/parseMessageReference.js.map +1 -0
  64. package/lib/commonjs/helpers/reactionsConfig.js +17 -0
  65. package/lib/commonjs/helpers/reactionsConfig.js.map +1 -0
  66. package/lib/commonjs/helpers/updateMessagesTillLast.js +17 -2
  67. package/lib/commonjs/helpers/updateMessagesTillLast.js.map +1 -1
  68. package/lib/commonjs/hooks/useHeapSender.js +3 -1
  69. package/lib/commonjs/hooks/useHeapSender.js.map +1 -1
  70. package/lib/commonjs/hooks/useMessageHeapState.js +3 -2
  71. package/lib/commonjs/hooks/useMessageHeapState.js.map +1 -1
  72. package/lib/commonjs/hooks/useRoomInitialization.js +16 -7
  73. package/lib/commonjs/hooks/useRoomInitialization.js.map +1 -1
  74. package/lib/commonjs/hooks/useSendMessage.js +14 -8
  75. package/lib/commonjs/hooks/useSendMessage.js.map +1 -1
  76. package/lib/commonjs/hooks/useUnreadMessagesCounter.js +1 -1
  77. package/lib/commonjs/hooks/useUnreadMessagesCounter.js.map +1 -1
  78. package/lib/commonjs/networking/stanzaHandlers.js +106 -50
  79. package/lib/commonjs/networking/stanzaHandlers.js.map +1 -1
  80. package/lib/commonjs/networking/xmpp/getHistory.xmpp.js +29 -74
  81. package/lib/commonjs/networking/xmpp/getHistory.xmpp.js.map +1 -1
  82. package/lib/commonjs/networking/xmpp/handleStanzas.xmpp.js +4 -0
  83. package/lib/commonjs/networking/xmpp/handleStanzas.xmpp.js.map +1 -1
  84. package/lib/commonjs/networking/xmpp/mamRouter.js +186 -0
  85. package/lib/commonjs/networking/xmpp/mamRouter.js.map +1 -0
  86. package/lib/commonjs/networking/xmpp/presenceInRoom.xmpp.js +41 -4
  87. package/lib/commonjs/networking/xmpp/presenceInRoom.xmpp.js.map +1 -1
  88. package/lib/commonjs/networking/xmppClient.js +98 -23
  89. package/lib/commonjs/networking/xmppClient.js.map +1 -1
  90. package/lib/commonjs/roomStore/Middleware/newMessageMidlleware.js +29 -34
  91. package/lib/commonjs/roomStore/Middleware/newMessageMidlleware.js.map +1 -1
  92. package/lib/commonjs/roomStore/Middleware/perfMiddleware.js +51 -0
  93. package/lib/commonjs/roomStore/Middleware/perfMiddleware.js.map +1 -0
  94. package/lib/commonjs/roomStore/Middleware/reactionsMiddleware.js +66 -43
  95. package/lib/commonjs/roomStore/Middleware/reactionsMiddleware.js.map +1 -1
  96. package/lib/commonjs/roomStore/Middleware/unreadMidlleware.js +88 -68
  97. package/lib/commonjs/roomStore/Middleware/unreadMidlleware.js.map +1 -1
  98. package/lib/commonjs/roomStore/index.js +18 -14
  99. package/lib/commonjs/roomStore/index.js.map +1 -1
  100. package/lib/commonjs/roomStore/persistBackend.js +96 -0
  101. package/lib/commonjs/roomStore/persistBackend.js.map +1 -0
  102. package/lib/commonjs/roomStore/persistence.js +245 -50
  103. package/lib/commonjs/roomStore/persistence.js.map +1 -1
  104. package/lib/commonjs/roomStore/roomsSlice.js +282 -136
  105. package/lib/commonjs/roomStore/roomsSlice.js.map +1 -1
  106. package/lib/commonjs/theme/theme.js +3 -0
  107. package/lib/commonjs/theme/theme.js.map +1 -1
  108. package/lib/commonjs/utils/devLogger.js +14 -0
  109. package/lib/commonjs/utils/devLogger.js.map +1 -1
  110. package/lib/commonjs/version.js +1 -1
  111. package/lib/module/assets/emojiData.js +36 -0
  112. package/lib/module/assets/emojiData.js.map +1 -0
  113. package/lib/module/assets/icons.js +1 -1
  114. package/lib/module/assets/icons.js.map +1 -1
  115. package/lib/module/components/MainComponents/ChatHeader.js +8 -10
  116. package/lib/module/components/MainComponents/ChatHeader.js.map +1 -1
  117. package/lib/module/components/MainComponents/ChatRoom.js +25 -24
  118. package/lib/module/components/MainComponents/ChatRoom.js.map +1 -1
  119. package/lib/module/components/MainComponents/ChatWrapper.js +23 -17
  120. package/lib/module/components/MainComponents/ChatWrapper.js.map +1 -1
  121. package/lib/module/components/MainComponents/MessageContainer.js +7 -14
  122. package/lib/module/components/MainComponents/MessageContainer.js.map +1 -1
  123. package/lib/module/components/MainComponents/MessageList.js +110 -35
  124. package/lib/module/components/MainComponents/MessageList.js.map +1 -1
  125. package/lib/module/components/MainComponents/RoomList.js +32 -29
  126. package/lib/module/components/MainComponents/RoomList.js.map +1 -1
  127. package/lib/module/components/MainComponents/RoomStack.js +131 -63
  128. package/lib/module/components/MainComponents/RoomStack.js.map +1 -1
  129. package/lib/module/components/MainComponents/SystemMessage.js +6 -2
  130. package/lib/module/components/MainComponents/SystemMessage.js.map +1 -1
  131. package/lib/module/components/MessageBubble/Avatar.js +5 -1
  132. package/lib/module/components/MessageBubble/Avatar.js.map +1 -1
  133. package/lib/module/components/MessageBubble/BottomReplyContainer.js +18 -22
  134. package/lib/module/components/MessageBubble/BottomReplyContainer.js.map +1 -1
  135. package/lib/module/components/MessageBubble/EmojiPickerSheet.js +438 -0
  136. package/lib/module/components/MessageBubble/EmojiPickerSheet.js.map +1 -0
  137. package/lib/module/components/MessageBubble/Message.js +203 -134
  138. package/lib/module/components/MessageBubble/Message.js.map +1 -1
  139. package/lib/module/components/MessageBubble/MessageInteractions.js +215 -14
  140. package/lib/module/components/MessageBubble/MessageInteractions.js.map +1 -1
  141. package/lib/module/components/MessageBubble/MessageReaction.js +115 -94
  142. package/lib/module/components/MessageBubble/MessageReaction.js.map +1 -1
  143. package/lib/module/components/MessageBubble/MessageReply.js +65 -24
  144. package/lib/module/components/MessageBubble/MessageReply.js.map +1 -1
  145. package/lib/module/components/Modals/Modal/SwipeBackLayer.js +76 -44
  146. package/lib/module/components/Modals/Modal/SwipeBackLayer.js.map +1 -1
  147. package/lib/module/components/RoomComponents/ChatRoomItem.js +5 -4
  148. package/lib/module/components/RoomComponents/ChatRoomItem.js.map +1 -1
  149. package/lib/module/components/RoomComponents/styled/LastMessageEmoji.js +8 -9
  150. package/lib/module/components/RoomComponents/styled/LastMessageEmoji.js.map +1 -1
  151. package/lib/module/components/Thread/ThreadWrapper.js +264 -152
  152. package/lib/module/components/Thread/ThreadWrapper.js.map +1 -1
  153. package/lib/module/components/styled/DateLabel.js +6 -3
  154. package/lib/module/components/styled/DateLabel.js.map +1 -1
  155. package/lib/module/context/MessageNotificationContext.js +190 -11
  156. package/lib/module/context/MessageNotificationContext.js.map +1 -1
  157. package/lib/module/context/xmppProvider.js +22 -7
  158. package/lib/module/context/xmppProvider.js.map +1 -1
  159. package/lib/module/helpers/createRoomFromApi.js +36 -2
  160. package/lib/module/helpers/createRoomFromApi.js.map +1 -1
  161. package/lib/module/helpers/emoji.js +44 -0
  162. package/lib/module/helpers/emoji.js.map +1 -0
  163. package/lib/module/helpers/haptics.js +24 -0
  164. package/lib/module/helpers/haptics.js.map +1 -0
  165. package/lib/module/helpers/historyPreloadScheduler.js +32 -66
  166. package/lib/module/helpers/historyPreloadScheduler.js.map +1 -1
  167. package/lib/module/helpers/insertMessageWithDelimiter.js +21 -12
  168. package/lib/module/helpers/insertMessageWithDelimiter.js.map +1 -1
  169. package/lib/module/helpers/mamReactions.js +51 -0
  170. package/lib/module/helpers/mamReactions.js.map +1 -0
  171. package/lib/module/helpers/parseMessageReference.js +37 -0
  172. package/lib/module/helpers/parseMessageReference.js.map +1 -0
  173. package/lib/module/helpers/reactionsConfig.js +10 -0
  174. package/lib/module/helpers/reactionsConfig.js.map +1 -0
  175. package/lib/module/helpers/updateMessagesTillLast.js +17 -2
  176. package/lib/module/helpers/updateMessagesTillLast.js.map +1 -1
  177. package/lib/module/hooks/useHeapSender.js +3 -1
  178. package/lib/module/hooks/useHeapSender.js.map +1 -1
  179. package/lib/module/hooks/useMessageHeapState.js +3 -2
  180. package/lib/module/hooks/useMessageHeapState.js.map +1 -1
  181. package/lib/module/hooks/useRoomInitialization.js +17 -8
  182. package/lib/module/hooks/useRoomInitialization.js.map +1 -1
  183. package/lib/module/hooks/useSendMessage.js +14 -8
  184. package/lib/module/hooks/useSendMessage.js.map +1 -1
  185. package/lib/module/hooks/useUnreadMessagesCounter.js +1 -1
  186. package/lib/module/hooks/useUnreadMessagesCounter.js.map +1 -1
  187. package/lib/module/networking/stanzaHandlers.js +107 -51
  188. package/lib/module/networking/stanzaHandlers.js.map +1 -1
  189. package/lib/module/networking/xmpp/getHistory.xmpp.js +29 -74
  190. package/lib/module/networking/xmpp/getHistory.xmpp.js.map +1 -1
  191. package/lib/module/networking/xmpp/handleStanzas.xmpp.js +4 -0
  192. package/lib/module/networking/xmpp/handleStanzas.xmpp.js.map +1 -1
  193. package/lib/module/networking/xmpp/mamRouter.js +175 -0
  194. package/lib/module/networking/xmpp/mamRouter.js.map +1 -0
  195. package/lib/module/networking/xmpp/presenceInRoom.xmpp.js +38 -2
  196. package/lib/module/networking/xmpp/presenceInRoom.xmpp.js.map +1 -1
  197. package/lib/module/networking/xmppClient.js +99 -24
  198. package/lib/module/networking/xmppClient.js.map +1 -1
  199. package/lib/module/roomStore/Middleware/newMessageMidlleware.js +29 -34
  200. package/lib/module/roomStore/Middleware/newMessageMidlleware.js.map +1 -1
  201. package/lib/module/roomStore/Middleware/perfMiddleware.js +45 -0
  202. package/lib/module/roomStore/Middleware/perfMiddleware.js.map +1 -0
  203. package/lib/module/roomStore/Middleware/reactionsMiddleware.js +66 -43
  204. package/lib/module/roomStore/Middleware/reactionsMiddleware.js.map +1 -1
  205. package/lib/module/roomStore/Middleware/unreadMidlleware.js +89 -69
  206. package/lib/module/roomStore/Middleware/unreadMidlleware.js.map +1 -1
  207. package/lib/module/roomStore/index.js +19 -15
  208. package/lib/module/roomStore/index.js.map +1 -1
  209. package/lib/module/roomStore/persistBackend.js +89 -0
  210. package/lib/module/roomStore/persistBackend.js.map +1 -0
  211. package/lib/module/roomStore/persistence.js +245 -48
  212. package/lib/module/roomStore/persistence.js.map +1 -1
  213. package/lib/module/roomStore/roomsSlice.js +275 -134
  214. package/lib/module/roomStore/roomsSlice.js.map +1 -1
  215. package/lib/module/theme/theme.js +3 -0
  216. package/lib/module/theme/theme.js.map +1 -1
  217. package/lib/module/utils/devLogger.js +13 -0
  218. package/lib/module/utils/devLogger.js.map +1 -1
  219. package/lib/module/version.js +1 -1
  220. package/lib/typescript/assets/emojiData.d.ts +8 -0
  221. package/lib/typescript/assets/emojiData.d.ts.map +1 -0
  222. package/lib/typescript/components/MainComponents/ChatHeader.d.ts.map +1 -1
  223. package/lib/typescript/components/MainComponents/ChatRoom.d.ts.map +1 -1
  224. package/lib/typescript/components/MainComponents/ChatWrapper.d.ts.map +1 -1
  225. package/lib/typescript/components/MainComponents/MessageContainer.d.ts +2 -2
  226. package/lib/typescript/components/MainComponents/MessageContainer.d.ts.map +1 -1
  227. package/lib/typescript/components/MainComponents/MessageList.d.ts.map +1 -1
  228. package/lib/typescript/components/MainComponents/RoomList.d.ts.map +1 -1
  229. package/lib/typescript/components/MainComponents/RoomStack.d.ts +7 -2
  230. package/lib/typescript/components/MainComponents/RoomStack.d.ts.map +1 -1
  231. package/lib/typescript/components/MainComponents/SystemMessage.d.ts.map +1 -1
  232. package/lib/typescript/components/MessageBubble/Avatar.d.ts +2 -0
  233. package/lib/typescript/components/MessageBubble/Avatar.d.ts.map +1 -1
  234. package/lib/typescript/components/MessageBubble/BottomReplyContainer.d.ts.map +1 -1
  235. package/lib/typescript/components/MessageBubble/EmojiPickerSheet.d.ts +11 -0
  236. package/lib/typescript/components/MessageBubble/EmojiPickerSheet.d.ts.map +1 -0
  237. package/lib/typescript/components/MessageBubble/Message.d.ts +2 -2
  238. package/lib/typescript/components/MessageBubble/Message.d.ts.map +1 -1
  239. package/lib/typescript/components/MessageBubble/MessageInteractions.d.ts +2 -0
  240. package/lib/typescript/components/MessageBubble/MessageInteractions.d.ts.map +1 -1
  241. package/lib/typescript/components/MessageBubble/MessageReaction.d.ts +1 -0
  242. package/lib/typescript/components/MessageBubble/MessageReaction.d.ts.map +1 -1
  243. package/lib/typescript/components/MessageBubble/MessageReply.d.ts +7 -7
  244. package/lib/typescript/components/MessageBubble/MessageReply.d.ts.map +1 -1
  245. package/lib/typescript/components/Modals/Modal/SwipeBackLayer.d.ts +2 -1
  246. package/lib/typescript/components/Modals/Modal/SwipeBackLayer.d.ts.map +1 -1
  247. package/lib/typescript/components/RoomComponents/ChatRoomItem.d.ts +2 -2
  248. package/lib/typescript/components/RoomComponents/ChatRoomItem.d.ts.map +1 -1
  249. package/lib/typescript/components/RoomComponents/styled/LastMessageEmoji.d.ts +3 -6
  250. package/lib/typescript/components/RoomComponents/styled/LastMessageEmoji.d.ts.map +1 -1
  251. package/lib/typescript/components/Thread/ThreadWrapper.d.ts +7 -1
  252. package/lib/typescript/components/Thread/ThreadWrapper.d.ts.map +1 -1
  253. package/lib/typescript/components/styled/DateLabel.d.ts +1 -0
  254. package/lib/typescript/components/styled/DateLabel.d.ts.map +1 -1
  255. package/lib/typescript/context/MessageNotificationContext.d.ts.map +1 -1
  256. package/lib/typescript/context/xmppProvider.d.ts.map +1 -1
  257. package/lib/typescript/helpers/createRoomFromApi.d.ts.map +1 -1
  258. package/lib/typescript/helpers/emoji.d.ts +6 -0
  259. package/lib/typescript/helpers/emoji.d.ts.map +1 -0
  260. package/lib/typescript/helpers/haptics.d.ts +3 -0
  261. package/lib/typescript/helpers/haptics.d.ts.map +1 -0
  262. package/lib/typescript/helpers/historyPreloadScheduler.d.ts +1 -0
  263. package/lib/typescript/helpers/historyPreloadScheduler.d.ts.map +1 -1
  264. package/lib/typescript/helpers/insertMessageWithDelimiter.d.ts.map +1 -1
  265. package/lib/typescript/helpers/mamReactions.d.ts +13 -0
  266. package/lib/typescript/helpers/mamReactions.d.ts.map +1 -0
  267. package/lib/typescript/helpers/parseMessageReference.d.ts +16 -0
  268. package/lib/typescript/helpers/parseMessageReference.d.ts.map +1 -0
  269. package/lib/typescript/helpers/reactionsConfig.d.ts +5 -0
  270. package/lib/typescript/helpers/reactionsConfig.d.ts.map +1 -0
  271. package/lib/typescript/helpers/updateMessagesTillLast.d.ts.map +1 -1
  272. package/lib/typescript/hooks/useHeapSender.d.ts.map +1 -1
  273. package/lib/typescript/hooks/useMessageHeapState.d.ts.map +1 -1
  274. package/lib/typescript/hooks/useRoomInitialization.d.ts +2 -2
  275. package/lib/typescript/hooks/useRoomInitialization.d.ts.map +1 -1
  276. package/lib/typescript/hooks/useSendMessage.d.ts.map +1 -1
  277. package/lib/typescript/networking/stanzaHandlers.d.ts +4 -2
  278. package/lib/typescript/networking/stanzaHandlers.d.ts.map +1 -1
  279. package/lib/typescript/networking/xmpp/getHistory.xmpp.d.ts +3 -1
  280. package/lib/typescript/networking/xmpp/getHistory.xmpp.d.ts.map +1 -1
  281. package/lib/typescript/networking/xmpp/handleStanzas.xmpp.d.ts.map +1 -1
  282. package/lib/typescript/networking/xmpp/mamRouter.d.ts +23 -0
  283. package/lib/typescript/networking/xmpp/mamRouter.d.ts.map +1 -0
  284. package/lib/typescript/networking/xmpp/presenceInRoom.xmpp.d.ts +1 -0
  285. package/lib/typescript/networking/xmpp/presenceInRoom.xmpp.d.ts.map +1 -1
  286. package/lib/typescript/networking/xmppClient.d.ts +22 -1
  287. package/lib/typescript/networking/xmppClient.d.ts.map +1 -1
  288. package/lib/typescript/roomStore/Middleware/newMessageMidlleware.d.ts.map +1 -1
  289. package/lib/typescript/roomStore/Middleware/perfMiddleware.d.ts +4 -0
  290. package/lib/typescript/roomStore/Middleware/perfMiddleware.d.ts.map +1 -0
  291. package/lib/typescript/roomStore/Middleware/reactionsMiddleware.d.ts +9 -0
  292. package/lib/typescript/roomStore/Middleware/reactionsMiddleware.d.ts.map +1 -1
  293. package/lib/typescript/roomStore/Middleware/unreadMidlleware.d.ts.map +1 -1
  294. package/lib/typescript/roomStore/index.d.ts.map +1 -1
  295. package/lib/typescript/roomStore/persistBackend.d.ts +11 -0
  296. package/lib/typescript/roomStore/persistBackend.d.ts.map +1 -0
  297. package/lib/typescript/roomStore/persistence.d.ts +5 -6
  298. package/lib/typescript/roomStore/persistence.d.ts.map +1 -1
  299. package/lib/typescript/roomStore/roomsSlice.d.ts +41 -1
  300. package/lib/typescript/roomStore/roomsSlice.d.ts.map +1 -1
  301. package/lib/typescript/theme/theme.d.ts +4 -1
  302. package/lib/typescript/theme/theme.d.ts.map +1 -1
  303. package/lib/typescript/types/models/message.model.d.ts +4 -0
  304. package/lib/typescript/types/models/message.model.d.ts.map +1 -1
  305. package/lib/typescript/types/models/room.model.d.ts +16 -0
  306. package/lib/typescript/types/models/room.model.d.ts.map +1 -1
  307. package/lib/typescript/types/models/xmpp.model.d.ts +6 -1
  308. package/lib/typescript/types/models/xmpp.model.d.ts.map +1 -1
  309. package/lib/typescript/types/types.d.ts +15 -3
  310. package/lib/typescript/types/types.d.ts.map +1 -1
  311. package/lib/typescript/utils/devLogger.d.ts +8 -0
  312. package/lib/typescript/utils/devLogger.d.ts.map +1 -1
  313. package/lib/typescript/version.d.ts +1 -1
  314. package/package.json +10 -1
  315. package/src/assets/emojiData.ts +2146 -0
  316. package/src/assets/icons.tsx +5 -5
  317. package/src/components/MainComponents/ChatHeader.tsx +16 -7
  318. package/src/components/MainComponents/ChatRoom.tsx +35 -29
  319. package/src/components/MainComponents/ChatWrapper.tsx +28 -10
  320. package/src/components/MainComponents/MessageContainer.tsx +7 -15
  321. package/src/components/MainComponents/MessageList.tsx +96 -43
  322. package/src/components/MainComponents/RoomList.tsx +28 -29
  323. package/src/components/MainComponents/RoomStack.tsx +156 -83
  324. package/src/components/MainComponents/SystemMessage.tsx +6 -2
  325. package/src/components/MessageBubble/Avatar.tsx +7 -1
  326. package/src/components/MessageBubble/BottomReplyContainer.tsx +19 -21
  327. package/src/components/MessageBubble/EmojiPickerSheet.tsx +468 -0
  328. package/src/components/MessageBubble/Message.tsx +146 -87
  329. package/src/components/MessageBubble/MessageInteractions.tsx +213 -12
  330. package/src/components/MessageBubble/MessageReaction.tsx +120 -96
  331. package/src/components/MessageBubble/MessageReply.tsx +65 -32
  332. package/src/components/Modals/Modal/SwipeBackLayer.tsx +114 -63
  333. package/src/components/RoomComponents/ChatRoomItem.tsx +11 -4
  334. package/src/components/RoomComponents/styled/LastMessageEmoji.tsx +7 -8
  335. package/src/components/Thread/ThreadWrapper.tsx +274 -198
  336. package/src/components/styled/DateLabel.tsx +7 -3
  337. package/src/context/MessageNotificationContext.tsx +205 -7
  338. package/src/context/xmppProvider.tsx +29 -9
  339. package/src/helpers/createRoomFromApi.tsx +37 -1
  340. package/src/helpers/emoji.ts +39 -0
  341. package/src/helpers/haptics.ts +19 -0
  342. package/src/helpers/historyPreloadScheduler.ts +37 -69
  343. package/src/helpers/insertMessageWithDelimiter.ts +23 -16
  344. package/src/helpers/mamReactions.ts +59 -0
  345. package/src/helpers/parseMessageReference.ts +38 -0
  346. package/src/helpers/reactionsConfig.ts +13 -0
  347. package/src/helpers/updateMessagesTillLast.tsx +14 -2
  348. package/src/hooks/useHeapSender.tsx +3 -2
  349. package/src/hooks/useMessageHeapState.tsx +6 -2
  350. package/src/hooks/useRoomInitialization.tsx +32 -15
  351. package/src/hooks/useSendMessage.tsx +18 -11
  352. package/src/hooks/useUnreadMessagesCounter.ts +1 -1
  353. package/src/networking/stanzaHandlers.ts +116 -60
  354. package/src/networking/xmpp/getHistory.xmpp.ts +44 -106
  355. package/src/networking/xmpp/handleStanzas.xmpp.ts +2 -0
  356. package/src/networking/xmpp/mamRouter.ts +176 -0
  357. package/src/networking/xmpp/presenceInRoom.xmpp.ts +46 -3
  358. package/src/networking/xmppClient.ts +105 -20
  359. package/src/roomStore/Middleware/newMessageMidlleware.tsx +35 -38
  360. package/src/roomStore/Middleware/perfMiddleware.ts +50 -0
  361. package/src/roomStore/Middleware/reactionsMiddleware.tsx +53 -52
  362. package/src/roomStore/Middleware/unreadMidlleware.tsx +92 -80
  363. package/src/roomStore/index.ts +28 -27
  364. package/src/roomStore/persistBackend.ts +96 -0
  365. package/src/roomStore/persistence.ts +280 -73
  366. package/src/roomStore/roomsSlice.ts +304 -155
  367. package/src/theme/theme.ts +10 -1
  368. package/src/types/models/message.model.ts +4 -0
  369. package/src/types/models/room.model.ts +17 -0
  370. package/src/types/models/xmpp.model.ts +4 -2
  371. package/src/types/types.ts +15 -3
  372. package/src/utils/devLogger.ts +16 -0
  373. package/src/version.ts +1 -1
@@ -1,52 +1,44 @@
1
- /* eslint-disable react-hooks/rules-of-hooks -- pre-existing port artifacts; hooks called conditionally / inside helpers. TODO: refactor */
2
- import React, { FC, useMemo, useState } from 'react';
3
- import { View, Text, TouchableOpacity, Animated } from 'react-native';
4
- import styled from 'styled-components/native';
1
+ import React, { FC, useMemo, useRef, useState } from 'react';
2
+ import { View, Text, TouchableOpacity, Animated, StyleSheet } from 'react-native';
5
3
  import { ReactionMessage } from '../../types/types';
6
4
  import { useTheme } from '../../hooks/useTheme';
7
-
8
- const ReactionContainer = styled.View`
9
- flex-direction: row;
10
- align-items: center;
11
- gap: 8px;
12
- `;
13
-
14
- const ReactionBox = styled(TouchableOpacity)<{ active: boolean; color: string }>`
15
- padding: 4px 8px;
16
- border-radius: 20px;
17
- background-color: ${({ active, color, theme }) =>
18
- active ? color : theme.surface};
19
- flex-direction: row;
20
- align-items: center;
21
- justify-content: center;
22
- elevation: 3;
23
- `;
5
+ import { getEmojiNativeById } from '../../helpers/emoji';
24
6
 
25
7
  interface MessageReactionProps {
26
8
  color: string;
27
9
  reaction: Record<string, ReactionMessage>;
28
10
  changeReaction: (reaction: string) => void;
29
11
  userName?: string;
30
- }
31
12
 
32
- const emojiMap: Record<string, string> = {
33
- joy: '😂',
34
- heart: '❤️',
35
- fire: '🔥',
36
- '+1': '👍',
37
- smile: '😄',
38
- scream: '😱',
39
- };
13
+ interactive?: boolean;
14
+ }
40
15
 
41
16
  export const MessageReaction: FC<MessageReactionProps> = ({
42
17
  reaction,
43
18
  color,
44
19
  changeReaction,
45
20
  userName,
21
+ interactive = true,
46
22
  }) => {
47
23
  const theme = useTheme();
48
24
  const [tooltipEmoji, setTooltipEmoji] = useState<string | null>(null);
49
- const fadeAnim = new Animated.Value(0);
25
+ const fadeAnim = useRef(new Animated.Value(0)).current;
26
+
27
+ const reactionDetails = useMemo(() => {
28
+ const result: Record<string, { count: number; users: string[] }> = {};
29
+ Object.values(reaction || {}).forEach(({ emoji, data }) => {
30
+ (emoji || []).forEach((em) => {
31
+ if (!result[em]) {result[em] = { count: 0, users: [] };}
32
+ result[em].count += 1;
33
+ result[em].users.push(
34
+ `${data?.senderFirstName || ''} ${data?.senderLastName || ''}`.trim()
35
+ );
36
+ });
37
+ });
38
+ return result;
39
+ }, [reaction]);
40
+
41
+ if (!reaction || Object.keys(reactionDetails).length === 0) {return null;}
50
42
 
51
43
  const showTooltip = (emoji: string) => {
52
44
  setTooltipEmoji(emoji);
@@ -65,90 +57,122 @@ export const MessageReaction: FC<MessageReactionProps> = ({
65
57
  }).start(() => setTooltipEmoji(null));
66
58
  };
67
59
 
68
- if (!reaction) {return null;}
69
-
70
- const reactionDetails = useMemo(() => {
71
- const result: Record<string, { count: number; users: string[] }> = {};
72
-
73
- Object.values(reaction).forEach(({ emoji, data }) => {
74
- if (emoji && emoji.length > 0)
75
- {emoji.forEach((em) => {
76
- if (!result[em]) {
77
- result[em] = { count: 0, users: [] };
78
- }
79
- result[em].count += 1;
80
- result[em].users.push(`${data?.senderFirstName} ${data?.senderLastName}`);
81
- });}
82
- });
83
-
84
- return result;
85
- }, [reaction]);
86
-
87
60
  return (
88
- <ReactionContainer>
61
+ <View style={styles.row}>
89
62
  {Object.entries(reactionDetails).map(([emoji, details]) => {
90
- const isUserReacted = userName
91
- ? details.users.includes(userName)
92
- : false;
93
-
63
+ const isUserReacted = !!userName && details.users.includes(userName);
94
64
  return (
95
- <View key={emoji} style={{ position: 'relative' }}>
96
- <ReactionBox
97
- active={isUserReacted}
98
- color={color}
65
+ <View key={emoji} style={styles.chipWrap}>
66
+ <TouchableOpacity
67
+ testID={`reaction-chip-${emoji}`}
68
+ activeOpacity={0.7}
69
+ disabled={!interactive}
99
70
  onPress={() => changeReaction(emoji)}
100
71
  onLongPress={() => showTooltip(emoji)}
101
72
  onPressOut={hideTooltip}
73
+ style={[
74
+ styles.chip,
75
+ {
76
+ backgroundColor: theme.surface,
77
+ borderColor: isUserReacted ? color : theme.border,
78
+ shadowColor: theme.shadow,
79
+ },
80
+ ]}
102
81
  >
103
- <Text style={{ fontSize: 18, marginRight: 4 }}>
104
- {emojiMap[emoji] || emoji}
105
- </Text>
82
+ {isUserReacted && (
83
+ <View
84
+ pointerEvents="none"
85
+ style={[styles.tint, { backgroundColor: `${color}26` }]}
86
+ />
87
+ )}
88
+ <Text style={styles.glyph}>{getEmojiNativeById(emoji)}</Text>
106
89
  <Text
107
- style={{
108
- fontSize: 14,
109
- fontWeight: '600',
110
- color: isUserReacted ? theme.textOnPrimary : color,
111
- }}
90
+ style={[
91
+ styles.count,
92
+ { color: isUserReacted ? color : theme.textSecondary },
93
+ ]}
112
94
  >
113
95
  {details.count}
114
96
  </Text>
115
- </ReactionBox>
97
+ </TouchableOpacity>
116
98
 
117
- {/* Tooltip */}
118
99
  {tooltipEmoji === emoji && (
119
100
  <Animated.View
120
- style={{
121
- position: 'absolute',
122
- bottom: 36,
123
- left: '50%',
124
- transform: [
125
- { translateX: -50 },
126
- {
127
- translateY: fadeAnim.interpolate({
128
- inputRange: [0, 1],
129
- outputRange: [4, 0],
130
- }),
131
- },
132
- ],
133
- opacity: fadeAnim,
134
- // Inverted pill: text colour as ground, surface as ink,
135
- // so it stays high-contrast on both palettes.
136
- backgroundColor: theme.text,
137
- borderRadius: 6,
138
- paddingHorizontal: 10,
139
- paddingVertical: 6,
140
- maxWidth: 220,
141
- zIndex: 999,
142
- }}
101
+ pointerEvents="none"
102
+ style={[
103
+ styles.tooltip,
104
+ {
105
+ opacity: fadeAnim,
106
+ transform: [
107
+ {
108
+ translateY: fadeAnim.interpolate({
109
+ inputRange: [0, 1],
110
+ outputRange: [4, 0],
111
+ }),
112
+ },
113
+ ],
114
+ // Inverted pill: text colour as ground, surface as ink,
115
+ // so it stays high-contrast on both palettes.
116
+ backgroundColor: theme.text,
117
+ },
118
+ ]}
143
119
  >
144
- <Text style={{ color: theme.surface, fontSize: 12 }}>
145
- {details.users.join(', ')}
120
+ <Text style={[styles.tooltipText, { color: theme.surface }]}>
121
+ {details.users.filter(Boolean).join(', ')}
146
122
  </Text>
147
123
  </Animated.View>
148
124
  )}
149
125
  </View>
150
126
  );
151
127
  })}
152
- </ReactionContainer>
128
+ </View>
153
129
  );
154
- };
130
+ };
131
+
132
+ const styles = StyleSheet.create({
133
+ row: {
134
+ flexDirection: 'row',
135
+ flexWrap: 'wrap',
136
+ alignItems: 'center',
137
+ gap: 6,
138
+ },
139
+ chipWrap: {
140
+ position: 'relative',
141
+ },
142
+ chip: {
143
+ flexDirection: 'row',
144
+ alignItems: 'center',
145
+ paddingVertical: 3,
146
+ paddingHorizontal: 8,
147
+ borderRadius: 14,
148
+ borderWidth: StyleSheet.hairlineWidth,
149
+ shadowOpacity: 0.08,
150
+ shadowOffset: { width: 0, height: 1 },
151
+ shadowRadius: 2,
152
+ elevation: 1,
153
+ },
154
+ tint: {
155
+ position: "absolute", top: 0, right: 0, bottom: 0, left: 0,
156
+ borderRadius: 14,
157
+ },
158
+ glyph: {
159
+ fontSize: 16,
160
+ marginRight: 4,
161
+ },
162
+ count: {
163
+ fontSize: 13,
164
+ fontWeight: '600',
165
+ },
166
+ tooltip: {
167
+ position: 'absolute',
168
+ bottom: 34,
169
+ left: 0,
170
+ borderRadius: 6,
171
+ paddingHorizontal: 10,
172
+ paddingVertical: 6,
173
+ maxWidth: 220,
174
+ },
175
+ tooltipText: {
176
+ fontSize: 12,
177
+ },
178
+ });
@@ -1,50 +1,83 @@
1
- import { FC } from 'react';
2
- import { IMessage } from '../../types/types';
3
- import { styled } from 'styled-components/native';
4
- import { Text } from 'react-native';
5
-
6
- export const StyledMessageReply = styled.TouchableOpacity<{
7
- isUser: boolean;
8
- configColor: string;
9
- }>`
10
- background-color: ${(props) => (props.isUser ? '#ffffff' : '#E7EDF9')};
11
- padding: 8px 16px;
12
- margin-bottom: 8px;
13
- border-radius: 4px;
14
- border-style: solid;
15
- border-start-width: ${(props) => (props.isUser ? 4 : 0)}px;
16
- border-start-color: ${(props) =>
17
- props.isUser ? props.configColor : 'transparent'};
18
- border-end-width: ${(props) => (!props.isUser ? 4 : 0)}px;
19
- border-end-color: ${(props) =>
20
- !props.isUser ? props.configColor : 'transparent'};
21
- `;
22
-
23
- const StyledText = styled.Text`
24
- font-size: 14px;
25
- overflow: hidden;
26
- `;
1
+ import React, { FC } from 'react';
2
+ import { StyleSheet, Text, TouchableOpacity, View } from 'react-native';
3
+ import { useTheme } from '../../hooks/useTheme';
27
4
 
28
5
  interface MessageReplyProps {
29
6
  isUser: boolean;
30
7
  text: string;
8
+ /** The parent's author, when the reply carries it. */
9
+ userName?: string;
31
10
  color?: string;
32
11
  handleReplyMessage: () => void;
33
12
  }
34
13
 
14
+ /**
15
+ * Quote of the parent at the top of a reply that was also sent to the
16
+ * channel (WhatsApp-style): accent bar, author, up to two lines of text.
17
+ * Tapping opens the parent's thread.
18
+ */
35
19
  export const MessageReply: FC<MessageReplyProps> = ({
36
20
  isUser,
37
21
  text,
38
- color = '#0052CD',
22
+ userName,
23
+ color,
39
24
  handleReplyMessage,
40
25
  }) => {
26
+ const theme = useTheme();
27
+ const accent = color || theme.primary;
41
28
  return (
42
- <StyledMessageReply
29
+ <TouchableOpacity
30
+ testID="message-reply-quote"
31
+ activeOpacity={0.7}
43
32
  onPress={handleReplyMessage}
44
- isUser={isUser}
45
- configColor={color}
33
+ style={[
34
+ styles.quote,
35
+ {
36
+ // A tint of the bubble's own ground, so it reads on both sides
37
+ // and in both themes.
38
+ backgroundColor: isUser ? 'rgba(0,0,0,0.12)' : theme.surfaceSecondary,
39
+ },
40
+ ]}
46
41
  >
47
- <StyledText>{text}</StyledText>
48
- </StyledMessageReply>
42
+ <View style={[styles.bar, { backgroundColor: accent }]} />
43
+ <View style={styles.body}>
44
+ {!!userName && (
45
+ <Text numberOfLines={1} style={[styles.author, { color: accent }]}>
46
+ {userName}
47
+ </Text>
48
+ )}
49
+ <Text
50
+ numberOfLines={2}
51
+ style={[styles.text, { color: isUser ? theme.messageTextUser : theme.text }]}
52
+ >
53
+ {text}
54
+ </Text>
55
+ </View>
56
+ </TouchableOpacity>
49
57
  );
50
58
  };
59
+
60
+ const styles = StyleSheet.create({
61
+ quote: {
62
+ flexDirection: 'row',
63
+ borderRadius: 8,
64
+ overflow: 'hidden',
65
+ marginBottom: 8,
66
+ },
67
+ bar: {
68
+ width: 4,
69
+ },
70
+ body: {
71
+ flexShrink: 1,
72
+ paddingVertical: 6,
73
+ paddingHorizontal: 10,
74
+ },
75
+ author: {
76
+ fontSize: 13,
77
+ fontWeight: '600',
78
+ marginBottom: 2,
79
+ },
80
+ text: {
81
+ fontSize: 14,
82
+ },
83
+ });
@@ -1,18 +1,19 @@
1
- import React, { ReactNode, useCallback, useEffect, useRef } from 'react';
1
+ import React, {
2
+ ReactNode,
3
+ useCallback,
4
+ useEffect,
5
+ useMemo,
6
+ useRef,
7
+ useState,
8
+ } from 'react';
2
9
  import {
10
+ Animated,
3
11
  BackHandler,
4
12
  Keyboard,
5
13
  StyleSheet,
6
14
  useWindowDimensions,
7
15
  View,
8
16
  } from 'react-native';
9
- import Animated, {
10
- interpolate,
11
- runOnJS,
12
- useAnimatedStyle,
13
- useSharedValue,
14
- withTiming,
15
- } from 'react-native-reanimated';
16
17
  import { Gesture, GestureDetector } from 'react-native-gesture-handler';
17
18
  import {
18
19
  COMPLETE_DISTANCE,
@@ -33,37 +34,76 @@ interface SwipeBackLayerProps {
33
34
  /**
34
35
  * Full-screen modal layer with the same navigation feel as RoomStack: it
35
36
  * slides in from the right, and a swipe from the left edge drags it back
36
- * out over whatever is underneath (the room or the list).
37
+ * out over whatever is underneath (the room or the list). Like RoomStack it
38
+ * runs on RN's own `Animated`, one value driving every layer.
37
39
  */
38
40
  export const SwipeBackLayer: React.FC<SwipeBackLayerProps> = ({
39
41
  onClose,
40
42
  children,
41
43
  }) => {
42
44
  const { width: windowWidth } = useWindowDimensions();
43
- const width = useSharedValue(windowWidth);
44
- const x = useSharedValue(windowWidth);
45
- const closing = useSharedValue(false);
45
+ const [width, setWidth] = useState(windowWidth);
46
+ const widthRef = useRef(width);
47
+ widthRef.current = width;
48
+ const x = useRef(new Animated.Value(windowWidth)).current;
49
+ const closing = useRef(false);
50
+
51
+ const slideTo = useCallback(
52
+ (
53
+ toValue: number,
54
+ config: typeof PUSH,
55
+ done?: (finished: boolean) => void
56
+ ) => {
57
+ Animated.timing(x, {
58
+ toValue,
59
+ ...config,
60
+ useNativeDriver: true,
61
+ }).start(({ finished }) => done?.(finished));
62
+ },
63
+ [x]
64
+ );
46
65
 
47
66
  useEffect(() => {
48
- x.value = withTiming(0, PUSH);
67
+ slideTo(0, PUSH);
49
68
  }, []); // eslint-disable-line react-hooks/exhaustive-deps
50
69
 
51
70
  const onCloseRef = useRef(onClose);
52
71
  onCloseRef.current = onClose;
53
- const finish = useCallback(() => onCloseRef.current(), []);
72
+ const [closeCount, setCloseCount] = useState(0);
73
+ const finish = useCallback(() => {
74
+ onCloseRef.current();
75
+ setCloseCount(count => count + 1);
76
+ }, []);
54
77
 
55
- const close = useCallback(() => {
56
- if (closing.value) {
78
+ // `onClose` normally unmounts this layer. If it is still here afterwards
79
+ // (the modal did not close), slide the screen back rather than leave it
80
+ // parked off-screen.
81
+ useEffect(() => {
82
+ if (closeCount === 0) {
57
83
  return;
58
84
  }
59
- closing.value = true;
60
- Keyboard.dismiss();
61
- x.value = withTiming(width.value, POP, finished => {
85
+ closing.current = false;
86
+ slideTo(0, POP);
87
+ }, [closeCount]); // eslint-disable-line react-hooks/exhaustive-deps
88
+
89
+ const slideOut = useCallback(() => {
90
+ closing.current = true;
91
+ slideTo(widthRef.current, POP, finished => {
62
92
  if (finished) {
63
- runOnJS(finish)();
93
+ finish();
94
+ } else {
95
+ closing.current = false;
64
96
  }
65
97
  });
66
- }, [finish]); // eslint-disable-line react-hooks/exhaustive-deps
98
+ }, [finish, slideTo]);
99
+
100
+ const close = useCallback(() => {
101
+ if (closing.current) {
102
+ return;
103
+ }
104
+ Keyboard.dismiss();
105
+ slideOut();
106
+ }, [slideOut]);
67
107
 
68
108
  useEffect(() => {
69
109
  const sub = BackHandler.addEventListener('hardwareBackPress', () => {
@@ -73,46 +113,51 @@ export const SwipeBackLayer: React.FC<SwipeBackLayerProps> = ({
73
113
  return () => sub.remove();
74
114
  }, [close]);
75
115
 
76
- const dismissKeyboard = useCallback(() => Keyboard.dismiss(), []);
77
-
78
- const swipeBack = Gesture.Pan()
79
- .hitSlop({ left: 0, width: EDGE_WIDTH })
80
- .activeOffsetX(12)
81
- .failOffsetY([-16, 16])
82
- .onStart(() => {
83
- runOnJS(dismissKeyboard)();
84
- })
85
- .onUpdate(e => {
86
- if (closing.value) {
87
- return;
88
- }
89
- x.value = Math.min(Math.max(e.translationX, 0), width.value);
90
- })
91
- .onEnd(e => {
92
- if (closing.value) {
93
- return;
94
- }
95
- const complete =
96
- x.value > width.value * COMPLETE_DISTANCE ||
97
- e.velocityX > COMPLETE_VELOCITY;
98
- if (complete) {
99
- closing.value = true;
100
- x.value = withTiming(width.value, POP, finished => {
101
- if (finished) {
102
- runOnJS(finish)();
116
+ const swipeBack = useMemo(
117
+ () =>
118
+ Gesture.Pan()
119
+ .runOnJS(true)
120
+ .hitSlop({ left: 0, width: EDGE_WIDTH })
121
+ .activeOffsetX(12)
122
+ .failOffsetY([-16, 16])
123
+ .onStart(() => {
124
+ if (closing.current) {
125
+ return;
103
126
  }
104
- });
105
- } else {
106
- x.value = withTiming(0, POP);
107
- }
108
- });
127
+ Keyboard.dismiss();
128
+ x.stopAnimation();
129
+ })
130
+ .onUpdate(e => {
131
+ if (closing.current) {
132
+ return;
133
+ }
134
+ x.setValue(Math.min(Math.max(e.translationX, 0), widthRef.current));
135
+ })
136
+ .onEnd(e => {
137
+ if (closing.current) {
138
+ return;
139
+ }
140
+ const complete =
141
+ e.translationX > widthRef.current * COMPLETE_DISTANCE ||
142
+ e.velocityX > COMPLETE_VELOCITY;
143
+ if (complete) {
144
+ slideOut();
145
+ } else {
146
+ slideTo(0, POP);
147
+ }
148
+ }),
149
+ [slideOut, slideTo, x]
150
+ );
109
151
 
110
- const screenStyle = useAnimatedStyle(() => ({
111
- transform: [{ translateX: x.value }],
112
- }));
113
- const dimStyle = useAnimatedStyle(() => ({
114
- opacity: interpolate(x.value, [0, width.value], [LIST_DIM, 0]),
115
- }));
152
+ const dimOpacity = useMemo(
153
+ () =>
154
+ x.interpolate({
155
+ inputRange: [0, width],
156
+ outputRange: [LIST_DIM, 0],
157
+ extrapolate: 'clamp',
158
+ }),
159
+ [x, width]
160
+ );
116
161
 
117
162
  return (
118
163
  <View
@@ -120,17 +165,23 @@ export const SwipeBackLayer: React.FC<SwipeBackLayerProps> = ({
120
165
  style={styles.host}
121
166
  onLayout={e => {
122
167
  const next = e.nativeEvent.layout.width;
123
- if (next > 0) {
124
- width.value = next;
168
+ if (next > 0 && next !== widthRef.current) {
169
+ setWidth(next);
125
170
  }
126
171
  }}
127
172
  >
128
173
  <Animated.View
129
174
  pointerEvents="none"
130
- style={[styles.fill, styles.dim, dimStyle]}
175
+ style={[styles.fill, styles.dim, { opacity: dimOpacity }]}
131
176
  />
132
177
  <GestureDetector gesture={swipeBack}>
133
- <Animated.View style={[styles.fill, styles.screen, screenStyle]}>
178
+ <Animated.View
179
+ style={[
180
+ styles.fill,
181
+ styles.screen,
182
+ { transform: [{ translateX: x }] },
183
+ ]}
184
+ >
134
185
  {children(close)}
135
186
  </Animated.View>
136
187
  </GestureDetector>
@@ -1,4 +1,5 @@
1
1
  import React, { useCallback, useMemo } from 'react';
2
+ import { UNREAD_CAP_PAGE } from '../../roomStore/roomsSlice';
2
3
  import { useSelector } from 'react-redux';
3
4
  import { RootState } from '../../roomStore';
4
5
  import { IMessage } from '../../types/types';
@@ -86,7 +87,11 @@ const ChatRoomItem: React.FC<ChatRoomItemProps> = ({
86
87
  );
87
88
 
88
89
  const lastMessage = useMemo(() => {
89
- if (!chat?.messages || chat.messages.length === 0) {return undefined;}
90
+ if (!chat?.messages || chat.messages.length === 0) {
91
+ return chat?.lastMessage?.body
92
+ ? withAuthorFallback(chat.lastMessage as IMessage)
93
+ : undefined;
94
+ }
90
95
 
91
96
  for (let i = chat.messages.length - 1; i >= 0; i--) {
92
97
  const msg = chat.messages[i];
@@ -95,7 +100,7 @@ const ChatRoomItem: React.FC<ChatRoomItemProps> = ({
95
100
  }
96
101
  }
97
102
  return undefined;
98
- }, [chat?.messages, withAuthorFallback]);
103
+ }, [chat?.messages, chat?.lastMessage, withAuthorFallback]);
99
104
 
100
105
  // Mirrors web's formatter: tolerates undefined/garbage inputs (returns
101
106
  // undefined instead of "NaN:NaN"), and uses HH:MM today / MM/DD this
@@ -266,7 +271,9 @@ const ChatRoomItem: React.FC<ChatRoomItemProps> = ({
266
271
  fontWeight: '600',
267
272
  }}
268
273
  >
269
- {chat.unreadMessages || ''}
274
+ {chat.unreadCapped && (chat.unreadMessages || 0) >= UNREAD_CAP_PAGE
275
+ ? `${chat.unreadMessages}+`
276
+ : chat.unreadMessages || ''}
270
277
  </Text>
271
278
  </View>
272
279
  ) : null}
@@ -284,4 +291,4 @@ const ChatRoomItem: React.FC<ChatRoomItemProps> = ({
284
291
  );
285
292
  };
286
293
 
287
- export default ChatRoomItem;
294
+ export default React.memo(ChatRoomItem);
@@ -5,22 +5,21 @@ import {
5
5
  LastRoomMessageText,
6
6
  } from './StyledRoomComponents';
7
7
  import { LastMessage } from '../../../types/types';
8
+ import { getEmojiNativeById } from '../../../helpers/emoji';
8
9
 
9
10
  interface LastMessageEmojiProps extends Pick<LastMessage, 'user' | 'emoji'> {}
10
11
 
11
12
  /**
12
- * Renders the per-room last-message preview when the latest message
13
- * is a reaction (emoji). The `emoji` field is expected to already be
14
- * a unicode glyph (the reaction stanza carries the rendered character,
15
- * not an `:id:`) so we just render it as-is — no emoji-id resolution
16
- * library needed. If a legacy payload still ships an `:id:`, it
17
- * renders verbatim instead of crashing.
13
+ * The room-list preview when the latest event in a room is a reaction.
14
+ * The stanza carries the emoji's short name (`joy`, `+1`), as on web — it
15
+ * is resolved to the glyph here; a glyph or unknown id renders as is.
18
16
  */
19
17
  const LastMessageEmoji: FC<LastMessageEmojiProps> = ({ user, emoji }) => {
18
+ const name = (user?.name || '').trim();
20
19
  return (
21
20
  <LastRoomMessageContainer>
22
- <LastRoomMessageName>{user?.name || ''}:</LastRoomMessageName>
23
- <LastRoomMessageText>{emoji || ''}</LastRoomMessageText>
21
+ {!!name && <LastRoomMessageName>{name}:</LastRoomMessageName>}
22
+ <LastRoomMessageText>{emoji ? getEmojiNativeById(emoji) : ''}</LastRoomMessageText>
24
23
  </LastRoomMessageContainer>
25
24
  );
26
25
  };