@ethora/chat-component-rn 26.8.6 → 26.8.8

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 (537) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/README.md +64 -2
  3. package/lib/commonjs/assets/icons.js +4 -2
  4. package/lib/commonjs/assets/icons.js.map +1 -1
  5. package/lib/commonjs/components/MainComponents/ChatHeader.js +28 -6
  6. package/lib/commonjs/components/MainComponents/ChatHeader.js.map +1 -1
  7. package/lib/commonjs/components/MainComponents/ChatRoom.js +9 -1
  8. package/lib/commonjs/components/MainComponents/ChatRoom.js.map +1 -1
  9. package/lib/commonjs/components/MainComponents/ChatWrapper.js +5 -3
  10. package/lib/commonjs/components/MainComponents/ChatWrapper.js.map +1 -1
  11. package/lib/commonjs/components/MainComponents/EncryptedSendNotice.js +47 -0
  12. package/lib/commonjs/components/MainComponents/EncryptedSendNotice.js.map +1 -0
  13. package/lib/commonjs/components/MainComponents/EncryptionCard.js +286 -0
  14. package/lib/commonjs/components/MainComponents/EncryptionCard.js.map +1 -0
  15. package/lib/commonjs/components/MainComponents/MediaMessage.js +7 -0
  16. package/lib/commonjs/components/MainComponents/MediaMessage.js.map +1 -1
  17. package/lib/commonjs/components/MainComponents/ReduxWrapper.js +13 -0
  18. package/lib/commonjs/components/MainComponents/ReduxWrapper.js.map +1 -1
  19. package/lib/commonjs/components/MainComponents/SealedAttachment.js +231 -0
  20. package/lib/commonjs/components/MainComponents/SealedAttachment.js.map +1 -0
  21. package/lib/commonjs/components/Menu/HeaderRoomListMenu.js +26 -13
  22. package/lib/commonjs/components/Menu/HeaderRoomListMenu.js.map +1 -1
  23. package/lib/commonjs/components/MenuRoom/MenuRoom.js +5 -3
  24. package/lib/commonjs/components/MenuRoom/MenuRoom.js.map +1 -1
  25. package/lib/commonjs/components/MessageBubble/BottomReplyContainer.js +2 -1
  26. package/lib/commonjs/components/MessageBubble/BottomReplyContainer.js.map +1 -1
  27. package/lib/commonjs/components/MessageBubble/Message.js +69 -9
  28. package/lib/commonjs/components/MessageBubble/Message.js.map +1 -1
  29. package/lib/commonjs/components/MessageBubble/MessageInteractions.js +7 -4
  30. package/lib/commonjs/components/MessageBubble/MessageInteractions.js.map +1 -1
  31. package/lib/commonjs/components/Modals/ChatProfileModal/ChatProfileModal.js +8 -5
  32. package/lib/commonjs/components/Modals/ChatProfileModal/ChatProfileModal.js.map +1 -1
  33. package/lib/commonjs/components/Modals/ChatProfileModal/ReportChatModal.js +2 -2
  34. package/lib/commonjs/components/Modals/ChatProfileModal/ReportChatModal.js.map +1 -1
  35. package/lib/commonjs/components/Modals/FilePreviewModal/FilePreviewModal.js +166 -21
  36. package/lib/commonjs/components/Modals/FilePreviewModal/FilePreviewModal.js.map +1 -1
  37. package/lib/commonjs/components/Modals/FilePreviewModal/PdfView.js +4 -0
  38. package/lib/commonjs/components/Modals/FilePreviewModal/PdfView.js.map +1 -1
  39. package/lib/commonjs/components/Modals/Modal/Modal.js +33 -11
  40. package/lib/commonjs/components/Modals/Modal/Modal.js.map +1 -1
  41. package/lib/commonjs/components/Modals/NewChatModal/NewChatModal.js +8 -8
  42. package/lib/commonjs/components/Modals/NewChatModal/NewChatModal.js.map +1 -1
  43. package/lib/commonjs/components/Modals/SettingsModals/ChangePassword/ChangePasswordModal.js +279 -0
  44. package/lib/commonjs/components/Modals/SettingsModals/ChangePassword/ChangePasswordModal.js.map +1 -0
  45. package/lib/commonjs/components/Modals/SettingsModals/ManageDataModal/ManageDataModal.js +10 -8
  46. package/lib/commonjs/components/Modals/SettingsModals/ManageDataModal/ManageDataModal.js.map +1 -1
  47. package/lib/commonjs/components/Modals/SettingsModals/Visibility/VisibilityModal.js +13 -11
  48. package/lib/commonjs/components/Modals/SettingsModals/Visibility/VisibilityModal.js.map +1 -1
  49. package/lib/commonjs/components/Modals/UserProfileModal/UserProfileModal.js +50 -15
  50. package/lib/commonjs/components/Modals/UserProfileModal/UserProfileModal.js.map +1 -1
  51. package/lib/commonjs/components/Modals/UserSettingsModal/LanguageCard.js +121 -0
  52. package/lib/commonjs/components/Modals/UserSettingsModal/LanguageCard.js.map +1 -0
  53. package/lib/commonjs/components/Modals/UserSettingsModal/UserSettingsModal.js +10 -1
  54. package/lib/commonjs/components/Modals/UserSettingsModal/UserSettingsModal.js.map +1 -1
  55. package/lib/commonjs/components/RoomComponents/ChatRoomItem.js +32 -9
  56. package/lib/commonjs/components/RoomComponents/ChatRoomItem.js.map +1 -1
  57. package/lib/commonjs/components/RoomComponents/LastMessageItem.js +6 -0
  58. package/lib/commonjs/components/RoomComponents/LastMessageItem.js.map +1 -1
  59. package/lib/commonjs/components/RoomComponents/styled/LastAudioMessage.js +2 -2
  60. package/lib/commonjs/components/RoomComponents/styled/LastAudioMessage.js.map +1 -1
  61. package/lib/commonjs/components/RoomComponents/styled/LastMessageFile.js +4 -6
  62. package/lib/commonjs/components/RoomComponents/styled/LastMessageFile.js.map +1 -1
  63. package/lib/commonjs/components/RoomComponents/styled/LastMessagePhoto.js +2 -2
  64. package/lib/commonjs/components/RoomComponents/styled/LastMessagePhoto.js.map +1 -1
  65. package/lib/commonjs/components/RoomComponents/styled/LastMessageSealed.js +41 -0
  66. package/lib/commonjs/components/RoomComponents/styled/LastMessageSealed.js.map +1 -0
  67. package/lib/commonjs/components/RoomComponents/styled/LastMessageVideo.js +2 -2
  68. package/lib/commonjs/components/RoomComponents/styled/LastMessageVideo.js.map +1 -1
  69. package/lib/commonjs/components/Thread/ThreadWrapper.js +56 -46
  70. package/lib/commonjs/components/Thread/ThreadWrapper.js.map +1 -1
  71. package/lib/commonjs/components/UsersList/UsersList.js +2 -1
  72. package/lib/commonjs/components/UsersList/UsersList.js.map +1 -1
  73. package/lib/commonjs/components/styled/SendInput.js +4 -2
  74. package/lib/commonjs/components/styled/SendInput.js.map +1 -1
  75. package/lib/commonjs/e2ee/crypto.js +207 -0
  76. package/lib/commonjs/e2ee/crypto.js.map +1 -0
  77. package/lib/commonjs/e2ee/deviceStore.js +84 -0
  78. package/lib/commonjs/e2ee/deviceStore.js.map +1 -0
  79. package/lib/commonjs/e2ee/fileCipher.js +95 -0
  80. package/lib/commonjs/e2ee/fileCipher.js.map +1 -0
  81. package/lib/commonjs/e2ee/fileEnvelope.js +79 -0
  82. package/lib/commonjs/e2ee/fileEnvelope.js.map +1 -0
  83. package/lib/commonjs/e2ee/index.js +210 -0
  84. package/lib/commonjs/e2ee/index.js.map +1 -0
  85. package/lib/commonjs/e2ee/limits.js +9 -0
  86. package/lib/commonjs/e2ee/limits.js.map +1 -0
  87. package/lib/commonjs/e2ee/ns.js +8 -0
  88. package/lib/commonjs/e2ee/ns.js.map +1 -0
  89. package/lib/commonjs/e2ee/omemo.js +622 -0
  90. package/lib/commonjs/e2ee/omemo.js.map +1 -0
  91. package/lib/commonjs/e2ee/protobuf.js +149 -0
  92. package/lib/commonjs/e2ee/protobuf.js.map +1 -0
  93. package/lib/commonjs/e2ee/ratchet.js +238 -0
  94. package/lib/commonjs/e2ee/ratchet.js.map +1 -0
  95. package/lib/commonjs/e2ee/sealedBody.js +23 -0
  96. package/lib/commonjs/e2ee/sealedBody.js.map +1 -0
  97. package/lib/commonjs/e2ee/sealedFiles.js +174 -0
  98. package/lib/commonjs/e2ee/sealedFiles.js.map +1 -0
  99. package/lib/commonjs/e2ee/send.js +54 -0
  100. package/lib/commonjs/e2ee/send.js.map +1 -0
  101. package/lib/commonjs/e2ee/stanza.js +114 -0
  102. package/lib/commonjs/e2ee/stanza.js.map +1 -0
  103. package/lib/commonjs/e2ee/store.js +43 -0
  104. package/lib/commonjs/e2ee/store.js.map +1 -0
  105. package/lib/commonjs/helpers/accountName.js +23 -0
  106. package/lib/commonjs/helpers/accountName.js.map +1 -0
  107. package/lib/commonjs/helpers/constants/MODAL_COMPONENTS.js +2 -0
  108. package/lib/commonjs/helpers/constants/MODAL_COMPONENTS.js.map +1 -1
  109. package/lib/commonjs/helpers/constants/MODAL_TYPES.js +1 -0
  110. package/lib/commonjs/helpers/constants/MODAL_TYPES.js.map +1 -1
  111. package/lib/commonjs/helpers/createMessageFromXml.js +19 -4
  112. package/lib/commonjs/helpers/createMessageFromXml.js.map +1 -1
  113. package/lib/commonjs/helpers/createUserNameFromSetUser.js +2 -1
  114. package/lib/commonjs/helpers/createUserNameFromSetUser.js.map +1 -1
  115. package/lib/commonjs/helpers/displayName.js +16 -0
  116. package/lib/commonjs/helpers/displayName.js.map +1 -0
  117. package/lib/commonjs/helpers/persistCrypto.js +5 -0
  118. package/lib/commonjs/helpers/persistCrypto.js.map +1 -1
  119. package/lib/commonjs/helpers/preferencesStorage.js.map +1 -1
  120. package/lib/commonjs/helpers/secureKeyValue.js +20 -0
  121. package/lib/commonjs/helpers/secureKeyValue.js.map +1 -1
  122. package/lib/commonjs/helpers/videoCache.js +136 -0
  123. package/lib/commonjs/helpers/videoCache.js.map +1 -0
  124. package/lib/commonjs/hooks/useChatSettingState.js +2 -0
  125. package/lib/commonjs/hooks/useChatSettingState.js.map +1 -1
  126. package/lib/commonjs/hooks/useChatWrapperInit.js +4 -0
  127. package/lib/commonjs/hooks/useChatWrapperInit.js.map +1 -1
  128. package/lib/commonjs/hooks/useLogout.js +8 -0
  129. package/lib/commonjs/hooks/useLogout.js.map +1 -1
  130. package/lib/commonjs/hooks/useSendMessage.js +71 -7
  131. package/lib/commonjs/hooks/useSendMessage.js.map +1 -1
  132. package/lib/commonjs/i18n/strings.js +367 -1
  133. package/lib/commonjs/i18n/strings.js.map +1 -1
  134. package/lib/commonjs/i18n/useT.js +8 -4
  135. package/lib/commonjs/i18n/useT.js.map +1 -1
  136. package/lib/commonjs/main.js +13 -0
  137. package/lib/commonjs/main.js.map +1 -1
  138. package/lib/commonjs/networking/api-requests/auth.api.js +4 -1
  139. package/lib/commonjs/networking/api-requests/auth.api.js.map +1 -1
  140. package/lib/commonjs/networking/api-requests/rooms.api.js +111 -17
  141. package/lib/commonjs/networking/api-requests/rooms.api.js.map +1 -1
  142. package/lib/commonjs/networking/api-requests/user.api.js +13 -0
  143. package/lib/commonjs/networking/api-requests/user.api.js.map +1 -1
  144. package/lib/commonjs/networking/stanzaHandlers.js +1 -1
  145. package/lib/commonjs/networking/stanzaHandlers.js.map +1 -1
  146. package/lib/commonjs/networking/xmpp/handleStanzas.xmpp.js +40 -0
  147. package/lib/commonjs/networking/xmpp/handleStanzas.xmpp.js.map +1 -1
  148. package/lib/commonjs/networking/xmpp/sendMediaMessage.xmpp.js +16 -3
  149. package/lib/commonjs/networking/xmpp/sendMediaMessage.xmpp.js.map +1 -1
  150. package/lib/commonjs/networking/xmpp/sendTextMessage.xmpp.js +13 -6
  151. package/lib/commonjs/networking/xmpp/sendTextMessage.xmpp.js.map +1 -1
  152. package/lib/commonjs/networking/xmpp/sendTextMessageWithTranslateTag.xmpp.js +14 -6
  153. package/lib/commonjs/networking/xmpp/sendTextMessageWithTranslateTag.xmpp.js.map +1 -1
  154. package/lib/commonjs/networking/xmppClient.js +6 -0
  155. package/lib/commonjs/networking/xmppClient.js.map +1 -1
  156. package/lib/commonjs/roomStore/chatSettingsSlice.js +7 -2
  157. package/lib/commonjs/roomStore/chatSettingsSlice.js.map +1 -1
  158. package/lib/commonjs/roomStore/persistBackend.js +9 -12
  159. package/lib/commonjs/roomStore/persistBackend.js.map +1 -1
  160. package/lib/commonjs/roomStore/persistence.js +8 -1
  161. package/lib/commonjs/roomStore/persistence.js.map +1 -1
  162. package/lib/commonjs/services/languageSettings.js +177 -0
  163. package/lib/commonjs/services/languageSettings.js.map +1 -0
  164. package/lib/commonjs/version.js +1 -1
  165. package/lib/module/assets/icons.js +3 -1
  166. package/lib/module/assets/icons.js.map +1 -1
  167. package/lib/module/components/MainComponents/ChatHeader.js +29 -7
  168. package/lib/module/components/MainComponents/ChatHeader.js.map +1 -1
  169. package/lib/module/components/MainComponents/ChatRoom.js +9 -1
  170. package/lib/module/components/MainComponents/ChatRoom.js.map +1 -1
  171. package/lib/module/components/MainComponents/ChatWrapper.js +5 -3
  172. package/lib/module/components/MainComponents/ChatWrapper.js.map +1 -1
  173. package/lib/module/components/MainComponents/EncryptedSendNotice.js +42 -0
  174. package/lib/module/components/MainComponents/EncryptedSendNotice.js.map +1 -0
  175. package/lib/module/components/MainComponents/EncryptionCard.js +281 -0
  176. package/lib/module/components/MainComponents/EncryptionCard.js.map +1 -0
  177. package/lib/module/components/MainComponents/MediaMessage.js +7 -0
  178. package/lib/module/components/MainComponents/MediaMessage.js.map +1 -1
  179. package/lib/module/components/MainComponents/ReduxWrapper.js +14 -1
  180. package/lib/module/components/MainComponents/ReduxWrapper.js.map +1 -1
  181. package/lib/module/components/MainComponents/SealedAttachment.js +224 -0
  182. package/lib/module/components/MainComponents/SealedAttachment.js.map +1 -0
  183. package/lib/module/components/Menu/HeaderRoomListMenu.js +26 -13
  184. package/lib/module/components/Menu/HeaderRoomListMenu.js.map +1 -1
  185. package/lib/module/components/MenuRoom/MenuRoom.js +5 -3
  186. package/lib/module/components/MenuRoom/MenuRoom.js.map +1 -1
  187. package/lib/module/components/MessageBubble/BottomReplyContainer.js +2 -1
  188. package/lib/module/components/MessageBubble/BottomReplyContainer.js.map +1 -1
  189. package/lib/module/components/MessageBubble/Message.js +72 -12
  190. package/lib/module/components/MessageBubble/Message.js.map +1 -1
  191. package/lib/module/components/MessageBubble/MessageInteractions.js +7 -4
  192. package/lib/module/components/MessageBubble/MessageInteractions.js.map +1 -1
  193. package/lib/module/components/Modals/ChatProfileModal/ChatProfileModal.js +8 -5
  194. package/lib/module/components/Modals/ChatProfileModal/ChatProfileModal.js.map +1 -1
  195. package/lib/module/components/Modals/ChatProfileModal/ReportChatModal.js +2 -2
  196. package/lib/module/components/Modals/ChatProfileModal/ReportChatModal.js.map +1 -1
  197. package/lib/module/components/Modals/FilePreviewModal/FilePreviewModal.js +168 -23
  198. package/lib/module/components/Modals/FilePreviewModal/FilePreviewModal.js.map +1 -1
  199. package/lib/module/components/Modals/FilePreviewModal/PdfView.js +4 -0
  200. package/lib/module/components/Modals/FilePreviewModal/PdfView.js.map +1 -1
  201. package/lib/module/components/Modals/Modal/Modal.js +33 -11
  202. package/lib/module/components/Modals/Modal/Modal.js.map +1 -1
  203. package/lib/module/components/Modals/NewChatModal/NewChatModal.js +8 -8
  204. package/lib/module/components/Modals/NewChatModal/NewChatModal.js.map +1 -1
  205. package/lib/module/components/Modals/SettingsModals/ChangePassword/ChangePasswordModal.js +274 -0
  206. package/lib/module/components/Modals/SettingsModals/ChangePassword/ChangePasswordModal.js.map +1 -0
  207. package/lib/module/components/Modals/SettingsModals/ManageDataModal/ManageDataModal.js +10 -8
  208. package/lib/module/components/Modals/SettingsModals/ManageDataModal/ManageDataModal.js.map +1 -1
  209. package/lib/module/components/Modals/SettingsModals/Visibility/VisibilityModal.js +13 -11
  210. package/lib/module/components/Modals/SettingsModals/Visibility/VisibilityModal.js.map +1 -1
  211. package/lib/module/components/Modals/UserProfileModal/UserProfileModal.js +54 -18
  212. package/lib/module/components/Modals/UserProfileModal/UserProfileModal.js.map +1 -1
  213. package/lib/module/components/Modals/UserSettingsModal/LanguageCard.js +116 -0
  214. package/lib/module/components/Modals/UserSettingsModal/LanguageCard.js.map +1 -0
  215. package/lib/module/components/Modals/UserSettingsModal/UserSettingsModal.js +10 -1
  216. package/lib/module/components/Modals/UserSettingsModal/UserSettingsModal.js.map +1 -1
  217. package/lib/module/components/RoomComponents/ChatRoomItem.js +32 -9
  218. package/lib/module/components/RoomComponents/ChatRoomItem.js.map +1 -1
  219. package/lib/module/components/RoomComponents/LastMessageItem.js +6 -0
  220. package/lib/module/components/RoomComponents/LastMessageItem.js.map +1 -1
  221. package/lib/module/components/RoomComponents/styled/LastAudioMessage.js +2 -2
  222. package/lib/module/components/RoomComponents/styled/LastAudioMessage.js.map +1 -1
  223. package/lib/module/components/RoomComponents/styled/LastMessageFile.js +4 -6
  224. package/lib/module/components/RoomComponents/styled/LastMessageFile.js.map +1 -1
  225. package/lib/module/components/RoomComponents/styled/LastMessagePhoto.js +2 -2
  226. package/lib/module/components/RoomComponents/styled/LastMessagePhoto.js.map +1 -1
  227. package/lib/module/components/RoomComponents/styled/LastMessageSealed.js +36 -0
  228. package/lib/module/components/RoomComponents/styled/LastMessageSealed.js.map +1 -0
  229. package/lib/module/components/RoomComponents/styled/LastMessageVideo.js +2 -2
  230. package/lib/module/components/RoomComponents/styled/LastMessageVideo.js.map +1 -1
  231. package/lib/module/components/Thread/ThreadWrapper.js +57 -47
  232. package/lib/module/components/Thread/ThreadWrapper.js.map +1 -1
  233. package/lib/module/components/UsersList/UsersList.js +2 -1
  234. package/lib/module/components/UsersList/UsersList.js.map +1 -1
  235. package/lib/module/components/styled/SendInput.js +4 -2
  236. package/lib/module/components/styled/SendInput.js.map +1 -1
  237. package/lib/module/e2ee/crypto.js +170 -0
  238. package/lib/module/e2ee/crypto.js.map +1 -0
  239. package/lib/module/e2ee/deviceStore.js +77 -0
  240. package/lib/module/e2ee/deviceStore.js.map +1 -0
  241. package/lib/module/e2ee/fileCipher.js +90 -0
  242. package/lib/module/e2ee/fileCipher.js.map +1 -0
  243. package/lib/module/e2ee/fileEnvelope.js +66 -0
  244. package/lib/module/e2ee/fileEnvelope.js.map +1 -0
  245. package/lib/module/e2ee/index.js +185 -0
  246. package/lib/module/e2ee/index.js.map +1 -0
  247. package/lib/module/e2ee/limits.js +5 -0
  248. package/lib/module/e2ee/limits.js.map +1 -0
  249. package/lib/module/e2ee/ns.js +4 -0
  250. package/lib/module/e2ee/ns.js.map +1 -0
  251. package/lib/module/e2ee/omemo.js +610 -0
  252. package/lib/module/e2ee/omemo.js.map +1 -0
  253. package/lib/module/e2ee/protobuf.js +140 -0
  254. package/lib/module/e2ee/protobuf.js.map +1 -0
  255. package/lib/module/e2ee/ratchet.js +228 -0
  256. package/lib/module/e2ee/ratchet.js.map +1 -0
  257. package/lib/module/e2ee/sealedBody.js +19 -0
  258. package/lib/module/e2ee/sealedBody.js.map +1 -0
  259. package/lib/module/e2ee/sealedFiles.js +154 -0
  260. package/lib/module/e2ee/sealedFiles.js.map +1 -0
  261. package/lib/module/e2ee/send.js +48 -0
  262. package/lib/module/e2ee/send.js.map +1 -0
  263. package/lib/module/e2ee/stanza.js +107 -0
  264. package/lib/module/e2ee/stanza.js.map +1 -0
  265. package/lib/module/e2ee/store.js +35 -0
  266. package/lib/module/e2ee/store.js.map +1 -0
  267. package/lib/module/helpers/accountName.js +18 -0
  268. package/lib/module/helpers/accountName.js.map +1 -0
  269. package/lib/module/helpers/constants/MODAL_COMPONENTS.js +2 -0
  270. package/lib/module/helpers/constants/MODAL_COMPONENTS.js.map +1 -1
  271. package/lib/module/helpers/constants/MODAL_TYPES.js +1 -0
  272. package/lib/module/helpers/constants/MODAL_TYPES.js.map +1 -1
  273. package/lib/module/helpers/createMessageFromXml.js +19 -4
  274. package/lib/module/helpers/createMessageFromXml.js.map +1 -1
  275. package/lib/module/helpers/createUserNameFromSetUser.js +3 -1
  276. package/lib/module/helpers/createUserNameFromSetUser.js.map +1 -1
  277. package/lib/module/helpers/displayName.js +11 -0
  278. package/lib/module/helpers/displayName.js.map +1 -0
  279. package/lib/module/helpers/persistCrypto.js +4 -0
  280. package/lib/module/helpers/persistCrypto.js.map +1 -1
  281. package/lib/module/helpers/preferencesStorage.js.map +1 -1
  282. package/lib/module/helpers/secureKeyValue.js +19 -0
  283. package/lib/module/helpers/secureKeyValue.js.map +1 -1
  284. package/lib/module/helpers/videoCache.js +125 -0
  285. package/lib/module/helpers/videoCache.js.map +1 -0
  286. package/lib/module/hooks/useChatSettingState.js +2 -0
  287. package/lib/module/hooks/useChatSettingState.js.map +1 -1
  288. package/lib/module/hooks/useChatWrapperInit.js +4 -0
  289. package/lib/module/hooks/useChatWrapperInit.js.map +1 -1
  290. package/lib/module/hooks/useLogout.js +8 -0
  291. package/lib/module/hooks/useLogout.js.map +1 -1
  292. package/lib/module/hooks/useSendMessage.js +71 -7
  293. package/lib/module/hooks/useSendMessage.js.map +1 -1
  294. package/lib/module/i18n/strings.js +367 -1
  295. package/lib/module/i18n/strings.js.map +1 -1
  296. package/lib/module/i18n/useT.js +8 -4
  297. package/lib/module/i18n/useT.js.map +1 -1
  298. package/lib/module/main.js +1 -0
  299. package/lib/module/main.js.map +1 -1
  300. package/lib/module/networking/api-requests/auth.api.js +4 -1
  301. package/lib/module/networking/api-requests/auth.api.js.map +1 -1
  302. package/lib/module/networking/api-requests/rooms.api.js +109 -18
  303. package/lib/module/networking/api-requests/rooms.api.js.map +1 -1
  304. package/lib/module/networking/api-requests/user.api.js +12 -0
  305. package/lib/module/networking/api-requests/user.api.js.map +1 -1
  306. package/lib/module/networking/stanzaHandlers.js +1 -1
  307. package/lib/module/networking/stanzaHandlers.js.map +1 -1
  308. package/lib/module/networking/xmpp/handleStanzas.xmpp.js +38 -0
  309. package/lib/module/networking/xmpp/handleStanzas.xmpp.js.map +1 -1
  310. package/lib/module/networking/xmpp/sendMediaMessage.xmpp.js +16 -3
  311. package/lib/module/networking/xmpp/sendMediaMessage.xmpp.js.map +1 -1
  312. package/lib/module/networking/xmpp/sendTextMessage.xmpp.js +13 -6
  313. package/lib/module/networking/xmpp/sendTextMessage.xmpp.js.map +1 -1
  314. package/lib/module/networking/xmpp/sendTextMessageWithTranslateTag.xmpp.js +14 -6
  315. package/lib/module/networking/xmpp/sendTextMessageWithTranslateTag.xmpp.js.map +1 -1
  316. package/lib/module/networking/xmppClient.js +6 -0
  317. package/lib/module/networking/xmppClient.js.map +1 -1
  318. package/lib/module/roomStore/chatSettingsSlice.js +5 -1
  319. package/lib/module/roomStore/chatSettingsSlice.js.map +1 -1
  320. package/lib/module/roomStore/persistBackend.js +10 -13
  321. package/lib/module/roomStore/persistBackend.js.map +1 -1
  322. package/lib/module/roomStore/persistence.js +8 -1
  323. package/lib/module/roomStore/persistence.js.map +1 -1
  324. package/lib/module/services/languageSettings.js +164 -0
  325. package/lib/module/services/languageSettings.js.map +1 -0
  326. package/lib/module/version.js +1 -1
  327. package/lib/typescript/assets/icons.d.ts +8 -0
  328. package/lib/typescript/assets/icons.d.ts.map +1 -1
  329. package/lib/typescript/components/MainComponents/ChatHeader.d.ts.map +1 -1
  330. package/lib/typescript/components/MainComponents/ChatRoom.d.ts.map +1 -1
  331. package/lib/typescript/components/MainComponents/ChatWrapper.d.ts.map +1 -1
  332. package/lib/typescript/components/MainComponents/EncryptedSendNotice.d.ts +4 -0
  333. package/lib/typescript/components/MainComponents/EncryptedSendNotice.d.ts.map +1 -0
  334. package/lib/typescript/components/MainComponents/EncryptionCard.d.ts +10 -0
  335. package/lib/typescript/components/MainComponents/EncryptionCard.d.ts.map +1 -0
  336. package/lib/typescript/components/MainComponents/MediaMessage.d.ts.map +1 -1
  337. package/lib/typescript/components/MainComponents/ReduxWrapper.d.ts.map +1 -1
  338. package/lib/typescript/components/MainComponents/SealedAttachment.d.ts +13 -0
  339. package/lib/typescript/components/MainComponents/SealedAttachment.d.ts.map +1 -0
  340. package/lib/typescript/components/Menu/HeaderRoomListMenu.d.ts +7 -1
  341. package/lib/typescript/components/Menu/HeaderRoomListMenu.d.ts.map +1 -1
  342. package/lib/typescript/components/MenuRoom/MenuRoom.d.ts.map +1 -1
  343. package/lib/typescript/components/MessageBubble/BottomReplyContainer.d.ts.map +1 -1
  344. package/lib/typescript/components/MessageBubble/Message.d.ts.map +1 -1
  345. package/lib/typescript/components/MessageBubble/MessageInteractions.d.ts.map +1 -1
  346. package/lib/typescript/components/Modals/ChatProfileModal/ChatProfileModal.d.ts.map +1 -1
  347. package/lib/typescript/components/Modals/FilePreviewModal/FilePreviewModal.d.ts.map +1 -1
  348. package/lib/typescript/components/Modals/FilePreviewModal/PdfView.d.ts.map +1 -1
  349. package/lib/typescript/components/Modals/Modal/Modal.d.ts.map +1 -1
  350. package/lib/typescript/components/Modals/SettingsModals/ChangePassword/ChangePasswordModal.d.ts +15 -0
  351. package/lib/typescript/components/Modals/SettingsModals/ChangePassword/ChangePasswordModal.d.ts.map +1 -0
  352. package/lib/typescript/components/Modals/SettingsModals/ManageDataModal/ManageDataModal.d.ts.map +1 -1
  353. package/lib/typescript/components/Modals/SettingsModals/Visibility/VisibilityModal.d.ts.map +1 -1
  354. package/lib/typescript/components/Modals/UserProfileModal/UserProfileModal.d.ts.map +1 -1
  355. package/lib/typescript/components/Modals/UserSettingsModal/LanguageCard.d.ts +14 -0
  356. package/lib/typescript/components/Modals/UserSettingsModal/LanguageCard.d.ts.map +1 -0
  357. package/lib/typescript/components/Modals/UserSettingsModal/UserSettingsModal.d.ts.map +1 -1
  358. package/lib/typescript/components/RoomComponents/ChatRoomItem.d.ts.map +1 -1
  359. package/lib/typescript/components/RoomComponents/LastMessageItem.d.ts.map +1 -1
  360. package/lib/typescript/components/RoomComponents/styled/LastAudioMessage.d.ts.map +1 -1
  361. package/lib/typescript/components/RoomComponents/styled/LastMessageSealed.d.ts +7 -0
  362. package/lib/typescript/components/RoomComponents/styled/LastMessageSealed.d.ts.map +1 -0
  363. package/lib/typescript/components/Thread/ThreadWrapper.d.ts.map +1 -1
  364. package/lib/typescript/components/UsersList/UsersList.d.ts.map +1 -1
  365. package/lib/typescript/components/styled/SendInput.d.ts +1 -0
  366. package/lib/typescript/components/styled/SendInput.d.ts.map +1 -1
  367. package/lib/typescript/e2ee/crypto.d.ts +28 -0
  368. package/lib/typescript/e2ee/crypto.d.ts.map +1 -0
  369. package/lib/typescript/e2ee/deviceStore.d.ts +4 -0
  370. package/lib/typescript/e2ee/deviceStore.d.ts.map +1 -0
  371. package/lib/typescript/e2ee/fileCipher.d.ts +7 -0
  372. package/lib/typescript/e2ee/fileCipher.d.ts.map +1 -0
  373. package/lib/typescript/e2ee/fileEnvelope.d.ts +27 -0
  374. package/lib/typescript/e2ee/fileEnvelope.d.ts.map +1 -0
  375. package/lib/typescript/e2ee/index.d.ts +23 -0
  376. package/lib/typescript/e2ee/index.d.ts.map +1 -0
  377. package/lib/typescript/e2ee/limits.d.ts +3 -0
  378. package/lib/typescript/e2ee/limits.d.ts.map +1 -0
  379. package/lib/typescript/e2ee/ns.d.ts +2 -0
  380. package/lib/typescript/e2ee/ns.d.ts.map +1 -0
  381. package/lib/typescript/e2ee/omemo.d.ts +64 -0
  382. package/lib/typescript/e2ee/omemo.d.ts.map +1 -0
  383. package/lib/typescript/e2ee/protobuf.d.ts +25 -0
  384. package/lib/typescript/e2ee/protobuf.d.ts.map +1 -0
  385. package/lib/typescript/e2ee/ratchet.d.ts +39 -0
  386. package/lib/typescript/e2ee/ratchet.d.ts.map +1 -0
  387. package/lib/typescript/e2ee/sealedBody.d.ts +2 -0
  388. package/lib/typescript/e2ee/sealedBody.d.ts.map +1 -0
  389. package/lib/typescript/e2ee/sealedFiles.d.ts +31 -0
  390. package/lib/typescript/e2ee/sealedFiles.d.ts.map +1 -0
  391. package/lib/typescript/e2ee/send.d.ts +6 -0
  392. package/lib/typescript/e2ee/send.d.ts.map +1 -0
  393. package/lib/typescript/e2ee/stanza.d.ts +8 -0
  394. package/lib/typescript/e2ee/stanza.d.ts.map +1 -0
  395. package/lib/typescript/e2ee/store.d.ts +16 -0
  396. package/lib/typescript/e2ee/store.d.ts.map +1 -0
  397. package/lib/typescript/helpers/accountName.d.ts +7 -0
  398. package/lib/typescript/helpers/accountName.d.ts.map +1 -0
  399. package/lib/typescript/helpers/constants/MODAL_COMPONENTS.d.ts.map +1 -1
  400. package/lib/typescript/helpers/constants/MODAL_TYPES.d.ts +1 -0
  401. package/lib/typescript/helpers/constants/MODAL_TYPES.d.ts.map +1 -1
  402. package/lib/typescript/helpers/createMessageFromXml.d.ts.map +1 -1
  403. package/lib/typescript/helpers/createUserNameFromSetUser.d.ts.map +1 -1
  404. package/lib/typescript/helpers/displayName.d.ts +2 -0
  405. package/lib/typescript/helpers/displayName.d.ts.map +1 -0
  406. package/lib/typescript/helpers/persistCrypto.d.ts +1 -0
  407. package/lib/typescript/helpers/persistCrypto.d.ts.map +1 -1
  408. package/lib/typescript/helpers/preferencesStorage.d.ts +4 -0
  409. package/lib/typescript/helpers/preferencesStorage.d.ts.map +1 -1
  410. package/lib/typescript/helpers/secureKeyValue.d.ts +4 -0
  411. package/lib/typescript/helpers/secureKeyValue.d.ts.map +1 -1
  412. package/lib/typescript/helpers/videoCache.d.ts +19 -0
  413. package/lib/typescript/helpers/videoCache.d.ts.map +1 -0
  414. package/lib/typescript/hooks/useChatSettingState.d.ts +1 -0
  415. package/lib/typescript/hooks/useChatSettingState.d.ts.map +1 -1
  416. package/lib/typescript/hooks/useChatWrapperInit.d.ts.map +1 -1
  417. package/lib/typescript/hooks/useLogout.d.ts.map +1 -1
  418. package/lib/typescript/hooks/useSendMessage.d.ts.map +1 -1
  419. package/lib/typescript/i18n/strings.d.ts.map +1 -1
  420. package/lib/typescript/i18n/useT.d.ts.map +1 -1
  421. package/lib/typescript/main.d.ts +2 -0
  422. package/lib/typescript/main.d.ts.map +1 -1
  423. package/lib/typescript/networking/api-requests/auth.api.d.ts +4 -1
  424. package/lib/typescript/networking/api-requests/auth.api.d.ts.map +1 -1
  425. package/lib/typescript/networking/api-requests/rooms.api.d.ts +22 -1
  426. package/lib/typescript/networking/api-requests/rooms.api.d.ts.map +1 -1
  427. package/lib/typescript/networking/api-requests/user.api.d.ts +6 -0
  428. package/lib/typescript/networking/api-requests/user.api.d.ts.map +1 -1
  429. package/lib/typescript/networking/stanzaHandlers.d.ts.map +1 -1
  430. package/lib/typescript/networking/xmpp/handleStanzas.xmpp.d.ts +1 -0
  431. package/lib/typescript/networking/xmpp/handleStanzas.xmpp.d.ts.map +1 -1
  432. package/lib/typescript/networking/xmpp/sendMediaMessage.xmpp.d.ts.map +1 -1
  433. package/lib/typescript/networking/xmpp/sendTextMessage.xmpp.d.ts.map +1 -1
  434. package/lib/typescript/networking/xmpp/sendTextMessageWithTranslateTag.xmpp.d.ts.map +1 -1
  435. package/lib/typescript/networking/xmppClient.d.ts.map +1 -1
  436. package/lib/typescript/roomStore/chatSettingsSlice.d.ts +8 -1
  437. package/lib/typescript/roomStore/chatSettingsSlice.d.ts.map +1 -1
  438. package/lib/typescript/roomStore/persistBackend.d.ts.map +1 -1
  439. package/lib/typescript/roomStore/persistence.d.ts.map +1 -1
  440. package/lib/typescript/services/languageSettings.d.ts +29 -0
  441. package/lib/typescript/services/languageSettings.d.ts.map +1 -0
  442. package/lib/typescript/types/models/message.model.d.ts +5 -0
  443. package/lib/typescript/types/models/message.model.d.ts.map +1 -1
  444. package/lib/typescript/types/models/room.model.d.ts +5 -0
  445. package/lib/typescript/types/models/room.model.d.ts.map +1 -1
  446. package/lib/typescript/types/models/user.model.d.ts +4 -0
  447. package/lib/typescript/types/models/user.model.d.ts.map +1 -1
  448. package/lib/typescript/types/types.d.ts +25 -0
  449. package/lib/typescript/types/types.d.ts.map +1 -1
  450. package/lib/typescript/version.d.ts +1 -1
  451. package/package.json +8 -4
  452. package/src/assets/icons.tsx +27 -0
  453. package/src/components/MainComponents/ChatHeader.tsx +30 -9
  454. package/src/components/MainComponents/ChatRoom.tsx +11 -1
  455. package/src/components/MainComponents/ChatWrapper.tsx +5 -3
  456. package/src/components/MainComponents/EncryptedSendNotice.tsx +35 -0
  457. package/src/components/MainComponents/EncryptionCard.tsx +287 -0
  458. package/src/components/MainComponents/MediaMessage.tsx +5 -0
  459. package/src/components/MainComponents/ReduxWrapper.tsx +11 -0
  460. package/src/components/MainComponents/SealedAttachment.tsx +251 -0
  461. package/src/components/Menu/HeaderRoomListMenu.tsx +40 -13
  462. package/src/components/MenuRoom/MenuRoom.tsx +5 -3
  463. package/src/components/MessageBubble/BottomReplyContainer.tsx +2 -1
  464. package/src/components/MessageBubble/Message.tsx +99 -9
  465. package/src/components/MessageBubble/MessageInteractions.tsx +7 -6
  466. package/src/components/Modals/ChatProfileModal/ChatProfileModal.tsx +8 -5
  467. package/src/components/Modals/ChatProfileModal/ReportChatModal.tsx +2 -2
  468. package/src/components/Modals/FilePreviewModal/FilePreviewModal.tsx +188 -40
  469. package/src/components/Modals/FilePreviewModal/PdfView.tsx +4 -0
  470. package/src/components/Modals/Modal/Modal.tsx +44 -16
  471. package/src/components/Modals/NewChatModal/NewChatModal.tsx +8 -8
  472. package/src/components/Modals/SettingsModals/ChangePassword/ChangePasswordModal.tsx +316 -0
  473. package/src/components/Modals/SettingsModals/ManageDataModal/ManageDataModal.tsx +10 -15
  474. package/src/components/Modals/SettingsModals/Visibility/VisibilityModal.tsx +13 -14
  475. package/src/components/Modals/UserProfileModal/UserProfileModal.tsx +72 -20
  476. package/src/components/Modals/UserSettingsModal/LanguageCard.tsx +144 -0
  477. package/src/components/Modals/UserSettingsModal/UserSettingsModal.tsx +13 -1
  478. package/src/components/RoomComponents/ChatRoomItem.tsx +23 -11
  479. package/src/components/RoomComponents/LastMessageItem.tsx +5 -0
  480. package/src/components/RoomComponents/styled/LastAudioMessage.tsx +3 -1
  481. package/src/components/RoomComponents/styled/LastMessageFile.tsx +2 -2
  482. package/src/components/RoomComponents/styled/LastMessagePhoto.tsx +1 -1
  483. package/src/components/RoomComponents/styled/LastMessageSealed.tsx +31 -0
  484. package/src/components/RoomComponents/styled/LastMessageVideo.tsx +1 -1
  485. package/src/components/Thread/ThreadWrapper.tsx +17 -2
  486. package/src/components/UsersList/UsersList.tsx +2 -1
  487. package/src/components/styled/SendInput.tsx +5 -2
  488. package/src/e2ee/crypto.ts +194 -0
  489. package/src/e2ee/deviceStore.ts +80 -0
  490. package/src/e2ee/fileCipher.ts +86 -0
  491. package/src/e2ee/fileEnvelope.ts +115 -0
  492. package/src/e2ee/index.ts +192 -0
  493. package/src/e2ee/limits.ts +2 -0
  494. package/src/e2ee/ns.ts +1 -0
  495. package/src/e2ee/omemo.ts +802 -0
  496. package/src/e2ee/protobuf.ts +188 -0
  497. package/src/e2ee/ratchet.ts +271 -0
  498. package/src/e2ee/sealedBody.ts +17 -0
  499. package/src/e2ee/sealedFiles.ts +181 -0
  500. package/src/e2ee/send.ts +70 -0
  501. package/src/e2ee/stanza.ts +133 -0
  502. package/src/e2ee/store.ts +54 -0
  503. package/src/helpers/accountName.ts +15 -0
  504. package/src/helpers/constants/MODAL_COMPONENTS.tsx +2 -0
  505. package/src/helpers/constants/MODAL_TYPES.ts +1 -0
  506. package/src/helpers/createMessageFromXml.ts +31 -6
  507. package/src/helpers/createUserNameFromSetUser.ts +2 -1
  508. package/src/helpers/displayName.ts +9 -0
  509. package/src/helpers/persistCrypto.ts +5 -0
  510. package/src/helpers/preferencesStorage.ts +4 -0
  511. package/src/helpers/secureKeyValue.ts +15 -0
  512. package/src/helpers/videoCache.ts +138 -0
  513. package/src/hooks/useChatSettingState.tsx +4 -0
  514. package/src/hooks/useChatWrapperInit.ts +4 -0
  515. package/src/hooks/useLogout.tsx +9 -0
  516. package/src/hooks/useSendMessage.tsx +71 -5
  517. package/src/i18n/strings.ts +367 -1
  518. package/src/i18n/useT.ts +6 -4
  519. package/src/main.ts +2 -0
  520. package/src/networking/api-requests/auth.api.ts +9 -1
  521. package/src/networking/api-requests/rooms.api.ts +121 -18
  522. package/src/networking/api-requests/user.api.ts +9 -0
  523. package/src/networking/stanzaHandlers.ts +1 -0
  524. package/src/networking/xmpp/handleStanzas.xmpp.ts +49 -0
  525. package/src/networking/xmpp/sendMediaMessage.xmpp.ts +19 -1
  526. package/src/networking/xmpp/sendTextMessage.xmpp.ts +17 -10
  527. package/src/networking/xmpp/sendTextMessageWithTranslateTag.xmpp.ts +23 -10
  528. package/src/networking/xmppClient.ts +6 -0
  529. package/src/roomStore/chatSettingsSlice.ts +13 -0
  530. package/src/roomStore/persistBackend.ts +8 -11
  531. package/src/roomStore/persistence.ts +15 -0
  532. package/src/services/languageSettings.ts +143 -0
  533. package/src/types/models/message.model.ts +5 -0
  534. package/src/types/models/room.model.ts +5 -0
  535. package/src/types/models/user.model.ts +4 -0
  536. package/src/types/types.ts +25 -0
  537. package/src/version.ts +1 -1
