@oxyhq/services 26.0.1 → 26.0.3

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 (599) hide show
  1. package/README.md +2 -2
  2. package/android/src/main/java/so/oxy/identity/OxyIdentityStore.kt +21 -127
  3. package/android/src/main/java/so/oxy/session/OxyBackgroundSession.kt +184 -0
  4. package/android/src/main/java/so/oxy/session/OxyBackgroundSessionApi.kt +162 -0
  5. package/android/src/main/java/so/oxy/session/OxyBackgroundSessionModule.kt +116 -0
  6. package/android/src/main/java/so/oxy/session/OxyBackgroundSessionStore.kt +179 -0
  7. package/android/src/main/java/so/oxy/session/OxyBackgroundToken.kt +61 -0
  8. package/android/src/main/java/so/oxy/storage/OxyEncryptedPrefs.kt +241 -0
  9. package/expo-module.config.json +4 -1
  10. package/lib/commonjs/index.js +18 -49
  11. package/lib/commonjs/index.js.map +1 -1
  12. package/lib/commonjs/notifications/deviceNotifications.js +63 -0
  13. package/lib/commonjs/notifications/deviceNotifications.js.map +1 -1
  14. package/lib/commonjs/ui/boot/runProviderColdBoot.js +20 -64
  15. package/lib/commonjs/ui/boot/runProviderColdBoot.js.map +1 -1
  16. package/lib/commonjs/ui/components/AvatarCameraBadge.js +2 -2
  17. package/lib/commonjs/ui/components/AvatarCameraBadge.js.map +1 -1
  18. package/lib/commonjs/ui/components/FollowButton.js +4 -4
  19. package/lib/commonjs/ui/components/FollowButton.js.map +1 -1
  20. package/lib/commonjs/ui/components/OxyAccountDialogScreen.js +13 -1
  21. package/lib/commonjs/ui/components/OxyAccountDialogScreen.js.map +1 -1
  22. package/lib/commonjs/ui/components/OxyAuthChooser.js +29 -24
  23. package/lib/commonjs/ui/components/OxyAuthChooser.js.map +1 -1
  24. package/lib/commonjs/ui/components/OxyProvider.js +8 -7
  25. package/lib/commonjs/ui/components/OxyProvider.js.map +1 -1
  26. package/lib/commonjs/ui/components/OxySignInButton.js.map +1 -1
  27. package/lib/commonjs/ui/components/ProfileButton.js +20 -26
  28. package/lib/commonjs/ui/components/ProfileButton.js.map +1 -1
  29. package/lib/commonjs/ui/components/authChooser/AccountsMenuView.js +68 -58
  30. package/lib/commonjs/ui/components/authChooser/AccountsMenuView.js.map +1 -1
  31. package/lib/commonjs/ui/components/authChooser/types.js.map +1 -1
  32. package/lib/commonjs/ui/components/authChooser/useUsernameAvailability.js +2 -2
  33. package/lib/commonjs/ui/components/authChooser/useUsernameAvailability.js.map +1 -1
  34. package/lib/commonjs/ui/components/fileManagement/UploadPreview.js +2 -2
  35. package/lib/commonjs/ui/components/fileManagement/UploadPreview.js.map +1 -1
  36. package/lib/commonjs/ui/components/internal/PinInput.js +3 -1
  37. package/lib/commonjs/ui/components/internal/PinInput.js.map +1 -1
  38. package/lib/commonjs/ui/components/logo/LogoText.js +4 -4
  39. package/lib/commonjs/ui/components/logo/LogoText.js.map +1 -1
  40. package/lib/commonjs/ui/components/payment/PaymentDetailsStep.js +2 -2
  41. package/lib/commonjs/ui/components/payment/PaymentDetailsStep.js.map +1 -1
  42. package/lib/commonjs/ui/components/payment/PaymentSummaryStep.js +2 -2
  43. package/lib/commonjs/ui/components/payment/PaymentSummaryStep.js.map +1 -1
  44. package/lib/commonjs/ui/components/styles/shadow.js.map +1 -1
  45. package/lib/commonjs/ui/context/OxyContext.js +32 -46
  46. package/lib/commonjs/ui/context/OxyContext.js.map +1 -1
  47. package/lib/commonjs/ui/context/commitSessionFlow.js +3 -43
  48. package/lib/commonjs/ui/context/commitSessionFlow.js.map +1 -1
  49. package/lib/commonjs/ui/context/hooks/useAuthOperations.js +15 -2
  50. package/lib/commonjs/ui/context/hooks/useAuthOperations.js.map +1 -1
  51. package/lib/commonjs/ui/context/useOxyAccountGraph.js +3 -4
  52. package/lib/commonjs/ui/context/useOxyAccountGraph.js.map +1 -1
  53. package/lib/commonjs/ui/hooks/mutations/mutationFactory.js +5 -5
  54. package/lib/commonjs/ui/hooks/mutations/mutationFactory.js.map +1 -1
  55. package/lib/commonjs/ui/hooks/mutations/useAccountMutations.js +11 -11
  56. package/lib/commonjs/ui/hooks/mutations/useAccountMutations.js.map +1 -1
  57. package/lib/commonjs/ui/hooks/mutations/useServicesMutations.js +9 -9
  58. package/lib/commonjs/ui/hooks/mutations/useServicesMutations.js.map +1 -1
  59. package/lib/commonjs/ui/hooks/queries/usePaymentQueries.js +3 -2
  60. package/lib/commonjs/ui/hooks/queries/usePaymentQueries.js.map +1 -1
  61. package/lib/commonjs/ui/hooks/queries/userCache.js +17 -17
  62. package/lib/commonjs/ui/hooks/queries/userCache.js.map +1 -1
  63. package/lib/commonjs/ui/hooks/useAssets.js.map +1 -1
  64. package/lib/commonjs/ui/hooks/useAsyncAction.js +7 -7
  65. package/lib/commonjs/ui/hooks/useAsyncAction.js.map +1 -1
  66. package/lib/commonjs/ui/hooks/useAuth.js +8 -4
  67. package/lib/commonjs/ui/hooks/useAuth.js.map +1 -1
  68. package/lib/commonjs/ui/hooks/useAvatarPicker.js +5 -5
  69. package/lib/commonjs/ui/hooks/useAvatarPicker.js.map +1 -1
  70. package/lib/commonjs/ui/hooks/useOnlineStatus.js +3 -2
  71. package/lib/commonjs/ui/hooks/useOnlineStatus.js.map +1 -1
  72. package/lib/commonjs/ui/hooks/useSessionManagement.js +0 -2
  73. package/lib/commonjs/ui/hooks/useSessionManagement.js.map +1 -1
  74. package/lib/commonjs/ui/hooks/useSettingToggle.js +4 -4
  75. package/lib/commonjs/ui/hooks/useSettingToggle.js.map +1 -1
  76. package/lib/commonjs/ui/hooks/useSurfaceHeader.js +68 -11
  77. package/lib/commonjs/ui/hooks/useSurfaceHeader.js.map +1 -1
  78. package/lib/commonjs/ui/navigation/accountDialogManager.js +2 -0
  79. package/lib/commonjs/ui/navigation/accountDialogManager.js.map +1 -1
  80. package/lib/commonjs/ui/oauth/browserAuthTransport.js +66 -64
  81. package/lib/commonjs/ui/oauth/browserAuthTransport.js.map +1 -1
  82. package/lib/commonjs/ui/oauth/oauthPopup.js +47 -0
  83. package/lib/commonjs/ui/oauth/oauthPopup.js.map +1 -1
  84. package/lib/commonjs/ui/screens/AccountMembersScreen.js +10 -10
  85. package/lib/commonjs/ui/screens/AccountMembersScreen.js.map +1 -1
  86. package/lib/commonjs/ui/screens/AccountSettingsScreen.js +41 -19
  87. package/lib/commonjs/ui/screens/AccountSettingsScreen.js.map +1 -1
  88. package/lib/commonjs/ui/screens/AccountVerificationScreen.js +4 -4
  89. package/lib/commonjs/ui/screens/AccountVerificationScreen.js.map +1 -1
  90. package/lib/commonjs/ui/screens/AppInfoScreen.js +9 -9
  91. package/lib/commonjs/ui/screens/AppInfoScreen.js.map +1 -1
  92. package/lib/commonjs/ui/screens/AvatarCropScreen.js +3 -3
  93. package/lib/commonjs/ui/screens/AvatarCropScreen.js.map +1 -1
  94. package/lib/commonjs/ui/screens/ChangeAvatarScreen.js +6 -7
  95. package/lib/commonjs/ui/screens/ChangeAvatarScreen.js.map +1 -1
  96. package/lib/commonjs/ui/screens/ConnectedAppsScreen.js +4 -4
  97. package/lib/commonjs/ui/screens/ConnectedAppsScreen.js.map +1 -1
  98. package/lib/commonjs/ui/screens/CreateAccountScreen.js +46 -14
  99. package/lib/commonjs/ui/screens/CreateAccountScreen.js.map +1 -1
  100. package/lib/commonjs/ui/screens/EditProfileFieldScreen.js +5 -5
  101. package/lib/commonjs/ui/screens/EditProfileFieldScreen.js.map +1 -1
  102. package/lib/commonjs/ui/screens/EditProfileScreen.js +2 -3
  103. package/lib/commonjs/ui/screens/EditProfileScreen.js.map +1 -1
  104. package/lib/commonjs/ui/screens/FAQScreen.js +2 -2
  105. package/lib/commonjs/ui/screens/FAQScreen.js.map +1 -1
  106. package/lib/commonjs/ui/screens/FeedbackScreen.js +90 -89
  107. package/lib/commonjs/ui/screens/FeedbackScreen.js.map +1 -1
  108. package/lib/commonjs/ui/screens/FileManagementScreen.js +20 -20
  109. package/lib/commonjs/ui/screens/FileManagementScreen.js.map +1 -1
  110. package/lib/commonjs/ui/screens/FollowersListScreen.js.map +1 -1
  111. package/lib/commonjs/ui/screens/FollowingListScreen.js.map +1 -1
  112. package/lib/commonjs/ui/screens/HelpSupportScreen.js +7 -7
  113. package/lib/commonjs/ui/screens/HelpSupportScreen.js.map +1 -1
  114. package/lib/commonjs/ui/screens/HistoryViewScreen.js +9 -34
  115. package/lib/commonjs/ui/screens/HistoryViewScreen.js.map +1 -1
  116. package/lib/commonjs/ui/screens/LanguageSelectorScreen.js +3 -3
  117. package/lib/commonjs/ui/screens/LanguageSelectorScreen.js.map +1 -1
  118. package/lib/commonjs/ui/screens/LegalDocumentsScreen.js +3 -3
  119. package/lib/commonjs/ui/screens/LegalDocumentsScreen.js.map +1 -1
  120. package/lib/commonjs/ui/screens/ManageAccountScreen.js +15 -15
  121. package/lib/commonjs/ui/screens/ManageAccountScreen.js.map +1 -1
  122. package/lib/commonjs/ui/screens/PremiumSubscriptionScreen.js +19 -19
  123. package/lib/commonjs/ui/screens/PremiumSubscriptionScreen.js.map +1 -1
  124. package/lib/commonjs/ui/screens/PrivacySettingsScreen.js +15 -15
  125. package/lib/commonjs/ui/screens/PrivacySettingsScreen.js.map +1 -1
  126. package/lib/commonjs/ui/screens/ProfileScreen.js +17 -7
  127. package/lib/commonjs/ui/screens/ProfileScreen.js.map +1 -1
  128. package/lib/commonjs/ui/screens/SavesCollectionsScreen.js +2 -2
  129. package/lib/commonjs/ui/screens/SavesCollectionsScreen.js.map +1 -1
  130. package/lib/commonjs/ui/screens/UserListScreen.js +13 -7
  131. package/lib/commonjs/ui/screens/UserListScreen.js.map +1 -1
  132. package/lib/commonjs/ui/screens/WelcomeNewUserScreen.js +5 -6
  133. package/lib/commonjs/ui/screens/WelcomeNewUserScreen.js.map +1 -1
  134. package/lib/commonjs/ui/screens/fileManagement/PhotoPickerSection.js +1 -4
  135. package/lib/commonjs/ui/screens/fileManagement/PhotoPickerSection.js.map +1 -1
  136. package/lib/commonjs/ui/screens/fileManagement/hooks/useFileUploadState.js +34 -24
  137. package/lib/commonjs/ui/screens/fileManagement/hooks/useFileUploadState.js.map +1 -1
  138. package/lib/commonjs/ui/screens/trust/TrustCenterScreen.js +1 -1
  139. package/lib/commonjs/ui/screens/trust/TrustCenterScreen.js.map +1 -1
  140. package/lib/commonjs/ui/screens/trust/TrustLeaderboardScreen.js +3 -4
  141. package/lib/commonjs/ui/screens/trust/TrustLeaderboardScreen.js.map +1 -1
  142. package/lib/commonjs/ui/screens/trust/TrustRewardsScreen.js +1 -1
  143. package/lib/commonjs/ui/screens/trust/TrustRewardsScreen.js.map +1 -1
  144. package/lib/commonjs/ui/session/backgroundSession.js +258 -0
  145. package/lib/commonjs/ui/session/backgroundSession.js.map +1 -0
  146. package/lib/commonjs/ui/session/index.js +7 -0
  147. package/lib/commonjs/ui/session/index.js.map +1 -1
  148. package/lib/commonjs/ui/session/useBackgroundSessionSync.js +81 -0
  149. package/lib/commonjs/ui/session/useBackgroundSessionSync.js.map +1 -0
  150. package/lib/commonjs/ui/utils/fileManagement.js +24 -24
  151. package/lib/commonjs/ui/utils/fileManagement.js.map +1 -1
  152. package/lib/commonjs/ui/utils/netConnectivity.js +28 -0
  153. package/lib/commonjs/ui/utils/netConnectivity.js.map +1 -0
  154. package/lib/commonjs/ui/utils/oauthReturn.js +19 -30
  155. package/lib/commonjs/ui/utils/oauthReturn.js.map +1 -1
  156. package/lib/commonjs/ui/utils/userUtils.js +27 -28
  157. package/lib/commonjs/ui/utils/userUtils.js.map +1 -1
  158. package/lib/module/index.js +20 -8
  159. package/lib/module/index.js.map +1 -1
  160. package/lib/module/notifications/deviceNotifications.js +62 -0
  161. package/lib/module/notifications/deviceNotifications.js.map +1 -1
  162. package/lib/module/ui/boot/runProviderColdBoot.js +21 -65
  163. package/lib/module/ui/boot/runProviderColdBoot.js.map +1 -1
  164. package/lib/module/ui/components/AvatarCameraBadge.js +1 -1
  165. package/lib/module/ui/components/AvatarCameraBadge.js.map +1 -1
  166. package/lib/module/ui/components/FollowButton.js +1 -1
  167. package/lib/module/ui/components/FollowButton.js.map +1 -1
  168. package/lib/module/ui/components/OxyAccountDialogScreen.js +13 -1
  169. package/lib/module/ui/components/OxyAccountDialogScreen.js.map +1 -1
  170. package/lib/module/ui/components/OxyAuthChooser.js +25 -20
  171. package/lib/module/ui/components/OxyAuthChooser.js.map +1 -1
  172. package/lib/module/ui/components/OxyProvider.js +7 -6
  173. package/lib/module/ui/components/OxyProvider.js.map +1 -1
  174. package/lib/module/ui/components/OxySignInButton.js.map +1 -1
  175. package/lib/module/ui/components/ProfileButton.js +12 -18
  176. package/lib/module/ui/components/ProfileButton.js.map +1 -1
  177. package/lib/module/ui/components/authChooser/AccountsMenuView.js +68 -58
  178. package/lib/module/ui/components/authChooser/AccountsMenuView.js.map +1 -1
  179. package/lib/module/ui/components/authChooser/types.js.map +1 -1
  180. package/lib/module/ui/components/authChooser/useUsernameAvailability.js +1 -1
  181. package/lib/module/ui/components/authChooser/useUsernameAvailability.js.map +1 -1
  182. package/lib/module/ui/components/fileManagement/UploadPreview.js +1 -1
  183. package/lib/module/ui/components/fileManagement/UploadPreview.js.map +1 -1
  184. package/lib/module/ui/components/internal/PinInput.js +3 -1
  185. package/lib/module/ui/components/internal/PinInput.js.map +1 -1
  186. package/lib/module/ui/components/logo/LogoText.js +4 -4
  187. package/lib/module/ui/components/logo/LogoText.js.map +1 -1
  188. package/lib/module/ui/components/payment/PaymentDetailsStep.js +1 -1
  189. package/lib/module/ui/components/payment/PaymentDetailsStep.js.map +1 -1
  190. package/lib/module/ui/components/payment/PaymentSummaryStep.js +2 -2
  191. package/lib/module/ui/components/payment/PaymentSummaryStep.js.map +1 -1
  192. package/lib/module/ui/components/styles/shadow.js.map +1 -1
  193. package/lib/module/ui/context/OxyContext.js +35 -49
  194. package/lib/module/ui/context/OxyContext.js.map +1 -1
  195. package/lib/module/ui/context/commitSessionFlow.js +3 -42
  196. package/lib/module/ui/context/commitSessionFlow.js.map +1 -1
  197. package/lib/module/ui/context/hooks/useAuthOperations.js +15 -2
  198. package/lib/module/ui/context/hooks/useAuthOperations.js.map +1 -1
  199. package/lib/module/ui/context/useOxyAccountGraph.js +3 -4
  200. package/lib/module/ui/context/useOxyAccountGraph.js.map +1 -1
  201. package/lib/module/ui/hooks/mutations/mutationFactory.js +1 -1
  202. package/lib/module/ui/hooks/mutations/mutationFactory.js.map +1 -1
  203. package/lib/module/ui/hooks/mutations/useAccountMutations.js +1 -1
  204. package/lib/module/ui/hooks/mutations/useAccountMutations.js.map +1 -1
  205. package/lib/module/ui/hooks/mutations/useServicesMutations.js +1 -1
  206. package/lib/module/ui/hooks/mutations/useServicesMutations.js.map +1 -1
  207. package/lib/module/ui/hooks/queries/usePaymentQueries.js +3 -2
  208. package/lib/module/ui/hooks/queries/usePaymentQueries.js.map +1 -1
  209. package/lib/module/ui/hooks/queries/userCache.js +17 -17
  210. package/lib/module/ui/hooks/queries/userCache.js.map +1 -1
  211. package/lib/module/ui/hooks/useAssets.js.map +1 -1
  212. package/lib/module/ui/hooks/useAsyncAction.js +1 -1
  213. package/lib/module/ui/hooks/useAsyncAction.js.map +1 -1
  214. package/lib/module/ui/hooks/useAuth.js +8 -4
  215. package/lib/module/ui/hooks/useAuth.js.map +1 -1
  216. package/lib/module/ui/hooks/useAvatarPicker.js +1 -1
  217. package/lib/module/ui/hooks/useAvatarPicker.js.map +1 -1
  218. package/lib/module/ui/hooks/useOnlineStatus.js +3 -2
  219. package/lib/module/ui/hooks/useOnlineStatus.js.map +1 -1
  220. package/lib/module/ui/hooks/useSessionManagement.js +0 -2
  221. package/lib/module/ui/hooks/useSessionManagement.js.map +1 -1
  222. package/lib/module/ui/hooks/useSettingToggle.js +1 -1
  223. package/lib/module/ui/hooks/useSettingToggle.js.map +1 -1
  224. package/lib/module/ui/hooks/useSurfaceHeader.js +68 -11
  225. package/lib/module/ui/hooks/useSurfaceHeader.js.map +1 -1
  226. package/lib/module/ui/navigation/accountDialogManager.js +2 -0
  227. package/lib/module/ui/navigation/accountDialogManager.js.map +1 -1
  228. package/lib/module/ui/oauth/browserAuthTransport.js +66 -64
  229. package/lib/module/ui/oauth/browserAuthTransport.js.map +1 -1
  230. package/lib/module/ui/oauth/oauthPopup.js +48 -1
  231. package/lib/module/ui/oauth/oauthPopup.js.map +1 -1
  232. package/lib/module/ui/screens/AccountMembersScreen.js +1 -1
  233. package/lib/module/ui/screens/AccountMembersScreen.js.map +1 -1
  234. package/lib/module/ui/screens/AccountSettingsScreen.js +37 -15
  235. package/lib/module/ui/screens/AccountSettingsScreen.js.map +1 -1
  236. package/lib/module/ui/screens/AccountVerificationScreen.js +1 -1
  237. package/lib/module/ui/screens/AccountVerificationScreen.js.map +1 -1
  238. package/lib/module/ui/screens/AppInfoScreen.js +1 -1
  239. package/lib/module/ui/screens/AppInfoScreen.js.map +1 -1
  240. package/lib/module/ui/screens/AvatarCropScreen.js +1 -1
  241. package/lib/module/ui/screens/AvatarCropScreen.js.map +1 -1
  242. package/lib/module/ui/screens/ChangeAvatarScreen.js +4 -5
  243. package/lib/module/ui/screens/ChangeAvatarScreen.js.map +1 -1
  244. package/lib/module/ui/screens/ConnectedAppsScreen.js +2 -2
  245. package/lib/module/ui/screens/ConnectedAppsScreen.js.map +1 -1
  246. package/lib/module/ui/screens/CreateAccountScreen.js +45 -13
  247. package/lib/module/ui/screens/CreateAccountScreen.js.map +1 -1
  248. package/lib/module/ui/screens/EditProfileFieldScreen.js +4 -4
  249. package/lib/module/ui/screens/EditProfileFieldScreen.js.map +1 -1
  250. package/lib/module/ui/screens/EditProfileScreen.js +3 -4
  251. package/lib/module/ui/screens/EditProfileScreen.js.map +1 -1
  252. package/lib/module/ui/screens/FAQScreen.js +1 -1
  253. package/lib/module/ui/screens/FAQScreen.js.map +1 -1
  254. package/lib/module/ui/screens/FeedbackScreen.js +94 -91
  255. package/lib/module/ui/screens/FeedbackScreen.js.map +1 -1
  256. package/lib/module/ui/screens/FileManagementScreen.js +1 -1
  257. package/lib/module/ui/screens/FileManagementScreen.js.map +1 -1
  258. package/lib/module/ui/screens/FollowersListScreen.js.map +1 -1
  259. package/lib/module/ui/screens/FollowingListScreen.js.map +1 -1
  260. package/lib/module/ui/screens/HelpSupportScreen.js +1 -1
  261. package/lib/module/ui/screens/HelpSupportScreen.js.map +1 -1
  262. package/lib/module/ui/screens/HistoryViewScreen.js +5 -30
  263. package/lib/module/ui/screens/HistoryViewScreen.js.map +1 -1
  264. package/lib/module/ui/screens/LanguageSelectorScreen.js +1 -1
  265. package/lib/module/ui/screens/LanguageSelectorScreen.js.map +1 -1
  266. package/lib/module/ui/screens/LegalDocumentsScreen.js +1 -1
  267. package/lib/module/ui/screens/LegalDocumentsScreen.js.map +1 -1
  268. package/lib/module/ui/screens/ManageAccountScreen.js +3 -3
  269. package/lib/module/ui/screens/ManageAccountScreen.js.map +1 -1
  270. package/lib/module/ui/screens/PremiumSubscriptionScreen.js +4 -4
  271. package/lib/module/ui/screens/PremiumSubscriptionScreen.js.map +1 -1
  272. package/lib/module/ui/screens/PrivacySettingsScreen.js +11 -11
  273. package/lib/module/ui/screens/PrivacySettingsScreen.js.map +1 -1
  274. package/lib/module/ui/screens/ProfileScreen.js +18 -8
  275. package/lib/module/ui/screens/ProfileScreen.js.map +1 -1
  276. package/lib/module/ui/screens/SavesCollectionsScreen.js +1 -1
  277. package/lib/module/ui/screens/SavesCollectionsScreen.js.map +1 -1
  278. package/lib/module/ui/screens/UserListScreen.js +14 -8
  279. package/lib/module/ui/screens/UserListScreen.js.map +1 -1
  280. package/lib/module/ui/screens/WelcomeNewUserScreen.js +5 -6
  281. package/lib/module/ui/screens/WelcomeNewUserScreen.js.map +1 -1
  282. package/lib/module/ui/screens/fileManagement/PhotoPickerSection.js +1 -4
  283. package/lib/module/ui/screens/fileManagement/PhotoPickerSection.js.map +1 -1
  284. package/lib/module/ui/screens/fileManagement/hooks/useFileUploadState.js +15 -5
  285. package/lib/module/ui/screens/fileManagement/hooks/useFileUploadState.js.map +1 -1
  286. package/lib/module/ui/screens/trust/TrustCenterScreen.js +1 -1
  287. package/lib/module/ui/screens/trust/TrustCenterScreen.js.map +1 -1
  288. package/lib/module/ui/screens/trust/TrustLeaderboardScreen.js +4 -5
  289. package/lib/module/ui/screens/trust/TrustLeaderboardScreen.js.map +1 -1
  290. package/lib/module/ui/screens/trust/TrustRewardsScreen.js +1 -1
  291. package/lib/module/ui/screens/trust/TrustRewardsScreen.js.map +1 -1
  292. package/lib/module/ui/session/backgroundSession.js +252 -0
  293. package/lib/module/ui/session/backgroundSession.js.map +1 -0
  294. package/lib/module/ui/session/index.js +1 -0
  295. package/lib/module/ui/session/index.js.map +1 -1
  296. package/lib/module/ui/session/useBackgroundSessionSync.js +76 -0
  297. package/lib/module/ui/session/useBackgroundSessionSync.js.map +1 -0
  298. package/lib/module/ui/utils/fileManagement.js +25 -25
  299. package/lib/module/ui/utils/fileManagement.js.map +1 -1
  300. package/lib/module/ui/utils/netConnectivity.js +23 -0
  301. package/lib/module/ui/utils/netConnectivity.js.map +1 -0
  302. package/lib/module/ui/utils/oauthReturn.js +20 -30
  303. package/lib/module/ui/utils/oauthReturn.js.map +1 -1
  304. package/lib/module/ui/utils/userUtils.js +27 -28
  305. package/lib/module/ui/utils/userUtils.js.map +1 -1
  306. package/lib/typescript/commonjs/index.d.ts +1 -2
  307. package/lib/typescript/commonjs/index.d.ts.map +1 -1
  308. package/lib/typescript/commonjs/notifications/deviceNotifications.d.ts +51 -0
  309. package/lib/typescript/commonjs/notifications/deviceNotifications.d.ts.map +1 -1
  310. package/lib/typescript/commonjs/ui/boot/runProviderColdBoot.d.ts +11 -30
  311. package/lib/typescript/commonjs/ui/boot/runProviderColdBoot.d.ts.map +1 -1
  312. package/lib/typescript/commonjs/ui/components/AvatarCameraBadge.d.ts.map +1 -1
  313. package/lib/typescript/commonjs/ui/components/OxyAccountDialogScreen.d.ts.map +1 -1
  314. package/lib/typescript/commonjs/ui/components/OxyAuthChooser.d.ts +7 -0
  315. package/lib/typescript/commonjs/ui/components/OxyAuthChooser.d.ts.map +1 -1
  316. package/lib/typescript/commonjs/ui/components/OxyProvider.d.ts.map +1 -1
  317. package/lib/typescript/commonjs/ui/components/OxySignInButton.d.ts +2 -1
  318. package/lib/typescript/commonjs/ui/components/OxySignInButton.d.ts.map +1 -1
  319. package/lib/typescript/commonjs/ui/components/ProfileButton.d.ts +3 -0
  320. package/lib/typescript/commonjs/ui/components/ProfileButton.d.ts.map +1 -1
  321. package/lib/typescript/commonjs/ui/components/authChooser/AccountsMenuView.d.ts.map +1 -1
  322. package/lib/typescript/commonjs/ui/components/authChooser/types.d.ts +6 -0
  323. package/lib/typescript/commonjs/ui/components/authChooser/types.d.ts.map +1 -1
  324. package/lib/typescript/commonjs/ui/components/fileManagement/UploadPreview.d.ts +1 -1
  325. package/lib/typescript/commonjs/ui/components/fileManagement/UploadPreview.d.ts.map +1 -1
  326. package/lib/typescript/commonjs/ui/components/internal/PinInput.d.ts.map +1 -1
  327. package/lib/typescript/commonjs/ui/components/payment/types.d.ts +6 -6
  328. package/lib/typescript/commonjs/ui/components/payment/types.d.ts.map +1 -1
  329. package/lib/typescript/commonjs/ui/context/OxyContext.d.ts.map +1 -1
  330. package/lib/typescript/commonjs/ui/context/commitSessionFlow.d.ts +0 -40
  331. package/lib/typescript/commonjs/ui/context/commitSessionFlow.d.ts.map +1 -1
  332. package/lib/typescript/commonjs/ui/context/hooks/useAuthOperations.d.ts +11 -2
  333. package/lib/typescript/commonjs/ui/context/hooks/useAuthOperations.d.ts.map +1 -1
  334. package/lib/typescript/commonjs/ui/context/oxyContextTypes.d.ts +26 -7
  335. package/lib/typescript/commonjs/ui/context/oxyContextTypes.d.ts.map +1 -1
  336. package/lib/typescript/commonjs/ui/context/useOxyAccountGraph.d.ts +0 -1
  337. package/lib/typescript/commonjs/ui/context/useOxyAccountGraph.d.ts.map +1 -1
  338. package/lib/typescript/commonjs/ui/hooks/mutations/useAccountMutations.d.ts.map +1 -1
  339. package/lib/typescript/commonjs/ui/hooks/queries/paymentTypes.d.ts +3 -2
  340. package/lib/typescript/commonjs/ui/hooks/queries/paymentTypes.d.ts.map +1 -1
  341. package/lib/typescript/commonjs/ui/hooks/queries/usePaymentQueries.d.ts +3 -2
  342. package/lib/typescript/commonjs/ui/hooks/queries/usePaymentQueries.d.ts.map +1 -1
  343. package/lib/typescript/commonjs/ui/hooks/queries/userCache.d.ts +2 -2
  344. package/lib/typescript/commonjs/ui/hooks/queries/userCache.d.ts.map +1 -1
  345. package/lib/typescript/commonjs/ui/hooks/useAssets.d.ts +1 -1
  346. package/lib/typescript/commonjs/ui/hooks/useAssets.d.ts.map +1 -1
  347. package/lib/typescript/commonjs/ui/hooks/useAsyncAction.d.ts +2 -2
  348. package/lib/typescript/commonjs/ui/hooks/useAsyncAction.d.ts.map +1 -1
  349. package/lib/typescript/commonjs/ui/hooks/useAuth.d.ts +10 -6
  350. package/lib/typescript/commonjs/ui/hooks/useAuth.d.ts.map +1 -1
  351. package/lib/typescript/commonjs/ui/hooks/useOnlineStatus.d.ts +3 -2
  352. package/lib/typescript/commonjs/ui/hooks/useOnlineStatus.d.ts.map +1 -1
  353. package/lib/typescript/commonjs/ui/hooks/useSessionManagement.d.ts.map +1 -1
  354. package/lib/typescript/commonjs/ui/hooks/useSurfaceHeader.d.ts +7 -2
  355. package/lib/typescript/commonjs/ui/hooks/useSurfaceHeader.d.ts.map +1 -1
  356. package/lib/typescript/commonjs/ui/navigation/accountDialogManager.d.ts +8 -0
  357. package/lib/typescript/commonjs/ui/navigation/accountDialogManager.d.ts.map +1 -1
  358. package/lib/typescript/commonjs/ui/oauth/browserAuthTransport.d.ts.map +1 -1
  359. package/lib/typescript/commonjs/ui/oauth/oauthPopup.d.ts +6 -0
  360. package/lib/typescript/commonjs/ui/oauth/oauthPopup.d.ts.map +1 -1
  361. package/lib/typescript/commonjs/ui/screens/AccountSettingsScreen.d.ts.map +1 -1
  362. package/lib/typescript/commonjs/ui/screens/ChangeAvatarScreen.d.ts.map +1 -1
  363. package/lib/typescript/commonjs/ui/screens/CreateAccountScreen.d.ts.map +1 -1
  364. package/lib/typescript/commonjs/ui/screens/EditProfileScreen.d.ts.map +1 -1
  365. package/lib/typescript/commonjs/ui/screens/FeedbackScreen.d.ts +2 -2
  366. package/lib/typescript/commonjs/ui/screens/FeedbackScreen.d.ts.map +1 -1
  367. package/lib/typescript/commonjs/ui/screens/FollowersListScreen.d.ts +3 -0
  368. package/lib/typescript/commonjs/ui/screens/FollowersListScreen.d.ts.map +1 -1
  369. package/lib/typescript/commonjs/ui/screens/FollowingListScreen.d.ts +3 -0
  370. package/lib/typescript/commonjs/ui/screens/FollowingListScreen.d.ts.map +1 -1
  371. package/lib/typescript/commonjs/ui/screens/HistoryViewScreen.d.ts.map +1 -1
  372. package/lib/typescript/commonjs/ui/screens/ManageAccountScreen.d.ts.map +1 -1
  373. package/lib/typescript/commonjs/ui/screens/PrivacySettingsScreen.d.ts.map +1 -1
  374. package/lib/typescript/commonjs/ui/screens/ProfileScreen.d.ts.map +1 -1
  375. package/lib/typescript/commonjs/ui/screens/UserListScreen.d.ts +7 -0
  376. package/lib/typescript/commonjs/ui/screens/UserListScreen.d.ts.map +1 -1
  377. package/lib/typescript/commonjs/ui/screens/WelcomeNewUserScreen.d.ts.map +1 -1
  378. package/lib/typescript/commonjs/ui/screens/fileManagement/hooks/useFileUploadState.d.ts.map +1 -1
  379. package/lib/typescript/commonjs/ui/screens/trust/TrustLeaderboardScreen.d.ts.map +1 -1
  380. package/lib/typescript/commonjs/ui/screens/trust/trustTier.d.ts +1 -1
  381. package/lib/typescript/commonjs/ui/screens/trust/trustTier.d.ts.map +1 -1
  382. package/lib/typescript/commonjs/ui/session/backgroundSession.d.ts +42 -0
  383. package/lib/typescript/commonjs/ui/session/backgroundSession.d.ts.map +1 -0
  384. package/lib/typescript/commonjs/ui/session/index.d.ts +1 -0
  385. package/lib/typescript/commonjs/ui/session/index.d.ts.map +1 -1
  386. package/lib/typescript/commonjs/ui/session/useBackgroundSessionSync.d.ts +23 -0
  387. package/lib/typescript/commonjs/ui/session/useBackgroundSessionSync.d.ts.map +1 -0
  388. package/lib/typescript/commonjs/ui/types/navigation.d.ts +27 -19
  389. package/lib/typescript/commonjs/ui/types/navigation.d.ts.map +1 -1
  390. package/lib/typescript/commonjs/ui/utils/fileManagement.d.ts +5 -5
  391. package/lib/typescript/commonjs/ui/utils/fileManagement.d.ts.map +1 -1
  392. package/lib/typescript/commonjs/ui/utils/netConnectivity.d.ts +17 -0
  393. package/lib/typescript/commonjs/ui/utils/netConnectivity.d.ts.map +1 -0
  394. package/lib/typescript/commonjs/ui/utils/oauthReturn.d.ts +15 -12
  395. package/lib/typescript/commonjs/ui/utils/oauthReturn.d.ts.map +1 -1
  396. package/lib/typescript/commonjs/ui/utils/userUtils.d.ts +7 -14
  397. package/lib/typescript/commonjs/ui/utils/userUtils.d.ts.map +1 -1
  398. package/lib/typescript/module/index.d.ts +1 -2
  399. package/lib/typescript/module/index.d.ts.map +1 -1
  400. package/lib/typescript/module/notifications/deviceNotifications.d.ts +51 -0
  401. package/lib/typescript/module/notifications/deviceNotifications.d.ts.map +1 -1
  402. package/lib/typescript/module/ui/boot/runProviderColdBoot.d.ts +11 -30
  403. package/lib/typescript/module/ui/boot/runProviderColdBoot.d.ts.map +1 -1
  404. package/lib/typescript/module/ui/components/AvatarCameraBadge.d.ts.map +1 -1
  405. package/lib/typescript/module/ui/components/OxyAccountDialogScreen.d.ts.map +1 -1
  406. package/lib/typescript/module/ui/components/OxyAuthChooser.d.ts +7 -0
  407. package/lib/typescript/module/ui/components/OxyAuthChooser.d.ts.map +1 -1
  408. package/lib/typescript/module/ui/components/OxyProvider.d.ts.map +1 -1
  409. package/lib/typescript/module/ui/components/OxySignInButton.d.ts +2 -1
  410. package/lib/typescript/module/ui/components/OxySignInButton.d.ts.map +1 -1
  411. package/lib/typescript/module/ui/components/ProfileButton.d.ts +3 -0
  412. package/lib/typescript/module/ui/components/ProfileButton.d.ts.map +1 -1
  413. package/lib/typescript/module/ui/components/authChooser/AccountsMenuView.d.ts.map +1 -1
  414. package/lib/typescript/module/ui/components/authChooser/types.d.ts +6 -0
  415. package/lib/typescript/module/ui/components/authChooser/types.d.ts.map +1 -1
  416. package/lib/typescript/module/ui/components/fileManagement/UploadPreview.d.ts +1 -1
  417. package/lib/typescript/module/ui/components/fileManagement/UploadPreview.d.ts.map +1 -1
  418. package/lib/typescript/module/ui/components/internal/PinInput.d.ts.map +1 -1
  419. package/lib/typescript/module/ui/components/payment/types.d.ts +6 -6
  420. package/lib/typescript/module/ui/components/payment/types.d.ts.map +1 -1
  421. package/lib/typescript/module/ui/context/OxyContext.d.ts.map +1 -1
  422. package/lib/typescript/module/ui/context/commitSessionFlow.d.ts +0 -40
  423. package/lib/typescript/module/ui/context/commitSessionFlow.d.ts.map +1 -1
  424. package/lib/typescript/module/ui/context/hooks/useAuthOperations.d.ts +11 -2
  425. package/lib/typescript/module/ui/context/hooks/useAuthOperations.d.ts.map +1 -1
  426. package/lib/typescript/module/ui/context/oxyContextTypes.d.ts +26 -7
  427. package/lib/typescript/module/ui/context/oxyContextTypes.d.ts.map +1 -1
  428. package/lib/typescript/module/ui/context/useOxyAccountGraph.d.ts +0 -1
  429. package/lib/typescript/module/ui/context/useOxyAccountGraph.d.ts.map +1 -1
  430. package/lib/typescript/module/ui/hooks/mutations/useAccountMutations.d.ts.map +1 -1
  431. package/lib/typescript/module/ui/hooks/queries/paymentTypes.d.ts +3 -2
  432. package/lib/typescript/module/ui/hooks/queries/paymentTypes.d.ts.map +1 -1
  433. package/lib/typescript/module/ui/hooks/queries/usePaymentQueries.d.ts +3 -2
  434. package/lib/typescript/module/ui/hooks/queries/usePaymentQueries.d.ts.map +1 -1
  435. package/lib/typescript/module/ui/hooks/queries/userCache.d.ts +2 -2
  436. package/lib/typescript/module/ui/hooks/queries/userCache.d.ts.map +1 -1
  437. package/lib/typescript/module/ui/hooks/useAssets.d.ts +1 -1
  438. package/lib/typescript/module/ui/hooks/useAssets.d.ts.map +1 -1
  439. package/lib/typescript/module/ui/hooks/useAsyncAction.d.ts +2 -2
  440. package/lib/typescript/module/ui/hooks/useAsyncAction.d.ts.map +1 -1
  441. package/lib/typescript/module/ui/hooks/useAuth.d.ts +10 -6
  442. package/lib/typescript/module/ui/hooks/useAuth.d.ts.map +1 -1
  443. package/lib/typescript/module/ui/hooks/useOnlineStatus.d.ts +3 -2
  444. package/lib/typescript/module/ui/hooks/useOnlineStatus.d.ts.map +1 -1
  445. package/lib/typescript/module/ui/hooks/useSessionManagement.d.ts.map +1 -1
  446. package/lib/typescript/module/ui/hooks/useSurfaceHeader.d.ts +7 -2
  447. package/lib/typescript/module/ui/hooks/useSurfaceHeader.d.ts.map +1 -1
  448. package/lib/typescript/module/ui/navigation/accountDialogManager.d.ts +8 -0
  449. package/lib/typescript/module/ui/navigation/accountDialogManager.d.ts.map +1 -1
  450. package/lib/typescript/module/ui/oauth/browserAuthTransport.d.ts.map +1 -1
  451. package/lib/typescript/module/ui/oauth/oauthPopup.d.ts +6 -0
  452. package/lib/typescript/module/ui/oauth/oauthPopup.d.ts.map +1 -1
  453. package/lib/typescript/module/ui/screens/AccountSettingsScreen.d.ts.map +1 -1
  454. package/lib/typescript/module/ui/screens/ChangeAvatarScreen.d.ts.map +1 -1
  455. package/lib/typescript/module/ui/screens/CreateAccountScreen.d.ts.map +1 -1
  456. package/lib/typescript/module/ui/screens/EditProfileScreen.d.ts.map +1 -1
  457. package/lib/typescript/module/ui/screens/FeedbackScreen.d.ts +2 -2
  458. package/lib/typescript/module/ui/screens/FeedbackScreen.d.ts.map +1 -1
  459. package/lib/typescript/module/ui/screens/FollowersListScreen.d.ts +3 -0
  460. package/lib/typescript/module/ui/screens/FollowersListScreen.d.ts.map +1 -1
  461. package/lib/typescript/module/ui/screens/FollowingListScreen.d.ts +3 -0
  462. package/lib/typescript/module/ui/screens/FollowingListScreen.d.ts.map +1 -1
  463. package/lib/typescript/module/ui/screens/HistoryViewScreen.d.ts.map +1 -1
  464. package/lib/typescript/module/ui/screens/ManageAccountScreen.d.ts.map +1 -1
  465. package/lib/typescript/module/ui/screens/PrivacySettingsScreen.d.ts.map +1 -1
  466. package/lib/typescript/module/ui/screens/ProfileScreen.d.ts.map +1 -1
  467. package/lib/typescript/module/ui/screens/UserListScreen.d.ts +7 -0
  468. package/lib/typescript/module/ui/screens/UserListScreen.d.ts.map +1 -1
  469. package/lib/typescript/module/ui/screens/WelcomeNewUserScreen.d.ts.map +1 -1
  470. package/lib/typescript/module/ui/screens/fileManagement/hooks/useFileUploadState.d.ts.map +1 -1
  471. package/lib/typescript/module/ui/screens/trust/TrustLeaderboardScreen.d.ts.map +1 -1
  472. package/lib/typescript/module/ui/screens/trust/trustTier.d.ts +1 -1
  473. package/lib/typescript/module/ui/screens/trust/trustTier.d.ts.map +1 -1
  474. package/lib/typescript/module/ui/session/backgroundSession.d.ts +42 -0
  475. package/lib/typescript/module/ui/session/backgroundSession.d.ts.map +1 -0
  476. package/lib/typescript/module/ui/session/index.d.ts +1 -0
  477. package/lib/typescript/module/ui/session/index.d.ts.map +1 -1
  478. package/lib/typescript/module/ui/session/useBackgroundSessionSync.d.ts +23 -0
  479. package/lib/typescript/module/ui/session/useBackgroundSessionSync.d.ts.map +1 -0
  480. package/lib/typescript/module/ui/types/navigation.d.ts +27 -19
  481. package/lib/typescript/module/ui/types/navigation.d.ts.map +1 -1
  482. package/lib/typescript/module/ui/utils/fileManagement.d.ts +5 -5
  483. package/lib/typescript/module/ui/utils/fileManagement.d.ts.map +1 -1
  484. package/lib/typescript/module/ui/utils/netConnectivity.d.ts +17 -0
  485. package/lib/typescript/module/ui/utils/netConnectivity.d.ts.map +1 -0
  486. package/lib/typescript/module/ui/utils/oauthReturn.d.ts +15 -12
  487. package/lib/typescript/module/ui/utils/oauthReturn.d.ts.map +1 -1
  488. package/lib/typescript/module/ui/utils/userUtils.d.ts +7 -14
  489. package/lib/typescript/module/ui/utils/userUtils.d.ts.map +1 -1
  490. package/lib/typescript/types/expo-image-picker.d.ts +35 -0
  491. package/package.json +33 -12
  492. package/src/index.ts +19 -16
  493. package/src/notifications/deviceNotifications.ts +82 -0
  494. package/src/types/expo-image-picker.d.ts +35 -0
  495. package/src/ui/boot/__tests__/coldBootNoIdpRedirect.test.ts +215 -0
  496. package/src/ui/boot/runProviderColdBoot.ts +24 -101
  497. package/src/ui/components/AvatarCameraBadge.tsx +2 -1
  498. package/src/ui/components/FollowButton.tsx +1 -1
  499. package/src/ui/components/OxyAccountDialogScreen.tsx +13 -1
  500. package/src/ui/components/OxyAuthChooser.tsx +31 -20
  501. package/src/ui/components/OxyProvider.tsx +8 -7
  502. package/src/ui/components/OxySignInButton.tsx +2 -1
  503. package/src/ui/components/ProfileButton.tsx +15 -20
  504. package/src/ui/components/authChooser/AccountsMenuView.tsx +66 -57
  505. package/src/ui/components/authChooser/types.ts +6 -0
  506. package/src/ui/components/authChooser/useUsernameAvailability.ts +1 -1
  507. package/src/ui/components/fileManagement/UploadPreview.tsx +1 -1
  508. package/src/ui/components/internal/PinInput.tsx +1 -0
  509. package/src/ui/components/logo/LogoText.tsx +4 -4
  510. package/src/ui/components/payment/PaymentDetailsStep.tsx +1 -1
  511. package/src/ui/components/payment/PaymentSummaryStep.tsx +2 -2
  512. package/src/ui/components/payment/types.ts +24 -24
  513. package/src/ui/components/styles/shadow.tsx +2 -2
  514. package/src/ui/context/OxyContext.tsx +35 -46
  515. package/src/ui/context/__tests__/commitSessionFlow.test.ts +13 -89
  516. package/src/ui/context/commitSessionFlow.ts +3 -61
  517. package/src/ui/context/hooks/useAuthOperations.ts +26 -1
  518. package/src/ui/context/oxyContextTypes.ts +26 -7
  519. package/src/ui/context/useOxyAccountGraph.ts +4 -4
  520. package/src/ui/hooks/mutations/mutationFactory.ts +1 -1
  521. package/src/ui/hooks/mutations/useAccountMutations.ts +1 -1
  522. package/src/ui/hooks/mutations/useServicesMutations.ts +1 -1
  523. package/src/ui/hooks/queries/paymentTypes.ts +3 -2
  524. package/src/ui/hooks/queries/usePaymentQueries.ts +3 -2
  525. package/src/ui/hooks/queries/userCache.ts +169 -148
  526. package/src/ui/hooks/useAssets.ts +1 -1
  527. package/src/ui/hooks/useAsyncAction.ts +3 -3
  528. package/src/ui/hooks/useAuth.ts +12 -6
  529. package/src/ui/hooks/useAvatarPicker.ts +1 -1
  530. package/src/ui/hooks/useOnlineStatus.ts +3 -2
  531. package/src/ui/hooks/useSessionManagement.ts +0 -2
  532. package/src/ui/hooks/useSettingToggle.ts +1 -1
  533. package/src/ui/hooks/useSurfaceHeader.ts +90 -15
  534. package/src/ui/navigation/accountDialogManager.ts +9 -0
  535. package/src/ui/oauth/__tests__/oauthPopup.test.ts +26 -0
  536. package/src/ui/oauth/browserAuthTransport.ts +55 -49
  537. package/src/ui/oauth/oauthPopup.ts +61 -3
  538. package/src/ui/screens/AccountMembersScreen.tsx +1 -1
  539. package/src/ui/screens/AccountSettingsScreen.tsx +45 -17
  540. package/src/ui/screens/AccountVerificationScreen.tsx +1 -1
  541. package/src/ui/screens/AppInfoScreen.tsx +1 -1
  542. package/src/ui/screens/AvatarCropScreen.tsx +1 -1
  543. package/src/ui/screens/ChangeAvatarScreen.tsx +7 -4
  544. package/src/ui/screens/ConnectedAppsScreen.tsx +2 -2
  545. package/src/ui/screens/CreateAccountScreen.tsx +55 -15
  546. package/src/ui/screens/EditProfileFieldScreen.tsx +4 -4
  547. package/src/ui/screens/EditProfileScreen.tsx +6 -3
  548. package/src/ui/screens/FAQScreen.tsx +1 -1
  549. package/src/ui/screens/FeedbackScreen.tsx +741 -575
  550. package/src/ui/screens/FileManagementScreen.tsx +1 -1
  551. package/src/ui/screens/FollowersListScreen.tsx +3 -0
  552. package/src/ui/screens/FollowingListScreen.tsx +3 -0
  553. package/src/ui/screens/HelpSupportScreen.tsx +1 -1
  554. package/src/ui/screens/HistoryViewScreen.tsx +5 -20
  555. package/src/ui/screens/LanguageSelectorScreen.tsx +1 -1
  556. package/src/ui/screens/LegalDocumentsScreen.tsx +1 -1
  557. package/src/ui/screens/ManageAccountScreen.tsx +9 -2
  558. package/src/ui/screens/PremiumSubscriptionScreen.tsx +4 -4
  559. package/src/ui/screens/PrivacySettingsScreen.tsx +15 -12
  560. package/src/ui/screens/ProfileScreen.tsx +24 -6
  561. package/src/ui/screens/SavesCollectionsScreen.tsx +1 -1
  562. package/src/ui/screens/UserListScreen.tsx +18 -8
  563. package/src/ui/screens/WelcomeNewUserScreen.tsx +6 -6
  564. package/src/ui/screens/fileManagement/PhotoPickerSection.tsx +1 -1
  565. package/src/ui/screens/fileManagement/hooks/useFileUploadState.ts +14 -5
  566. package/src/ui/screens/trust/TrustCenterScreen.tsx +2 -2
  567. package/src/ui/screens/trust/TrustLeaderboardScreen.tsx +6 -5
  568. package/src/ui/screens/trust/TrustRewardsScreen.tsx +1 -1
  569. package/src/ui/screens/trust/TrustRulesScreen.tsx +1 -1
  570. package/src/ui/screens/trust/trustTier.ts +1 -1
  571. package/src/ui/session/__tests__/backgroundSession.test.ts +392 -0
  572. package/src/ui/session/backgroundSession.ts +313 -0
  573. package/src/ui/session/index.ts +1 -0
  574. package/src/ui/session/useBackgroundSessionSync.ts +92 -0
  575. package/src/ui/types/navigation.ts +27 -19
  576. package/src/ui/utils/fileManagement.ts +108 -92
  577. package/src/ui/utils/netConnectivity.ts +27 -0
  578. package/src/ui/utils/oauthReturn.ts +23 -33
  579. package/src/ui/utils/userUtils.ts +27 -32
  580. package/lib/commonjs/ui/oauth/legacyRedirectLanes.js +0 -48
  581. package/lib/commonjs/ui/oauth/legacyRedirectLanes.js.map +0 -1
  582. package/lib/commonjs/ui/utils/crossOriginRestore.js +0 -140
  583. package/lib/commonjs/ui/utils/crossOriginRestore.js.map +0 -1
  584. package/lib/module/ui/oauth/legacyRedirectLanes.js +0 -44
  585. package/lib/module/ui/oauth/legacyRedirectLanes.js.map +0 -1
  586. package/lib/module/ui/utils/crossOriginRestore.js +0 -131
  587. package/lib/module/ui/utils/crossOriginRestore.js.map +0 -1
  588. package/lib/typescript/commonjs/ui/oauth/legacyRedirectLanes.d.ts +0 -40
  589. package/lib/typescript/commonjs/ui/oauth/legacyRedirectLanes.d.ts.map +0 -1
  590. package/lib/typescript/commonjs/ui/utils/crossOriginRestore.d.ts +0 -43
  591. package/lib/typescript/commonjs/ui/utils/crossOriginRestore.d.ts.map +0 -1
  592. package/lib/typescript/module/ui/oauth/legacyRedirectLanes.d.ts +0 -40
  593. package/lib/typescript/module/ui/oauth/legacyRedirectLanes.d.ts.map +0 -1
  594. package/lib/typescript/module/ui/utils/crossOriginRestore.d.ts +0 -43
  595. package/lib/typescript/module/ui/utils/crossOriginRestore.d.ts.map +0 -1
  596. package/src/ui/boot/__tests__/coldBootWebAuthMode.test.ts +0 -281
  597. package/src/ui/oauth/legacyRedirectLanes.ts +0 -43
  598. package/src/ui/utils/__tests__/crossOriginRestore.test.ts +0 -143
  599. package/src/ui/utils/crossOriginRestore.ts +0 -169
