@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
@@ -1,4 +1,5 @@
1
1
  import React, { useEffect, useId, useMemo, useRef, useState } from 'react';
2
+ import { canEditMessage } from '../../e2ee';
2
3
  import { Delimeter, MenuItem } from '../ContextMenu/ContextMenuComponents';
3
4
  import { useSelector } from 'react-redux';
4
5
  import { RootState } from '../../roomStore';
@@ -21,6 +22,7 @@ import * as Clipboard from 'expo-clipboard';
21
22
  import { useToast } from '../../context/ToastContext';
22
23
  import { useInteractionsOverlay } from './InteractionsOverlay';
23
24
  import { useTheme } from '../../hooks/useTheme';
25
+ import { useT } from '../../i18n/useT';
24
26
  import { getEmojiNativeById } from '../../helpers/emoji';
25
27
  import {
26
28
  quickReactionIds,
@@ -60,6 +62,7 @@ const MessageInteractions: React.FC<MessageInteractionsProps> = ({
60
62
  onOpenEmojiPicker,
61
63
  }) => {
62
64
  const { showToast } = useToast();
65
+ const t = useT();
63
66
  const { present, dismiss, originX, originY } = useInteractionsOverlay();
64
67
  const overlayId = useId();
65
68
  const theme = useTheme();
@@ -143,15 +146,15 @@ const MessageInteractions: React.FC<MessageInteractionsProps> = ({
143
146
  await Clipboard.setStringAsync(text);
144
147
  showToast({
145
148
  id: Date.now().toString(),
146
- title: 'Success',
147
- message: 'Copied to clipboard!',
149
+ title: t('toast.successTitle'),
150
+ message: t('toast.copied'),
148
151
  type: 'success',
149
152
  });
150
153
  } catch (err) {
151
154
  console.log(err);
152
155
  showToast({
153
156
  id: Date.now().toString(),
154
- title: 'Copy failed',
157
+ title: t('toast.copyFailed'),
155
158
  message: (err as Error)?.message || 'Unknown error',
156
159
  type: 'error',
157
160
  });
@@ -362,9 +365,7 @@ const MessageInteractions: React.FC<MessageInteractionsProps> = ({
362
365
  </MenuItem>
363
366
  {isUser && (
364
367
  <>
365
- {/* Edit only for non-media messages (upstream guard) +
366
- consistent label styling (menuText). */}
367
- {message?.isMediafile !== 'true' && (
368
+ {message?.isMediafile !== 'true' && canEditMessage(message) && (
368
369
  <>
369
370
  <Delimeter />
370
371
  <MenuItem onPress={handleEditMessage}>
@@ -1,5 +1,6 @@
1
1
  /** @format */
2
2
 
3
+ import { composeName } from '../../../helpers/displayName';
3
4
  import React, { useEffect, useMemo, useRef, useState } from 'react';
4
5
  import {
5
6
  Alert,
@@ -268,7 +269,7 @@ const ChatProfileModal: React.FC<ChatProfileModalProps> = ({
268
269
  const confirmRemoveMember = (user: RoomMember) => {
269
270
  Alert.alert(
270
271
  t('modal.chatProfile.removeMember'),
271
- `${user.firstName} ${user.lastName}`.trim(),
272
+ composeName(user.firstName, user.lastName),
272
273
  [
273
274
  { text: t('action.cancel'), style: 'cancel' },
274
275
  {
@@ -287,7 +288,8 @@ const ChatProfileModal: React.FC<ChatProfileModalProps> = ({
287
288
  id: user._id,
288
289
  firstName: user.firstName,
289
290
  lastName: user.lastName,
290
- name: `${user.firstName} ${user.lastName}`,
291
+ name: composeName(user.firstName, user.lastName),
292
+ profileImage: user.profileImage,
291
293
  userJID: user?.xmppUsername,
292
294
  token: '',
293
295
  refreshToken: '',
@@ -377,7 +379,7 @@ const ChatProfileModal: React.FC<ChatProfileModalProps> = ({
377
379
  console.warn('[ethora-rn] mute toggle failed', error);
378
380
  showToast({
379
381
  id: Date.now().toString(),
380
- title: 'Error',
382
+ title: t('toast.error'),
381
383
  message: t('toast.muteFailed'),
382
384
  type: 'error',
383
385
  });
@@ -488,7 +490,7 @@ const ChatProfileModal: React.FC<ChatProfileModalProps> = ({
488
490
  const query = memberQuery.trim().toLowerCase();
489
491
  const visibleMembers = query
490
492
  ? members.filter((user) =>
491
- `${user.firstName ?? ''} ${user.lastName ?? ''}`
493
+ composeName(user.firstName, user.lastName)
492
494
  .toLowerCase()
493
495
  .includes(query)
494
496
  )
@@ -648,7 +650,8 @@ const ChatProfileModal: React.FC<ChatProfileModalProps> = ({
648
650
  disabled={!!config?.disableChatInfo?.disableMemberTap}
649
651
  >
650
652
  <ProfileImagePlaceholder
651
- name={`${user.firstName} ${user.lastName}`}
653
+ name={composeName(user.firstName, user.lastName)}
654
+ icon={appendFileToken(user.profileImage, fileToken) || null}
652
655
  size={40}
653
656
  />
654
657
  <View style={styles.memberText}>
@@ -72,7 +72,7 @@ const ReportChatModal: React.FC<ReportChatModalProps> = ({
72
72
  });
73
73
  showToast({
74
74
  id: Date.now().toString(),
75
- title: 'Success',
75
+ title: t('toast.successTitle'),
76
76
  message: t('modal.report.chatTitle'),
77
77
  type: 'success',
78
78
  });
@@ -81,7 +81,7 @@ const ReportChatModal: React.FC<ReportChatModalProps> = ({
81
81
  console.error('Failed to report chat:', error);
82
82
  showToast({
83
83
  id: Date.now().toString(),
84
- title: 'Error',
84
+ title: t('toast.error'),
85
85
  message: t('modal.report.chatTitle'),
86
86
  type: 'error',
87
87
  });
@@ -1,4 +1,4 @@
1
- import React, { useEffect, useRef, useState } from 'react';
1
+ import React, { useCallback, useEffect, useRef, useState } from 'react';
2
2
  import { withFileToken } from '../../../helpers/secureFileUrl';
3
3
  import styled from 'styled-components/native';
4
4
  import {
@@ -16,6 +16,7 @@ import { RootState } from '../../../roomStore';
16
16
  import { FullScreenImage } from '../../styled/StyledInputComponents/MediaComponents';
17
17
  import { setActiveFile } from '../../../roomStore/chatSettingsSlice';
18
18
  import {
19
+ ActivityIndicator,
19
20
  Alert,
20
21
  Text,
21
22
  View,
@@ -29,10 +30,18 @@ import { PlayIcon } from '../../../assets/icons';
29
30
  import * as FileSystem from 'expo-file-system/legacy';
30
31
  import { getMediaLibrary } from '../../../helpers/mediaLibraryRuntime';
31
32
  import { useToast } from '../../../context/ToastContext';
33
+ import { useT } from '../../../i18n/useT';
32
34
  import PdfViewer from './PdfView';
33
35
  import DocumentViewer from './DocumentViewer';
34
36
  import AudioMessage from '../../styled/AudioMessage';
35
37
  import { isLikelyAudio } from '../../../helpers/mimeToExtension';
38
+ import {
39
+ downloadVideoToCache,
40
+ findCachedVideo,
41
+ isRemoteUrl,
42
+ isStreamingUnsupported,
43
+ markStreamingUnsupported,
44
+ } from '../../../helpers/videoCache';
36
45
  import {
37
46
  getDisplayFileName,
38
47
  getUniqueFileName,
@@ -52,6 +61,15 @@ const GVIEW_PREVIEWABLE = new Set<string>([
52
61
  'text/csv',
53
62
  'application/rtf',
54
63
  ]);
64
+
65
+ const isLocalFile = (url: string | undefined | null) =>
66
+ /^file:\/\//i.test(url || '');
67
+
68
+ const fetchToCache = async (url: string, cachePath: string) =>
69
+ isLocalFile(url)
70
+ ? { status: 200, uri: url }
71
+ : FileSystem.downloadAsync(withFileToken(url), cachePath);
72
+
55
73
  const isGviewPreviewable = (mime: string | undefined | null) => {
56
74
  if (!mime) {return false;}
57
75
  return GVIEW_PREVIEWABLE.has(mime.toLowerCase().split(';')[0]!.trim());
@@ -62,52 +80,163 @@ const isGviewPreviewable = (mime: string | undefined | null) => {
62
80
  // the area with the surrounding letterbox painted as the view's own
63
81
  // (transparent → theme) background, NOT black. `textureView` so the play
64
82
  // overlay composites on top and nothing is clipped on Android.
65
- const ModalVideo: React.FC<{ uri: string }> = ({ uri }) => {
83
+ //
84
+ // The clip is streamed when the server allows it. AVPlayer does not play
85
+ // from a server that ignores byte-range requests (it answers 200 instead of
86
+ // 206 and the player stops with "server is not correctly configured"), so
87
+ // a failed stream falls back to a downloaded copy in the cache — which is
88
+ // also what a reopened video plays from.
89
+ const ModalVideo: React.FC<{ uri: string; mimetype?: string }> = ({
90
+ uri,
91
+ mimetype,
92
+ }) => {
93
+ const theme = useTheme();
94
+ const remote = isRemoteUrl(uri);
95
+ // What the player is given; null until we know where to play from.
96
+ const [source, setSource] = useState<string | null>(remote ? null : uri);
66
97
  const [showPlay, setShowPlay] = useState(true);
98
+ // null = not downloading, otherwise 0..1 (0 while the size is unknown).
99
+ const [progress, setProgress] = useState<number | null>(null);
100
+ const [failed, setFailed] = useState(false);
101
+ const wantsPlay = useRef(false);
102
+ const downloadStarted = useRef(false);
103
+ const mounted = useRef(true);
104
+ useEffect(
105
+ () => () => {
106
+ mounted.current = false;
107
+ },
108
+ []
109
+ );
67
110
 
68
- const player = useVideoPlayer(uri, (p) => {
111
+ const download = useCallback(() => {
112
+ if (downloadStarted.current) {return;}
113
+ downloadStarted.current = true;
114
+ setProgress(0);
115
+ downloadVideoToCache(uri, mimetype, (fraction) => {
116
+ if (mounted.current) {setProgress(fraction);}
117
+ })
118
+ .then((localUri) => {
119
+ if (!mounted.current) {return;}
120
+ setProgress(null);
121
+ setSource(localUri);
122
+ })
123
+ .catch((err) => {
124
+ console.warn('video download failed', err);
125
+ if (!mounted.current) {return;}
126
+ setProgress(null);
127
+ setFailed(true);
128
+ });
129
+ }, [mimetype, uri]);
130
+
131
+ useEffect(() => {
132
+ if (!remote) {return;}
133
+ let active = true;
134
+ findCachedVideo(uri, mimetype).then((cached) => {
135
+ if (!active) {return;}
136
+ if (cached) {
137
+ setSource(cached);
138
+ } else if (isStreamingUnsupported(uri)) {
139
+ download();
140
+ } else {
141
+ setSource(uri);
142
+ }
143
+ });
144
+ return () => {
145
+ active = false;
146
+ };
147
+ }, [download, mimetype, remote, uri]);
148
+
149
+ const player = useVideoPlayer(source, (p) => {
69
150
  p.muted = false;
151
+ // A player made for the downloaded copy picks up a play the user
152
+ // already asked for.
153
+ if (wantsPlay.current) {p.play();}
70
154
  });
71
155
 
72
156
  useEffect(() => {
73
- const sub = player.addListener('playingChange', ({ isPlaying }) => {
157
+ const playing = player.addListener('playingChange', ({ isPlaying }) => {
74
158
  if (isPlaying) {setShowPlay(false);}
75
159
  });
76
- return () => sub.remove();
77
- }, [player]);
160
+ const status = player.addListener('statusChange', (event) => {
161
+ if (event.status !== 'error') {return;}
162
+ if (source === uri && remote) {
163
+ markStreamingUnsupported(uri);
164
+ download();
165
+ } else {
166
+ setFailed(true);
167
+ }
168
+ });
169
+ return () => {
170
+ playing.remove();
171
+ status.remove();
172
+ };
173
+ }, [download, player, remote, source, uri]);
78
174
 
79
175
  const handlePlay = () => {
176
+ wantsPlay.current = true;
80
177
  setShowPlay(false);
81
178
  player.play();
82
179
  };
83
180
 
181
+ if (failed) {
182
+ return (
183
+ <View style={styles.videoMessage}>
184
+ <Text style={{ fontSize: 16, fontWeight: '600', color: theme.text }}>
185
+ This video can't be played
186
+ </Text>
187
+ <Text style={{ color: theme.textSecondary, textAlign: 'center' }}>
188
+ Tap the save icon above to download it.
189
+ </Text>
190
+ </View>
191
+ );
192
+ }
193
+
194
+ const loading = progress !== null || source === null;
195
+
84
196
  return (
85
197
  <View style={{ flex: 1, width: '100%' }}>
86
- <VideoView
87
- player={player}
88
- style={{ flex: 1, backgroundColor: 'transparent' }}
89
- contentFit="contain"
90
- nativeControls
91
- surfaceType="textureView"
92
- // Fullscreen stays available by default on both expo-video lines:
93
- // `allowsFullscreen` (SDK 54, default true) was replaced by
94
- // `fullscreenOptions.enable` (SDK 57, default true). Passing neither
95
- // keeps this file compiling against both.
96
- />
97
- {/* Play affordance shown immediately on open; tapping starts
98
- playback and the native controls take over. */}
99
- {showPlay && (
100
- <TouchableOpacity
101
- activeOpacity={0.8}
102
- onPress={handlePlay}
103
- style={StyleSheet.absoluteFill}
104
- >
105
- <View style={styles.playOverlay}>
106
- <View style={styles.playButton}>
107
- <PlayIcon width={28} height={28} />
108
- </View>
198
+ {/* No surface while the copy downloads: the failed stream would
199
+ show the system's "can't play" glyph under the spinner. */}
200
+ {!loading && (
201
+ <VideoView
202
+ player={player}
203
+ style={{ flex: 1, backgroundColor: 'transparent' }}
204
+ contentFit="contain"
205
+ nativeControls
206
+ surfaceType="textureView"
207
+ // Fullscreen stays available by default on both expo-video lines:
208
+ // `allowsFullscreen` (SDK 54, default true) was replaced by
209
+ // `fullscreenOptions.enable` (SDK 57, default true). Passing
210
+ // neither keeps this file compiling against both.
211
+ />
212
+ )}
213
+ {loading ? (
214
+ <View style={styles.playOverlay} pointerEvents="none">
215
+ <View style={styles.playButton}>
216
+ <ActivityIndicator color="#FFFFFF" />
109
217
  </View>
110
- </TouchableOpacity>
218
+ {!!progress && (
219
+ <Text style={[styles.progress, { color: theme.textSecondary }]}>
220
+ {Math.round(progress * 100)}%
221
+ </Text>
222
+ )}
223
+ </View>
224
+ ) : (
225
+ showPlay && (
226
+ // Play affordance shown immediately on open; tapping starts
227
+ // playback and the native controls take over.
228
+ <TouchableOpacity
229
+ activeOpacity={0.8}
230
+ onPress={handlePlay}
231
+ style={StyleSheet.absoluteFill}
232
+ >
233
+ <View style={styles.playOverlay}>
234
+ <View style={styles.playButton}>
235
+ <PlayIcon width={28} height={28} />
236
+ </View>
237
+ </View>
238
+ </TouchableOpacity>
239
+ )
111
240
  )}
112
241
  </View>
113
242
  );
@@ -122,6 +251,7 @@ const FilePreviewModal: React.FC<FilePreviewModalProps> = ({
122
251
  }) => {
123
252
  const dispatch = useDispatch();
124
253
  const { showToast } = useToast();
254
+ const t = useT();
125
255
  const { config } = useChatSettingState();
126
256
  const theme = useTheme();
127
257
  // Info / audio cards: light keeps its warm tint (not in the palette),
@@ -175,14 +305,14 @@ const FilePreviewModal: React.FC<FilePreviewModalProps> = ({
175
305
 
176
306
  try {
177
307
  const filePath = FileSystem.cacheDirectory + displayFileName;
178
- const download = await FileSystem.downloadAsync(withFileToken(activeFile.fileURL), filePath);
308
+ const download = await fetchToCache(activeFile.fileURL, filePath);
179
309
 
180
310
  if (download.status === 200) {
181
311
  await getMediaLibrary()?.saveToLibraryAsync(download.uri);
182
312
  showToast({
183
313
  id: Date.now().toString(),
184
- title: 'Success',
185
- message: 'Save successful',
314
+ title: t('toast.successTitle'),
315
+ message: t('toast.saveSuccessful'),
186
316
  type: 'success',
187
317
  });
188
318
  } else {
@@ -222,7 +352,7 @@ const FilePreviewModal: React.FC<FilePreviewModalProps> = ({
222
352
  const saveFileToDownloads = async () => {
223
353
  try {
224
354
  const filePath = FileSystem.cacheDirectory + displayFileName;
225
- const download = await FileSystem.downloadAsync(withFileToken(activeFile.fileURL), filePath);
355
+ const download = await fetchToCache(activeFile.fileURL, filePath);
226
356
 
227
357
  if (download.status !== 200) {
228
358
  Alert.alert('Error', 'Failed to save the file.');
@@ -266,8 +396,8 @@ const FilePreviewModal: React.FC<FilePreviewModalProps> = ({
266
396
 
267
397
  showToast({
268
398
  id: Date.now().toString(),
269
- title: 'Success',
270
- message: 'Save successful',
399
+ title: t('toast.successTitle'),
400
+ message: t('toast.saveSuccessful'),
271
401
  type: 'success',
272
402
  });
273
403
  return;
@@ -332,7 +462,14 @@ const FilePreviewModal: React.FC<FilePreviewModalProps> = ({
332
462
  />
333
463
  );
334
464
  case activeFile.mimetype.startsWith('video/'):
335
- return <ModalVideo uri={withFileToken(activeFile.fileURL)} />;
465
+ return (
466
+ <ModalVideo
467
+ // Remount per file: the player state belongs to one clip.
468
+ key={activeFile.fileURL}
469
+ uri={withFileToken(activeFile.fileURL)}
470
+ mimetype={activeFile.mimetype}
471
+ />
472
+ );
336
473
  case activeFile.mimetype.includes('application/octet-stream'):
337
474
  return (
338
475
  <View
@@ -394,13 +531,14 @@ const FilePreviewModal: React.FC<FilePreviewModalProps> = ({
394
531
  />
395
532
  </View>
396
533
  );
397
- case activeFile.mimetype === 'application/pdf':
534
+ case activeFile.mimetype === 'application/pdf' &&
535
+ !(Platform.OS === 'android' && isLocalFile(activeFile.fileURL)):
398
536
  return <PdfViewer pdfUrl={withFileToken(activeFile.fileURL)} />;
399
537
  default: {
400
538
  // Office docs (.docx / .xlsx / .pptx / .doc / .xls / .ppt /
401
539
  // .txt / .csv / .rtf) → render inline via Google's gview embed
402
540
  // — fixes the "blank preview" complaint for docs (bug #9).
403
- if (isGviewPreviewable(activeFile.mimetype)) {
541
+ if (isGviewPreviewable(activeFile.mimetype) && !isLocalFile(activeFile.fileURL)) {
404
542
  return (
405
543
  <DocumentViewer
406
544
  url={activeFile.fileURL}
@@ -440,7 +578,7 @@ const FilePreviewModal: React.FC<FilePreviewModalProps> = ({
440
578
  <ModalContainerFullScreen>
441
579
  <ModalHeaderComponent
442
580
  handleCloseModal={closeModal}
443
- headerTitle={'File preview'}
581
+ headerTitle={t('modal.filePreview.title')}
444
582
  titleStyle={chatTextStyle(config?.typography?.profile?.screenTitle)}
445
583
  rightMenu={
446
584
  <>
@@ -486,6 +624,16 @@ const styles = StyleSheet.create({
486
624
  justifyContent: 'center',
487
625
  alignItems: 'center',
488
626
  },
627
+ progress: {
628
+ marginTop: 10,
629
+ fontSize: 13,
630
+ fontWeight: '600',
631
+ },
632
+ videoMessage: {
633
+ alignItems: 'center',
634
+ gap: 8,
635
+ padding: 20,
636
+ },
489
637
  });
490
638
 
491
639
  export default FilePreviewModal;
@@ -25,6 +25,10 @@ const PdfViewer: React.FC<PdfViewerProps> = ({ pdfUrl }) => {
25
25
  let cancelled = false;
26
26
  const run = async () => {
27
27
  try {
28
+ if (/^file:\/\//i.test(pdfUrl)) {
29
+ setLocalUri(pdfUrl);
30
+ return;
31
+ }
28
32
  const target = FileSystem.cacheDirectory + `pdf-${Date.now()}.pdf`;
29
33
  const result = await FileSystem.downloadAsync(withFileToken(pdfUrl), target);
30
34
  if (cancelled) {return;}
@@ -16,6 +16,17 @@ interface ModalProps {
16
16
  setOpenModal: (value?: ModalType) => any;
17
17
  }
18
18
 
19
+ /** Screens reached from Settings: closing them goes back there. */
20
+ const SETTINGS_SCREENS = new Set<string>([
21
+ MODAL_TYPES.MANAGE_DATA,
22
+ MODAL_TYPES.VISIBILITY,
23
+ MODAL_TYPES.REFERRALS,
24
+ MODAL_TYPES.DOCUMENT_SHARES,
25
+ MODAL_TYPES.PROFILE_SHARES,
26
+ MODAL_TYPES.BLOCKED_USERS,
27
+ MODAL_TYPES.CHANGE_PASSWORD,
28
+ ]);
29
+
19
30
  const Modal: React.FC<ModalProps> = ({ children, modal, setOpenModal }) => {
20
31
  const dispatch = useDispatch();
21
32
  const handleCloseModal = () => setOpenModal();
@@ -29,15 +40,9 @@ const Modal: React.FC<ModalProps> = ({ children, modal, setOpenModal }) => {
29
40
 
30
41
  if (!ModalComponent) {return null;}
31
42
 
32
- const handleClose =
33
- modal === MODAL_TYPES.MANAGE_DATA ||
34
- modal === MODAL_TYPES.VISIBILITY ||
35
- modal === MODAL_TYPES.REFERRALS ||
36
- modal === MODAL_TYPES.DOCUMENT_SHARES ||
37
- modal === MODAL_TYPES.PROFILE_SHARES ||
38
- modal === MODAL_TYPES.BLOCKED_USERS
39
- ? handleBackButtonClick
40
- : handleCloseModal;
43
+ const handleClose = SETTINGS_SCREENS.has(modal)
44
+ ? handleBackButtonClick
45
+ : handleCloseModal;
41
46
 
42
47
  return <ModalComponent handleCloseModal={handleClose} />;
43
48
  };
@@ -75,15 +80,38 @@ const Modal: React.FC<ModalProps> = ({ children, modal, setOpenModal }) => {
75
80
  }
76
81
  }
77
82
 
83
+ // Screens under Settings are pages too: they slide in over Settings and
84
+ // a swipe from the left edge takes them back to it, same as the header's
85
+ // back button. Settings stays mounted underneath the whole time, so the
86
+ // slide reveals it - not the chat list - and nothing is rebuilt once the
87
+ // page has gone. The elements below keep the same shape as the plain
88
+ // branch, so Settings is the same instance before, during and after.
89
+ const subScreen = modal && SETTINGS_SCREENS.has(modal) ? modal : undefined;
90
+ const SubScreenComponent = subScreen ? MODAL_COMPONENTS[subScreen] : undefined;
91
+ const SettingsComponent = MODAL_COMPONENTS[MODAL_TYPES.SETTINGS];
92
+ const underneath =
93
+ SubScreenComponent && SettingsComponent ? (
94
+ <SettingsComponent handleCloseModal={handleCloseModal} />
95
+ ) : (
96
+ renderModalContent()
97
+ );
98
+
78
99
  return (
79
100
  modal && (
80
- <ModalBackground
81
- id="modal-background"
82
- style={{ position: 'absolute', top: 0, left: 0, right: 0, bottom: 0 }}
83
- >
84
- {renderModalContent()}
85
- {children}
86
- </ModalBackground>
101
+ <>
102
+ <ModalBackground
103
+ id="modal-background"
104
+ style={{ position: 'absolute', top: 0, left: 0, right: 0, bottom: 0 }}
105
+ >
106
+ {underneath}
107
+ {children}
108
+ </ModalBackground>
109
+ {SubScreenComponent && (
110
+ <SwipeBackLayer onClose={handleBackButtonClick}>
111
+ {(close) => <SubScreenComponent handleCloseModal={close} />}
112
+ </SwipeBackLayer>
113
+ )}
114
+ </>
87
115
  )
88
116
  );
89
117
  };
@@ -187,16 +187,16 @@ const NewChatModal: React.FC<NewChatModalProps> = ({
187
187
 
188
188
  showToast({
189
189
  id: Date.now().toString(),
190
- title: 'Success',
191
- message: 'Room created successfully',
190
+ title: t('toast.successTitle'),
191
+ message: t('toast.roomCreatedSuccess'),
192
192
  type: 'success',
193
193
  });
194
194
  } catch (error) {
195
195
  console.error('Error handling room creation:', error);
196
196
  showToast({
197
197
  id: Date.now().toString(),
198
- title: 'Error',
199
- message: 'Failed to create room',
198
+ title: t('toast.error'),
199
+ message: t('toast.failedToCreateRoom'),
200
200
  type: 'error',
201
201
  });
202
202
  }
@@ -258,8 +258,8 @@ const NewChatModal: React.FC<NewChatModalProps> = ({
258
258
 
259
259
  showToast({
260
260
  id: Date.now().toString(),
261
- title: 'Success',
262
- message: 'Room created successfully',
261
+ title: t('toast.successTitle'),
262
+ message: t('toast.roomCreatedSuccess'),
263
263
  type: 'success',
264
264
  });
265
265
  handleCloseModal();
@@ -267,8 +267,8 @@ const NewChatModal: React.FC<NewChatModalProps> = ({
267
267
  console.error('Failed to create room:', error);
268
268
  showToast({
269
269
  id: Date.now().toString(),
270
- title: 'Error',
271
- message: 'Failed to create room',
270
+ title: t('toast.error'),
271
+ message: t('toast.failedToCreateRoom'),
272
272
  type: 'error',
273
273
  });
274
274
  }