@@ -11,6 +11,8 @@ import {
11
11
  setConfig,
12
12
  setPushEnabled,
13
13
  setThemePreference,
14
+ setUiLocale,
15
+ setLangSource,
14
16
  } from '../../roomStore/chatSettingsSlice';
15
17
  import {loadPreferences} from '../../helpers/preferencesStorage';
16
18
  import {ConfigUser, IConfig, MessageProps} from '../../types/types';
@@ -22,6 +24,7 @@ import '../../helpers/storeConsole';
22
24
  import {installPromiseRejectionTracker} from '../../utils/installPromiseRejectionTracker';
23
25
  import {useChatFonts} from '../../hooks/useChatFonts';
24
26
  import {installPushTokenHook} from '../../services/pushRegistration';
27
+ import {setE2eeEnabled} from '../../e2ee';
25
28
 
26
29
  // Mount-time, dev-only — wire a global unhandled-promise-rejection
27
30
  // tracker so any future leak surfaces with a real stack trace in Metro
@@ -57,6 +60,10 @@ const ConfigEnabler: React.FC<{config?: IConfig}> = ({config}) => {
57
60
  if (!config) {return;}
58
61
  dispatch(setConfig(config));
59
62
  }, [config, dispatch]);
63
+ const e2eeEnabled = config?.e2ee?.enabled === true;
64
+ React.useEffect(() => {
65
+ setE2eeEnabled(e2eeEnabled);
66
+ }, [e2eeEnabled]);
60
67
  return null;