@@ -10,8 +10,13 @@ import type { DialogHeaderConfig } from '@oxyhq/bloom/dialog';
10
10
  * design-system fields Bloom's nav header supports: the single trailing
11
11
  * `primaryAction` CTA (Upload / Save), a trailing icon `actions` row, a header
12
12
  * `search` / `segments` in the large-title zone, an `onImage` `tone` over media,
13
- * and a wizard `progress` bar. Object/slot fields MUST be referentially stable
14
- * (memoize them with `useMemo`) so the header does not thrash.
13
+ * and a wizard `progress` bar.
14
+ *
15
+ * Only the NODE fields (`left`/`right`/`titleContent`, and an action's `icon`)
16
+ * must be referentially stable — a node can only be compared by identity, so an
17
+ * inline one thrashes the header. The rich OBJECT fields are compared by value
18
+ * (see {@link surfaceHeaderContentEqual}), so an inline `primaryAction` /
19
+ * `actions` / `search` / `segments` / `progress` is safe to pass.
15
20
  */
16
21
  export type SurfaceHeaderContent = Pick<
17
22
  DialogHeaderConfig,
@@ -42,16 +47,86 @@ interface SurfaceHeaderContextValue {
42
47
  */
43
48
  export const SurfaceHeaderContext = createContext<SurfaceHeaderContextValue | null>(null);
44
49
 
50
+ type HeaderPrimaryAction = NonNullable<SurfaceHeaderContent['primaryAction']>;
51
+ type HeaderAction = NonNullable<SurfaceHeaderContent['actions']>[number];
52
+ type HeaderSearch = NonNullable<SurfaceHeaderContent['search']>;
53
+ type HeaderSegments = NonNullable<SurfaceHeaderContent['segments']>;
54
+ type HeaderProgress = NonNullable<SurfaceHeaderContent['progress']>;
55
+
56
+ function primaryActionEqual(
57
+ a: HeaderPrimaryAction | undefined,
58
+ b: HeaderPrimaryAction | undefined,
59
+ ): boolean {
60
+ if (a === b) return true;
61
+ if (!a || !b) return false;
62
+ // `onPress` is a fresh closure each render — its identity never changes what
63
+ // the button renders, so compare only the render-affecting scalars.
64
+ return a.label === b.label && !!a.disabled === !!b.disabled && !!a.loading === !!b.loading;
65
+ }
66
+
67
+ function actionsEqual(a: HeaderAction[] | undefined, b: HeaderAction[] | undefined): boolean {
68
+ if (a === b) return true;
69
+ if (!a || !b || a.length !== b.length) return false;
70
+ for (let i = 0; i < a.length; i += 1) {
71
+ const x = a[i];
72
+ const y = b[i];
73
+ if (!x || !y) return false;
74
+ // `icon` is a node (identity); `onPress` is ignored, like `primaryAction`'s.
75
+ if (
76
+ x.accessibilityLabel !== y.accessibilityLabel ||
77
+ !!x.disabled !== !!y.disabled ||
78
+ x.icon !== y.icon
79
+ ) {
80
+ return false;
81
+ }
82
+ }
83
+ return true;
84
+ }
85
+
86
+ function searchEqual(a: HeaderSearch | undefined, b: HeaderSearch | undefined): boolean {
87
+ if (a === b) return true;
88
+ if (!a || !b) return false;
89
+ return a.value === b.value && a.placeholder === b.placeholder;
90
+ }
91
+
92
+ function segmentsEqual(a: HeaderSegments | undefined, b: HeaderSegments | undefined): boolean {
93
+ if (a === b) return true;
94
+ if (!a || !b || a.value !== b.value || a.items.length !== b.items.length) return false;
95
+ for (let i = 0; i < a.items.length; i += 1) {
96
+ const x = a.items[i];
97
+ const y = b.items[i];
98
+ if (!x || !y || x.key !== y.key || x.label !== y.label) return false;
99
+ }
100
+ return true;
101
+ }
102
+
103
+ function progressEqual(a: HeaderProgress | undefined, b: HeaderProgress | undefined): boolean {
104
+ if (a === b) return true;
105
+ if (!a || !b) return false;
106
+ return a.step === b.step && a.total === b.total;
107
+ }
108
+
45
109
  /**
46
- * Shallow value-equality for a surface's header contribution.
110
+ * Value-equality for a surface's header contribution.
111
+ *
112
+ * This MIRRORS Bloom's own `configsEqual` (`@oxyhq/bloom/dialog`), which guards
113
+ * the header store one layer down — deliberately field for field. The two must
114
+ * not diverge: this comparator is the gate that decides whether the host's
115
+ * `setContent` fires, so a comparator STRICTER than Bloom's re-introduces the
116
+ * update loop Bloom's own guard was written to prevent.
117
+ *
118
+ * Scalars (`title`/`subtitle`/`largeTitle`/`tone`) compare by value. The rich
119
+ * object fields (`primaryAction`/`actions`/`search`/`segments`/`progress`)
120
+ * compare by their render-affecting scalars, so a screen may build them inline:
121
+ * a fresh object with unchanged contents is NOT a change. Only the node fields
122
+ * (`titleContent`/`left`/`right`, and an action's `icon`) compare by identity —
123
+ * there is nothing else to compare a `ReactNode` by — so those, and only those,
124
+ * carry the memoize-me contract.
47
125
  *
48
- * Scalars (`title`/`subtitle`/`largeTitle`/`tone`) compare by value; the object
49
- * and node fields (`titleContent`/`left`/`right`/`primaryAction`/`actions`/
50
- * `search`/`segments`/`progress`) compare by identity callers memoize them, per
51
- * this hook's contract. Function-typed affordances compare by PRESENCE, never
52
- * identity: `onBack` legitimately gets a fresh closure each render, and its
53
- * identity never changes what the header renders, so it must not count as a
54
- * change (that is exactly what would drive the update loop).
126
+ * Function-typed affordances compare by PRESENCE, never identity: `onBack`
127
+ * legitimately gets a fresh closure each render and its identity never changes
128
+ * what the header renders, so it must not count as a change (that is exactly
129
+ * what would drive the update loop).
55
130
  */
56
131
  function surfaceHeaderContentEqual(
57
132
  a: SurfaceHeaderContent | null,
@@ -67,12 +142,12 @@ function surfaceHeaderContentEqual(
67
142
  a.left === b.left &&
68
143
  a.right === b.right &&
69
144
  !!a.onBack === !!b.onBack &&
70
- a.primaryAction === b.primaryAction &&
71
- a.actions === b.actions &&
72
- a.search === b.search &&
73
- a.segments === b.segments &&
74
145
  a.tone === b.tone &&
75
- a.progress === b.progress
146
+ primaryActionEqual(a.primaryAction, b.primaryAction) &&
147
+ actionsEqual(a.actions, b.actions) &&
148
+ searchEqual(a.search, b.search) &&
149
+ segmentsEqual(a.segments, b.segments) &&
150
+ progressEqual(a.progress, b.progress)
76
151
  );
77
152
  }
78
153
 
@@ -12,6 +12,14 @@
12
12
 
13
13
  import type { AccountDialogView } from '@oxyhq/core';
14
14
 
15
+ /** An app-owned action rendered inside the shared account menu. */
16
+ export interface AccountDialogMenuItem {
17
+ key: string;
18
+ label: string;
19
+ icon?: string;
20
+ onPress: () => void;
21
+ }
22
+
15
23
  /**
16
24
  * Live open/close handles registered by the mounted provider. `open` presents
17
25
  * the `AccountDialog` surface (and points its view); `close` dismisses it. Both
@@ -31,6 +39,7 @@ export interface AccountDialogConsumerHooks {
31
39
  onNavigateManage?: () => void;
32
40
  onAddAccount?: () => void;
33
41
  onNavigateProfile?: () => void;
42
+ menuItems?: readonly AccountDialogMenuItem[];
34
43
  }
35
44
 
36
45
  let controls: AccountDialogControls | null = null;
@@ -9,6 +9,7 @@ import { OXY_OAUTH_CODE_MESSAGE_TYPE, OXY_OAUTH_ERROR_MESSAGE_TYPE } from '../oa
9
9
  import type { OAuthPopupHandle, OAuthPopupOutcome } from '../types';
10
10
 
11
11
  const IDP_ORIGIN = 'https://auth.oxy.so';
12
+ const REDIRECT_URI = 'https://mention.earth';
12
13
  const STATE = 'state-abc';
13
14
 
14
15
  interface ControllablePopup extends OAuthPopupHandle {
@@ -161,6 +162,7 @@ describe('awaitOAuthPopupResult', () => {
161
162
  popup,
162
163
  expectedOrigin: IDP_ORIGIN,
163
164
  expectedState: STATE,
165
+ redirectUri: REDIRECT_URI,
164
166
  });
165
167
 
166
168
  dispatchMessage(codeMessage(popup));
@@ -175,6 +177,7 @@ describe('awaitOAuthPopupResult', () => {
175
177
  popup,
176
178
  expectedOrigin: IDP_ORIGIN,
177
179
  expectedState: STATE,
180
+ redirectUri: REDIRECT_URI,
178
181
  });
179
182
 
180
183
  dispatchMessage({
@@ -202,6 +205,7 @@ describe('awaitOAuthPopupResult', () => {
202
205
  popup,
203
206
  expectedOrigin: IDP_ORIGIN,
204
207
  expectedState: STATE,
208
+ redirectUri: REDIRECT_URI,
205
209
  });
206
210
 
207
211
  dispatchMessage(codeMessage(popup, 'a-different-state'));
@@ -219,6 +223,7 @@ describe('awaitOAuthPopupResult', () => {
219
223
  popup,
220
224
  expectedOrigin: IDP_ORIGIN,
221
225
  expectedState: STATE,
226
+ redirectUri: REDIRECT_URI,
222
227
  timeoutMs: 60_000,
223
228
  });
224
229
 
@@ -237,6 +242,7 @@ describe('awaitOAuthPopupResult', () => {
237
242
  popup,
238
243
  expectedOrigin: IDP_ORIGIN,
239
244
  expectedState: STATE,
245
+ redirectUri: REDIRECT_URI,
240
246
  timeoutMs: 60_000,
241
247
  });
242
248
 
@@ -254,6 +260,7 @@ describe('awaitOAuthPopupResult', () => {
254
260
  popup,
255
261
  expectedOrigin: IDP_ORIGIN,
256
262
  expectedState: STATE,
263
+ redirectUri: REDIRECT_URI,
257
264
  });
258
265
 
259
266
  dispatchMessage(codeMessage(popup));
@@ -277,6 +284,7 @@ describe('awaitOAuthPopupResult', () => {
277
284
  popup,
278
285
  expectedOrigin: IDP_ORIGIN,
279
286
  expectedState: STATE,
287
+ redirectUri: REDIRECT_URI,
280
288
  });
281
289
 
282
290
  popup.setClosed();
@@ -295,6 +303,7 @@ describe('awaitOAuthPopupResult', () => {
295
303
  popup,
296
304
  expectedOrigin: IDP_ORIGIN,
297
305
  expectedState: STATE,
306
+ redirectUri: REDIRECT_URI,
298
307
  });
299
308
 
300
309
  // The IdP posts its result and immediately closes itself.
@@ -313,6 +322,7 @@ describe('awaitOAuthPopupResult', () => {
313
322
  popup,
314
323
  expectedOrigin: IDP_ORIGIN,
315
324
  expectedState: STATE,
325
+ redirectUri: REDIRECT_URI,
316
326
  timeoutMs: 30_000,
317
327
  });
318
328
 
@@ -323,4 +333,20 @@ describe('awaitOAuthPopupResult', () => {
323
333
  await expect(promise).resolves.toEqual({ kind: 'timed-out' });
324
334
  expectFullCleanup();
325
335
  });
336
+
337
+ it('reads a same-origin redirect fallback from the popup URL when postMessage is unavailable', async () => {
338
+ const popup = fakePopup();
339
+ popup.location.href = `${REDIRECT_URI}?code=auth-code&state=${STATE}`;
340
+ const promise = awaitOAuthPopupResult({
341
+ popup,
342
+ expectedOrigin: IDP_ORIGIN,
343
+ expectedState: STATE,
344
+ redirectUri: REDIRECT_URI,
345
+ });
346
+
347
+ jest.advanceTimersByTime(1000);
348
+
349
+ await expect(promise).resolves.toEqual({ kind: 'code', code: 'auth-code', state: STATE });
350
+ expectFullCleanup();
351
+ });
326
352
  });
@@ -102,58 +102,60 @@ export async function startWebOAuthSignIn(
102
102
  return startRedirectSignIn(context, options, 'popup-blocked');
103
103
  }
104
104
 
105
- const prepared = await prepareAuthorizeRequest({
106
- clientId: context.clientId,
107
- redirectUri: options.redirectUri,
108
- authorizeBaseUrl: context.authorizeBaseUrl,
109
- scope: options.scope,
110
- responseMode: 'web_message',
111
- });
105
+ try {
106
+ const prepared = await prepareAuthorizeRequest({
107
+ clientId: context.clientId,
108
+ redirectUri: options.redirectUri,
109
+ authorizeBaseUrl: context.authorizeBaseUrl,
110
+ scope: options.scope,
111
+ responseMode: 'web_message',
112
+ });
112
113
 
113
- if (!navigateOAuthPopup(popup, prepared.authorizeUrl)) {
114
- closeOAuthPopup(popup);
115
- return startRedirectSignIn(context, options, 'popup-navigation-failed');
116
- }
114
+ if (!navigateOAuthPopup(popup, prepared.authorizeUrl)) {
115
+ return startRedirectSignIn(context, options, 'popup-navigation-failed');
116
+ }
117
117
 
118
- const outcome = await awaitOAuthPopupResult({
119
- popup,
120
- expectedOrigin: prepared.authorizeOrigin,
121
- expectedState: prepared.handshake.state,
122
- ...(options.timeoutMs !== undefined ? { timeoutMs: options.timeoutMs } : {}),
123
- });
124
- // The IdP closes itself after delivering; this covers every other outcome
125
- // (timeout, mismatch, an error the IdP reported before closing).
126
- closeOAuthPopup(popup);
118
+ const outcome = await awaitOAuthPopupResult({
119
+ popup,
120
+ expectedOrigin: prepared.authorizeOrigin,
121
+ expectedState: prepared.handshake.state,
122
+ redirectUri: options.redirectUri,
123
+ ...(options.timeoutMs !== undefined ? { timeoutMs: options.timeoutMs } : {}),
124
+ });
127
125
 
128
- switch (outcome.kind) {
129
- case 'code': {
130
- const completion = await completeOAuthCode({
131
- oxyServices: context.oxyServices,
132
- clientId: context.clientId,
133
- code: outcome.code,
134
- returnedState: outcome.state,
135
- handshake: prepared.handshake,
136
- redirectUri: options.redirectUri,
137
- commitSession: context.commitSession,
138
- });
139
- return completion.ok
140
- ? { status: 'signed-in' }
141
- : { status: 'failed', reason: completion.reason };
126
+ switch (outcome.kind) {
127
+ case 'code': {
128
+ const completion = await completeOAuthCode({
129
+ oxyServices: context.oxyServices,
130
+ clientId: context.clientId,
131
+ code: outcome.code,
132
+ returnedState: outcome.state,
133
+ handshake: prepared.handshake,
134
+ redirectUri: options.redirectUri,
135
+ commitSession: context.commitSession,
136
+ });
137
+ return completion.ok
138
+ ? { status: 'signed-in' }
139
+ : { status: 'failed', reason: completion.reason };
140
+ }
141
+ case 'oauth-error':
142
+ return {
143
+ status: 'failed',
144
+ reason: 'idp-error',
145
+ description: outcome.errorDescription ?? outcome.error,
146
+ };
147
+ case 'state-mismatch':
148
+ return { status: 'failed', reason: 'state-mismatch' };
149
+ case 'closed':
150
+ return { status: 'cancelled' };
151
+ case 'timed-out':
152
+ return { status: 'timed-out' };
153
+ case 'unsupported':
154
+ return { status: 'unsupported', reason: 'no-browser' };
142
155
  }
143
- case 'oauth-error':
144
- return {
145
- status: 'failed',
146
- reason: 'idp-error',
147
- description: outcome.errorDescription ?? outcome.error,
148
- };
149
- case 'state-mismatch':
150
- return { status: 'failed', reason: 'state-mismatch' };
151
- case 'closed':
152
- return { status: 'cancelled' };
153
- case 'timed-out':
154
- return { status: 'timed-out' };
155
- case 'unsupported':
156
- return { status: 'unsupported', reason: 'no-browser' };
156
+ } finally {
157
+ // Covers throws after open (prepare/exchange/commit) and every settled outcome.
158
+ closeOAuthPopup(popup);
157
159
  }
158
160
  }
159
161
 
@@ -178,7 +180,11 @@ async function startRedirectSignIn(
178
180
  scope: options.scope,
179
181
  });
180
182
 
181
- if (!persistOAuthHandshake(prepared.handshake.state, prepared.handshake.codeVerifier)) {
183
+ if (!persistOAuthHandshake(
184
+ prepared.handshake.state,
185
+ prepared.handshake.codeVerifier,
186
+ options.redirectUri,
187
+ )) {
182
188
  return { status: 'failed', reason: 'handshake-storage' };
183
189
  }
184
190
 
@@ -19,7 +19,7 @@
19
19
  * opaque. The authorization result arrives ONLY as a `postMessage`.
20
20
  */
21
21
 
22
- import { logger } from '@oxyhq/core';
22
+ import { canonicalizeOAuthRedirectUri, logger } from '@oxyhq/core';
23
23
  import { readOAuthPopupMessage } from './oauthPopupMessages';
24
24
  import type { OAuthPopupHandle, OAuthPopupOutcome } from './types';
25
25
 
@@ -119,6 +119,47 @@ export function closeOAuthPopup(popup: OAuthPopupHandle | null): void {
119
119
  }
120
120
  }
121
121
 
122
+ /**
123
+ * When the IdP falls back to a top-level redirect inside the popup (no usable
124
+ * `window.opener`), a same-origin `redirect_uri` is readable from the opener.
125
+ * Cross-origin redirects remain opaque and are not handled here.
126
+ */
127
+ function readSameOriginRedirectOutcome(
128
+ popup: OAuthPopupHandle,
129
+ redirectUri: string,
130
+ expectedState: string,
131
+ ): OAuthPopupOutcome | null {
132
+ try {
133
+ const href = popup.location.href;
134
+ if (!href) return null;
135
+
136
+ const popupUrl = new URL(href);
137
+ const expected = new URL(canonicalizeOAuthRedirectUri(redirectUri));
138
+ if (popupUrl.origin !== expected.origin) return null;
139
+ if (popupUrl.pathname !== expected.pathname) return null;
140
+
141
+ const oauthError = popupUrl.searchParams.get('error');
142
+ if (oauthError) {
143
+ const errorDescription = popupUrl.searchParams.get('error_description') ?? undefined;
144
+ return {
145
+ kind: 'oauth-error',
146
+ error: oauthError,
147
+ ...(errorDescription ? { errorDescription } : {}),
148
+ };
149
+ }
150
+
151
+ const code = popupUrl.searchParams.get('code');
152
+ if (!code) return null;
153
+
154
+ const state = popupUrl.searchParams.get('state');
155
+ if (!state || state !== expectedState) return { kind: 'state-mismatch' };
156
+ return { kind: 'code', code, state };
157
+ } catch {
158
+ // Cross-origin navigation — the popup URL is opaque to the opener.
159
+ return null;
160
+ }
161
+ }
162
+
122
163
  /** Inputs for {@link awaitOAuthPopupResult}. */
123
164
  export interface AwaitOAuthPopupOptions {
124
165
  /** The exact window reference returned by {@link openOAuthPopup}. */
@@ -127,6 +168,12 @@ export interface AwaitOAuthPopupOptions {
127
168
  expectedOrigin: string;
128
169
  /** The CSRF `state` sent on the authorize request. */
129
170
  expectedState: string;
171
+ /**
172
+ * EXACT registered redirect URI for this attempt. When the IdP cannot
173
+ * `postMessage` (no usable opener) it falls back to redirecting the popup;
174
+ * if that lands on the same origin, the result is read from the popup URL.
175
+ */
176
+ redirectUri: string;
130
177
  /** @default DEFAULT_OAUTH_POPUP_TIMEOUT_MS */
131
178
  timeoutMs?: number;
132
179
  }
@@ -145,8 +192,13 @@ export interface AwaitOAuthPopupOptions {
145
192
  export function awaitOAuthPopupResult(
146
193
  options: AwaitOAuthPopupOptions,
147
194
  ): Promise<OAuthPopupOutcome> {
148
- const { popup, expectedOrigin, expectedState, timeoutMs = DEFAULT_OAUTH_POPUP_TIMEOUT_MS } =
149
- options;
195
+ const {
196
+ popup,
197
+ expectedOrigin,
198
+ expectedState,
199
+ redirectUri,
200
+ timeoutMs = DEFAULT_OAUTH_POPUP_TIMEOUT_MS,
201
+ } = options;
150
202
 
151
203
  const host = messageEventHost();
152
204
  if (!host) return Promise.resolve({ kind: 'unsupported' });
@@ -206,6 +258,12 @@ export function awaitOAuthPopupResult(
206
258
  timeoutTimer = setTimeout(() => settle({ kind: 'timed-out' }), timeoutMs);
207
259
 
208
260
  closePoll = setInterval(() => {
261
+ const redirectOutcome = readSameOriginRedirectOutcome(popup, redirectUri, expectedState);
262
+ if (redirectOutcome) {
263
+ settle(redirectOutcome);
264
+ return;
265
+ }
266
+
209
267
  if (!popup.closed) return;
210
268
  // Stop sampling immediately: the window is gone and only the in-flight
211
269
  // message (if any) can still change the outcome.
@@ -7,7 +7,7 @@ import {
7
7
  } from 'react-native';
8
8
  import Ionicons from '@expo/vector-icons/Ionicons';
9
9
  import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
10
- import { toast } from '@oxyhq/bloom';
10
+ import { toast } from '@oxyhq/bloom/toast';
11
11
  import { surfaces } from '@oxyhq/bloom/surfaces';
12
12
  import { useTheme } from '@oxyhq/bloom/theme';
13
13
  import { Text } from '@oxyhq/bloom/typography';
@@ -5,21 +5,21 @@ import {
5
5
  ActivityIndicator,
6
6
  } from 'react-native';
7
7
  import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
8
- import { toast } from '@oxyhq/bloom';
8
+ import { toast } from '@oxyhq/bloom/toast';
9
9
  import { surfaces } from '@oxyhq/bloom/surfaces';
10
10
  import { useTheme } from '@oxyhq/bloom/theme';
11
11
  import { Text } from '@oxyhq/bloom/typography';
12
12
  import { Button } from '@oxyhq/bloom/button';
13
13
  import { TextField, TextFieldInput } from '@oxyhq/bloom/text-field';
14
14
  import { SettingsListGroup, SettingsListItem } from '@oxyhq/bloom/settings-list';
15
- import type { UpdateAccountInput } from '@oxyhq/core';
15
+ import { DISPLAY_NAME_INVALID_MESSAGE, getNormalizedUserHandle, isValidDisplayName, MAX_DISPLAY_NAME_LENGTH, type UpdateAccountInput } from '@oxyhq/core';
16
16
  import type { BaseScreenProps } from '../types/navigation';
17
17
  import { SettingsIcon } from '../components/SettingsIcon';
18
18
  import { useOxy } from '../context/OxyContext';
19
19
  import { useI18n } from '../hooks/useI18n';
20
20
  import { useSurfaceHeader } from '../hooks/useSurfaceHeader';
21
21
 
22
- const DISPLAY_NAME_MAX = 50;
22
+ const DISPLAY_NAME_MAX = MAX_DISPLAY_NAME_LENGTH;
23
23
  const BIO_MAX = 160;
24
24
 
25
25
  const errorMessage = (error: unknown, fallback: string): string =>
@@ -62,14 +62,15 @@ const AccountSettingsScreen: React.FC<BaseScreenProps> = ({ onClose, goBack, nav
62
62
  // Editable fields, seeded lazily from the loaded account once.
63
63
  const [seeded, setSeeded] = useState(false);
64
64
  const [displayName, setDisplayName] = useState('');
65
+ const [displayNameError, setDisplayNameError] = useState('');
65
66
  const [bio, setBio] = useState('');
66
67
 
67
68
  // Seed the form from the account during render (no useEffect): the first time
68
69
  // the query resolves we capture its values into local edit state.
69
70
  if (node && !seeded) {
70
- const first = node.account?.name?.first ?? '';
71
- const last = node.account?.name?.last ?? '';
72
- setDisplayName([first, last].filter(Boolean).join(' '));
71
+ setDisplayName(
72
+ node.account?.name?.displayName ?? getNormalizedUserHandle(node.account) ?? '',
73
+ );
73
74
  setBio(node.account?.bio ?? '');
74
75
  setSeeded(true);
75
76
  }
@@ -121,8 +122,27 @@ const AccountSettingsScreen: React.FC<BaseScreenProps> = ({ onClose, goBack, nav
121
122
  if (confirmed) archiveMutation.mutate();
122
123
  }, [archiveMutation, t]);
123
124
 
125
+ const handleDisplayNameChange = useCallback((value: string) => {
126
+ setDisplayName(value);
127
+ const trimmed = value.trim();
128
+ if (!trimmed) {
129
+ setDisplayNameError('');
130
+ return;
131
+ }
132
+ const nameParts = trimmed.split(/\s+/).filter(Boolean);
133
+ const first = nameParts[0] || '';
134
+ const last = nameParts.length > 1 ? nameParts.slice(1).join(' ') : '';
135
+ const invalidPart = [first, last].find((part) => part && !isValidDisplayName(part));
136
+ setDisplayNameError(
137
+ invalidPart
138
+ ? (t('accounts.settings.displayName.invalidChars') || DISPLAY_NAME_INVALID_MESSAGE)
139
+ : '',
140
+ );
141
+ }, [t]);
142
+
124
143
  const handleSave = useCallback(() => {
125
144
  const trimmed = displayName.trim();
145
+ if (!trimmed || displayNameError) return;
126
146
  const nameParts = trimmed.split(/\s+/).filter(Boolean);
127
147
  const first = nameParts[0] || '';
128
148
  const last = nameParts.length > 1 ? nameParts.slice(1).join(' ') : undefined;
@@ -130,7 +150,7 @@ const AccountSettingsScreen: React.FC<BaseScreenProps> = ({ onClose, goBack, nav
130
150
  name: { first, last },
131
151
  bio: bio.trim() ? bio.trim() : null,
132
152
  });
133
- }, [displayName, bio, updateMutation]);
153
+ }, [displayName, displayNameError, bio, updateMutation]);
134
154
 
135
155
  const title = t('accounts.settings.title') || 'Account settings';
136
156
 
@@ -171,15 +191,23 @@ const AccountSettingsScreen: React.FC<BaseScreenProps> = ({ onClose, goBack, nav
171
191
  {/* Profile edit */}
172
192
  {canUpdate ? (
173
193
  <View className="gap-space-16 p-space-16 rounded-radius-20 bg-fill">
174
- <TextField>
175
- <TextFieldInput
176
- floatingLabel
177
- label={t('accounts.settings.displayName.label') || 'Display name'}
178
- value={displayName}
179
- onChangeText={setDisplayName}
180
- maxLength={DISPLAY_NAME_MAX}
181
- />
182
- </TextField>
194
+ <View className="gap-space-4">
195
+ <TextField isInvalid={Boolean(displayNameError)}>
196
+ <TextFieldInput
197
+ floatingLabel
198
+ label={t('accounts.settings.displayName.label') || 'Display name'}
199
+ value={displayName}
200
+ onChangeText={handleDisplayNameChange}
201
+ isInvalid={Boolean(displayNameError)}
202
+ maxLength={DISPLAY_NAME_MAX}
203
+ />
204
+ </TextField>
205
+ {displayNameError ? (
206
+ <Text className="text-caption font-caption text-negative px-space-4">
207
+ {displayNameError}
208
+ </Text>
209
+ ) : null}
210
+ </View>
183
211
  <View className="gap-space-4">
184
212
  <TextField>
185
213
  <TextFieldInput
@@ -200,7 +228,7 @@ const AccountSettingsScreen: React.FC<BaseScreenProps> = ({ onClose, goBack, nav
200
228
  <Button
201
229
  variant="primary"
202
230
  onPress={handleSave}
203
- disabled={updateMutation.isPending || !displayName.trim()}
231
+ disabled={updateMutation.isPending || !displayName.trim() || Boolean(displayNameError)}
204
232
  loading={updateMutation.isPending}
205
233
  accessibilityLabel={t('accounts.settings.save') || 'Save changes'}
206
234
  className="w-full"
@@ -4,7 +4,7 @@ import {
4
4
  StyleSheet,
5
5
  } from 'react-native';
6
6
  import type { BaseScreenProps } from '../types/navigation';
7
- import { toast } from '@oxyhq/bloom';
7
+ import { toast } from '@oxyhq/bloom/toast';
8
8
  import { surfaces } from '@oxyhq/bloom/surfaces';
9
9
  import { useTheme } from '@oxyhq/bloom/theme';
10
10
  import { H4, Text } from '@oxyhq/bloom/typography';
@@ -9,7 +9,7 @@ import {
9
9
  } from 'react-native';
10
10
  import type { BaseScreenProps } from '../types/navigation';
11
11
  import { packageInfo } from '@oxyhq/core';
12
- import { toast } from '@oxyhq/bloom';
12
+ import { toast } from '@oxyhq/bloom/toast';
13
13
  import OxyServicesLogo from '../../assets/icons/OxyServices';
14
14
  import { SettingsIcon } from '../components/SettingsIcon';
15
15
  import { useTheme } from '@oxyhq/bloom/theme';
@@ -55,7 +55,7 @@ import { useOxy } from '../context/OxyContext';
55
55
  import { useI18n } from '../hooks/useI18n';
56
56
  import { useReduceMotion } from '../hooks/useReduceMotion';
57
57
  import { useSurfaceHeader, type SurfaceHeaderContent } from '../hooks/useSurfaceHeader';
58
- import { toast } from '@oxyhq/bloom';
58
+ import { toast } from '@oxyhq/bloom/toast';
59
59
  import type { BaseScreenProps } from '../types/navigation';
60
60
 
61
61
  /** Component name used in `logger` context for filtered diagnostics. */
@@ -39,8 +39,8 @@ import {
39
39
  } from '@oxyhq/bloom/admonition';
40
40
  import { surfaces as bloomSurfaces } from '@oxyhq/bloom/surfaces';
41
41
  import { useTheme } from '@oxyhq/bloom/theme';
42
- import { toast } from '@oxyhq/bloom';
43
- import { getAccountDisplayName, logger } from '@oxyhq/core';
42
+ import { toast } from '@oxyhq/bloom/toast';
43
+ import { getNormalizedUserHandle, logger } from '@oxyhq/core';
44
44
  import type { FileMetadata } from '@oxyhq/core';
45
45
  import { useOxy } from '../context/OxyContext';
46
46
  import { useI18n } from '../hooks/useI18n';
@@ -133,7 +133,7 @@ async function loadImagePicker(): Promise<ImagePickerModule | null> {
133
133
 
134
134
  const ChangeAvatarScreen: React.FC<BaseScreenProps> = ({ navigate, dismiss }) => {
135
135
  const bloomTheme = useTheme();
136
- const { t, locale } = useI18n();
136
+ const { t } = useI18n();
137
137
  const { user, oxyServices } = useOxy();
138
138
 
139
139
  /** Set when a permission was refused — drives the inline denied notice. */
@@ -143,7 +143,10 @@ const ChangeAvatarScreen: React.FC<BaseScreenProps> = ({ navigate, dismiss }) =>
143
143
 
144
144
  useSurfaceHeader(useMemo(() => ({ title: t('changeAvatar.title') }), [t]));
145
145
 
146
- const displayName = useMemo(() => getAccountDisplayName(user, locale), [user, locale]);
146
+ const displayName = useMemo(
147
+ () => user?.name?.displayName ?? getNormalizedUserHandle(user) ?? '',
148
+ [user],
149
+ );
147
150
  const avatarUri = useMemo(
148
151
  // `thumb` is 256x256 — exactly a 2x source for the 132dp hero.
149
152
  () => (user?.avatar ? oxyServices.getFileDownloadUrl(user.avatar, 'thumb') : undefined),