61
68
  };
62
69
 
@@ -85,6 +92,10 @@ const ChatThemeProvider: React.FC<{config?: IConfig; children: React.ReactNode}>
85
92
  if (typeof prefs.pushEnabled === 'boolean') {
86
93
  dispatch(setPushEnabled(prefs.pushEnabled));
87
94
  }
95
+ // The user's languages, as last picked here; the profile's values
96
+ // take over once the session is up (see languageSettings).
97
+ if (prefs.uiLocale) {dispatch(setUiLocale(prefs.uiLocale));}
98
+ if (prefs.chatLanguage) {dispatch(setLangSource(prefs.chatLanguage as any));}
88
99
  });
89
100
  }, [dispatch]);
90
101
 
@@ -0,0 +1,251 @@
1
+ import React, { useCallback, useEffect, useRef, useState } from 'react';
2
+ import { ActivityIndicator, StyleSheet, View } from 'react-native';
3
+ import { LockIcon } from '../../assets/icons';
4
+ import FileDownload from '../styled/UnsupportedType';
5
+ import CustomMessageImage from '../styled/MessageImage';
6
+ import CustomMessageVideo from '../styled/VideoMessage';
7
+ import AudioMessage from '../styled/AudioMessage';
8
+ import {
9
+ BackgroundFile,
10
+ FileInformation,
11
+ FileName,
12
+ FileSize,
13
+ FileSizeContainer,
14
+ UnsupportedContainer,
15
+ } from '../styled/StyledInputComponents/MediaComponents';
16
+ import { useTheme } from '../../hooks/useTheme';
17
+ import { useT } from '../../i18n/useT';
18
+ import { useChatSettingState } from '../../hooks/useChatSettingState';
19
+ import { IMessage } from '../../types/types';
20
+ import { withFileToken } from '../../helpers/secureFileUrl';
21
+ import type { OpenedFile } from '../../e2ee/sealedFiles';
22
+
23
+ const sealedFiles = () =>
24
+ require('../../e2ee/sealedFiles') as typeof import('../../e2ee/sealedFiles');
25
+
26
+ interface SealedRef {
27
+ location: string;
28
+ size?: string | number;
29
+ }
30
+
31
+ export const sealedAttachmentsOf = (message?: IMessage | null): SealedRef[] => {
32
+ if (!message) {return [];}
33
+ let raw: unknown = (message as any).attachments;
34
+ if (typeof raw === 'string') {
35
+ try {
36
+ raw = JSON.parse(raw);
37
+ } catch {
38
+ raw = undefined;
39
+ }
40
+ }
41
+ if (Array.isArray(raw) && raw.length > 0) {
42
+ return raw
43
+ .filter((item) => item && typeof item.location === 'string' && item.location)
44
+ .map((item) => ({ location: item.location, size: item.size }));
45
+ }
46
+ return message.location
47
+ ? [{ location: message.location, size: message.size }]
48
+ : [];
49
+ };
50
+
51
+ const formatBytes = (value?: string | number): string => {
52
+ const bytes = Number(value);
53
+ if (!Number.isFinite(bytes) || bytes <= 0) {return '';}
54
+ if (bytes < 1024) {return `${bytes} B`;}
55
+ if (bytes < 1024 * 1024) {return `${(bytes / 1024).toFixed(0)} KB`;}
56
+ return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
57
+ };
58
+
59
+ type CardState = 'idle' | 'working' | 'failed';
60
+
61
+ const SealedItem: React.FC<{
62
+ attachment: SealedRef;
63
+ keyMaterial?: string;
64
+ isUser: boolean;
65
+ }> = ({ attachment, keyMaterial, isUser }) => {
66
+ const theme = useTheme();
67
+ const t = useT();
68
+ const { config } = useChatSettingState();
69
+ const [state, setState] = useState<CardState>('idle');
70
+ const [progress, setProgress] = useState(0);
71
+ const [opened, setOpened] = useState<OpenedFile | null>(null);
72
+ const mounted = useRef(true);
73
+ useEffect(
74
+ () => () => {
75
+ mounted.current = false;
76
+ },
77
+ []
78
+ );
79
+
80
+ const { location } = attachment;
81
+
82
+ useEffect(() => {
83
+ if (!keyMaterial || !location) {return;}
84
+ let active = true;
85
+ sealedFiles()
86
+ .findOpened(location)
87
+ .then((found) => {
88
+ if (active && found) {setOpened(found);}
89
+ })
90
+ .catch(() => {});
91
+ return () => {
92
+ active = false;
93
+ };
94
+ }, [keyMaterial, location]);
95
+
96
+ const handlePress = useCallback(async () => {
97
+ if (opened || !keyMaterial || !location || state === 'working') {return;}
98
+ setState('working');
99
+ setProgress(0);
100
+ try {
101
+ const file = await sealedFiles().openSealedAttachment(
102
+ location,
103
+ withFileToken(location),
104
+ keyMaterial,
105
+ (fraction) => {
106
+ if (mounted.current) {setProgress(fraction);}
107
+ }
108
+ );
109
+ if (!mounted.current) {return;}
110
+ setOpened(file);
111
+ setState('idle');
112
+ } catch (error) {
113
+ console.warn('sealed attachment could not be opened', error);
114
+ if (mounted.current) {setState('failed');}
115
+ }
116
+ }, [keyMaterial, location, opened, state]);
117
+
118
+ if (opened) {
119
+ if (opened.mimetype.startsWith('image/')) {
120
+ return (
121
+ <View testID="sealed-attachment-image">
122
+ <CustomMessageImage
123
+ fileName={opened.name}
124
+ originalName={opened.name}
125
+ fileURL={opened.uri}
126
+ locationPreview={opened.uri}
127
+ mimetype={opened.mimetype}
128
+ />
129
+ </View>
130
+ );
131
+ }
132
+ if (opened.mimetype.startsWith('video/')) {
133
+ return (
134
+ <CustomMessageVideo
135
+ fileName={opened.name}
136
+ originalName={opened.name}
137
+ fileURL={opened.uri}
138
+ mimetype={opened.mimetype}
139
+ />
140
+ );
141
+ }
142
+ if (opened.mimetype.startsWith('audio/')) {
143
+ return (
144
+ <AudioMessage
145
+ src={opened.uri}
146
+ mimeType={opened.mimetype}
147
+ fileName={opened.name}
148
+ originalName={opened.name}
149
+ />
150
+ );
151
+ }
152
+ return (
153
+ <View testID="sealed-attachment">
154
+ <FileDownload
155
+ fileURL={opened.uri}
156
+ fileName={opened.name}
157
+ originalName={opened.name}
158
+ mimetype={opened.mimetype}
159
+ isUser={isUser}
160
+ />
161
+ </View>
162
+ );
163
+ }
164
+
165
+ const canOpen = !!keyMaterial && !!location;
166
+ const working = state === 'working';
167
+ const note = !canOpen
168
+ ? t(
169
+ config?.e2ee?.enabled === true
170
+ ? 'media.sealedUnavailable'
171
+ : 'media.sealedUnsupported'
172
+ )
173
+ : working
174
+ ? `${t('media.sealedDownloading')} ${Math.round(progress * 100)}%`
175
+ : state === 'failed'
176
+ ? t('media.sealedDownloadFailed')
177
+ : formatBytes(attachment.size) || t('media.sealedDownload');
178
+
179
+ return (
180
+ <UnsupportedContainer
181
+ isUser={isUser}
182
+ onPress={handlePress}
183
+ disabled={!canOpen || working}
184
+ activeOpacity={canOpen && !working ? 0.7 : 1}
185
+ testID="sealed-attachment"
186
+ accessibilityRole="button"
187
+ accessibilityLabel={t(canOpen ? 'media.sealedDownload' : 'media.sealedFile')}
188
+ >
189
+ <BackgroundFile>
190
+ {working ? (
191
+ <ActivityIndicator size="small" color={theme.textSecondary} />
192
+ ) : (
193
+ <LockIcon width={26} height={26} color={theme.textSecondary} />
194
+ )}
195
+ </BackgroundFile>
196
+ <FileInformation>
197
+ <FileName
198
+ numberOfLines={1}
199
+ isUser={isUser}
200
+ colorIsUser={config?.colors?.primary}
201
+ colorUsers={config?.colors?.secondary}
202
+ >
203
+ {t('media.sealedFile')}
204
+ </FileName>
205
+ <FileSizeContainer style={styles.note}>
206
+ <FileSize
207
+ numberOfLines={2}
208
+ style={state === 'failed' && canOpen ? { color: theme.danger } : undefined}
209
+ >
210
+ {note}
211
+ </FileSize>
212
+ </FileSizeContainer>
213
+ </FileInformation>
214
+ </UnsupportedContainer>
215
+ );
216
+ };
217
+
218
+ const SealedAttachment: React.FC<{ message?: IMessage; isUser: boolean }> = ({
219
+ message,
220
+ isUser,
221
+ }) => {
222
+ const attachments = sealedAttachmentsOf(message);
223
+ const keys = message?.e2eeKeys;
224
+ if (attachments.length === 0) {
225
+ return <SealedItem attachment={{ location: '' }} isUser={isUser} />;
226
+ }
227
+ return (
228
+ <View style={styles.stack}>
229
+ {attachments.map((attachment, index) => (
230
+ <SealedItem
231
+ key={attachment.location || index}
232
+ attachment={attachment}
233
+ keyMaterial={keys?.[index]}
234
+ isUser={isUser}
235
+ />
236
+ ))}
237
+ </View>
238
+ );
239
+ };
240
+
241
+ export default SealedAttachment;
242
+
243
+ const styles = StyleSheet.create({
244
+ stack: {
245
+ gap: 8,
246
+ },
247
+ note: {
248
+ flexShrink: 1,
249
+ borderRadius: 10,
250
+ },
251
+ });
@@ -30,14 +30,27 @@ import {
30
30
  shouldDismissOnDrag,
31
31
  } from '../../helpers/sheetGestures';
32
32
  import type { IConfig } from '../../types/types';
33
+ import { useT } from '../../i18n/useT';
33
34
 
34
35
  type LogoutConfig = NonNullable<IConfig['logout']>;
35
36
 
36
- const DEFAULT_LOGOUT_LABEL = 'Sign out';
37
+ /** The sign-out copy in the UI language; a host's `logout.label` etc. win. */
38
+ export interface LogoutStrings {
39
+ label: string;
40
+ message: string;
41
+ cancel: string;
42
+ }
43
+
44
+ const DEFAULT_LOGOUT_STRINGS: LogoutStrings = {
45
+ label: 'Sign out',
46
+ message: 'Are you sure you want to sign out?',
47
+ cancel: 'Cancel',
48
+ };
37
49
 
38
50
  const confirmLogout = (
39
51
  confirm: LogoutConfig['confirm'],
40
- label: string
52
+ label: string,
53
+ strings: LogoutStrings
41
54
  ): Promise<boolean> => {
42
55
  if (confirm === false) {
43
56
  return Promise.resolve(true);
@@ -46,10 +59,10 @@ const confirmLogout = (
46
59
  return new Promise<boolean>((resolve) => {
47
60
  Alert.alert(
48
61
  copy.title ?? label,
49
- copy.message ?? 'Are you sure you want to sign out?',
62
+ copy.message ?? strings.message,
50
63
  [
51
64
  {
52
- text: copy.cancelText ?? 'Cancel',
65
+ text: copy.cancelText ?? strings.cancel,
53
66
  style: 'cancel',
54
67
  onPress: () => resolve(false),
55
68
  },
@@ -66,10 +79,15 @@ const confirmLogout = (
66
79
 
67
80
  export const runLogoutFlow = async (
68
81
  logoutConfig: LogoutConfig,
69
- performLogout: () => Promise<void>
82
+ performLogout: () => Promise<void>,
83
+ strings: LogoutStrings = DEFAULT_LOGOUT_STRINGS
70
84
  ): Promise<void> => {
71
- const label = logoutConfig.label ?? DEFAULT_LOGOUT_LABEL;
72
- const confirmed = await confirmLogout(logoutConfig.confirm ?? true, label);
85
+ const label = logoutConfig.label ?? strings.label;
86
+ const confirmed = await confirmLogout(
87
+ logoutConfig.confirm ?? true,
88
+ label,
89
+ strings
90
+ );
73
91
  if (!confirmed) {
74
92
  return;
75
93
  }
@@ -112,7 +130,16 @@ export const HeaderRoomListMenu: FC<HeaderRoomListMenuProps> = ({
112
130
  const dispatch = useDispatch();
113
131
  const { config } = useChatSettingState();
114
132
  const performLogout = useLogout();
133
+ const t = useT();
115
134
  const logoutConfig = config?.logout?.enabled ? config.logout : undefined;
135
+ const logoutStrings = useMemo<LogoutStrings>(
136
+ () => ({
137
+ label: t('menu.logout'),
138
+ message: t('menu.logoutConfirm'),
139
+ cancel: t('action.cancel'),
140
+ }),
141
+ [t]
142
+ );
116
143
  const theme = useTheme();
117
144
  const primaryColor = theme.primary;
118
145
  const iconColor = theme.icon;
@@ -246,7 +273,7 @@ export const HeaderRoomListMenu: FC<HeaderRoomListMenuProps> = ({
246
273
  styles?: { color: string };
247
274
  }[] = [
248
275
  {
249
- label: 'New Chat',
276
+ label: t('menu.newChat'),
250
277
  icon: <AddNewIcon color={iconColor} />,
251
278
  onClick: () => {
252
279
  dispatch(setActiveModal(MODAL_TYPES.NEW_CHAT));
@@ -254,14 +281,14 @@ export const HeaderRoomListMenu: FC<HeaderRoomListMenuProps> = ({
254
281
  styles: { color: labelColor },
255
282
  },
256
283
  {
257
- label: 'Profile',
284
+ label: t('menu.profile'),
258
285
  icon: <ProfileIcon color={iconColor} />,
259
286
  onClick: () => {
260
287
  dispatch(setActiveModal(MODAL_TYPES.PROFILE));
261
288
  },
262
289
  },
263
290
  {
264
- label: 'Settings',
291
+ label: t('menu.settings'),
265
292
  icon: <SettingIcon color={iconColor} />,
266
293
  onClick: () => {
267
294
  dispatch(setActiveModal(MODAL_TYPES.SETTINGS));
@@ -270,16 +297,16 @@ export const HeaderRoomListMenu: FC<HeaderRoomListMenuProps> = ({
270
297
  ];
271
298
  if (logoutConfig) {
272
299
  options.push({
273
- label: logoutConfig.label ?? DEFAULT_LOGOUT_LABEL,
300
+ label: logoutConfig.label ?? logoutStrings.label,
274
301
  icon: <LogoutIcon color={iconColor} />,
275
302
  styles: { color: primaryColor },
276
303
  onClick: () => {
277
- runLogoutFlow(logoutConfig, performLogout).catch(() => {});
304
+ runLogoutFlow(logoutConfig, performLogout, logoutStrings).catch(() => {});
278
305
  },
279
306
  });
280
307
  }
281
308
  return options;
282
- }, [dispatch, logoutConfig, performLogout, primaryColor, iconColor, labelColor]);
309
+ }, [dispatch, logoutConfig, logoutStrings, performLogout, primaryColor, iconColor, labelColor, t]);
283
310
 
284
311
  return (
285
312
  // Presented through a real <Modal>: as an in-tree overlay the sheet was
@@ -2,16 +2,18 @@ import { FC, useMemo } from 'react';
2
2
  import DropdownMenu from '../DropdownMenu/DropdownMenu';
3
3
  import Button from '../styled/Button';
4
4
  import { LeaveIcon, MoreIcon, ReportIcon } from '../../assets/icons';
5
+ import { useT } from '../../i18n/useT';
5
6
 
6
7
  interface RoomMenuProps {
7
8
  handleLeaveClick: () => void;
8
9
  }
9
10
 
10
11
  export const RoomMenu: FC<RoomMenuProps> = ({ handleLeaveClick }) => {
12
+ const t = useT();
11
13
  const menuOptions = useMemo(
12
14
  () => [
13
15
  {
14
- label: 'Report',
16
+ label: t('action.report'),
15
17
  icon: <ReportIcon />,
16
18
  onClick: () => {
17
19
  console.log('Report clicked');
@@ -19,7 +21,7 @@ export const RoomMenu: FC<RoomMenuProps> = ({ handleLeaveClick }) => {
19
21
  styles: { color: 'red' },
20
22
  },
21
23
  {
22
- label: 'Leave',
24
+ label: t('action.leave'),
23
25
  icon: <LeaveIcon />,
24
26
  onClick: () => {
25
27
  handleLeaveClick();
@@ -27,7 +29,7 @@ export const RoomMenu: FC<RoomMenuProps> = ({ handleLeaveClick }) => {
27
29
  styles: { color: 'red' },
28
30
  },
29
31
  ],
30
- [handleLeaveClick]
32
+ [handleLeaveClick, t]
31
33
  );
32
34
 
33
35
  return (
@@ -1,4 +1,5 @@
1
1
  import { FC, useMemo } from 'react';
2
+ import { composeName } from '../../helpers/displayName';
2
3
  import { IReply, IUser } from '../../types/types';
3
4
  import { Avatar } from './Avatar';
4
5
  import { styled } from 'styled-components/native';
@@ -68,7 +69,7 @@ export const BottomReplyContainer: FC<BottomReplyContainerProps> = ({
68
69
  const raw = String(u?.id || '');
69
70
  const entry = usersSet?.[raw.split('@')[0]] || usersSet?.[raw];
70
71
  const full = entry
71
- ? `${entry.firstName || ''} ${entry.lastName || ''}`.trim() || entry.name
72
+ ? composeName(entry.firstName, entry.lastName) || entry.name
72
73
  : '';
73
74
  return full || u?.name || '';
74
75
  };
@@ -1,5 +1,6 @@
1
1
  import React, { useEffect, useMemo, useRef, useState } from 'react';
2
2
  import {
3
+ Alert,
3
4
  Animated,
4
5
  View,
5
6
  Pressable,
@@ -36,7 +37,16 @@ import { useChatSettingState } from '../../hooks/useChatSettingState';
36
37
  import { parseMessageBody } from '../../helpers/parseMessageBody';
37
38
  import { chatTextStyle } from '../../helpers/typography';
38
39
  import { useMessageHeapState } from '../../hooks/useMessageHeapState';
39
- import { DoubleTick } from '../../assets/icons';
40
+ import { DoubleTick, LockIcon, LockOffIcon } from '../../assets/icons';
41
+ import { useT } from '../../i18n/useT';
42
+ import { composeName } from '../../helpers/displayName';
43
+ import { useFileToken } from '../../hooks/useFileToken';
44
+ import {
45
+ appendFileToken,
46
+ isSecureFileUrl,
47
+ requestFileTokenRecovery,
48
+ } from '../../helpers/secureFileUrl';
49
+ import { placeholderKey } from '../../e2ee/stanza';
40
50
  import { useXmppClient } from '../../context/xmppProvider';
41
51
  import { useSendMessage } from '../../hooks/useSendMessage';
42
52
  import { MessageReaction } from './MessageReaction';
@@ -168,6 +178,7 @@ const Message: React.FC<MessageProps> = ({ message, isUser, isReply }) => {
168
178
  // only per-render allocations added for theming (memoized on the theme
169
179
  // object, which useTheme keeps stable across renders).
170
180
  const theme = useTheme();
181
+ const t = useT();
171
182
  const themedStyles = useMemo(
172
183
  () => ({
173
184
  muted: { color: theme.textMuted },
@@ -226,7 +237,7 @@ const Message: React.FC<MessageProps> = ({ message, isUser, isReply }) => {
226
237
  // (which may carry senderFirstName/senderLastName from the wire) only when
227
238
  // usersSet has never seen this sender.
228
239
  const senderDisplayName = senderEntry
229
- ? `${senderEntry.firstName ?? ''} ${senderEntry.lastName ?? ''}`.trim() ||
240
+ ? composeName(senderEntry.firstName, senderEntry.lastName) ||
230
241
  senderEntry.name ||
231
242
  senderLocal
232
243
  : message.user?.name || senderLocal || 'Unknown';
@@ -235,8 +246,18 @@ const Message: React.FC<MessageProps> = ({ message, isUser, isReply }) => {
235
246
  // ends at 50 characters of hex. Captioning a bubble with that tells the
236
247
  // reader strictly less than showing nothing.
237
248
  const hasRealSenderName = !isUnresolvedSenderId(senderDisplayName);
249
+ const fileToken = useFileToken();
250
+ const [avatarFailed, setAvatarFailed] = useState<string | null>(null);
251
+ const rawProfileImage = String(
252
+ senderEntry?.profileImage ||
253
+ message.user?.profileImage ||
254
+ (message.user as any)?.photoURL ||
255
+ ''
256
+ ).trim();
238
257
  const senderProfileImage =
239
- senderEntry?.profileImage || message.user?.profileImage || '';
258
+ rawProfileImage && rawProfileImage !== 'none' && rawProfileImage !== avatarFailed
259
+ ? appendFileToken(rawProfileImage, fileToken)
260
+ : '';
240
261
  const { idSet, failedIdSet } = useMessageHeapState();
241
262
  const { retryMessage } = useSendMessage();
242
263
 
@@ -407,8 +428,13 @@ const Message: React.FC<MessageProps> = ({ message, isUser, isReply }) => {
407
428
  );
408
429
  // In auto mode, render the translation as the primary body — but NEVER for
409
430
  // the reader's own messages (they wrote it; no point translating it back).
431
+ const isUndecryptable =
432
+ message.undecryptable === 'true' && !message.isDeleted;
410
433
  const showInlineTranslation =
411
- isAutoTranslate && translationDisplay.hasTranslation && !isUser;
434
+ isAutoTranslate &&
435
+ translationDisplay.hasTranslation &&
436
+ !isUser &&
437
+ !isUndecryptable;
412
438
  const bodyToRender = showInlineTranslation
413
439
  ? translationDisplay.displayText
414
440
  : message.body;
@@ -460,13 +486,32 @@ const Message: React.FC<MessageProps> = ({ message, isUser, isReply }) => {
460
486
  onPress={
461
487
  config?.disableProfilesInteractions
462
488
  ? undefined
463
- : () => handleUserAvatarClick(message.user)
489
+ : () =>
490
+ handleUserAvatarClick({
491
+ ...message.user,
492
+ ...(senderEntry
493
+ ? {
494
+ firstName: senderEntry.firstName,
495
+ lastName: senderEntry.lastName,
496
+ profileImage: senderEntry.profileImage,
497
+ description: senderEntry.description,
498
+ }
499
+ : {}),
500
+ name: hasRealSenderName ? senderDisplayName : '',
501
+ } as IUser)
464
502
  }
465
503
  disabled={!!config?.disableProfilesInteractions}
466
504
  accessible={!config?.disableProfilesInteractions}
467
505
  >
468
506
  {senderProfileImage ? (
469
- <CustomMessagePhoto source={{ uri: senderProfileImage }} />
507
+ <CustomMessagePhoto
508
+ testID="message-sender-avatar"
509
+ source={{ uri: senderProfileImage }}
510
+ onError={() => {
511
+ if (isSecureFileUrl(rawProfileImage)) {requestFileTokenRecovery();}
512
+ setAvatarFailed(rawProfileImage);
513
+ }}
514
+ />
470
515
  ) : (
471
516
  <Avatar username={senderDisplayName} />
472
517
  )}
@@ -537,6 +582,26 @@ const Message: React.FC<MessageProps> = ({ message, isUser, isReply }) => {
537
582
  <>
538
583
  {message.isDeleted && message.id !== 'delimiter-new' ? (
539
584
  <DeletedMessage />
585
+ ) : isUndecryptable ? (
586
+ <View style={styles.undecryptable}>
587
+ <LockIcon
588
+ width={15}
589
+ height={15}
590
+ color={theme.textSecondary}
591
+ />
592
+ <Text
593
+ style={[
594
+ styles.undecryptableText,
595
+ themedStyles.muted,
596
+ {
597
+ fontSize:
598
+ config?.typography?.messageText?.fontSize ?? 15,
599
+ },
600
+ ]}
601
+ >
602
+ {t(placeholderKey(message.e2eeError))}
603
+ </Text>
604
+ </View>
540
605
  ) : (
541
606
  <CustomMessageText
542
607
  isUser={isUser}
@@ -565,6 +630,7 @@ const Message: React.FC<MessageProps> = ({ message, isUser, isReply }) => {
565
630
  renders the translation inline in the body above). Never on
566
631
  the reader's own messages. */}
567
632
  {!isUser &&
633
+ !isUndecryptable &&
568
634
  isTranslatesEnabled &&
569
635
  effectiveTranslateMode === 'manual' && (
570
636
  <MessageTranslate
@@ -578,7 +644,7 @@ const Message: React.FC<MessageProps> = ({ message, isUser, isReply }) => {
578
644
  <CustomTimestampRow media={message?.isMediafile === 'true'}>
579
645
  {!config?.disableSentLogic && isUser && isPending && (
580
646
  <Text style={[styles.timestampText, themedStyles.muted]}>
581
- sending...
647
+ {t('message.sending')}
582
648
  </Text>
583
649
  )}
584
650
  {!config?.disableSentLogic && isUser && isFailed && (
@@ -588,11 +654,25 @@ const Message: React.FC<MessageProps> = ({ message, isUser, isReply }) => {
588
654
  accessibilityRole="button"
589
655
  accessibilityLabel="Retry sending message"
590
656
  >
591
- ! Failed — tap to retry
657
+ {t('message.failedRetry')}
592
658
  </Text>
593
659
  )}
594
660
  {message?.isEdited && !message?.isDeleted && (
595
- <Text style={[styles.editedText, themedStyles.muted]}>edited</Text>
661
+ <Text style={[styles.editedText, themedStyles.muted]}>{t('message.edited')}</Text>
662
+ )}
663
+ {message?.unencrypted && !message?.isDeleted && (
664
+ <Pressable
665
+ hitSlop={10}
666
+ accessibilityRole="button"
667
+ accessibilityLabel={t('e2ee.notEncrypted')}
668
+ accessibilityHint={t('e2ee.notEncryptedHint')}
669
+ testID="message-not-encrypted"
670
+ onPress={() =>
671
+ Alert.alert(t('e2ee.notEncrypted'), t('e2ee.notEncryptedHint'))
672
+ }
673
+ >
674
+ <LockOffIcon width={13} height={13} color={theme.danger} />
675
+ </Pressable>
596
676
  )}
597
677
  <Text style={[styles.timestampText, themedStyles.muted]}>
598
678
  {timeLabel}
@@ -718,6 +798,16 @@ const styles = StyleSheet.create({
718
798
  marginTop: 4,
719
799
  gap: 4,
720
800
  },
801
+ undecryptable: {
802
+ flexDirection: 'row',
803
+ alignItems: 'flex-start',
804
+ gap: 6,
805
+ maxWidth: 260,
806
+ },
807
+ undecryptableText: {
808
+ flexShrink: 1,
809
+ fontStyle: 'italic',
810
+ },
721
811
  timestampText: {
722
812
  fontSize: 12,
723
813
  lineHeight: 16,